1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 #define _IOCTL_LINUX_C_ 8 9 #include <linux/etherdevice.h> 10 #include <drv_types.h> 11 #include <rtw_debug.h> 12 #include <rtw_mp.h> 13 #include <hal_btcoex.h> 14 #include <linux/jiffies.h> 15 #include <linux/kernel.h> 16 17 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV+30) 18 19 #define SCAN_ITEM_SIZE 768 20 #define MAX_CUSTOM_LEN 64 21 #define RATE_COUNT 4 22 23 /* combo scan */ 24 #define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00" 25 #define WEXT_CSCAN_HEADER_SIZE 12 26 #define WEXT_CSCAN_SSID_SECTION 'S' 27 #define WEXT_CSCAN_CHANNEL_SECTION 'C' 28 #define WEXT_CSCAN_ACTV_DWELL_SECTION 'A' 29 #define WEXT_CSCAN_PASV_DWELL_SECTION 'P' 30 #define WEXT_CSCAN_HOME_DWELL_SECTION 'H' 31 #define WEXT_CSCAN_TYPE_SECTION 'T' 32 33 static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000, 34 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000}; 35 36 void indicate_wx_scan_complete_event(struct adapter *padapter) 37 { 38 union iwreq_data wrqu; 39 40 memset(&wrqu, 0, sizeof(union iwreq_data)); 41 } 42 43 44 void rtw_indicate_wx_assoc_event(struct adapter *padapter) 45 { 46 union iwreq_data wrqu; 47 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 48 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 49 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 50 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 51 52 memset(&wrqu, 0, sizeof(union iwreq_data)); 53 54 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 55 56 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) 57 memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN); 58 else 59 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN); 60 61 netdev_dbg(padapter->pnetdev, "assoc success\n"); 62 } 63 64 void rtw_indicate_wx_disassoc_event(struct adapter *padapter) 65 { 66 union iwreq_data wrqu; 67 68 memset(&wrqu, 0, sizeof(union iwreq_data)); 69 70 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 71 eth_zero_addr(wrqu.ap_addr.sa_data); 72 } 73 74 static char *translate_scan(struct adapter *padapter, 75 struct iw_request_info *info, struct wlan_network *pnetwork, 76 char *start, char *stop) 77 { 78 struct iw_event iwe; 79 u16 cap; 80 u32 ht_ielen = 0; 81 char *custom = NULL; 82 char *p; 83 u16 max_rate = 0, rate, ht_cap = false, vht_cap = false; 84 u32 i = 0; 85 u8 bw_40MHz = 0, short_GI = 0; 86 u16 mcs_rate = 0, vht_data_rate = 0; 87 u8 ie_offset = (pnetwork->network.Reserved[0] == 2 ? 0 : 12); 88 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 89 u8 ss, sq; 90 91 /* AP MAC address */ 92 iwe.cmd = SIOCGIWAP; 93 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 94 95 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN); 96 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); 97 98 /* Add the ESSID */ 99 iwe.cmd = SIOCGIWESSID; 100 iwe.u.data.flags = 1; 101 iwe.u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32); 102 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); 103 104 /* parsing HT_CAP_IE */ 105 if (pnetwork->network.Reserved[0] == 2) { /* Probe Request */ 106 p = rtw_get_ie(&pnetwork->network.IEs[0], WLAN_EID_HT_CAPABILITY, &ht_ielen, pnetwork->network.IELength); 107 } else { 108 p = rtw_get_ie(&pnetwork->network.IEs[12], WLAN_EID_HT_CAPABILITY, &ht_ielen, pnetwork->network.IELength-12); 109 } 110 if (p && ht_ielen > 0) { 111 struct ieee80211_ht_cap *pht_capie; 112 ht_cap = true; 113 pht_capie = (struct ieee80211_ht_cap *)(p+2); 114 memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2); 115 bw_40MHz = (le16_to_cpu(pht_capie->cap_info) & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0; 116 short_GI = (le16_to_cpu(pht_capie->cap_info) & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; 117 } 118 119 /* Add the protocol name */ 120 iwe.cmd = SIOCGIWNAME; 121 if (rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) { 122 if (ht_cap) 123 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn"); 124 else 125 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b"); 126 } else if (rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) { 127 if (ht_cap) 128 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn"); 129 else 130 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg"); 131 } else { 132 if (pnetwork->network.Configuration.DSConfig > 14) { 133 if (vht_cap) 134 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC"); 135 else if (ht_cap) 136 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an"); 137 else 138 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a"); 139 } else { 140 if (ht_cap) 141 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn"); 142 else 143 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g"); 144 } 145 } 146 147 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN); 148 149 /* Add mode */ 150 if (pnetwork->network.Reserved[0] == 2) { /* Probe Request */ 151 cap = 0; 152 } else { 153 __le16 le_tmp; 154 155 iwe.cmd = SIOCGIWMODE; 156 memcpy((u8 *)&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); 157 cap = le16_to_cpu(le_tmp); 158 } 159 160 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_ESS)) { 161 if (cap & WLAN_CAPABILITY_ESS) 162 iwe.u.mode = IW_MODE_MASTER; 163 else 164 iwe.u.mode = IW_MODE_ADHOC; 165 166 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN); 167 } 168 169 if (pnetwork->network.Configuration.DSConfig < 1 /*|| pnetwork->network.Configuration.DSConfig > 14*/) 170 pnetwork->network.Configuration.DSConfig = 1; 171 172 /* Add frequency/channel */ 173 iwe.cmd = SIOCGIWFREQ; 174 iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000; 175 iwe.u.freq.e = 1; 176 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig; 177 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN); 178 179 /* Add encryption capability */ 180 iwe.cmd = SIOCGIWENCODE; 181 if (cap & WLAN_CAPABILITY_PRIVACY) 182 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 183 else 184 iwe.u.data.flags = IW_ENCODE_DISABLED; 185 iwe.u.data.length = 0; 186 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); 187 188 /*Add basic and extended rates */ 189 max_rate = 0; 190 custom = kzalloc(MAX_CUSTOM_LEN, GFP_ATOMIC); 191 if (!custom) 192 return start; 193 p = custom; 194 p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); 195 while (pnetwork->network.SupportedRates[i] != 0) { 196 rate = pnetwork->network.SupportedRates[i]&0x7F; 197 if (rate > max_rate) 198 max_rate = rate; 199 p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), 200 "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); 201 i++; 202 } 203 204 if (vht_cap) { 205 max_rate = vht_data_rate; 206 } else if (ht_cap) { 207 if (mcs_rate & 0x8000) /* MCS15 */ 208 max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130); 209 else /* default MCS7 */ 210 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65); 211 212 max_rate = max_rate*2;/* Mbps/2; */ 213 } 214 215 iwe.cmd = SIOCGIWRATE; 216 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; 217 iwe.u.bitrate.value = max_rate * 500000; 218 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN); 219 220 /* parsing WPA/WPA2 IE */ 221 if (pnetwork->network.Reserved[0] != 2) { /* Probe Request */ 222 u8 *buf; 223 u8 wpa_ie[255], rsn_ie[255]; 224 u16 wpa_len = 0, rsn_len = 0; 225 u8 *p; 226 rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len); 227 228 buf = kzalloc(MAX_WPA_IE_LEN*2, GFP_ATOMIC); 229 if (!buf) 230 return start; 231 if (wpa_len > 0) { 232 p = buf; 233 p += scnprintf(p, (MAX_WPA_IE_LEN * 2) - (p - buf), "wpa_ie ="); 234 for (i = 0; i < wpa_len; i++) 235 p += scnprintf(p, (MAX_WPA_IE_LEN * 2) - (p - buf), 236 "%02x", wpa_ie[i]); 237 238 if (wpa_len > 100) { 239 printk("-----------------Len %d----------------\n", wpa_len); 240 for (i = 0; i < wpa_len; i++) 241 printk("%02x ", wpa_ie[i]); 242 printk("\n"); 243 printk("-----------------Len %d----------------\n", wpa_len); 244 } 245 246 memset(&iwe, 0, sizeof(iwe)); 247 iwe.cmd = IWEVCUSTOM; 248 iwe.u.data.length = strlen(buf); 249 start = iwe_stream_add_point(info, start, stop, &iwe, buf); 250 251 memset(&iwe, 0, sizeof(iwe)); 252 iwe.cmd = IWEVGENIE; 253 iwe.u.data.length = wpa_len; 254 start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie); 255 } 256 if (rsn_len > 0) { 257 p = buf; 258 memset(buf, 0, MAX_WPA_IE_LEN*2); 259 p += scnprintf(p, (MAX_WPA_IE_LEN * 2) - (p - buf), "rsn_ie ="); 260 for (i = 0; i < rsn_len; i++) 261 p += scnprintf(p, (MAX_WPA_IE_LEN * 2) - (p - buf), 262 "%02x", rsn_ie[i]); 263 memset(&iwe, 0, sizeof(iwe)); 264 iwe.cmd = IWEVCUSTOM; 265 iwe.u.data.length = strlen(buf); 266 start = iwe_stream_add_point(info, start, stop, &iwe, buf); 267 268 memset(&iwe, 0, sizeof(iwe)); 269 iwe.cmd = IWEVGENIE; 270 iwe.u.data.length = rsn_len; 271 start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie); 272 } 273 kfree(buf); 274 } 275 276 { /* parsing WPS IE */ 277 uint cnt = 0, total_ielen; 278 u8 *wpsie_ptr = NULL; 279 uint wps_ielen = 0; 280 281 u8 *ie_ptr; 282 total_ielen = pnetwork->network.IELength - ie_offset; 283 284 if (pnetwork->network.Reserved[0] == 2) { /* Probe Request */ 285 ie_ptr = pnetwork->network.IEs; 286 total_ielen = pnetwork->network.IELength; 287 } else { /* Beacon or Probe Respones */ 288 ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_; 289 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_; 290 } 291 292 while (cnt < total_ielen) { 293 if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) { 294 wpsie_ptr = &ie_ptr[cnt]; 295 iwe.cmd = IWEVGENIE; 296 iwe.u.data.length = (u16)wps_ielen; 297 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr); 298 } 299 cnt += ie_ptr[cnt + 1] + 2; /* goto next */ 300 } 301 } 302 303 /* Add quality statistics */ 304 iwe.cmd = IWEVQUAL; 305 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED 306 | IW_QUAL_NOISE_INVALID; 307 308 if (check_fwstate(pmlmepriv, _FW_LINKED) == true && 309 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) { 310 ss = padapter->recvpriv.signal_strength; 311 sq = padapter->recvpriv.signal_qual; 312 } else { 313 ss = pnetwork->network.PhyInfo.SignalStrength; 314 sq = pnetwork->network.PhyInfo.SignalQuality; 315 } 316 317 318 iwe.u.qual.level = (u8)ss;/* */ 319 320 iwe.u.qual.qual = (u8)sq; /* signal quality */ 321 322 iwe.u.qual.noise = 0; /* noise level */ 323 324 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); 325 326 { 327 u8 *buf; 328 u8 *pos; 329 330 buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC); 331 if (!buf) 332 goto exit; 333 334 pos = pnetwork->network.Reserved; 335 memset(&iwe, 0, sizeof(iwe)); 336 iwe.cmd = IWEVCUSTOM; 337 iwe.u.data.length = scnprintf(buf, MAX_WPA_IE_LEN, "fm =%02X%02X", pos[1], pos[0]); 338 start = iwe_stream_add_point(info, start, stop, &iwe, buf); 339 kfree(buf); 340 } 341 exit: 342 kfree(custom); 343 344 return start; 345 } 346 347 static int wpa_set_auth_algs(struct net_device *dev, u32 value) 348 { 349 struct adapter *padapter = rtw_netdev_priv(dev); 350 int ret = 0; 351 352 if ((value & WLAN_AUTH_SHARED_KEY) && (value & WLAN_AUTH_OPEN)) { 353 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 354 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; 355 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; 356 } else if (value & WLAN_AUTH_SHARED_KEY) { 357 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 358 359 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; 360 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; 361 } else if (value & WLAN_AUTH_OPEN) { 362 /* padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; */ 363 if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) { 364 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; 365 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 366 } 367 } else { 368 ret = -EINVAL; 369 } 370 371 return ret; 372 373 } 374 375 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) 376 { 377 int ret = 0; 378 u32 wep_key_idx, wep_key_len, wep_total_len; 379 struct ndis_802_11_wep *pwep = NULL; 380 struct adapter *padapter = rtw_netdev_priv(dev); 381 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 382 struct security_priv *psecuritypriv = &padapter->securitypriv; 383 384 param->u.crypt.err = 0; 385 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; 386 387 if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) { 388 ret = -EINVAL; 389 goto exit; 390 } 391 392 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 393 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 394 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 395 if (param->u.crypt.idx >= WEP_KEYS || 396 param->u.crypt.idx >= BIP_MAX_KEYID) { 397 ret = -EINVAL; 398 goto exit; 399 } 400 } else { 401 { 402 ret = -EINVAL; 403 goto exit; 404 } 405 } 406 407 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 408 409 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 410 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; 411 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; 412 413 wep_key_idx = param->u.crypt.idx; 414 wep_key_len = param->u.crypt.key_len; 415 416 if (wep_key_idx > WEP_KEYS) 417 return -EINVAL; 418 419 if (wep_key_len > 0) { 420 wep_key_len = wep_key_len <= 5 ? 5 : 13; 421 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); 422 pwep = kzalloc(wep_total_len, GFP_KERNEL); 423 if (!pwep) { 424 ret = -ENOMEM; 425 goto exit; 426 } 427 428 pwep->KeyLength = wep_key_len; 429 pwep->Length = wep_total_len; 430 431 if (wep_key_len == 13) { 432 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; 433 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_; 434 } 435 } else { 436 ret = -EINVAL; 437 goto exit; 438 } 439 440 pwep->KeyIndex = wep_key_idx; 441 pwep->KeyIndex |= 0x80000000; 442 443 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); 444 445 if (param->u.crypt.set_tx) { 446 if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL) 447 ret = -EOPNOTSUPP; 448 } else { 449 /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */ 450 /* psecuritypriv->dot11PrivacyKeyIndex =keyid", but can rtw_set_key to fw/cam */ 451 452 if (wep_key_idx >= WEP_KEYS) { 453 ret = -EOPNOTSUPP; 454 goto exit; 455 } 456 457 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); 458 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; 459 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, true); 460 } 461 462 goto exit; 463 } 464 465 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */ 466 struct sta_info *psta, *pbcmc_sta; 467 struct sta_priv *pstapriv = &padapter->stapriv; 468 469 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */ 470 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); 471 if (psta == NULL) { 472 /* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */ 473 } else { 474 /* Jeff: don't disable ieee8021x_blocked while clearing key */ 475 if (strcmp(param->u.crypt.alg, "none") != 0) 476 psta->ieee8021x_blocked = false; 477 478 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || 479 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) { 480 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; 481 } 482 483 if (param->u.crypt.set_tx == 1) { /* pairwise key */ 484 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 485 486 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ 487 /* DEBUG_ERR(("\nset key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */ 488 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); 489 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); 490 491 padapter->securitypriv.busetkipkey = false; 492 /* _set_timer(&padapter->securitypriv.tkip_timer, 50); */ 493 } 494 495 rtw_setstakey_cmd(padapter, psta, true, true); 496 } else { /* group key */ 497 if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) { 498 memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 499 /* only TKIP group key need to install this */ 500 if (param->u.crypt.key_len > 16) { 501 memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); 502 memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); 503 } 504 padapter->securitypriv.binstallGrpkey = true; 505 506 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; 507 508 rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, true); 509 } else if (strcmp(param->u.crypt.alg, "BIP") == 0) { 510 /* printk("BIP key_len =%d , index =%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); */ 511 /* save the IGTK key, length 16 bytes */ 512 memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 513 /*printk("IGTK key below:\n"); 514 for (no = 0;no<16;no++) 515 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]); 516 printk("\n");*/ 517 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; 518 padapter->securitypriv.binstallBIPkey = true; 519 } 520 } 521 } 522 523 pbcmc_sta = rtw_get_bcmc_stainfo(padapter); 524 if (pbcmc_sta == NULL) { 525 /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */ 526 } else { 527 /* Jeff: don't disable ieee8021x_blocked while clearing key */ 528 if (strcmp(param->u.crypt.alg, "none") != 0) 529 pbcmc_sta->ieee8021x_blocked = false; 530 531 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || 532 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) { 533 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; 534 } 535 } 536 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 537 /* adhoc mode */ 538 } 539 } 540 541 exit: 542 543 kfree(pwep); 544 return ret; 545 } 546 547 static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen) 548 { 549 u8 *buf = NULL; 550 int group_cipher = 0, pairwise_cipher = 0; 551 int ret = 0; 552 u8 null_addr[] = {0, 0, 0, 0, 0, 0}; 553 554 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) { 555 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); 556 if (pie == NULL) 557 return ret; 558 else 559 return -EINVAL; 560 } 561 562 if (ielen) { 563 buf = rtw_zmalloc(ielen); 564 if (buf == NULL) { 565 ret = -ENOMEM; 566 goto exit; 567 } 568 569 memcpy(buf, pie, ielen); 570 571 if (ielen < RSN_HEADER_LEN) { 572 ret = -1; 573 goto exit; 574 } 575 576 if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { 577 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; 578 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; 579 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); 580 } 581 582 if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { 583 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; 584 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; 585 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); 586 } 587 588 if (group_cipher == 0) 589 group_cipher = WPA_CIPHER_NONE; 590 if (pairwise_cipher == 0) 591 pairwise_cipher = WPA_CIPHER_NONE; 592 593 switch (group_cipher) { 594 case WPA_CIPHER_NONE: 595 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; 596 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; 597 break; 598 case WPA_CIPHER_WEP40: 599 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; 600 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 601 break; 602 case WPA_CIPHER_TKIP: 603 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_; 604 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; 605 break; 606 case WPA_CIPHER_CCMP: 607 padapter->securitypriv.dot118021XGrpPrivacy = _AES_; 608 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; 609 break; 610 case WPA_CIPHER_WEP104: 611 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_; 612 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 613 break; 614 } 615 616 switch (pairwise_cipher) { 617 case WPA_CIPHER_NONE: 618 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 619 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; 620 break; 621 case WPA_CIPHER_WEP40: 622 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; 623 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 624 break; 625 case WPA_CIPHER_TKIP: 626 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_; 627 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; 628 break; 629 case WPA_CIPHER_CCMP: 630 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_; 631 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; 632 break; 633 case WPA_CIPHER_WEP104: 634 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; 635 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 636 break; 637 } 638 639 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); 640 {/* set wps_ie */ 641 u16 cnt = 0; 642 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; 643 644 while (cnt < ielen) { 645 eid = buf[cnt]; 646 647 if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (!memcmp(&buf[cnt+2], wps_oui, 4))) { 648 padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < MAX_WPS_IE_LEN) ? (buf[cnt+1]+2):MAX_WPS_IE_LEN; 649 650 memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len); 651 652 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); 653 654 cnt += buf[cnt+1]+2; 655 656 break; 657 } else { 658 cnt += buf[cnt+1]+2; /* goto next */ 659 } 660 } 661 } 662 } 663 664 /* TKIP and AES disallow multicast packets until installing group key */ 665 if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ 666 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ 667 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) 668 /* WPS open need to enable multicast */ 669 /* check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true) */ 670 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr); 671 672 exit: 673 674 kfree(buf); 675 676 return ret; 677 } 678 679 static int rtw_wx_get_name(struct net_device *dev, 680 struct iw_request_info *info, 681 union iwreq_data *wrqu, char *extra) 682 { 683 struct adapter *padapter = rtw_netdev_priv(dev); 684 u32 ht_ielen = 0; 685 char *p; 686 u8 ht_cap = false, vht_cap = false; 687 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 688 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 689 NDIS_802_11_RATES_EX *prates = NULL; 690 691 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) { 692 /* parsing HT_CAP_IE */ 693 p = rtw_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY, &ht_ielen, pcur_bss->IELength-12); 694 if (p && ht_ielen > 0) 695 ht_cap = true; 696 697 prates = &pcur_bss->SupportedRates; 698 699 if (rtw_is_cckratesonly_included((u8 *)prates)) { 700 if (ht_cap) 701 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn"); 702 else 703 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b"); 704 } else if (rtw_is_cckrates_included((u8 *)prates)) { 705 if (ht_cap) 706 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn"); 707 else 708 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg"); 709 } else { 710 if (pcur_bss->Configuration.DSConfig > 14) { 711 if (vht_cap) 712 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC"); 713 else if (ht_cap) 714 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an"); 715 else 716 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a"); 717 } else { 718 if (ht_cap) 719 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn"); 720 else 721 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); 722 } 723 } 724 } else { 725 /* prates = &padapter->registrypriv.dev_network.SupportedRates; */ 726 /* snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); */ 727 snprintf(wrqu->name, IFNAMSIZ, "unassociated"); 728 } 729 return 0; 730 } 731 732 static int rtw_wx_set_freq(struct net_device *dev, 733 struct iw_request_info *info, 734 union iwreq_data *wrqu, char *extra) 735 { 736 return 0; 737 } 738 739 static int rtw_wx_get_freq(struct net_device *dev, 740 struct iw_request_info *info, 741 union iwreq_data *wrqu, char *extra) 742 { 743 struct adapter *padapter = rtw_netdev_priv(dev); 744 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 745 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 746 747 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { 748 /* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */ 749 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000; 750 wrqu->freq.e = 1; 751 wrqu->freq.i = pcur_bss->Configuration.DSConfig; 752 753 } else { 754 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000; 755 wrqu->freq.e = 1; 756 wrqu->freq.i = padapter->mlmeextpriv.cur_channel; 757 } 758 759 return 0; 760 } 761 762 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, 763 union iwreq_data *wrqu, char *b) 764 { 765 struct adapter *padapter = rtw_netdev_priv(dev); 766 enum ndis_802_11_network_infrastructure networkType; 767 int ret = 0; 768 769 if (_FAIL == rtw_pwr_wakeup(padapter)) { 770 ret = -EPERM; 771 goto exit; 772 } 773 774 if (!padapter->hw_init_completed) { 775 ret = -EPERM; 776 goto exit; 777 } 778 779 switch (wrqu->mode) { 780 case IW_MODE_AUTO: 781 networkType = Ndis802_11AutoUnknown; 782 break; 783 case IW_MODE_ADHOC: 784 networkType = Ndis802_11IBSS; 785 break; 786 case IW_MODE_MASTER: 787 networkType = Ndis802_11APMode; 788 /* rtw_setopmode_cmd(padapter, networkType, true); */ 789 break; 790 case IW_MODE_INFRA: 791 networkType = Ndis802_11Infrastructure; 792 break; 793 default: 794 ret = -EINVAL; 795 goto exit; 796 } 797 798 /* 799 if (Ndis802_11APMode == networkType) 800 { 801 rtw_setopmode_cmd(padapter, networkType, true); 802 } 803 else 804 { 805 rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown, true); 806 } 807 */ 808 809 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == false) { 810 811 ret = -EPERM; 812 goto exit; 813 814 } 815 816 rtw_setopmode_cmd(padapter, networkType, true); 817 818 exit: 819 return ret; 820 } 821 822 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a, 823 union iwreq_data *wrqu, char *b) 824 { 825 struct adapter *padapter = rtw_netdev_priv(dev); 826 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 827 828 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { 829 wrqu->mode = IW_MODE_INFRA; 830 } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) || 831 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) { 832 wrqu->mode = IW_MODE_ADHOC; 833 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) { 834 wrqu->mode = IW_MODE_MASTER; 835 } else { 836 wrqu->mode = IW_MODE_AUTO; 837 } 838 return 0; 839 } 840 841 842 static int rtw_wx_set_pmkid(struct net_device *dev, 843 struct iw_request_info *a, 844 union iwreq_data *wrqu, char *extra) 845 { 846 struct adapter *padapter = rtw_netdev_priv(dev); 847 u8 j, blInserted = false; 848 int intReturn = false; 849 struct security_priv *psecuritypriv = &padapter->securitypriv; 850 struct iw_pmksa *pPMK = (struct iw_pmksa *)extra; 851 u8 strZeroMacAddress[ETH_ALEN] = { 0x00 }; 852 u8 strIssueBssid[ETH_ALEN] = { 0x00 }; 853 854 /* 855 There are the BSSID information in the bssid.sa_data array. 856 If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information. 857 If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID/BSSID to driver. 858 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID/BSSID from driver. 859 */ 860 861 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); 862 if (pPMK->cmd == IW_PMKSA_ADD) { 863 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN)) 864 return intReturn; 865 else 866 intReturn = true; 867 868 blInserted = false; 869 870 /* overwrite PMKID */ 871 for (j = 0; j < NUM_PMKID_CACHE; j++) { 872 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { 873 874 memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); 875 psecuritypriv->PMKIDList[j].bUsed = true; 876 psecuritypriv->PMKIDIndex = j+1; 877 blInserted = true; 878 break; 879 } 880 } 881 882 if (!blInserted) { 883 884 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN); 885 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN); 886 887 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true; 888 psecuritypriv->PMKIDIndex++; 889 if (psecuritypriv->PMKIDIndex == 16) 890 psecuritypriv->PMKIDIndex = 0; 891 } 892 } else if (pPMK->cmd == IW_PMKSA_REMOVE) { 893 intReturn = true; 894 for (j = 0; j < NUM_PMKID_CACHE; j++) { 895 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { 896 /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */ 897 eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid); 898 psecuritypriv->PMKIDList[j].bUsed = false; 899 break; 900 } 901 } 902 } else if (pPMK->cmd == IW_PMKSA_FLUSH) { 903 memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); 904 psecuritypriv->PMKIDIndex = 0; 905 intReturn = true; 906 } 907 return intReturn; 908 } 909 910 static int rtw_wx_get_sens(struct net_device *dev, 911 struct iw_request_info *info, 912 union iwreq_data *wrqu, char *extra) 913 { 914 { 915 wrqu->sens.value = 0; 916 wrqu->sens.fixed = 0; /* no auto select */ 917 wrqu->sens.disabled = 1; 918 } 919 return 0; 920 } 921 922 static int rtw_wx_get_range(struct net_device *dev, 923 struct iw_request_info *info, 924 union iwreq_data *wrqu, char *extra) 925 { 926 struct iw_range *range = (struct iw_range *)extra; 927 struct adapter *padapter = rtw_netdev_priv(dev); 928 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 929 930 u16 val; 931 int i; 932 933 wrqu->data.length = sizeof(*range); 934 memset(range, 0, sizeof(*range)); 935 936 /* Let's try to keep this struct in the same order as in 937 * linux/include/wireless.h 938 */ 939 940 /* TODO: See what values we can set, and remove the ones we can't 941 * set, or fill them with some default data. 942 */ 943 944 /* ~5 Mb/s real (802.11b) */ 945 range->throughput = 5 * 1000 * 1000; 946 947 /* signal level threshold range */ 948 949 /* percent values between 0 and 100. */ 950 range->max_qual.qual = 100; 951 range->max_qual.level = 100; 952 range->max_qual.noise = 100; 953 range->max_qual.updated = 7; /* Updated all three */ 954 955 956 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ 957 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ 958 range->avg_qual.level = 256 - 78; 959 range->avg_qual.noise = 0; 960 range->avg_qual.updated = 7; /* Updated all three */ 961 962 range->num_bitrates = RATE_COUNT; 963 964 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) 965 range->bitrate[i] = rtw_rates[i]; 966 967 range->min_frag = MIN_FRAG_THRESHOLD; 968 range->max_frag = MAX_FRAG_THRESHOLD; 969 970 range->pm_capa = 0; 971 972 range->we_version_compiled = WIRELESS_EXT; 973 range->we_version_source = 16; 974 975 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) { 976 977 /* Include only legal frequencies for some countries */ 978 if (pmlmeext->channel_set[i].ChannelNum != 0) { 979 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum; 980 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000; 981 range->freq[val].e = 1; 982 val++; 983 } 984 985 if (val == IW_MAX_FREQUENCIES) 986 break; 987 } 988 989 range->num_channels = val; 990 range->num_frequency = val; 991 992 /* Commented by Albert 2009/10/13 */ 993 /* The following code will proivde the security capability to network manager. */ 994 /* If the driver doesn't provide this capability to network manager, */ 995 /* the WPA/WPA2 routers can't be chosen in the network manager. */ 996 997 /* 998 #define IW_SCAN_CAPA_NONE 0x00 999 #define IW_SCAN_CAPA_ESSID 0x01 1000 #define IW_SCAN_CAPA_BSSID 0x02 1001 #define IW_SCAN_CAPA_CHANNEL 0x04 1002 #define IW_SCAN_CAPA_MODE 0x08 1003 #define IW_SCAN_CAPA_RATE 0x10 1004 #define IW_SCAN_CAPA_TYPE 0x20 1005 #define IW_SCAN_CAPA_TIME 0x40 1006 */ 1007 1008 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 1009 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 1010 1011 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_BSSID | 1012 IW_SCAN_CAPA_CHANNEL | IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE; 1013 1014 return 0; 1015 } 1016 1017 /* set bssid flow */ 1018 /* s1. rtw_set_802_11_infrastructure_mode() */ 1019 /* s2. rtw_set_802_11_authentication_mode() */ 1020 /* s3. set_802_11_encryption_mode() */ 1021 /* s4. rtw_set_802_11_bssid() */ 1022 static int rtw_wx_set_wap(struct net_device *dev, 1023 struct iw_request_info *info, 1024 union iwreq_data *awrq, 1025 char *extra) 1026 { 1027 uint ret = 0; 1028 struct adapter *padapter = rtw_netdev_priv(dev); 1029 struct sockaddr *temp = (struct sockaddr *)awrq; 1030 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1031 struct list_head *phead; 1032 u8 *dst_bssid, *src_bssid; 1033 struct __queue *queue = &(pmlmepriv->scanned_queue); 1034 struct wlan_network *pnetwork = NULL; 1035 enum ndis_802_11_authentication_mode authmode; 1036 1037 rtw_ps_deny(padapter, PS_DENY_JOIN); 1038 if (_FAIL == rtw_pwr_wakeup(padapter)) { 1039 ret = -1; 1040 goto exit; 1041 } 1042 1043 if (!padapter->bup) { 1044 ret = -1; 1045 goto exit; 1046 } 1047 1048 1049 if (temp->sa_family != ARPHRD_ETHER) { 1050 ret = -EINVAL; 1051 goto exit; 1052 } 1053 1054 authmode = padapter->securitypriv.ndisauthtype; 1055 spin_lock_bh(&queue->lock); 1056 phead = get_list_head(queue); 1057 list_for_each(pmlmepriv->pscanned, phead) { 1058 pnetwork = list_entry(pmlmepriv->pscanned, 1059 struct wlan_network, list); 1060 1061 dst_bssid = pnetwork->network.MacAddress; 1062 1063 src_bssid = temp->sa_data; 1064 1065 if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) { 1066 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) { 1067 ret = -1; 1068 spin_unlock_bh(&queue->lock); 1069 goto exit; 1070 } 1071 break; 1072 } 1073 1074 } 1075 spin_unlock_bh(&queue->lock); 1076 1077 rtw_set_802_11_authentication_mode(padapter, authmode); 1078 /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */ 1079 if (rtw_set_802_11_bssid(padapter, temp->sa_data) == false) { 1080 ret = -1; 1081 goto exit; 1082 } 1083 1084 exit: 1085 1086 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN); 1087 1088 return ret; 1089 } 1090 1091 static int rtw_wx_get_wap(struct net_device *dev, 1092 struct iw_request_info *info, 1093 union iwreq_data *wrqu, char *extra) 1094 { 1095 1096 struct adapter *padapter = rtw_netdev_priv(dev); 1097 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1098 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 1099 1100 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 1101 1102 eth_zero_addr(wrqu->ap_addr.sa_data); 1103 1104 if (((check_fwstate(pmlmepriv, _FW_LINKED)) == true) || 1105 ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) || 1106 ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == true)) { 1107 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN); 1108 } else { 1109 eth_zero_addr(wrqu->ap_addr.sa_data); 1110 } 1111 1112 return 0; 1113 } 1114 1115 static int rtw_wx_set_mlme(struct net_device *dev, 1116 struct iw_request_info *info, 1117 union iwreq_data *wrqu, char *extra) 1118 { 1119 int ret = 0; 1120 struct adapter *padapter = rtw_netdev_priv(dev); 1121 struct iw_mlme *mlme = (struct iw_mlme *)extra; 1122 1123 1124 if (mlme == NULL) 1125 return -1; 1126 1127 switch (mlme->cmd) { 1128 case IW_MLME_DEAUTH: 1129 if (!rtw_set_802_11_disassociate(padapter)) 1130 ret = -1; 1131 break; 1132 case IW_MLME_DISASSOC: 1133 if (!rtw_set_802_11_disassociate(padapter)) 1134 ret = -1; 1135 break; 1136 default: 1137 return -EOPNOTSUPP; 1138 } 1139 1140 return ret; 1141 } 1142 1143 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, 1144 union iwreq_data *wrqu, char *extra) 1145 { 1146 u8 _status = false; 1147 int ret = 0; 1148 struct adapter *padapter = rtw_netdev_priv(dev); 1149 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1150 struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; 1151 1152 rtw_ps_deny(padapter, PS_DENY_SCAN); 1153 if (_FAIL == rtw_pwr_wakeup(padapter)) { 1154 ret = -1; 1155 goto exit; 1156 } 1157 1158 if (padapter->bDriverStopped) { 1159 ret = -1; 1160 goto exit; 1161 } 1162 1163 if (!padapter->bup) { 1164 ret = -1; 1165 goto exit; 1166 } 1167 1168 if (!padapter->hw_init_completed) { 1169 ret = -1; 1170 goto exit; 1171 } 1172 1173 /* When Busy Traffic, driver do not site survey. So driver return success. */ 1174 /* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */ 1175 /* modify by thomas 2011-02-22. */ 1176 if (pmlmepriv->LinkDetectInfo.bBusyTraffic) { 1177 indicate_wx_scan_complete_event(padapter); 1178 goto exit; 1179 } 1180 1181 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) { 1182 indicate_wx_scan_complete_event(padapter); 1183 goto exit; 1184 } 1185 1186 memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT); 1187 1188 if (wrqu->data.length == sizeof(struct iw_scan_req)) { 1189 struct iw_scan_req *req = (struct iw_scan_req *)extra; 1190 1191 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 1192 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE); 1193 1194 memcpy(ssid[0].Ssid, req->essid, len); 1195 ssid[0].SsidLength = len; 1196 1197 spin_lock_bh(&pmlmepriv->lock); 1198 1199 _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0); 1200 1201 spin_unlock_bh(&pmlmepriv->lock); 1202 1203 } 1204 1205 } else if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE 1206 && !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) { 1207 int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE; 1208 char *pos = extra+WEXT_CSCAN_HEADER_SIZE; 1209 char section; 1210 char sec_len; 1211 int ssid_index = 0; 1212 1213 while (len >= 1) { 1214 section = *(pos++); len -= 1; 1215 1216 switch (section) { 1217 case WEXT_CSCAN_SSID_SECTION: 1218 if (len < 1) { 1219 len = 0; 1220 break; 1221 } 1222 1223 sec_len = *(pos++); len -= 1; 1224 1225 if (sec_len > 0 && sec_len <= len) { 1226 ssid[ssid_index].SsidLength = sec_len; 1227 memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength); 1228 ssid_index++; 1229 } 1230 1231 pos += sec_len; len -= sec_len; 1232 break; 1233 1234 1235 case WEXT_CSCAN_CHANNEL_SECTION: 1236 pos += 1; len -= 1; 1237 break; 1238 case WEXT_CSCAN_ACTV_DWELL_SECTION: 1239 pos += 2; len -= 2; 1240 break; 1241 case WEXT_CSCAN_PASV_DWELL_SECTION: 1242 pos += 2; len -= 2; 1243 break; 1244 case WEXT_CSCAN_HOME_DWELL_SECTION: 1245 pos += 2; len -= 2; 1246 break; 1247 case WEXT_CSCAN_TYPE_SECTION: 1248 pos += 1; len -= 1; 1249 break; 1250 default: 1251 len = 0; /* stop parsing */ 1252 } 1253 } 1254 1255 /* jeff: it has still some scan parameter to parse, we only do this now... */ 1256 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT); 1257 1258 } else { 1259 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); 1260 } 1261 1262 if (_status == false) 1263 ret = -1; 1264 1265 exit: 1266 1267 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN); 1268 1269 return ret; 1270 } 1271 1272 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, 1273 union iwreq_data *wrqu, char *extra) 1274 { 1275 struct list_head *plist, *phead; 1276 struct adapter *padapter = rtw_netdev_priv(dev); 1277 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1278 struct __queue *queue = &(pmlmepriv->scanned_queue); 1279 struct wlan_network *pnetwork = NULL; 1280 char *ev = extra; 1281 char *stop = ev + wrqu->data.length; 1282 u32 ret = 0; 1283 signed int wait_status; 1284 1285 if (adapter_to_pwrctl(padapter)->brfoffbyhw && padapter->bDriverStopped) { 1286 ret = -EINVAL; 1287 goto exit; 1288 } 1289 1290 wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING; 1291 1292 if (check_fwstate(pmlmepriv, wait_status)) 1293 return -EAGAIN; 1294 1295 spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); 1296 1297 phead = get_list_head(queue); 1298 list_for_each(plist, phead) { 1299 if ((stop - ev) < SCAN_ITEM_SIZE) { 1300 ret = -E2BIG; 1301 break; 1302 } 1303 1304 pnetwork = list_entry(plist, struct wlan_network, list); 1305 1306 /* report network only if the current channel set contains the channel to which this network belongs */ 1307 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0 1308 && true == rtw_validate_ssid(&(pnetwork->network.Ssid))) { 1309 1310 ev = translate_scan(padapter, a, pnetwork, ev, stop); 1311 } 1312 1313 } 1314 1315 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 1316 1317 wrqu->data.length = ev-extra; 1318 wrqu->data.flags = 0; 1319 1320 exit: 1321 1322 return ret; 1323 1324 } 1325 1326 /* set ssid flow */ 1327 /* s1. rtw_set_802_11_infrastructure_mode() */ 1328 /* s2. set_802_11_authenticaion_mode() */ 1329 /* s3. set_802_11_encryption_mode() */ 1330 /* s4. rtw_set_802_11_ssid() */ 1331 static int rtw_wx_set_essid(struct net_device *dev, 1332 struct iw_request_info *a, 1333 union iwreq_data *wrqu, char *extra) 1334 { 1335 struct adapter *padapter = rtw_netdev_priv(dev); 1336 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1337 struct __queue *queue = &pmlmepriv->scanned_queue; 1338 struct list_head *phead; 1339 struct wlan_network *pnetwork = NULL; 1340 enum ndis_802_11_authentication_mode authmode; 1341 struct ndis_802_11_ssid ndis_ssid; 1342 u8 *dst_ssid, *src_ssid; 1343 1344 uint ret = 0, len; 1345 1346 rtw_ps_deny(padapter, PS_DENY_JOIN); 1347 if (_FAIL == rtw_pwr_wakeup(padapter)) { 1348 ret = -1; 1349 goto exit; 1350 } 1351 1352 if (!padapter->bup) { 1353 ret = -1; 1354 goto exit; 1355 } 1356 1357 if (wrqu->essid.length > IW_ESSID_MAX_SIZE) { 1358 ret = -E2BIG; 1359 goto exit; 1360 } 1361 1362 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1363 ret = -1; 1364 goto exit; 1365 } 1366 1367 authmode = padapter->securitypriv.ndisauthtype; 1368 if (wrqu->essid.flags && wrqu->essid.length) { 1369 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE; 1370 1371 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid)); 1372 ndis_ssid.SsidLength = len; 1373 memcpy(ndis_ssid.Ssid, extra, len); 1374 src_ssid = ndis_ssid.Ssid; 1375 1376 spin_lock_bh(&queue->lock); 1377 phead = get_list_head(queue); 1378 list_for_each(pmlmepriv->pscanned, phead) { 1379 pnetwork = list_entry(pmlmepriv->pscanned, 1380 struct wlan_network, list); 1381 1382 dst_ssid = pnetwork->network.Ssid.Ssid; 1383 1384 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) && 1385 (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) { 1386 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) { 1387 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) 1388 continue; 1389 } 1390 1391 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == false) { 1392 ret = -1; 1393 spin_unlock_bh(&queue->lock); 1394 goto exit; 1395 } 1396 1397 break; 1398 } 1399 } 1400 spin_unlock_bh(&queue->lock); 1401 rtw_set_802_11_authentication_mode(padapter, authmode); 1402 /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */ 1403 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == false) { 1404 ret = -1; 1405 goto exit; 1406 } 1407 } 1408 1409 exit: 1410 1411 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN); 1412 1413 return ret; 1414 } 1415 1416 static int rtw_wx_get_essid(struct net_device *dev, 1417 struct iw_request_info *a, 1418 union iwreq_data *wrqu, char *extra) 1419 { 1420 u32 len, ret = 0; 1421 struct adapter *padapter = rtw_netdev_priv(dev); 1422 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1423 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 1424 1425 if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) || 1426 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) { 1427 len = pcur_bss->Ssid.SsidLength; 1428 1429 wrqu->essid.length = len; 1430 1431 memcpy(extra, pcur_bss->Ssid.Ssid, len); 1432 1433 wrqu->essid.flags = 1; 1434 } else { 1435 ret = -1; 1436 goto exit; 1437 } 1438 1439 exit: 1440 return ret; 1441 } 1442 1443 static int rtw_wx_set_rate(struct net_device *dev, 1444 struct iw_request_info *a, 1445 union iwreq_data *wrqu, char *extra) 1446 { 1447 int i, ret = 0; 1448 struct adapter *padapter = rtw_netdev_priv(dev); 1449 u8 datarates[NumRates]; 1450 u32 target_rate = wrqu->bitrate.value; 1451 u32 fixed = wrqu->bitrate.fixed; 1452 u32 ratevalue = 0; 1453 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; 1454 1455 if (target_rate == -1) { 1456 ratevalue = 11; 1457 goto set_rate; 1458 } 1459 target_rate = target_rate/100000; 1460 1461 switch (target_rate) { 1462 case 10: 1463 ratevalue = 0; 1464 break; 1465 case 20: 1466 ratevalue = 1; 1467 break; 1468 case 55: 1469 ratevalue = 2; 1470 break; 1471 case 60: 1472 ratevalue = 3; 1473 break; 1474 case 90: 1475 ratevalue = 4; 1476 break; 1477 case 110: 1478 ratevalue = 5; 1479 break; 1480 case 120: 1481 ratevalue = 6; 1482 break; 1483 case 180: 1484 ratevalue = 7; 1485 break; 1486 case 240: 1487 ratevalue = 8; 1488 break; 1489 case 360: 1490 ratevalue = 9; 1491 break; 1492 case 480: 1493 ratevalue = 10; 1494 break; 1495 case 540: 1496 ratevalue = 11; 1497 break; 1498 default: 1499 ratevalue = 11; 1500 break; 1501 } 1502 1503 set_rate: 1504 1505 for (i = 0; i < NumRates; i++) { 1506 if (ratevalue == mpdatarate[i]) { 1507 datarates[i] = mpdatarate[i]; 1508 if (fixed == 0) 1509 break; 1510 } else { 1511 datarates[i] = 0xff; 1512 } 1513 } 1514 1515 if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) 1516 ret = -1; 1517 1518 return ret; 1519 } 1520 1521 static int rtw_wx_get_rate(struct net_device *dev, 1522 struct iw_request_info *info, 1523 union iwreq_data *wrqu, char *extra) 1524 { 1525 u16 max_rate = 0; 1526 1527 max_rate = rtw_get_cur_max_rate(rtw_netdev_priv(dev)); 1528 1529 if (max_rate == 0) 1530 return -EPERM; 1531 1532 wrqu->bitrate.fixed = 0; /* no auto select */ 1533 wrqu->bitrate.value = max_rate * 100000; 1534 1535 return 0; 1536 } 1537 1538 static int rtw_wx_set_rts(struct net_device *dev, 1539 struct iw_request_info *info, 1540 union iwreq_data *wrqu, char *extra) 1541 { 1542 struct adapter *padapter = rtw_netdev_priv(dev); 1543 1544 if (wrqu->rts.disabled) 1545 padapter->registrypriv.rts_thresh = 2347; 1546 else { 1547 if (wrqu->rts.value < 0 || 1548 wrqu->rts.value > 2347) 1549 return -EINVAL; 1550 1551 padapter->registrypriv.rts_thresh = wrqu->rts.value; 1552 } 1553 1554 return 0; 1555 } 1556 1557 static int rtw_wx_get_rts(struct net_device *dev, 1558 struct iw_request_info *info, 1559 union iwreq_data *wrqu, char *extra) 1560 { 1561 struct adapter *padapter = rtw_netdev_priv(dev); 1562 1563 wrqu->rts.value = padapter->registrypriv.rts_thresh; 1564 wrqu->rts.fixed = 0; /* no auto select */ 1565 /* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */ 1566 1567 return 0; 1568 } 1569 1570 static int rtw_wx_set_frag(struct net_device *dev, 1571 struct iw_request_info *info, 1572 union iwreq_data *wrqu, char *extra) 1573 { 1574 struct adapter *padapter = rtw_netdev_priv(dev); 1575 1576 if (wrqu->frag.disabled) 1577 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; 1578 else { 1579 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 1580 wrqu->frag.value > MAX_FRAG_THRESHOLD) 1581 return -EINVAL; 1582 1583 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1; 1584 } 1585 1586 return 0; 1587 1588 } 1589 1590 static int rtw_wx_get_frag(struct net_device *dev, 1591 struct iw_request_info *info, 1592 union iwreq_data *wrqu, char *extra) 1593 { 1594 struct adapter *padapter = rtw_netdev_priv(dev); 1595 1596 wrqu->frag.value = padapter->xmitpriv.frag_len; 1597 wrqu->frag.fixed = 0; /* no auto select */ 1598 /* wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); */ 1599 1600 return 0; 1601 } 1602 1603 static int rtw_wx_get_retry(struct net_device *dev, 1604 struct iw_request_info *info, 1605 union iwreq_data *wrqu, char *extra) 1606 { 1607 /* struct adapter *padapter = rtw_netdev_priv(dev); */ 1608 1609 1610 wrqu->retry.value = 7; 1611 wrqu->retry.fixed = 0; /* no auto select */ 1612 wrqu->retry.disabled = 1; 1613 1614 return 0; 1615 1616 } 1617 1618 static int rtw_wx_set_enc(struct net_device *dev, 1619 struct iw_request_info *info, 1620 union iwreq_data *wrqu, char *keybuf) 1621 { 1622 u32 key, ret = 0; 1623 u32 keyindex_provided; 1624 struct ndis_802_11_wep wep; 1625 enum ndis_802_11_authentication_mode authmode; 1626 1627 struct iw_point *erq = &(wrqu->encoding); 1628 struct adapter *padapter = rtw_netdev_priv(dev); 1629 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1630 1631 memset(&wep, 0, sizeof(struct ndis_802_11_wep)); 1632 1633 key = erq->flags & IW_ENCODE_INDEX; 1634 1635 if (erq->flags & IW_ENCODE_DISABLED) { 1636 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; 1637 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 1638 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; 1639 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ 1640 authmode = Ndis802_11AuthModeOpen; 1641 padapter->securitypriv.ndisauthtype = authmode; 1642 1643 goto exit; 1644 } 1645 1646 if (key) { 1647 if (key > WEP_KEYS) 1648 return -EINVAL; 1649 key--; 1650 keyindex_provided = 1; 1651 } else { 1652 keyindex_provided = 0; 1653 key = padapter->securitypriv.dot11PrivacyKeyIndex; 1654 } 1655 1656 /* set authentication mode */ 1657 if (erq->flags & IW_ENCODE_OPEN) { 1658 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ 1659 1660 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 1661 1662 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 1663 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; 1664 authmode = Ndis802_11AuthModeOpen; 1665 padapter->securitypriv.ndisauthtype = authmode; 1666 } else if (erq->flags & IW_ENCODE_RESTRICTED) { 1667 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 1668 1669 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; 1670 1671 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; 1672 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; 1673 authmode = Ndis802_11AuthModeShared; 1674 padapter->securitypriv.ndisauthtype = authmode; 1675 } else { 1676 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ 1677 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ 1678 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 1679 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; 1680 authmode = Ndis802_11AuthModeOpen; 1681 padapter->securitypriv.ndisauthtype = authmode; 1682 } 1683 1684 wep.KeyIndex = key; 1685 if (erq->length > 0) { 1686 wep.KeyLength = erq->length <= 5 ? 5 : 13; 1687 1688 wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); 1689 } else { 1690 wep.KeyLength = 0; 1691 1692 if (keyindex_provided == 1) { /* set key_id only, no given KeyMaterial(erq->length == 0). */ 1693 padapter->securitypriv.dot11PrivacyKeyIndex = key; 1694 1695 switch (padapter->securitypriv.dot11DefKeylen[key]) { 1696 case 5: 1697 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; 1698 break; 1699 case 13: 1700 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; 1701 break; 1702 default: 1703 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 1704 break; 1705 } 1706 1707 goto exit; 1708 1709 } 1710 1711 } 1712 1713 wep.KeyIndex |= 0x80000000; 1714 1715 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength); 1716 1717 if (rtw_set_802_11_add_wep(padapter, &wep) == false) { 1718 if (rf_on == pwrpriv->rf_pwrstate) 1719 ret = -EOPNOTSUPP; 1720 goto exit; 1721 } 1722 1723 exit: 1724 return ret; 1725 } 1726 1727 static int rtw_wx_get_enc(struct net_device *dev, 1728 struct iw_request_info *info, 1729 union iwreq_data *wrqu, char *keybuf) 1730 { 1731 uint key, ret = 0; 1732 struct adapter *padapter = rtw_netdev_priv(dev); 1733 struct iw_point *erq = &(wrqu->encoding); 1734 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1735 1736 if (check_fwstate(pmlmepriv, _FW_LINKED) != true) { 1737 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != true) { 1738 erq->length = 0; 1739 erq->flags |= IW_ENCODE_DISABLED; 1740 return 0; 1741 } 1742 } 1743 1744 1745 key = erq->flags & IW_ENCODE_INDEX; 1746 1747 if (key) { 1748 if (key > WEP_KEYS) 1749 return -EINVAL; 1750 key--; 1751 } else { 1752 key = padapter->securitypriv.dot11PrivacyKeyIndex; 1753 } 1754 1755 erq->flags = key + 1; 1756 1757 /* if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) */ 1758 /* */ 1759 /* erq->flags |= IW_ENCODE_OPEN; */ 1760 /* */ 1761 1762 switch (padapter->securitypriv.ndisencryptstatus) { 1763 case Ndis802_11EncryptionNotSupported: 1764 case Ndis802_11EncryptionDisabled: 1765 erq->length = 0; 1766 erq->flags |= IW_ENCODE_DISABLED; 1767 break; 1768 case Ndis802_11Encryption1Enabled: 1769 erq->length = padapter->securitypriv.dot11DefKeylen[key]; 1770 1771 if (erq->length) { 1772 memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]); 1773 1774 erq->flags |= IW_ENCODE_ENABLED; 1775 1776 if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) 1777 erq->flags |= IW_ENCODE_OPEN; 1778 else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared) 1779 erq->flags |= IW_ENCODE_RESTRICTED; 1780 } else { 1781 erq->length = 0; 1782 erq->flags |= IW_ENCODE_DISABLED; 1783 } 1784 break; 1785 case Ndis802_11Encryption2Enabled: 1786 case Ndis802_11Encryption3Enabled: 1787 erq->length = 16; 1788 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY); 1789 break; 1790 default: 1791 erq->length = 0; 1792 erq->flags |= IW_ENCODE_DISABLED; 1793 break; 1794 } 1795 return ret; 1796 } 1797 1798 static int rtw_wx_get_power(struct net_device *dev, 1799 struct iw_request_info *info, 1800 union iwreq_data *wrqu, char *extra) 1801 { 1802 /* struct adapter *padapter = rtw_netdev_priv(dev); */ 1803 1804 wrqu->power.value = 0; 1805 wrqu->power.fixed = 0; /* no auto select */ 1806 wrqu->power.disabled = 1; 1807 1808 return 0; 1809 } 1810 1811 static int rtw_wx_set_gen_ie(struct net_device *dev, 1812 struct iw_request_info *info, 1813 union iwreq_data *wrqu, char *extra) 1814 { 1815 struct adapter *padapter = rtw_netdev_priv(dev); 1816 1817 return rtw_set_wpa_ie(padapter, extra, wrqu->data.length); 1818 } 1819 1820 static int rtw_wx_set_auth(struct net_device *dev, 1821 struct iw_request_info *info, 1822 union iwreq_data *wrqu, char *extra) 1823 { 1824 struct adapter *padapter = rtw_netdev_priv(dev); 1825 struct iw_param *param = (struct iw_param *)&(wrqu->param); 1826 int ret = 0; 1827 1828 switch (param->flags & IW_AUTH_INDEX) { 1829 case IW_AUTH_WPA_VERSION: 1830 break; 1831 case IW_AUTH_CIPHER_PAIRWISE: 1832 break; 1833 case IW_AUTH_CIPHER_GROUP: 1834 break; 1835 case IW_AUTH_KEY_MGMT: 1836 /* 1837 * ??? does not use these parameters 1838 */ 1839 break; 1840 case IW_AUTH_TKIP_COUNTERMEASURES: 1841 /* wpa_supplicant is setting the tkip countermeasure. */ 1842 if (param->value) /* enabling */ 1843 padapter->securitypriv.btkip_countermeasure = true; 1844 else /* disabling */ 1845 padapter->securitypriv.btkip_countermeasure = false; 1846 break; 1847 case IW_AUTH_DROP_UNENCRYPTED: 1848 /* HACK: 1849 * 1850 * wpa_supplicant calls set_wpa_enabled when the driver 1851 * is loaded and unloaded, regardless of if WPA is being 1852 * used. No other calls are made which can be used to 1853 * determine if encryption will be used or not prior to 1854 * association being expected. If encryption is not being 1855 * used, drop_unencrypted is set to false, else true -- we 1856 * can use this to determine if the CAP_PRIVACY_ON bit should 1857 * be set. 1858 */ 1859 1860 /* 1861 * This means init value, or using wep, ndisencryptstatus = 1862 * Ndis802_11Encryption1Enabled, then it needn't reset it; 1863 */ 1864 if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) 1865 break; 1866 1867 if (param->value) { 1868 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; 1869 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 1870 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; 1871 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ 1872 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; 1873 } 1874 1875 break; 1876 case IW_AUTH_80211_AUTH_ALG: 1877 /* 1878 * It's the starting point of a link layer connection using wpa_supplicant 1879 */ 1880 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { 1881 LeaveAllPowerSaveMode(padapter); 1882 rtw_disassoc_cmd(padapter, 500, false); 1883 rtw_indicate_disconnect(padapter); 1884 rtw_free_assoc_resources(padapter, 1); 1885 } 1886 1887 ret = wpa_set_auth_algs(dev, (u32)param->value); 1888 break; 1889 case IW_AUTH_WPA_ENABLED: 1890 break; 1891 case IW_AUTH_RX_UNENCRYPTED_EAPOL: 1892 break; 1893 case IW_AUTH_PRIVACY_INVOKED: 1894 break; 1895 default: 1896 return -EOPNOTSUPP; 1897 } 1898 1899 return ret; 1900 } 1901 1902 static int rtw_wx_set_enc_ext(struct net_device *dev, 1903 struct iw_request_info *info, 1904 union iwreq_data *wrqu, char *extra) 1905 { 1906 char *alg_name; 1907 u32 param_len; 1908 struct ieee_param *param = NULL; 1909 struct iw_point *pencoding = &wrqu->encoding; 1910 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra; 1911 int ret = 0; 1912 1913 param_len = sizeof(struct ieee_param) + pext->key_len; 1914 param = kzalloc(param_len, GFP_KERNEL); 1915 if (param == NULL) 1916 return -1; 1917 1918 param->cmd = IEEE_CMD_SET_ENCRYPTION; 1919 eth_broadcast_addr(param->sta_addr); 1920 1921 1922 switch (pext->alg) { 1923 case IW_ENCODE_ALG_NONE: 1924 /* todo: remove key */ 1925 /* remove = 1; */ 1926 alg_name = "none"; 1927 break; 1928 case IW_ENCODE_ALG_WEP: 1929 alg_name = "WEP"; 1930 break; 1931 case IW_ENCODE_ALG_TKIP: 1932 alg_name = "TKIP"; 1933 break; 1934 case IW_ENCODE_ALG_CCMP: 1935 alg_name = "CCMP"; 1936 break; 1937 case IW_ENCODE_ALG_AES_CMAC: 1938 alg_name = "BIP"; 1939 break; 1940 default: 1941 ret = -1; 1942 goto exit; 1943 } 1944 1945 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); 1946 1947 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 1948 param->u.crypt.set_tx = 1; 1949 1950 /* cliW: WEP does not have group key 1951 * just not checking GROUP key setting 1952 */ 1953 if ((pext->alg != IW_ENCODE_ALG_WEP) && 1954 ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) 1955 || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC))) { 1956 param->u.crypt.set_tx = 0; 1957 } 1958 1959 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1; 1960 1961 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) 1962 memcpy(param->u.crypt.seq, pext->rx_seq, 8); 1963 1964 if (pext->key_len) { 1965 param->u.crypt.key_len = pext->key_len; 1966 /* memcpy(param + 1, pext + 1, pext->key_len); */ 1967 memcpy(param->u.crypt.key, pext + 1, pext->key_len); 1968 } 1969 1970 if (pencoding->flags & IW_ENCODE_DISABLED) { 1971 /* todo: remove key */ 1972 /* remove = 1; */ 1973 } 1974 1975 ret = wpa_set_encryption(dev, param, param_len); 1976 1977 exit: 1978 kfree(param); 1979 1980 return ret; 1981 } 1982 1983 1984 static int rtw_wx_get_nick(struct net_device *dev, 1985 struct iw_request_info *info, 1986 union iwreq_data *wrqu, char *extra) 1987 { 1988 /* struct adapter *padapter = rtw_netdev_priv(dev); */ 1989 /* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */ 1990 /* struct security_priv *psecuritypriv = &padapter->securitypriv; */ 1991 1992 if (extra) { 1993 wrqu->data.length = 14; 1994 wrqu->data.flags = 1; 1995 memcpy(extra, "<WIFI@REALTEK>", 14); 1996 } 1997 return 0; 1998 } 1999 2000 static int rtw_wx_read32(struct net_device *dev, 2001 struct iw_request_info *info, 2002 union iwreq_data *wrqu, char *extra) 2003 { 2004 struct adapter *padapter; 2005 struct iw_point *p; 2006 u16 len; 2007 u32 addr; 2008 u32 data32; 2009 u32 bytes; 2010 u8 *ptmp; 2011 int ret; 2012 2013 2014 ret = 0; 2015 padapter = rtw_netdev_priv(dev); 2016 p = &wrqu->data; 2017 len = p->length; 2018 if (0 == len) 2019 return -EINVAL; 2020 2021 ptmp = rtw_malloc(len); 2022 if (NULL == ptmp) 2023 return -ENOMEM; 2024 2025 if (copy_from_user(ptmp, p->pointer, len)) { 2026 ret = -EFAULT; 2027 goto exit; 2028 } 2029 2030 bytes = 0; 2031 addr = 0; 2032 sscanf(ptmp, "%d,%x", &bytes, &addr); 2033 2034 switch (bytes) { 2035 case 1: 2036 data32 = rtw_read8(padapter, addr); 2037 sprintf(extra, "0x%02X", data32); 2038 break; 2039 case 2: 2040 data32 = rtw_read16(padapter, addr); 2041 sprintf(extra, "0x%04X", data32); 2042 break; 2043 case 4: 2044 data32 = rtw_read32(padapter, addr); 2045 sprintf(extra, "0x%08X", data32); 2046 break; 2047 default: 2048 ret = -EINVAL; 2049 goto exit; 2050 } 2051 2052 exit: 2053 kfree(ptmp); 2054 2055 return ret; 2056 } 2057 2058 static int rtw_wx_write32(struct net_device *dev, 2059 struct iw_request_info *info, 2060 union iwreq_data *wrqu, char *extra) 2061 { 2062 struct adapter *padapter = rtw_netdev_priv(dev); 2063 2064 u32 addr; 2065 u32 data32; 2066 u32 bytes; 2067 2068 2069 bytes = 0; 2070 addr = 0; 2071 data32 = 0; 2072 sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32); 2073 2074 switch (bytes) { 2075 case 1: 2076 rtw_write8(padapter, addr, (u8)data32); 2077 break; 2078 case 2: 2079 rtw_write16(padapter, addr, (u16)data32); 2080 break; 2081 case 4: 2082 rtw_write32(padapter, addr, data32); 2083 break; 2084 default: 2085 return -EINVAL; 2086 } 2087 2088 return 0; 2089 } 2090 2091 static int rtw_wx_read_rf(struct net_device *dev, 2092 struct iw_request_info *info, 2093 union iwreq_data *wrqu, char *extra) 2094 { 2095 struct adapter *padapter = rtw_netdev_priv(dev); 2096 u32 path, addr, data32; 2097 2098 2099 path = *(u32 *)extra; 2100 addr = *((u32 *)extra + 1); 2101 data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF); 2102 /* 2103 * IMPORTANT!! 2104 * Only when wireless private ioctl is at odd order, 2105 * "extra" would be copied to user space. 2106 */ 2107 sprintf(extra, "0x%05x", data32); 2108 2109 return 0; 2110 } 2111 2112 static int rtw_wx_write_rf(struct net_device *dev, 2113 struct iw_request_info *info, 2114 union iwreq_data *wrqu, char *extra) 2115 { 2116 struct adapter *padapter = rtw_netdev_priv(dev); 2117 u32 path, addr, data32; 2118 2119 2120 path = *(u32 *)extra; 2121 addr = *((u32 *)extra + 1); 2122 data32 = *((u32 *)extra + 2); 2123 rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32); 2124 2125 return 0; 2126 } 2127 2128 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a, 2129 union iwreq_data *wrqu, char *b) 2130 { 2131 return -1; 2132 } 2133 2134 static int dummy(struct net_device *dev, struct iw_request_info *a, 2135 union iwreq_data *wrqu, char *b) 2136 { 2137 /* struct adapter *padapter = rtw_netdev_priv(dev); */ 2138 /* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */ 2139 2140 return -1; 2141 2142 } 2143 2144 static int rtw_wx_set_channel_plan(struct net_device *dev, 2145 struct iw_request_info *info, 2146 union iwreq_data *wrqu, char *extra) 2147 { 2148 struct adapter *padapter = rtw_netdev_priv(dev); 2149 u8 channel_plan_req = (u8)(*((int *)wrqu)); 2150 2151 if (rtw_set_chplan_cmd(padapter, channel_plan_req, 1, 1) != _SUCCESS) 2152 return -EPERM; 2153 2154 return 0; 2155 } 2156 2157 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev, 2158 struct iw_request_info *a, 2159 union iwreq_data *wrqu, char *b) 2160 { 2161 return 0; 2162 } 2163 2164 static int rtw_wx_get_sensitivity(struct net_device *dev, 2165 struct iw_request_info *info, 2166 union iwreq_data *wrqu, char *buf) 2167 { 2168 return 0; 2169 } 2170 2171 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev, 2172 struct iw_request_info *info, 2173 union iwreq_data *wrqu, char *extra) 2174 { 2175 return 0; 2176 } 2177 2178 /* 2179 typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info, 2180 union iwreq_data *wrqu, char *extra); 2181 */ 2182 /* 2183 *For all data larger than 16 octets, we need to use a 2184 *pointer to memory allocated in user space. 2185 */ 2186 static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info, 2187 union iwreq_data *wrqu, char *extra) 2188 { 2189 return 0; 2190 } 2191 2192 static int rtw_get_ap_info(struct net_device *dev, 2193 struct iw_request_info *info, 2194 union iwreq_data *wrqu, char *extra) 2195 { 2196 int ret = 0; 2197 int wpa_ielen; 2198 u32 cnt = 0; 2199 struct list_head *plist, *phead; 2200 unsigned char *pbuf; 2201 u8 bssid[ETH_ALEN]; 2202 char data[32]; 2203 struct wlan_network *pnetwork = NULL; 2204 struct adapter *padapter = rtw_netdev_priv(dev); 2205 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2206 struct __queue *queue = &(pmlmepriv->scanned_queue); 2207 struct iw_point *pdata = &wrqu->data; 2208 2209 if ((padapter->bDriverStopped) || (pdata == NULL)) { 2210 ret = -EINVAL; 2211 goto exit; 2212 } 2213 2214 while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == true) { 2215 msleep(30); 2216 cnt++; 2217 if (cnt > 100) 2218 break; 2219 } 2220 2221 2222 /* pdata->length = 0;? */ 2223 pdata->flags = 0; 2224 if (pdata->length >= 32) { 2225 if (copy_from_user(data, pdata->pointer, 32)) { 2226 ret = -EINVAL; 2227 goto exit; 2228 } 2229 } else { 2230 ret = -EINVAL; 2231 goto exit; 2232 } 2233 2234 spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); 2235 2236 phead = get_list_head(queue); 2237 list_for_each(plist, phead) { 2238 pnetwork = list_entry(plist, struct wlan_network, list); 2239 2240 if (!mac_pton(data, bssid)) { 2241 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 2242 return -EINVAL; 2243 } 2244 2245 2246 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) { /* BSSID match, then check if supporting wpa/wpa2 */ 2247 2248 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); 2249 if (pbuf && (wpa_ielen > 0)) { 2250 pdata->flags = 1; 2251 break; 2252 } 2253 2254 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); 2255 if (pbuf && (wpa_ielen > 0)) { 2256 pdata->flags = 2; 2257 break; 2258 } 2259 } 2260 2261 } 2262 2263 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 2264 2265 if (pdata->length >= 34) { 2266 if (copy_to_user((u8 __force __user *)pdata->pointer+32, (u8 *)&pdata->flags, 1)) { 2267 ret = -EINVAL; 2268 goto exit; 2269 } 2270 } 2271 2272 exit: 2273 2274 return ret; 2275 2276 } 2277 2278 static int rtw_set_pid(struct net_device *dev, 2279 struct iw_request_info *info, 2280 union iwreq_data *wrqu, char *extra) 2281 { 2282 2283 int ret = 0; 2284 struct adapter *padapter = rtw_netdev_priv(dev); 2285 int *pdata = (int *)wrqu; 2286 int selector; 2287 2288 if ((padapter->bDriverStopped) || (pdata == NULL)) { 2289 ret = -EINVAL; 2290 goto exit; 2291 } 2292 2293 selector = *pdata; 2294 if (selector < 3 && selector >= 0) 2295 padapter->pid[selector] = *(pdata+1); 2296 2297 exit: 2298 2299 return ret; 2300 2301 } 2302 2303 static int rtw_wps_start(struct net_device *dev, 2304 struct iw_request_info *info, 2305 union iwreq_data *wrqu, char *extra) 2306 { 2307 2308 int ret = 0; 2309 struct adapter *padapter = rtw_netdev_priv(dev); 2310 struct iw_point *pdata = &wrqu->data; 2311 u32 u32wps_start = 0; 2312 2313 if ((true == padapter->bDriverStopped) || (true == padapter->bSurpriseRemoved) || (NULL == pdata)) { 2314 ret = -EINVAL; 2315 goto exit; 2316 } 2317 2318 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4)) { 2319 ret = -EFAULT; 2320 goto exit; 2321 } 2322 if (u32wps_start == 0) 2323 u32wps_start = *extra; 2324 2325 exit: 2326 2327 return ret; 2328 2329 } 2330 2331 static int rtw_p2p_set(struct net_device *dev, 2332 struct iw_request_info *info, 2333 union iwreq_data *wrqu, char *extra) 2334 { 2335 2336 return 0; 2337 2338 } 2339 2340 static int rtw_p2p_get(struct net_device *dev, 2341 struct iw_request_info *info, 2342 union iwreq_data *wrqu, char *extra) 2343 { 2344 2345 return 0; 2346 2347 } 2348 2349 static int rtw_p2p_get2(struct net_device *dev, 2350 struct iw_request_info *info, 2351 union iwreq_data *wrqu, char *extra) 2352 { 2353 2354 return 0; 2355 2356 } 2357 2358 static int rtw_rereg_nd_name(struct net_device *dev, 2359 struct iw_request_info *info, 2360 union iwreq_data *wrqu, char *extra) 2361 { 2362 int ret = 0; 2363 struct adapter *padapter = rtw_netdev_priv(dev); 2364 struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv; 2365 char new_ifname[IFNAMSIZ]; 2366 2367 if (rereg_priv->old_ifname[0] == 0) { 2368 char *reg_ifname; 2369 reg_ifname = padapter->registrypriv.ifname; 2370 2371 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ); 2372 rereg_priv->old_ifname[IFNAMSIZ-1] = 0; 2373 } 2374 2375 if (wrqu->data.length > IFNAMSIZ) 2376 return -EFAULT; 2377 2378 if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ)) 2379 return -EFAULT; 2380 2381 if (0 == strcmp(rereg_priv->old_ifname, new_ifname)) 2382 return ret; 2383 2384 ret = rtw_change_ifname(padapter, new_ifname); 2385 if (ret != 0) 2386 goto exit; 2387 2388 strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ); 2389 rereg_priv->old_ifname[IFNAMSIZ-1] = 0; 2390 2391 if (!memcmp(new_ifname, "disable%d", 9)) { 2392 /* free network queue for Android's timming issue */ 2393 rtw_free_network_queue(padapter, true); 2394 2395 /* the interface is being "disabled", we can do deeper IPS */ 2396 /* rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); */ 2397 } 2398 exit: 2399 return ret; 2400 2401 } 2402 2403 static int rtw_dbg_port(struct net_device *dev, 2404 struct iw_request_info *info, 2405 union iwreq_data *wrqu, char *extra) 2406 { 2407 u8 major_cmd, minor_cmd; 2408 u16 arg; 2409 u32 extra_arg, *pdata, val32; 2410 struct adapter *padapter = rtw_netdev_priv(dev); 2411 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2412 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2413 2414 pdata = (u32 *)&wrqu->data; 2415 2416 val32 = *pdata; 2417 arg = (u16)(val32&0x0000ffff); 2418 major_cmd = (u8)(val32>>24); 2419 minor_cmd = (u8)((val32>>16)&0x00ff); 2420 2421 extra_arg = *(pdata+1); 2422 2423 switch (major_cmd) { 2424 case 0x70:/* read_reg */ 2425 switch (minor_cmd) { 2426 case 1: 2427 break; 2428 case 2: 2429 break; 2430 case 4: 2431 break; 2432 } 2433 break; 2434 case 0x71:/* write_reg */ 2435 switch (minor_cmd) { 2436 case 1: 2437 rtw_write8(padapter, arg, extra_arg); 2438 break; 2439 case 2: 2440 rtw_write16(padapter, arg, extra_arg); 2441 break; 2442 case 4: 2443 rtw_write32(padapter, arg, extra_arg); 2444 break; 2445 } 2446 break; 2447 case 0x72:/* read_bb */ 2448 break; 2449 case 0x73:/* write_bb */ 2450 rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg); 2451 break; 2452 case 0x74:/* read_rf */ 2453 break; 2454 case 0x75:/* write_rf */ 2455 rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg); 2456 break; 2457 2458 case 0x76: 2459 switch (minor_cmd) { 2460 case 0x00: /* normal mode, */ 2461 padapter->recvpriv.is_signal_dbg = 0; 2462 break; 2463 case 0x01: /* dbg mode */ 2464 padapter->recvpriv.is_signal_dbg = 1; 2465 extra_arg = extra_arg > 100 ? 100 : extra_arg; 2466 padapter->recvpriv.signal_strength_dbg = extra_arg; 2467 break; 2468 } 2469 break; 2470 case 0x78: /* IOL test */ 2471 break; 2472 case 0x79: 2473 { 2474 /* 2475 * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15 2476 * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15 2477 */ 2478 u8 value = extra_arg & 0x0f; 2479 u8 sign = minor_cmd; 2480 u16 write_value = 0; 2481 2482 if (sign) 2483 value = value | 0x10; 2484 2485 write_value = value | (value << 5); 2486 rtw_write16(padapter, 0x6d9, write_value); 2487 } 2488 break; 2489 case 0x7a: 2490 receive_disconnect(padapter, pmlmeinfo->network.MacAddress 2491 , WLAN_REASON_EXPIRATION_CHK); 2492 break; 2493 case 0x7F: 2494 switch (minor_cmd) { 2495 case 0x0: 2496 break; 2497 case 0x01: 2498 break; 2499 case 0x02: 2500 break; 2501 case 0x03: 2502 break; 2503 case 0x04: 2504 2505 break; 2506 case 0x05: 2507 break; 2508 case 0x06: 2509 { 2510 u32 ODMFlag; 2511 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag)); 2512 ODMFlag = (u32)(0x0f&arg); 2513 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag)); 2514 } 2515 break; 2516 case 0x07: 2517 break; 2518 case 0x08: 2519 { 2520 } 2521 break; 2522 case 0x09: 2523 break; 2524 case 0x0a: 2525 { 2526 int max_mac_id = 0; 2527 max_mac_id = rtw_search_max_mac_id(padapter); 2528 printk("%s ==> max_mac_id = %d\n", __func__, max_mac_id); 2529 } 2530 break; 2531 case 0x0b: /* Enable = 1, Disable = 0 driver control vrtl_carrier_sense. */ 2532 if (arg == 0) { 2533 padapter->driver_vcs_en = 0; 2534 } else if (arg == 1) { 2535 padapter->driver_vcs_en = 1; 2536 2537 if (extra_arg > 2) 2538 padapter->driver_vcs_type = 1; 2539 else 2540 padapter->driver_vcs_type = extra_arg; 2541 } 2542 break; 2543 case 0x0c:/* dump rx/tx packet */ 2544 { 2545 if (arg == 0) 2546 /* pHalData->bDumpRxPkt =extra_arg; */ 2547 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg)); 2548 else if (arg == 1) 2549 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg)); 2550 } 2551 break; 2552 case 0x0e: 2553 { 2554 if (arg == 0) { 2555 padapter->driver_rx_ampdu_factor = 0xFF; 2556 } else if (arg == 1) { 2557 2558 if ((extra_arg & 0x03) > 0x03) 2559 padapter->driver_rx_ampdu_factor = 0xFF; 2560 else 2561 padapter->driver_rx_ampdu_factor = extra_arg; 2562 } 2563 } 2564 break; 2565 2566 case 0x10:/* driver version display */ 2567 netdev_dbg(dev, "%s %s\n", "rtl8723bs", DRIVERVERSION); 2568 break; 2569 case 0x11:/* dump linked status */ 2570 { 2571 linked_info_dump(padapter, extra_arg); 2572 } 2573 break; 2574 case 0x12: /* set rx_stbc */ 2575 { 2576 struct registry_priv *pregpriv = &padapter->registrypriv; 2577 /* 0: disable, bit(0):enable 2.4g */ 2578 /* default is set to enable 2.4GHZ */ 2579 if (extra_arg == 0 || extra_arg == 1) 2580 pregpriv->rx_stbc = extra_arg; 2581 } 2582 break; 2583 case 0x13: /* set ampdu_enable */ 2584 { 2585 struct registry_priv *pregpriv = &padapter->registrypriv; 2586 /* 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) */ 2587 if (extra_arg < 3) 2588 pregpriv->ampdu_enable = extra_arg; 2589 } 2590 break; 2591 case 0x14: 2592 { 2593 } 2594 break; 2595 case 0x16: 2596 { 2597 if (arg == 0xff) { 2598 rtw_odm_dbg_comp_msg(padapter); 2599 } else { 2600 u64 dbg_comp = (u64)extra_arg; 2601 rtw_odm_dbg_comp_set(padapter, dbg_comp); 2602 } 2603 } 2604 break; 2605 #ifdef DBG_FIXED_CHAN 2606 case 0x17: 2607 { 2608 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2609 printk("===> Fixed channel to %d\n", extra_arg); 2610 pmlmeext->fixed_chan = extra_arg; 2611 2612 } 2613 break; 2614 #endif 2615 case 0x18: 2616 { 2617 printk("===> Switch USB Mode %d\n", extra_arg); 2618 rtw_hal_set_hwreg(padapter, HW_VAR_USB_MODE, (u8 *)&extra_arg); 2619 } 2620 break; 2621 case 0x19: 2622 { 2623 struct registry_priv *pregistrypriv = &padapter->registrypriv; 2624 /* extra_arg : */ 2625 /* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, */ 2626 /* BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */ 2627 if (arg == 0) 2628 pregistrypriv->ldpc_cap = 0x00; 2629 else if (arg == 1) 2630 pregistrypriv->ldpc_cap = (u8)(extra_arg&0x33); 2631 } 2632 break; 2633 case 0x1a: 2634 { 2635 struct registry_priv *pregistrypriv = &padapter->registrypriv; 2636 /* extra_arg : */ 2637 /* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, */ 2638 /* BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */ 2639 if (arg == 0) 2640 pregistrypriv->stbc_cap = 0x00; 2641 else if (arg == 1) 2642 pregistrypriv->stbc_cap = (u8)(extra_arg&0x33); 2643 } 2644 break; 2645 case 0x1b: 2646 { 2647 struct registry_priv *pregistrypriv = &padapter->registrypriv; 2648 2649 if (arg == 0) { 2650 init_mlme_default_rate_set(padapter); 2651 pregistrypriv->ht_enable = (u8)rtw_ht_enable; 2652 } else if (arg == 1) { 2653 2654 int i; 2655 u8 max_rx_rate; 2656 2657 max_rx_rate = (u8)extra_arg; 2658 2659 if (max_rx_rate < 0xc) { /* max_rx_rate < MSC0 -> B or G -> disable HT */ 2660 pregistrypriv->ht_enable = 0; 2661 for (i = 0; i < NumRates; i++) { 2662 if (pmlmeext->datarate[i] > max_rx_rate) 2663 pmlmeext->datarate[i] = 0xff; 2664 } 2665 2666 } 2667 else if (max_rx_rate < 0x1c) { /* mcs0~mcs15 */ 2668 u32 mcs_bitmap = 0x0; 2669 2670 for (i = 0; i < ((max_rx_rate + 1) - 0xc); i++) 2671 mcs_bitmap |= BIT(i); 2672 2673 set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap); 2674 } 2675 } 2676 } 2677 break; 2678 case 0x1c: /* enable/disable driver control AMPDU Density for peer sta's rx */ 2679 { 2680 if (arg == 0) { 2681 padapter->driver_ampdu_spacing = 0xFF; 2682 } else if (arg == 1) { 2683 2684 if (extra_arg > 0x07) 2685 padapter->driver_ampdu_spacing = 0xFF; 2686 else 2687 padapter->driver_ampdu_spacing = extra_arg; 2688 } 2689 } 2690 break; 2691 case 0x23: 2692 { 2693 padapter->bNotifyChannelChange = extra_arg; 2694 break; 2695 } 2696 case 0x24: 2697 { 2698 break; 2699 } 2700 case 0xaa: 2701 { 2702 if ((extra_arg & 0x7F) > 0x3F) 2703 extra_arg = 0xFF; 2704 padapter->fix_rate = extra_arg; 2705 } 2706 break; 2707 case 0xdd:/* registers dump , 0 for mac reg, 1 for bb reg, 2 for rf reg */ 2708 { 2709 if (extra_arg == 0) 2710 mac_reg_dump(padapter); 2711 else if (extra_arg == 1) 2712 bb_reg_dump(padapter); 2713 else if (extra_arg == 2) 2714 rf_reg_dump(padapter); 2715 } 2716 break; 2717 2718 case 0xee:/* turn on/off dynamic funcs */ 2719 { 2720 u32 odm_flag; 2721 2722 if (0xf == extra_arg) { 2723 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag); 2724 } else { 2725 /*extra_arg = 0 - disable all dynamic func 2726 extra_arg = 1 - disable DIG 2727 extra_arg = 2 - disable tx power tracking 2728 extra_arg = 3 - turn on all dynamic func 2729 */ 2730 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg)); 2731 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag); 2732 } 2733 } 2734 break; 2735 2736 case 0xfd: 2737 rtw_write8(padapter, 0xc50, arg); 2738 rtw_write8(padapter, 0xc58, arg); 2739 break; 2740 case 0xfe: 2741 break; 2742 case 0xff: 2743 { 2744 } 2745 break; 2746 } 2747 break; 2748 default: 2749 break; 2750 } 2751 2752 2753 return 0; 2754 2755 } 2756 2757 static int wpa_set_param(struct net_device *dev, u8 name, u32 value) 2758 { 2759 uint ret = 0; 2760 struct adapter *padapter = rtw_netdev_priv(dev); 2761 2762 switch (name) { 2763 case IEEE_PARAM_WPA_ENABLED: 2764 2765 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */ 2766 2767 /* ret = ieee80211_wpa_enable(ieee, value); */ 2768 2769 switch ((value)&0xff) { 2770 case 1: /* WPA */ 2771 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */ 2772 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; 2773 break; 2774 case 2: /* WPA2 */ 2775 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */ 2776 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; 2777 break; 2778 } 2779 2780 break; 2781 2782 case IEEE_PARAM_TKIP_COUNTERMEASURES: 2783 /* ieee->tkip_countermeasures =value; */ 2784 break; 2785 2786 case IEEE_PARAM_DROP_UNENCRYPTED: 2787 { 2788 /* HACK: 2789 * 2790 * wpa_supplicant calls set_wpa_enabled when the driver 2791 * is loaded and unloaded, regardless of if WPA is being 2792 * used. No other calls are made which can be used to 2793 * determine if encryption will be used or not prior to 2794 * association being expected. If encryption is not being 2795 * used, drop_unencrypted is set to false, else true -- we 2796 * can use this to determine if the CAP_PRIVACY_ON bit should 2797 * be set. 2798 */ 2799 break; 2800 2801 } 2802 case IEEE_PARAM_PRIVACY_INVOKED: 2803 2804 /* ieee->privacy_invoked =value; */ 2805 2806 break; 2807 2808 case IEEE_PARAM_AUTH_ALGS: 2809 2810 ret = wpa_set_auth_algs(dev, value); 2811 2812 break; 2813 2814 case IEEE_PARAM_IEEE_802_1X: 2815 2816 /* ieee->ieee802_1x =value; */ 2817 2818 break; 2819 2820 case IEEE_PARAM_WPAX_SELECT: 2821 2822 /* added for WPA2 mixed mode */ 2823 /* 2824 spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags); 2825 ieee->wpax_type_set = 1; 2826 ieee->wpax_type_notify = value; 2827 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags); 2828 */ 2829 2830 break; 2831 2832 default: 2833 2834 2835 2836 ret = -EOPNOTSUPP; 2837 2838 2839 break; 2840 2841 } 2842 2843 return ret; 2844 2845 } 2846 2847 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason) 2848 { 2849 int ret = 0; 2850 struct adapter *padapter = rtw_netdev_priv(dev); 2851 2852 switch (command) { 2853 case IEEE_MLME_STA_DEAUTH: 2854 2855 if (!rtw_set_802_11_disassociate(padapter)) 2856 ret = -1; 2857 2858 break; 2859 2860 case IEEE_MLME_STA_DISASSOC: 2861 2862 if (!rtw_set_802_11_disassociate(padapter)) 2863 ret = -1; 2864 2865 break; 2866 2867 default: 2868 ret = -EOPNOTSUPP; 2869 break; 2870 } 2871 2872 return ret; 2873 2874 } 2875 2876 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) 2877 { 2878 struct ieee_param *param; 2879 uint ret = 0; 2880 2881 /* down(&ieee->wx_sem); */ 2882 2883 if (!p->pointer || p->length != sizeof(struct ieee_param)) 2884 return -EINVAL; 2885 2886 param = rtw_malloc(p->length); 2887 if (param == NULL) 2888 return -ENOMEM; 2889 2890 if (copy_from_user(param, p->pointer, p->length)) { 2891 kfree(param); 2892 return -EFAULT; 2893 } 2894 2895 switch (param->cmd) { 2896 2897 case IEEE_CMD_SET_WPA_PARAM: 2898 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value); 2899 break; 2900 2901 case IEEE_CMD_SET_WPA_IE: 2902 /* ret = wpa_set_wpa_ie(dev, param, p->length); */ 2903 ret = rtw_set_wpa_ie(rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len); 2904 break; 2905 2906 case IEEE_CMD_SET_ENCRYPTION: 2907 ret = wpa_set_encryption(dev, param, p->length); 2908 break; 2909 2910 case IEEE_CMD_MLME: 2911 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code); 2912 break; 2913 2914 default: 2915 ret = -EOPNOTSUPP; 2916 break; 2917 2918 } 2919 2920 if (ret == 0 && copy_to_user(p->pointer, param, p->length)) 2921 ret = -EFAULT; 2922 2923 kfree(param); 2924 2925 /* up(&ieee->wx_sem); */ 2926 return ret; 2927 } 2928 2929 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) 2930 { 2931 int ret = 0; 2932 u32 wep_key_idx, wep_key_len, wep_total_len; 2933 struct ndis_802_11_wep *pwep = NULL; 2934 struct sta_info *psta = NULL, *pbcmc_sta = NULL; 2935 struct adapter *padapter = rtw_netdev_priv(dev); 2936 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2937 struct security_priv *psecuritypriv = &(padapter->securitypriv); 2938 struct sta_priv *pstapriv = &padapter->stapriv; 2939 char *txkey = padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey; 2940 char *rxkey = padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey; 2941 char *grpkey = psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey; 2942 2943 param->u.crypt.err = 0; 2944 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; 2945 2946 /* sizeof(struct ieee_param) = 64 bytes; */ 2947 /* if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */ 2948 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) { 2949 ret = -EINVAL; 2950 goto exit; 2951 } 2952 2953 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 2954 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 2955 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 2956 if (param->u.crypt.idx >= WEP_KEYS) { 2957 ret = -EINVAL; 2958 goto exit; 2959 } 2960 } else { 2961 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 2962 if (!psta) 2963 /* ret = -EINVAL; */ 2964 goto exit; 2965 } 2966 2967 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) { 2968 /* todo:clear default encryption keys */ 2969 2970 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 2971 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled; 2972 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; 2973 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; 2974 2975 goto exit; 2976 } 2977 2978 2979 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) { 2980 wep_key_idx = param->u.crypt.idx; 2981 wep_key_len = param->u.crypt.key_len; 2982 2983 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) { 2984 ret = -EINVAL; 2985 goto exit; 2986 } 2987 2988 2989 if (wep_key_len > 0) { 2990 wep_key_len = wep_key_len <= 5 ? 5 : 13; 2991 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); 2992 pwep = kzalloc(wep_total_len, GFP_KERNEL); 2993 if (!pwep) 2994 goto exit; 2995 2996 pwep->KeyLength = wep_key_len; 2997 pwep->Length = wep_total_len; 2998 2999 } 3000 3001 pwep->KeyIndex = wep_key_idx; 3002 3003 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); 3004 3005 if (param->u.crypt.set_tx) { 3006 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; 3007 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; 3008 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; 3009 psecuritypriv->dot118021XGrpPrivacy = _WEP40_; 3010 3011 if (pwep->KeyLength == 13) { 3012 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; 3013 psecuritypriv->dot118021XGrpPrivacy = _WEP104_; 3014 } 3015 3016 3017 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; 3018 3019 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); 3020 3021 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; 3022 3023 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1); 3024 } else { 3025 /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */ 3026 /* psecuritypriv->dot11PrivacyKeyIndex =keyid", but can rtw_set_key to cam */ 3027 3028 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); 3029 3030 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; 3031 3032 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0); 3033 } 3034 3035 goto exit; 3036 3037 } 3038 3039 3040 if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* group key */ 3041 if (param->u.crypt.set_tx == 1) { 3042 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 3043 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 3044 3045 psecuritypriv->dot118021XGrpPrivacy = _WEP40_; 3046 if (param->u.crypt.key_len == 13) 3047 psecuritypriv->dot118021XGrpPrivacy = _WEP104_; 3048 3049 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 3050 psecuritypriv->dot118021XGrpPrivacy = _TKIP_; 3051 3052 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 3053 3054 /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ 3055 /* set mic key */ 3056 memcpy(txkey, &(param->u.crypt.key[16]), 8); 3057 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); 3058 3059 psecuritypriv->busetkipkey = true; 3060 3061 } 3062 else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 3063 psecuritypriv->dot118021XGrpPrivacy = _AES_; 3064 3065 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 3066 } else { 3067 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; 3068 } 3069 3070 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; 3071 3072 psecuritypriv->binstallGrpkey = true; 3073 3074 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* */ 3075 3076 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); 3077 3078 pbcmc_sta = rtw_get_bcmc_stainfo(padapter); 3079 if (pbcmc_sta) { 3080 pbcmc_sta->ieee8021x_blocked = false; 3081 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */ 3082 } 3083 } 3084 3085 goto exit; 3086 3087 } 3088 3089 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */ 3090 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 3091 if (param->u.crypt.set_tx == 1) { 3092 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 3093 3094 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 3095 psta->dot118021XPrivacy = _WEP40_; 3096 if (param->u.crypt.key_len == 13) 3097 psta->dot118021XPrivacy = _WEP104_; 3098 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 3099 psta->dot118021XPrivacy = _TKIP_; 3100 3101 /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ 3102 /* set mic key */ 3103 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); 3104 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); 3105 3106 psecuritypriv->busetkipkey = true; 3107 3108 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 3109 3110 psta->dot118021XPrivacy = _AES_; 3111 } else { 3112 psta->dot118021XPrivacy = _NO_PRIVACY_; 3113 } 3114 3115 rtw_ap_set_pairwise_key(padapter, psta); 3116 3117 psta->ieee8021x_blocked = false; 3118 3119 } else { /* group key??? */ 3120 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 3121 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 3122 3123 psecuritypriv->dot118021XGrpPrivacy = _WEP40_; 3124 if (param->u.crypt.key_len == 13) 3125 psecuritypriv->dot118021XGrpPrivacy = _WEP104_; 3126 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 3127 psecuritypriv->dot118021XGrpPrivacy = _TKIP_; 3128 3129 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 3130 3131 /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ 3132 /* set mic key */ 3133 memcpy(txkey, &(param->u.crypt.key[16]), 8); 3134 memcpy(rxkey, &(param->u.crypt.key[24]), 8); 3135 3136 psecuritypriv->busetkipkey = true; 3137 3138 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 3139 psecuritypriv->dot118021XGrpPrivacy = _AES_; 3140 3141 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 3142 } else { 3143 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; 3144 } 3145 3146 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; 3147 3148 psecuritypriv->binstallGrpkey = true; 3149 3150 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* */ 3151 3152 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); 3153 3154 pbcmc_sta = rtw_get_bcmc_stainfo(padapter); 3155 if (pbcmc_sta) { 3156 pbcmc_sta->ieee8021x_blocked = false; 3157 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */ 3158 } 3159 } 3160 } 3161 } 3162 3163 exit: 3164 kfree(pwep); 3165 3166 return ret; 3167 3168 } 3169 3170 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len) 3171 { 3172 int ret = 0; 3173 struct adapter *padapter = rtw_netdev_priv(dev); 3174 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3175 struct sta_priv *pstapriv = &padapter->stapriv; 3176 unsigned char *pbuf = param->u.bcn_ie.buf; 3177 3178 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 3179 return -EINVAL; 3180 3181 memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2); 3182 3183 if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0)) 3184 pstapriv->max_num_sta = NUM_STA; 3185 3186 3187 if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS)/* 12 = param header, 2:no packed */ 3188 ret = 0; 3189 else 3190 ret = -EINVAL; 3191 3192 3193 return ret; 3194 3195 } 3196 3197 static void rtw_hostapd_sta_flush(struct net_device *dev) 3198 { 3199 /* _irqL irqL; */ 3200 /* struct list_head *phead, *plist; */ 3201 /* struct sta_info *psta = NULL; */ 3202 struct adapter *padapter = rtw_netdev_priv(dev); 3203 /* struct sta_priv *pstapriv = &padapter->stapriv; */ 3204 3205 flush_all_cam_entry(padapter); /* clear CAM */ 3206 3207 rtw_sta_flush(padapter); 3208 } 3209 3210 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) 3211 { 3212 int ret = 0; 3213 struct sta_info *psta = NULL; 3214 struct adapter *padapter = rtw_netdev_priv(dev); 3215 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3216 struct sta_priv *pstapriv = &padapter->stapriv; 3217 3218 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 3219 return -EINVAL; 3220 3221 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 3222 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 3223 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3224 return -EINVAL; 3225 } 3226 3227 /* 3228 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 3229 if (psta) 3230 { 3231 spin_lock_bh(&(pstapriv->sta_hash_lock)); 3232 rtw_free_stainfo(padapter, psta); 3233 spin_unlock_bh(&(pstapriv->sta_hash_lock)); 3234 3235 psta = NULL; 3236 } 3237 */ 3238 /* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */ 3239 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 3240 if (psta) { 3241 int flags = param->u.add_sta.flags; 3242 3243 psta->aid = param->u.add_sta.aid;/* aid = 1~2007 */ 3244 3245 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16); 3246 3247 3248 /* check wmm cap. */ 3249 if (WLAN_STA_WME&flags) 3250 psta->qos_option = 1; 3251 else 3252 psta->qos_option = 0; 3253 3254 if (pmlmepriv->qospriv.qos_option == 0) 3255 psta->qos_option = 0; 3256 3257 /* chec 802.11n ht cap. */ 3258 if (WLAN_STA_HT&flags) { 3259 psta->htpriv.ht_option = true; 3260 psta->qos_option = 1; 3261 memcpy((void *)&psta->htpriv.ht_cap, (void *)¶m->u.add_sta.ht_cap, sizeof(struct ieee80211_ht_cap)); 3262 } else { 3263 psta->htpriv.ht_option = false; 3264 } 3265 3266 if (pmlmepriv->htpriv.ht_option == false) 3267 psta->htpriv.ht_option = false; 3268 3269 update_sta_info_apmode(padapter, psta); 3270 3271 3272 } else { 3273 ret = -ENOMEM; 3274 } 3275 3276 return ret; 3277 3278 } 3279 3280 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) 3281 { 3282 int ret = 0; 3283 struct sta_info *psta = NULL; 3284 struct adapter *padapter = rtw_netdev_priv(dev); 3285 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3286 struct sta_priv *pstapriv = &padapter->stapriv; 3287 3288 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 3289 return -EINVAL; 3290 3291 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 3292 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 3293 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3294 return -EINVAL; 3295 } 3296 3297 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 3298 if (psta) { 3299 u8 updated = false; 3300 3301 spin_lock_bh(&pstapriv->asoc_list_lock); 3302 if (list_empty(&psta->asoc_list) == false) { 3303 list_del_init(&psta->asoc_list); 3304 pstapriv->asoc_list_cnt--; 3305 updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); 3306 3307 } 3308 spin_unlock_bh(&pstapriv->asoc_list_lock); 3309 3310 associated_clients_update(padapter, updated); 3311 3312 psta = NULL; 3313 3314 } 3315 3316 return ret; 3317 3318 } 3319 3320 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len) 3321 { 3322 int ret = 0; 3323 struct sta_info *psta = NULL; 3324 struct adapter *padapter = rtw_netdev_priv(dev); 3325 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3326 struct sta_priv *pstapriv = &padapter->stapriv; 3327 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param; 3328 struct sta_data *psta_data = (struct sta_data *)param_ex->data; 3329 3330 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 3331 return -EINVAL; 3332 3333 if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff && 3334 param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff && 3335 param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) { 3336 return -EINVAL; 3337 } 3338 3339 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr); 3340 if (psta) { 3341 psta_data->aid = (u16)psta->aid; 3342 psta_data->capability = psta->capability; 3343 psta_data->flags = psta->flags; 3344 3345 /* 3346 nonerp_set : BIT(0) 3347 no_short_slot_time_set : BIT(1) 3348 no_short_preamble_set : BIT(2) 3349 no_ht_gf_set : BIT(3) 3350 no_ht_set : BIT(4) 3351 ht_20mhz_set : BIT(5) 3352 */ 3353 3354 psta_data->sta_set = ((psta->nonerp_set) | 3355 (psta->no_short_slot_time_set << 1) | 3356 (psta->no_short_preamble_set << 2) | 3357 (psta->no_ht_gf_set << 3) | 3358 (psta->no_ht_set << 4) | 3359 (psta->ht_20mhz_set << 5)); 3360 3361 psta_data->tx_supp_rates_len = psta->bssratelen; 3362 memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen); 3363 memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct ieee80211_ht_cap)); 3364 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts; 3365 psta_data->rx_bytes = psta->sta_stats.rx_bytes; 3366 psta_data->rx_drops = psta->sta_stats.rx_drops; 3367 3368 psta_data->tx_pkts = psta->sta_stats.tx_pkts; 3369 psta_data->tx_bytes = psta->sta_stats.tx_bytes; 3370 psta_data->tx_drops = psta->sta_stats.tx_drops; 3371 3372 3373 } else { 3374 ret = -1; 3375 } 3376 3377 return ret; 3378 3379 } 3380 3381 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param) 3382 { 3383 int ret = 0; 3384 struct sta_info *psta = NULL; 3385 struct adapter *padapter = rtw_netdev_priv(dev); 3386 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3387 struct sta_priv *pstapriv = &padapter->stapriv; 3388 3389 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 3390 return -EINVAL; 3391 3392 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 3393 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 3394 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3395 return -EINVAL; 3396 } 3397 3398 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 3399 if (psta) { 3400 if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC)) { 3401 int wpa_ie_len; 3402 int copy_len; 3403 3404 wpa_ie_len = psta->wpa_ie[1]; 3405 3406 copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2); 3407 3408 param->u.wpa_ie.len = copy_len; 3409 3410 memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len); 3411 } 3412 } else { 3413 ret = -1; 3414 } 3415 3416 return ret; 3417 3418 } 3419 3420 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len) 3421 { 3422 int ret = 0; 3423 unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; 3424 struct adapter *padapter = rtw_netdev_priv(dev); 3425 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3426 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3427 int ie_len; 3428 3429 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 3430 return -EINVAL; 3431 3432 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 3433 3434 3435 kfree(pmlmepriv->wps_beacon_ie); 3436 pmlmepriv->wps_beacon_ie = NULL; 3437 3438 if (ie_len > 0) { 3439 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len); 3440 pmlmepriv->wps_beacon_ie_len = ie_len; 3441 if (!pmlmepriv->wps_beacon_ie) 3442 return -EINVAL; 3443 3444 memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len); 3445 3446 update_beacon(padapter, WLAN_EID_VENDOR_SPECIFIC, wps_oui, true); 3447 3448 pmlmeext->bstart_bss = true; 3449 } 3450 3451 3452 return ret; 3453 3454 } 3455 3456 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len) 3457 { 3458 int ret = 0; 3459 struct adapter *padapter = rtw_netdev_priv(dev); 3460 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3461 int ie_len; 3462 3463 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 3464 return -EINVAL; 3465 3466 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 3467 3468 3469 kfree(pmlmepriv->wps_probe_resp_ie); 3470 pmlmepriv->wps_probe_resp_ie = NULL; 3471 3472 if (ie_len > 0) { 3473 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len); 3474 pmlmepriv->wps_probe_resp_ie_len = ie_len; 3475 if (!pmlmepriv->wps_probe_resp_ie) 3476 return -EINVAL; 3477 3478 memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len); 3479 } 3480 3481 3482 return ret; 3483 3484 } 3485 3486 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len) 3487 { 3488 int ret = 0; 3489 struct adapter *padapter = rtw_netdev_priv(dev); 3490 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3491 int ie_len; 3492 3493 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 3494 return -EINVAL; 3495 3496 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 3497 3498 3499 kfree(pmlmepriv->wps_assoc_resp_ie); 3500 pmlmepriv->wps_assoc_resp_ie = NULL; 3501 3502 if (ie_len > 0) { 3503 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); 3504 pmlmepriv->wps_assoc_resp_ie_len = ie_len; 3505 if (!pmlmepriv->wps_assoc_resp_ie) 3506 return -EINVAL; 3507 3508 memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len); 3509 } 3510 3511 3512 return ret; 3513 3514 } 3515 3516 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len) 3517 { 3518 int ret = 0; 3519 struct adapter *adapter = rtw_netdev_priv(dev); 3520 struct mlme_priv *mlmepriv = &(adapter->mlmepriv); 3521 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); 3522 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info); 3523 int ie_len; 3524 u8 *ssid_ie; 3525 char ssid[NDIS_802_11_LENGTH_SSID + 1]; 3526 signed int ssid_len; 3527 u8 ignore_broadcast_ssid; 3528 3529 if (check_fwstate(mlmepriv, WIFI_AP_STATE) != true) 3530 return -EPERM; 3531 3532 if (param->u.bcn_ie.reserved[0] != 0xea) 3533 return -EINVAL; 3534 3535 mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1]; 3536 3537 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 3538 ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len); 3539 3540 if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) { 3541 struct wlan_bssid_ex *pbss_network = &mlmepriv->cur_network.network; 3542 struct wlan_bssid_ex *pbss_network_ext = &mlmeinfo->network; 3543 3544 memcpy(ssid, ssid_ie+2, ssid_len); 3545 ssid[ssid_len] = 0x0; 3546 3547 memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len); 3548 pbss_network->Ssid.SsidLength = ssid_len; 3549 memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len); 3550 pbss_network_ext->Ssid.SsidLength = ssid_len; 3551 } 3552 3553 return ret; 3554 } 3555 3556 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len) 3557 { 3558 struct adapter *padapter = rtw_netdev_priv(dev); 3559 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3560 3561 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 3562 return -EINVAL; 3563 3564 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 3565 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 3566 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3567 return -EINVAL; 3568 } 3569 3570 rtw_acl_remove_sta(padapter, param->sta_addr); 3571 return 0; 3572 3573 } 3574 3575 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len) 3576 { 3577 struct adapter *padapter = rtw_netdev_priv(dev); 3578 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3579 3580 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 3581 return -EINVAL; 3582 3583 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 3584 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 3585 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3586 return -EINVAL; 3587 } 3588 3589 return rtw_acl_add_sta(padapter, param->sta_addr); 3590 3591 } 3592 3593 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len) 3594 { 3595 int ret = 0; 3596 struct adapter *padapter = rtw_netdev_priv(dev); 3597 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3598 3599 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 3600 return -EINVAL; 3601 3602 rtw_set_macaddr_acl(padapter, param->u.mlme.command); 3603 3604 return ret; 3605 } 3606 3607 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p) 3608 { 3609 struct ieee_param *param; 3610 int ret = 0; 3611 struct adapter *padapter = rtw_netdev_priv(dev); 3612 3613 /* 3614 * this function is expect to call in master mode, which allows no power saving 3615 * so, we just check hw_init_completed 3616 */ 3617 3618 if (!padapter->hw_init_completed) 3619 return -EPERM; 3620 3621 if (!p->pointer || p->length != sizeof(*param)) 3622 return -EINVAL; 3623 3624 param = rtw_malloc(p->length); 3625 if (param == NULL) 3626 return -ENOMEM; 3627 3628 if (copy_from_user(param, p->pointer, p->length)) { 3629 kfree(param); 3630 return -EFAULT; 3631 } 3632 3633 switch (param->cmd) { 3634 case RTL871X_HOSTAPD_FLUSH: 3635 3636 rtw_hostapd_sta_flush(dev); 3637 3638 break; 3639 3640 case RTL871X_HOSTAPD_ADD_STA: 3641 3642 ret = rtw_add_sta(dev, param); 3643 3644 break; 3645 3646 case RTL871X_HOSTAPD_REMOVE_STA: 3647 3648 ret = rtw_del_sta(dev, param); 3649 3650 break; 3651 3652 case RTL871X_HOSTAPD_SET_BEACON: 3653 3654 ret = rtw_set_beacon(dev, param, p->length); 3655 3656 break; 3657 3658 case RTL871X_SET_ENCRYPTION: 3659 3660 ret = rtw_set_encryption(dev, param, p->length); 3661 3662 break; 3663 3664 case RTL871X_HOSTAPD_GET_WPAIE_STA: 3665 3666 ret = rtw_get_sta_wpaie(dev, param); 3667 3668 break; 3669 3670 case RTL871X_HOSTAPD_SET_WPS_BEACON: 3671 3672 ret = rtw_set_wps_beacon(dev, param, p->length); 3673 3674 break; 3675 3676 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP: 3677 3678 ret = rtw_set_wps_probe_resp(dev, param, p->length); 3679 3680 break; 3681 3682 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP: 3683 3684 ret = rtw_set_wps_assoc_resp(dev, param, p->length); 3685 3686 break; 3687 3688 case RTL871X_HOSTAPD_SET_HIDDEN_SSID: 3689 3690 ret = rtw_set_hidden_ssid(dev, param, p->length); 3691 3692 break; 3693 3694 case RTL871X_HOSTAPD_GET_INFO_STA: 3695 3696 ret = rtw_ioctl_get_sta_data(dev, param, p->length); 3697 3698 break; 3699 3700 case RTL871X_HOSTAPD_SET_MACADDR_ACL: 3701 3702 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length); 3703 3704 break; 3705 3706 case RTL871X_HOSTAPD_ACL_ADD_STA: 3707 3708 ret = rtw_ioctl_acl_add_sta(dev, param, p->length); 3709 3710 break; 3711 3712 case RTL871X_HOSTAPD_ACL_REMOVE_STA: 3713 3714 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length); 3715 3716 break; 3717 3718 default: 3719 ret = -EOPNOTSUPP; 3720 break; 3721 3722 } 3723 3724 if (ret == 0 && copy_to_user(p->pointer, param, p->length)) 3725 ret = -EFAULT; 3726 3727 kfree(param); 3728 return ret; 3729 } 3730 3731 static int rtw_wx_set_priv(struct net_device *dev, 3732 struct iw_request_info *info, 3733 union iwreq_data *awrq, 3734 char *extra) 3735 { 3736 3737 #ifdef DEBUG_RTW_WX_SET_PRIV 3738 char *ext_dbg; 3739 #endif 3740 3741 int ret = 0; 3742 int len = 0; 3743 char *ext; 3744 3745 struct adapter *padapter = rtw_netdev_priv(dev); 3746 struct iw_point *dwrq = (struct iw_point *)awrq; 3747 3748 if (dwrq->length == 0) 3749 return -EFAULT; 3750 3751 len = dwrq->length; 3752 ext = vmalloc(len); 3753 if (!ext) 3754 return -ENOMEM; 3755 3756 if (copy_from_user(ext, dwrq->pointer, len)) { 3757 vfree(ext); 3758 return -EFAULT; 3759 } 3760 3761 #ifdef DEBUG_RTW_WX_SET_PRIV 3762 ext_dbg = vmalloc(len); 3763 if (!ext_dbg) { 3764 vfree(ext, len); 3765 return -ENOMEM; 3766 } 3767 3768 memcpy(ext_dbg, ext, len); 3769 #endif 3770 3771 /* added for wps2.0 @20110524 */ 3772 if (dwrq->flags == 0x8766 && len > 8) { 3773 u32 cp_sz; 3774 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3775 u8 *probereq_wpsie = ext; 3776 int probereq_wpsie_len = len; 3777 u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; 3778 3779 if ((WLAN_EID_VENDOR_SPECIFIC == probereq_wpsie[0]) && 3780 (!memcmp(&probereq_wpsie[2], wps_oui, 4))) { 3781 cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len; 3782 3783 if (pmlmepriv->wps_probe_req_ie) { 3784 pmlmepriv->wps_probe_req_ie_len = 0; 3785 kfree(pmlmepriv->wps_probe_req_ie); 3786 pmlmepriv->wps_probe_req_ie = NULL; 3787 } 3788 3789 pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz); 3790 if (pmlmepriv->wps_probe_req_ie == NULL) { 3791 printk("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__); 3792 ret = -EINVAL; 3793 goto FREE_EXT; 3794 3795 } 3796 3797 memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz); 3798 pmlmepriv->wps_probe_req_ie_len = cp_sz; 3799 3800 } 3801 3802 goto FREE_EXT; 3803 3804 } 3805 3806 if (len >= WEXT_CSCAN_HEADER_SIZE 3807 && !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) { 3808 ret = rtw_wx_set_scan(dev, info, awrq, ext); 3809 goto FREE_EXT; 3810 } 3811 3812 FREE_EXT: 3813 3814 vfree(ext); 3815 #ifdef DEBUG_RTW_WX_SET_PRIV 3816 vfree(ext_dbg); 3817 #endif 3818 3819 return ret; 3820 3821 } 3822 3823 static int rtw_pm_set(struct net_device *dev, 3824 struct iw_request_info *info, 3825 union iwreq_data *wrqu, char *extra) 3826 { 3827 int ret = 0; 3828 unsigned mode = 0; 3829 struct adapter *padapter = rtw_netdev_priv(dev); 3830 3831 if (!memcmp(extra, "lps =", 4)) { 3832 sscanf(extra+4, "%u", &mode); 3833 ret = rtw_pm_set_lps(padapter, mode); 3834 } else if (!memcmp(extra, "ips =", 4)) { 3835 sscanf(extra+4, "%u", &mode); 3836 ret = rtw_pm_set_ips(padapter, mode); 3837 } else { 3838 ret = -EINVAL; 3839 } 3840 3841 return ret; 3842 } 3843 3844 static int rtw_test( 3845 struct net_device *dev, 3846 struct iw_request_info *info, 3847 union iwreq_data *wrqu, char *extra) 3848 { 3849 u32 len; 3850 u8 *pbuf, *pch; 3851 char *ptmp; 3852 u8 *delim = ","; 3853 struct adapter *padapter = rtw_netdev_priv(dev); 3854 3855 3856 len = wrqu->data.length; 3857 3858 pbuf = rtw_zmalloc(len); 3859 if (!pbuf) 3860 return -ENOMEM; 3861 3862 if (copy_from_user(pbuf, wrqu->data.pointer, len)) { 3863 kfree(pbuf); 3864 return -EFAULT; 3865 } 3866 3867 ptmp = (char *)pbuf; 3868 pch = strsep(&ptmp, delim); 3869 if ((pch == NULL) || (strlen(pch) == 0)) { 3870 kfree(pbuf); 3871 return -EFAULT; 3872 } 3873 3874 if (strcmp(pch, "bton") == 0) 3875 hal_btcoex_SetManualControl(padapter, false); 3876 3877 if (strcmp(pch, "btoff") == 0) 3878 hal_btcoex_SetManualControl(padapter, true); 3879 3880 if (strcmp(pch, "h2c") == 0) { 3881 u8 param[8]; 3882 u8 count = 0; 3883 u32 tmp; 3884 u8 i; 3885 u32 pos; 3886 s32 ret; 3887 3888 3889 do { 3890 pch = strsep(&ptmp, delim); 3891 if ((pch == NULL) || (strlen(pch) == 0)) 3892 break; 3893 3894 sscanf(pch, "%x", &tmp); 3895 param[count++] = (u8)tmp; 3896 } while (count < 8); 3897 3898 if (count == 0) { 3899 kfree(pbuf); 3900 return -EFAULT; 3901 } 3902 3903 ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, ¶m[1]); 3904 3905 pos = sprintf(extra, "H2C ID = 0x%02x content =", param[0]); 3906 for (i = 1; i < count; i++) 3907 pos += sprintf(extra+pos, "%02x,", param[i]); 3908 extra[pos] = 0; 3909 pos--; 3910 pos += sprintf(extra+pos, " %s", ret == _FAIL?"FAIL":"OK"); 3911 3912 wrqu->data.length = strlen(extra) + 1; 3913 } 3914 3915 kfree(pbuf); 3916 return 0; 3917 } 3918 3919 static iw_handler rtw_handlers[] = { 3920 NULL, /* SIOCSIWCOMMIT */ 3921 rtw_wx_get_name, /* SIOCGIWNAME */ 3922 dummy, /* SIOCSIWNWID */ 3923 dummy, /* SIOCGIWNWID */ 3924 rtw_wx_set_freq, /* SIOCSIWFREQ */ 3925 rtw_wx_get_freq, /* SIOCGIWFREQ */ 3926 rtw_wx_set_mode, /* SIOCSIWMODE */ 3927 rtw_wx_get_mode, /* SIOCGIWMODE */ 3928 dummy, /* SIOCSIWSENS */ 3929 rtw_wx_get_sens, /* SIOCGIWSENS */ 3930 NULL, /* SIOCSIWRANGE */ 3931 rtw_wx_get_range, /* SIOCGIWRANGE */ 3932 rtw_wx_set_priv, /* SIOCSIWPRIV */ 3933 NULL, /* SIOCGIWPRIV */ 3934 NULL, /* SIOCSIWSTATS */ 3935 NULL, /* SIOCGIWSTATS */ 3936 dummy, /* SIOCSIWSPY */ 3937 dummy, /* SIOCGIWSPY */ 3938 NULL, /* SIOCGIWTHRSPY */ 3939 NULL, /* SIOCWIWTHRSPY */ 3940 rtw_wx_set_wap, /* SIOCSIWAP */ 3941 rtw_wx_get_wap, /* SIOCGIWAP */ 3942 rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */ 3943 dummy, /* SIOCGIWAPLIST -- depricated */ 3944 rtw_wx_set_scan, /* SIOCSIWSCAN */ 3945 rtw_wx_get_scan, /* SIOCGIWSCAN */ 3946 rtw_wx_set_essid, /* SIOCSIWESSID */ 3947 rtw_wx_get_essid, /* SIOCGIWESSID */ 3948 dummy, /* SIOCSIWNICKN */ 3949 rtw_wx_get_nick, /* SIOCGIWNICKN */ 3950 NULL, /* -- hole -- */ 3951 NULL, /* -- hole -- */ 3952 rtw_wx_set_rate, /* SIOCSIWRATE */ 3953 rtw_wx_get_rate, /* SIOCGIWRATE */ 3954 rtw_wx_set_rts, /* SIOCSIWRTS */ 3955 rtw_wx_get_rts, /* SIOCGIWRTS */ 3956 rtw_wx_set_frag, /* SIOCSIWFRAG */ 3957 rtw_wx_get_frag, /* SIOCGIWFRAG */ 3958 dummy, /* SIOCSIWTXPOW */ 3959 dummy, /* SIOCGIWTXPOW */ 3960 dummy, /* SIOCSIWRETRY */ 3961 rtw_wx_get_retry, /* SIOCGIWRETRY */ 3962 rtw_wx_set_enc, /* SIOCSIWENCODE */ 3963 rtw_wx_get_enc, /* SIOCGIWENCODE */ 3964 dummy, /* SIOCSIWPOWER */ 3965 rtw_wx_get_power, /* SIOCGIWPOWER */ 3966 NULL, /*---hole---*/ 3967 NULL, /*---hole---*/ 3968 rtw_wx_set_gen_ie, /* SIOCSIWGENIE */ 3969 NULL, /* SIOCGWGENIE */ 3970 rtw_wx_set_auth, /* SIOCSIWAUTH */ 3971 NULL, /* SIOCGIWAUTH */ 3972 rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ 3973 NULL, /* SIOCGIWENCODEEXT */ 3974 rtw_wx_set_pmkid, /* SIOCSIWPMKSA */ 3975 NULL, /*---hole---*/ 3976 }; 3977 3978 static const struct iw_priv_args rtw_private_args[] = { 3979 { 3980 SIOCIWFIRSTPRIV + 0x0, 3981 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write" 3982 }, 3983 { 3984 SIOCIWFIRSTPRIV + 0x1, 3985 IW_PRIV_TYPE_CHAR | 0x7FF, 3986 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read" 3987 }, 3988 { 3989 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext" 3990 }, 3991 { 3992 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl" 3993 }, 3994 { 3995 SIOCIWFIRSTPRIV + 0x4, 3996 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" 3997 }, 3998 { 3999 SIOCIWFIRSTPRIV + 0x5, 4000 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid" 4001 }, 4002 { 4003 SIOCIWFIRSTPRIV + 0x6, 4004 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start" 4005 }, 4006 /* for PLATFORM_MT53XX */ 4007 { 4008 SIOCIWFIRSTPRIV + 0x7, 4009 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity" 4010 }, 4011 { 4012 SIOCIWFIRSTPRIV + 0x8, 4013 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie" 4014 }, 4015 { 4016 SIOCIWFIRSTPRIV + 0x9, 4017 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie" 4018 }, 4019 4020 /* for RTK_DMP_PLATFORM */ 4021 { 4022 SIOCIWFIRSTPRIV + 0xA, 4023 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan" 4024 }, 4025 4026 { 4027 SIOCIWFIRSTPRIV + 0xB, 4028 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg" 4029 }, 4030 { 4031 SIOCIWFIRSTPRIV + 0xC, 4032 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw" 4033 }, 4034 { 4035 SIOCIWFIRSTPRIV + 0xD, 4036 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr" 4037 }, 4038 { 4039 SIOCIWFIRSTPRIV + 0x10, 4040 IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set" 4041 }, 4042 { 4043 SIOCIWFIRSTPRIV + 0x11, 4044 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "p2p_get" 4045 }, 4046 { 4047 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL" 4048 }, 4049 { 4050 SIOCIWFIRSTPRIV + 0x13, 4051 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64, "p2p_get2" 4052 }, 4053 { 4054 SIOCIWFIRSTPRIV + 0x14, 4055 IW_PRIV_TYPE_CHAR | 64, 0, "tdls" 4056 }, 4057 { 4058 SIOCIWFIRSTPRIV + 0x15, 4059 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024, "tdls_get" 4060 }, 4061 { 4062 SIOCIWFIRSTPRIV + 0x16, 4063 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set" 4064 }, 4065 4066 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ, 0, "rereg_nd_name"}, 4067 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"}, 4068 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"}, 4069 { 4070 SIOCIWFIRSTPRIV + 0x1D, 4071 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test" 4072 }, 4073 }; 4074 4075 static iw_handler rtw_private_handler[] = { 4076 rtw_wx_write32, /* 0x00 */ 4077 rtw_wx_read32, /* 0x01 */ 4078 rtw_drvext_hdl, /* 0x02 */ 4079 NULL, /* 0x03 */ 4080 4081 /* for MM DTV platform */ 4082 rtw_get_ap_info, /* 0x04 */ 4083 4084 rtw_set_pid, /* 0x05 */ 4085 rtw_wps_start, /* 0x06 */ 4086 4087 /* for PLATFORM_MT53XX */ 4088 rtw_wx_get_sensitivity, /* 0x07 */ 4089 rtw_wx_set_mtk_wps_probe_ie, /* 0x08 */ 4090 rtw_wx_set_mtk_wps_ie, /* 0x09 */ 4091 4092 /* for RTK_DMP_PLATFORM */ 4093 /* Set Channel depend on the country code */ 4094 rtw_wx_set_channel_plan, /* 0x0A */ 4095 4096 rtw_dbg_port, /* 0x0B */ 4097 rtw_wx_write_rf, /* 0x0C */ 4098 rtw_wx_read_rf, /* 0x0D */ 4099 rtw_wx_priv_null, /* 0x0E */ 4100 rtw_wx_priv_null, /* 0x0F */ 4101 rtw_p2p_set, /* 0x10 */ 4102 rtw_p2p_get, /* 0x11 */ 4103 NULL, /* 0x12 */ 4104 rtw_p2p_get2, /* 0x13 */ 4105 4106 NULL, /* 0x14 */ 4107 NULL, /* 0x15 */ 4108 4109 rtw_pm_set, /* 0x16 */ 4110 rtw_wx_priv_null, /* 0x17 */ 4111 rtw_rereg_nd_name, /* 0x18 */ 4112 rtw_wx_priv_null, /* 0x19 */ 4113 NULL, /* 0x1A */ 4114 NULL, /* 0x1B */ 4115 NULL, /* 0x1C is reserved for hostapd */ 4116 rtw_test, /* 0x1D */ 4117 }; 4118 4119 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) 4120 { 4121 struct adapter *padapter = rtw_netdev_priv(dev); 4122 struct iw_statistics *piwstats = &padapter->iwstats; 4123 int tmp_level = 0; 4124 int tmp_qual = 0; 4125 int tmp_noise = 0; 4126 4127 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) { 4128 piwstats->qual.qual = 0; 4129 piwstats->qual.level = 0; 4130 piwstats->qual.noise = 0; 4131 } else { 4132 tmp_level = padapter->recvpriv.signal_strength; 4133 tmp_qual = padapter->recvpriv.signal_qual; 4134 tmp_noise = padapter->recvpriv.noise; 4135 4136 piwstats->qual.level = tmp_level; 4137 piwstats->qual.qual = tmp_qual; 4138 piwstats->qual.noise = tmp_noise; 4139 } 4140 piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;/* IW_QUAL_DBM; */ 4141 4142 return &padapter->iwstats; 4143 } 4144 4145 struct iw_handler_def rtw_handlers_def = { 4146 .standard = rtw_handlers, 4147 .num_standard = ARRAY_SIZE(rtw_handlers), 4148 #if defined(CONFIG_WEXT_PRIV) 4149 .private = rtw_private_handler, 4150 .private_args = (struct iw_priv_args *)rtw_private_args, 4151 .num_private = ARRAY_SIZE(rtw_private_handler), 4152 .num_private_args = ARRAY_SIZE(rtw_private_args), 4153 #endif 4154 .get_wireless_stats = rtw_get_wireless_stats, 4155 }; 4156 4157 /* copy from net/wireless/wext.c start */ 4158 /* ---------------------------------------------------------------- */ 4159 /* 4160 * Calculate size of private arguments 4161 */ 4162 static const char iw_priv_type_size[] = { 4163 0, /* IW_PRIV_TYPE_NONE */ 4164 1, /* IW_PRIV_TYPE_BYTE */ 4165 1, /* IW_PRIV_TYPE_CHAR */ 4166 0, /* Not defined */ 4167 sizeof(__u32), /* IW_PRIV_TYPE_INT */ 4168 sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */ 4169 sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */ 4170 0, /* Not defined */ 4171 }; 4172 4173 static int get_priv_size(__u16 args) 4174 { 4175 int num = args & IW_PRIV_SIZE_MASK; 4176 int type = (args & IW_PRIV_TYPE_MASK) >> 12; 4177 4178 return num * iw_priv_type_size[type]; 4179 } 4180 /* copy from net/wireless/wext.c end */ 4181 4182 static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data) 4183 { 4184 int err = 0; 4185 u8 *input = NULL; 4186 u32 input_len = 0; 4187 const char delim[] = " "; 4188 u8 *output = NULL; 4189 u32 output_len = 0; 4190 u32 count = 0; 4191 u8 *buffer = NULL; 4192 u32 buffer_len = 0; 4193 char *ptr = NULL; 4194 u8 cmdname[17] = {0}; /* IFNAMSIZ+1 */ 4195 u32 cmdlen; 4196 s32 len; 4197 u8 *extra = NULL; 4198 u32 extra_size = 0; 4199 4200 s32 k; 4201 const iw_handler *priv; /* Private ioctl */ 4202 const struct iw_priv_args *priv_args; /* Private ioctl description */ 4203 u32 num_priv_args; /* Number of descriptions */ 4204 iw_handler handler; 4205 int temp; 4206 int subcmd = 0; /* sub-ioctl index */ 4207 int offset = 0; /* Space for sub-ioctl index */ 4208 4209 union iwreq_data wdata; 4210 4211 4212 memcpy(&wdata, wrq_data, sizeof(wdata)); 4213 4214 input_len = 2048; 4215 input = rtw_zmalloc(input_len); 4216 if (NULL == input) 4217 return -ENOMEM; 4218 if (copy_from_user(input, wdata.data.pointer, input_len)) { 4219 err = -EFAULT; 4220 goto exit; 4221 } 4222 ptr = input; 4223 len = strlen(input); 4224 4225 sscanf(ptr, "%16s", cmdname); 4226 cmdlen = strlen(cmdname); 4227 4228 /* skip command string */ 4229 if (cmdlen > 0) 4230 cmdlen += 1; /* skip one space */ 4231 ptr += cmdlen; 4232 len -= cmdlen; 4233 4234 priv = rtw_private_handler; 4235 priv_args = rtw_private_args; 4236 num_priv_args = ARRAY_SIZE(rtw_private_args); 4237 4238 if (num_priv_args == 0) { 4239 err = -EOPNOTSUPP; 4240 goto exit; 4241 } 4242 4243 /* Search the correct ioctl */ 4244 k = -1; 4245 while ((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname)); 4246 4247 /* If not found... */ 4248 if (k == num_priv_args) { 4249 err = -EOPNOTSUPP; 4250 goto exit; 4251 } 4252 4253 /* Watch out for sub-ioctls ! */ 4254 if (priv_args[k].cmd < SIOCDEVPRIVATE) { 4255 int j = -1; 4256 4257 /* Find the matching *real* ioctl */ 4258 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') || 4259 (priv_args[j].set_args != priv_args[k].set_args) || 4260 (priv_args[j].get_args != priv_args[k].get_args))); 4261 4262 /* If not found... */ 4263 if (j == num_priv_args) { 4264 err = -EINVAL; 4265 goto exit; 4266 } 4267 4268 /* Save sub-ioctl number */ 4269 subcmd = priv_args[k].cmd; 4270 /* Reserve one int (simplify alignment issues) */ 4271 offset = sizeof(__u32); 4272 /* Use real ioctl definition from now on */ 4273 k = j; 4274 } 4275 4276 buffer = rtw_zmalloc(4096); 4277 if (NULL == buffer) { 4278 err = -ENOMEM; 4279 goto exit; 4280 } 4281 4282 /* If we have to set some data */ 4283 if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) && 4284 (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) { 4285 u8 *str; 4286 4287 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) { 4288 case IW_PRIV_TYPE_BYTE: 4289 /* Fetch args */ 4290 count = 0; 4291 do { 4292 str = strsep(&ptr, delim); 4293 if (NULL == str) 4294 break; 4295 sscanf(str, "%i", &temp); 4296 buffer[count++] = (u8)temp; 4297 } while (1); 4298 buffer_len = count; 4299 4300 /* Number of args to fetch */ 4301 wdata.data.length = count; 4302 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) 4303 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK; 4304 4305 break; 4306 4307 case IW_PRIV_TYPE_INT: 4308 /* Fetch args */ 4309 count = 0; 4310 do { 4311 str = strsep(&ptr, delim); 4312 if (NULL == str) 4313 break; 4314 sscanf(str, "%i", &temp); 4315 ((s32 *)buffer)[count++] = (s32)temp; 4316 } while (1); 4317 buffer_len = count * sizeof(s32); 4318 4319 /* Number of args to fetch */ 4320 wdata.data.length = count; 4321 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) 4322 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK; 4323 4324 break; 4325 4326 case IW_PRIV_TYPE_CHAR: 4327 if (len > 0) { 4328 /* Size of the string to fetch */ 4329 wdata.data.length = len; 4330 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) 4331 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK; 4332 4333 /* Fetch string */ 4334 memcpy(buffer, ptr, wdata.data.length); 4335 } else { 4336 wdata.data.length = 1; 4337 buffer[0] = '\0'; 4338 } 4339 buffer_len = wdata.data.length; 4340 break; 4341 4342 default: 4343 err = -1; 4344 goto exit; 4345 } 4346 4347 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) && 4348 (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) { 4349 err = -EINVAL; 4350 goto exit; 4351 } 4352 } else { /* if args to set */ 4353 wdata.data.length = 0L; 4354 } 4355 4356 /* Those two tests are important. They define how the driver 4357 * will have to handle the data */ 4358 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) && 4359 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) { 4360 /* First case : all SET args fit within wrq */ 4361 if (offset) 4362 wdata.mode = subcmd; 4363 memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset); 4364 } else { 4365 if ((priv_args[k].set_args == 0) && 4366 (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) && 4367 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) { 4368 /* Second case : no SET args, GET args fit within wrq */ 4369 if (offset) 4370 wdata.mode = subcmd; 4371 } else { 4372 /* Third case : args won't fit in wrq, or variable number of args */ 4373 if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) { 4374 err = -EFAULT; 4375 goto exit; 4376 } 4377 wdata.data.flags = subcmd; 4378 } 4379 } 4380 4381 kfree(input); 4382 input = NULL; 4383 4384 extra_size = 0; 4385 if (IW_IS_SET(priv_args[k].cmd)) { 4386 /* Size of set arguments */ 4387 extra_size = get_priv_size(priv_args[k].set_args); 4388 4389 /* Does it fits in iwr ? */ 4390 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) && 4391 ((extra_size + offset) <= IFNAMSIZ)) 4392 extra_size = 0; 4393 } else { 4394 /* Size of get arguments */ 4395 extra_size = get_priv_size(priv_args[k].get_args); 4396 4397 /* Does it fits in iwr ? */ 4398 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) && 4399 (extra_size <= IFNAMSIZ)) 4400 extra_size = 0; 4401 } 4402 4403 if (extra_size == 0) { 4404 extra = (u8 *)&wdata; 4405 kfree(buffer); 4406 buffer = NULL; 4407 } else 4408 extra = buffer; 4409 4410 handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV]; 4411 err = handler(dev, NULL, &wdata, extra); 4412 4413 /* If we have to get some data */ 4414 if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) && 4415 (priv_args[k].get_args & IW_PRIV_SIZE_MASK)) { 4416 int j; 4417 int n = 0; /* number of args */ 4418 u8 str[20] = {0}; 4419 4420 /* Check where is the returned data */ 4421 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) && 4422 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) 4423 n = priv_args[k].get_args & IW_PRIV_SIZE_MASK; 4424 else 4425 n = wdata.data.length; 4426 4427 output = rtw_zmalloc(4096); 4428 if (NULL == output) { 4429 err = -ENOMEM; 4430 goto exit; 4431 } 4432 4433 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) { 4434 case IW_PRIV_TYPE_BYTE: 4435 /* Display args */ 4436 for (j = 0; j < n; j++) { 4437 len = scnprintf(str, sizeof(str), "%d ", extra[j]); 4438 output_len = strlen(output); 4439 if ((output_len + len + 1) > 4096) { 4440 err = -E2BIG; 4441 goto exit; 4442 } 4443 memcpy(output+output_len, str, len); 4444 } 4445 break; 4446 4447 case IW_PRIV_TYPE_INT: 4448 /* Display args */ 4449 for (j = 0; j < n; j++) { 4450 len = scnprintf(str, sizeof(str), "%d ", ((__s32 *)extra)[j]); 4451 output_len = strlen(output); 4452 if ((output_len + len + 1) > 4096) { 4453 err = -E2BIG; 4454 goto exit; 4455 } 4456 memcpy(output+output_len, str, len); 4457 } 4458 break; 4459 4460 case IW_PRIV_TYPE_CHAR: 4461 /* Display args */ 4462 memcpy(output, extra, n); 4463 break; 4464 4465 default: 4466 err = -1; 4467 goto exit; 4468 } 4469 4470 output_len = strlen(output) + 1; 4471 wrq_data->data.length = output_len; 4472 if (copy_to_user(wrq_data->data.pointer, output, output_len)) { 4473 err = -EFAULT; 4474 goto exit; 4475 } 4476 } else { /* if args to set */ 4477 wrq_data->data.length = 0; 4478 } 4479 4480 exit: 4481 kfree(input); 4482 kfree(buffer); 4483 kfree(output); 4484 4485 return err; 4486 } 4487 4488 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 4489 { 4490 struct iwreq *wrq = (struct iwreq *)rq; 4491 int ret = 0; 4492 4493 switch (cmd) { 4494 case RTL_IOCTL_WPA_SUPPLICANT: 4495 ret = wpa_supplicant_ioctl(dev, &wrq->u.data); 4496 break; 4497 case RTL_IOCTL_HOSTAPD: 4498 ret = rtw_hostapd_ioctl(dev, &wrq->u.data); 4499 break; 4500 case SIOCDEVPRIVATE: 4501 ret = rtw_ioctl_wext_private(dev, &wrq->u); 4502 break; 4503 default: 4504 ret = -EOPNOTSUPP; 4505 break; 4506 } 4507 4508 return ret; 4509 } 4510