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