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