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