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_get_ap_info(struct net_device *dev, 2429 struct iw_request_info *info, 2430 union iwreq_data *wrqu, char *extra) 2431 { 2432 int ret = 0; 2433 int wpa_ielen; 2434 u32 cnt = 0; 2435 struct list_head *plist, *phead; 2436 unsigned char *pbuf; 2437 u8 bssid[ETH_ALEN]; 2438 char data[32]; 2439 struct wlan_network *pnetwork = NULL; 2440 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2441 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2442 struct __queue *queue = &(pmlmepriv->scanned_queue); 2443 struct iw_point *pdata = &wrqu->data; 2444 2445 DBG_871X("+rtw_get_aplist_info\n"); 2446 2447 if ((padapter->bDriverStopped) || (pdata == NULL)) { 2448 ret = -EINVAL; 2449 goto exit; 2450 } 2451 2452 while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == true) { 2453 msleep(30); 2454 cnt++; 2455 if (cnt > 100) 2456 break; 2457 } 2458 2459 2460 /* pdata->length = 0;? */ 2461 pdata->flags = 0; 2462 if (pdata->length>=32) { 2463 if (copy_from_user(data, pdata->pointer, 32)) { 2464 ret = -EINVAL; 2465 goto exit; 2466 } 2467 } else { 2468 ret = -EINVAL; 2469 goto exit; 2470 } 2471 2472 spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); 2473 2474 phead = get_list_head(queue); 2475 plist = get_next(phead); 2476 2477 while (1) { 2478 if (phead == plist) 2479 break; 2480 2481 2482 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); 2483 2484 if (!mac_pton(data, bssid)) { 2485 DBG_871X("Invalid BSSID '%s'.\n", (u8 *)data); 2486 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 2487 return -EINVAL; 2488 } 2489 2490 2491 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) { /* BSSID match, then check if supporting wpa/wpa2 */ 2492 DBG_871X("BSSID:" MAC_FMT "\n", MAC_ARG(bssid)); 2493 2494 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); 2495 if (pbuf && (wpa_ielen>0)) { 2496 pdata->flags = 1; 2497 break; 2498 } 2499 2500 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); 2501 if (pbuf && (wpa_ielen>0)) { 2502 pdata->flags = 2; 2503 break; 2504 } 2505 } 2506 2507 plist = get_next(plist); 2508 2509 } 2510 2511 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 2512 2513 if (pdata->length>=34) { 2514 if (copy_to_user((u8 __force __user *)pdata->pointer+32, (u8 *)&pdata->flags, 1)) { 2515 ret = -EINVAL; 2516 goto exit; 2517 } 2518 } 2519 2520 exit: 2521 2522 return ret; 2523 2524 } 2525 2526 static int rtw_set_pid(struct net_device *dev, 2527 struct iw_request_info *info, 2528 union iwreq_data *wrqu, char *extra) 2529 { 2530 2531 int ret = 0; 2532 struct adapter *padapter = rtw_netdev_priv(dev); 2533 int *pdata = (int *)wrqu; 2534 int selector; 2535 2536 if ((padapter->bDriverStopped) || (pdata == NULL)) { 2537 ret = -EINVAL; 2538 goto exit; 2539 } 2540 2541 selector = *pdata; 2542 if (selector < 3 && selector >= 0) { 2543 padapter->pid[selector] = *(pdata+1); 2544 DBG_871X("%s set pid[%d]=%d\n", __func__, selector , padapter->pid[selector]); 2545 } 2546 else 2547 DBG_871X("%s selector %d error\n", __func__, selector); 2548 2549 exit: 2550 2551 return ret; 2552 2553 } 2554 2555 static int rtw_wps_start(struct net_device *dev, 2556 struct iw_request_info *info, 2557 union iwreq_data *wrqu, char *extra) 2558 { 2559 2560 int ret = 0; 2561 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2562 struct iw_point *pdata = &wrqu->data; 2563 u32 u32wps_start = 0; 2564 unsigned int uintRet = 0; 2565 2566 if ((true == padapter->bDriverStopped) ||(true ==padapter->bSurpriseRemoved) || (NULL == pdata)) { 2567 ret = -EINVAL; 2568 goto exit; 2569 } 2570 2571 uintRet = copy_from_user((void *)&u32wps_start, pdata->pointer, 4); 2572 if (u32wps_start == 0) 2573 u32wps_start = *extra; 2574 2575 DBG_871X("[%s] wps_start = %d\n", __func__, u32wps_start); 2576 2577 exit: 2578 2579 return ret; 2580 2581 } 2582 2583 static int rtw_p2p_set(struct net_device *dev, 2584 struct iw_request_info *info, 2585 union iwreq_data *wrqu, char *extra) 2586 { 2587 2588 return 0; 2589 2590 } 2591 2592 static int rtw_p2p_get(struct net_device *dev, 2593 struct iw_request_info *info, 2594 union iwreq_data *wrqu, char *extra) 2595 { 2596 2597 return 0; 2598 2599 } 2600 2601 static int rtw_p2p_get2(struct net_device *dev, 2602 struct iw_request_info *info, 2603 union iwreq_data *wrqu, char *extra) 2604 { 2605 2606 return 0; 2607 2608 } 2609 2610 static int rtw_rereg_nd_name(struct net_device *dev, 2611 struct iw_request_info *info, 2612 union iwreq_data *wrqu, char *extra) 2613 { 2614 int ret = 0; 2615 struct adapter *padapter = rtw_netdev_priv(dev); 2616 struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv; 2617 char new_ifname[IFNAMSIZ]; 2618 2619 if (rereg_priv->old_ifname[0] == 0) { 2620 char *reg_ifname; 2621 reg_ifname = padapter->registrypriv.ifname; 2622 2623 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ); 2624 rereg_priv->old_ifname[IFNAMSIZ-1] = 0; 2625 } 2626 2627 /* DBG_871X("%s wrqu->data.length:%d\n", __func__, wrqu->data.length); */ 2628 if (wrqu->data.length > IFNAMSIZ) 2629 return -EFAULT; 2630 2631 if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ)) 2632 return -EFAULT; 2633 2634 if (0 == strcmp(rereg_priv->old_ifname, new_ifname)) 2635 return ret; 2636 2637 DBG_871X("%s new_ifname:%s\n", __func__, new_ifname); 2638 if (0 != (ret = rtw_change_ifname(padapter, new_ifname))) 2639 goto exit; 2640 2641 strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ); 2642 rereg_priv->old_ifname[IFNAMSIZ-1] = 0; 2643 2644 if (!memcmp(new_ifname, "disable%d", 9)) { 2645 2646 DBG_871X("%s disable\n", __func__); 2647 /* free network queue for Android's timming issue */ 2648 rtw_free_network_queue(padapter, true); 2649 2650 /* the interface is being "disabled", we can do deeper IPS */ 2651 /* rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); */ 2652 /* rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); */ 2653 } 2654 exit: 2655 return ret; 2656 2657 } 2658 2659 static int rtw_dbg_port(struct net_device *dev, 2660 struct iw_request_info *info, 2661 union iwreq_data *wrqu, char *extra) 2662 { 2663 u8 major_cmd, minor_cmd; 2664 u16 arg; 2665 u32 extra_arg, *pdata, val32; 2666 struct sta_info *psta; 2667 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2668 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2669 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2670 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2671 struct wlan_network *cur_network = &(pmlmepriv->cur_network); 2672 struct sta_priv *pstapriv = &padapter->stapriv; 2673 2674 2675 pdata = (u32 *)&wrqu->data; 2676 2677 val32 = *pdata; 2678 arg = (u16)(val32&0x0000ffff); 2679 major_cmd = (u8)(val32>>24); 2680 minor_cmd = (u8)((val32>>16)&0x00ff); 2681 2682 extra_arg = *(pdata+1); 2683 2684 switch (major_cmd) { 2685 case 0x70:/* read_reg */ 2686 switch (minor_cmd) { 2687 case 1: 2688 DBG_871X("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg)); 2689 break; 2690 case 2: 2691 DBG_871X("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg)); 2692 break; 2693 case 4: 2694 DBG_871X("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg)); 2695 break; 2696 } 2697 break; 2698 case 0x71:/* write_reg */ 2699 switch (minor_cmd) { 2700 case 1: 2701 rtw_write8(padapter, arg, extra_arg); 2702 DBG_871X("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg)); 2703 break; 2704 case 2: 2705 rtw_write16(padapter, arg, extra_arg); 2706 DBG_871X("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg)); 2707 break; 2708 case 4: 2709 rtw_write32(padapter, arg, extra_arg); 2710 DBG_871X("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg)); 2711 break; 2712 } 2713 break; 2714 case 0x72:/* read_bb */ 2715 DBG_871X("read_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff)); 2716 break; 2717 case 0x73:/* write_bb */ 2718 rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg); 2719 DBG_871X("write_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff)); 2720 break; 2721 case 0x74:/* read_rf */ 2722 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)); 2723 break; 2724 case 0x75:/* write_rf */ 2725 rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg); 2726 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)); 2727 break; 2728 2729 case 0x76: 2730 switch (minor_cmd) { 2731 case 0x00: /* normal mode, */ 2732 padapter->recvpriv.is_signal_dbg = 0; 2733 break; 2734 case 0x01: /* dbg mode */ 2735 padapter->recvpriv.is_signal_dbg = 1; 2736 extra_arg = extra_arg>100?100:extra_arg; 2737 padapter->recvpriv.signal_strength_dbg =extra_arg; 2738 break; 2739 } 2740 break; 2741 case 0x78: /* IOL test */ 2742 break; 2743 case 0x79: 2744 { 2745 /* 2746 * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15 2747 * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15 2748 */ 2749 u8 value = extra_arg & 0x0f; 2750 u8 sign = minor_cmd; 2751 u16 write_value = 0; 2752 2753 DBG_871X("%s set RESP_TXAGC to %s %u\n", __func__, sign?"minus":"plus", value); 2754 2755 if (sign) 2756 value = value | 0x10; 2757 2758 write_value = value | (value << 5); 2759 rtw_write16(padapter, 0x6d9, write_value); 2760 } 2761 break; 2762 case 0x7a: 2763 receive_disconnect(padapter, pmlmeinfo->network.MacAddress 2764 , WLAN_REASON_EXPIRATION_CHK); 2765 break; 2766 case 0x7F: 2767 switch (minor_cmd) { 2768 case 0x0: 2769 DBG_871X("fwstate = 0x%x\n", get_fwstate(pmlmepriv)); 2770 break; 2771 case 0x01: 2772 DBG_871X("minor_cmd 0x%x\n", minor_cmd); 2773 break; 2774 case 0x02: 2775 DBG_871X("pmlmeinfo->state = 0x%x\n", pmlmeinfo->state); 2776 DBG_871X("DrvBcnEarly =%d\n", pmlmeext->DrvBcnEarly); 2777 DBG_871X("DrvBcnTimeOut =%d\n", pmlmeext->DrvBcnTimeOut); 2778 break; 2779 case 0x03: 2780 DBG_871X("qos_option =%d\n", pmlmepriv->qospriv.qos_option); 2781 DBG_871X("ht_option =%d\n", pmlmepriv->htpriv.ht_option); 2782 break; 2783 case 0x04: 2784 DBG_871X("cur_ch =%d\n", pmlmeext->cur_channel); 2785 DBG_871X("cur_bw =%d\n", pmlmeext->cur_bwmode); 2786 DBG_871X("cur_ch_off =%d\n", pmlmeext->cur_ch_offset); 2787 2788 DBG_871X("oper_ch =%d\n", rtw_get_oper_ch(padapter)); 2789 DBG_871X("oper_bw =%d\n", rtw_get_oper_bw(padapter)); 2790 DBG_871X("oper_ch_offset =%d\n", rtw_get_oper_choffset(padapter)); 2791 2792 break; 2793 case 0x05: 2794 psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); 2795 if (psta) { 2796 int i; 2797 struct recv_reorder_ctrl *preorder_ctrl; 2798 2799 DBG_871X("SSID =%s\n", cur_network->network.Ssid.Ssid); 2800 DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); 2801 DBG_871X("cur_channel =%d, cur_bwmode =%d, cur_ch_offset =%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); 2802 DBG_871X("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self); 2803 DBG_871X("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); 2804 DBG_871X("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); 2805 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); 2806 DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable); 2807 DBG_871X("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); 2808 2809 for (i = 0;i<16;i++) { 2810 preorder_ctrl = &psta->recvreorder_ctrl[i]; 2811 if (preorder_ctrl->enable) 2812 DBG_871X("tid =%d, indicate_seq =%d\n", i, preorder_ctrl->indicate_seq); 2813 } 2814 2815 } else { 2816 DBG_871X("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress)); 2817 } 2818 break; 2819 case 0x06: 2820 { 2821 u32 ODMFlag; 2822 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag)); 2823 DBG_871X("(B)DMFlag = 0x%x, arg = 0x%x\n", ODMFlag, arg); 2824 ODMFlag = (u32)(0x0f&arg); 2825 DBG_871X("(A)DMFlag = 0x%x\n", ODMFlag); 2826 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag)); 2827 } 2828 break; 2829 case 0x07: 2830 DBG_871X("bSurpriseRemoved =%d, bDriverStopped =%d\n", 2831 padapter->bSurpriseRemoved, padapter->bDriverStopped); 2832 break; 2833 case 0x08: 2834 { 2835 DBG_871X("minor_cmd 0x%x\n", minor_cmd); 2836 } 2837 break; 2838 case 0x09: 2839 { 2840 int i, j; 2841 struct list_head *plist, *phead; 2842 struct recv_reorder_ctrl *preorder_ctrl; 2843 2844 DBG_871X("sta_dz_bitmap = 0x%x, tim_bitmap = 0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); 2845 2846 spin_lock_bh(&pstapriv->sta_hash_lock); 2847 2848 for (i = 0; i< NUM_STA; i++) { 2849 phead = &(pstapriv->sta_hash[i]); 2850 plist = get_next(phead); 2851 2852 while (phead != plist) { 2853 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); 2854 2855 plist = get_next(plist); 2856 2857 if (extra_arg == psta->aid) { 2858 DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); 2859 DBG_871X("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self); 2860 DBG_871X("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); 2861 DBG_871X("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); 2862 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); 2863 DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable); 2864 DBG_871X("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); 2865 DBG_871X("capability = 0x%x\n", psta->capability); 2866 DBG_871X("flags = 0x%x\n", psta->flags); 2867 DBG_871X("wpa_psk = 0x%x\n", psta->wpa_psk); 2868 DBG_871X("wpa2_group_cipher = 0x%x\n", psta->wpa2_group_cipher); 2869 DBG_871X("wpa2_pairwise_cipher = 0x%x\n", psta->wpa2_pairwise_cipher); 2870 DBG_871X("qos_info = 0x%x\n", psta->qos_info); 2871 DBG_871X("dot118021XPrivacy = 0x%x\n", psta->dot118021XPrivacy); 2872 2873 2874 2875 for (j = 0;j<16;j++) { 2876 preorder_ctrl = &psta->recvreorder_ctrl[j]; 2877 if (preorder_ctrl->enable) 2878 DBG_871X("tid =%d, indicate_seq =%d\n", j, preorder_ctrl->indicate_seq); 2879 } 2880 } 2881 } 2882 } 2883 2884 spin_unlock_bh(&pstapriv->sta_hash_lock); 2885 2886 } 2887 break; 2888 case 0x0a: 2889 { 2890 int max_mac_id = 0; 2891 max_mac_id = rtw_search_max_mac_id(padapter); 2892 printk("%s ==> max_mac_id = %d\n", __func__, max_mac_id); 2893 } 2894 break; 2895 case 0x0b: /* Enable = 1, Disable = 0 driver control vrtl_carrier_sense. */ 2896 if (arg == 0) { 2897 DBG_871X("disable driver ctrl vcs\n"); 2898 padapter->driver_vcs_en = 0; 2899 } else if (arg == 1) { 2900 DBG_871X("enable driver ctrl vcs = %d\n", extra_arg); 2901 padapter->driver_vcs_en = 1; 2902 2903 if (extra_arg>2) 2904 padapter->driver_vcs_type = 1; 2905 else 2906 padapter->driver_vcs_type = extra_arg; 2907 } 2908 break; 2909 case 0x0c:/* dump rx/tx packet */ 2910 { 2911 if (arg == 0) { 2912 DBG_871X("dump rx packet (%d)\n", extra_arg); 2913 /* pHalData->bDumpRxPkt =extra_arg; */ 2914 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg)); 2915 } else if (arg == 1) { 2916 DBG_871X("dump tx packet (%d)\n", extra_arg); 2917 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg)); 2918 } 2919 } 2920 break; 2921 case 0x0e: 2922 { 2923 if (arg == 0) { 2924 DBG_871X("disable driver ctrl rx_ampdu_factor\n"); 2925 padapter->driver_rx_ampdu_factor = 0xFF; 2926 } else if (arg == 1) { 2927 2928 DBG_871X("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg); 2929 2930 if ((extra_arg & 0x03) > 0x03) 2931 padapter->driver_rx_ampdu_factor = 0xFF; 2932 else 2933 padapter->driver_rx_ampdu_factor = extra_arg; 2934 } 2935 } 2936 break; 2937 2938 case 0x10:/* driver version display */ 2939 dump_drv_version(RTW_DBGDUMP); 2940 break; 2941 case 0x11:/* dump linked status */ 2942 { 2943 linked_info_dump(padapter, extra_arg); 2944 } 2945 break; 2946 case 0x12: /* set rx_stbc */ 2947 { 2948 struct registry_priv *pregpriv = &padapter->registrypriv; 2949 /* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */ 2950 /* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */ 2951 if (extra_arg == 0 || extra_arg == 1 || extra_arg == 2 || extra_arg == 3) { 2952 pregpriv->rx_stbc = extra_arg; 2953 DBG_871X("set rx_stbc =%d\n", pregpriv->rx_stbc); 2954 } else 2955 DBG_871X("get rx_stbc =%d\n", pregpriv->rx_stbc); 2956 2957 } 2958 break; 2959 case 0x13: /* set ampdu_enable */ 2960 { 2961 struct registry_priv *pregpriv = &padapter->registrypriv; 2962 /* 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) */ 2963 if (extra_arg < 3) { 2964 pregpriv->ampdu_enable = extra_arg; 2965 DBG_871X("set ampdu_enable =%d\n", pregpriv->ampdu_enable); 2966 } else 2967 DBG_871X("get ampdu_enable =%d\n", pregpriv->ampdu_enable); 2968 2969 } 2970 break; 2971 case 0x14: 2972 { 2973 DBG_871X("minor_cmd 0x%x\n", minor_cmd); 2974 } 2975 break; 2976 case 0x16: 2977 { 2978 if (arg == 0xff) { 2979 rtw_odm_dbg_comp_msg(RTW_DBGDUMP, padapter); 2980 } else { 2981 u64 dbg_comp = (u64)extra_arg; 2982 rtw_odm_dbg_comp_set(padapter, dbg_comp); 2983 } 2984 } 2985 break; 2986 #ifdef DBG_FIXED_CHAN 2987 case 0x17: 2988 { 2989 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2990 printk("===> Fixed channel to %d\n", extra_arg); 2991 pmlmeext->fixed_chan = extra_arg; 2992 2993 } 2994 break; 2995 #endif 2996 case 0x18: 2997 { 2998 printk("===> Switch USB Mode %d\n", extra_arg); 2999 rtw_hal_set_hwreg(padapter, HW_VAR_USB_MODE, (u8 *)&extra_arg); 3000 } 3001 break; 3002 case 0x19: 3003 { 3004 struct registry_priv *pregistrypriv = &padapter->registrypriv; 3005 /* extra_arg : */ 3006 /* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, */ 3007 /* BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */ 3008 if (arg == 0) { 3009 DBG_871X("driver disable LDPC\n"); 3010 pregistrypriv->ldpc_cap = 0x00; 3011 } else if (arg == 1) { 3012 DBG_871X("driver set LDPC cap = 0x%x\n", extra_arg); 3013 pregistrypriv->ldpc_cap = (u8)(extra_arg&0x33); 3014 } 3015 } 3016 break; 3017 case 0x1a: 3018 { 3019 struct registry_priv *pregistrypriv = &padapter->registrypriv; 3020 /* extra_arg : */ 3021 /* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, */ 3022 /* BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */ 3023 if (arg == 0) { 3024 DBG_871X("driver disable STBC\n"); 3025 pregistrypriv->stbc_cap = 0x00; 3026 } else if (arg == 1) { 3027 DBG_871X("driver set STBC cap = 0x%x\n", extra_arg); 3028 pregistrypriv->stbc_cap = (u8)(extra_arg&0x33); 3029 } 3030 } 3031 break; 3032 case 0x1b: 3033 { 3034 struct registry_priv *pregistrypriv = &padapter->registrypriv; 3035 3036 if (arg == 0) { 3037 DBG_871X("disable driver ctrl max_rx_rate, reset to default_rate_set\n"); 3038 init_mlme_default_rate_set(padapter); 3039 pregistrypriv->ht_enable = (u8)rtw_ht_enable; 3040 } else if (arg == 1) { 3041 3042 int i; 3043 u8 max_rx_rate; 3044 3045 DBG_871X("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg); 3046 3047 max_rx_rate = (u8)extra_arg; 3048 3049 if (max_rx_rate < 0xc) { /* max_rx_rate < MSC0 -> B or G -> disable HT */ 3050 pregistrypriv->ht_enable = 0; 3051 for (i = 0; i<NumRates; i++) { 3052 if (pmlmeext->datarate[i] > max_rx_rate) 3053 pmlmeext->datarate[i] = 0xff; 3054 } 3055 3056 } 3057 else if (max_rx_rate < 0x1c) { /* mcs0~mcs15 */ 3058 u32 mcs_bitmap = 0x0; 3059 3060 for (i = 0; i<((max_rx_rate+1)-0xc); i++) 3061 mcs_bitmap |= BIT(i); 3062 3063 set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap); 3064 } 3065 } 3066 } 3067 break; 3068 case 0x1c: /* enable/disable driver control AMPDU Density for peer sta's rx */ 3069 { 3070 if (arg == 0) { 3071 DBG_871X("disable driver ctrl ampdu density\n"); 3072 padapter->driver_ampdu_spacing = 0xFF; 3073 } else if (arg == 1) { 3074 3075 DBG_871X("enable driver ctrl ampdu density = %d\n", extra_arg); 3076 3077 if (extra_arg > 0x07) 3078 padapter->driver_ampdu_spacing = 0xFF; 3079 else 3080 padapter->driver_ampdu_spacing = extra_arg; 3081 } 3082 } 3083 break; 3084 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR 3085 case 0x1e: 3086 { 3087 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 3088 PDM_ODM_T pDM_Odm = &pHalData->odmpriv; 3089 u8 chan = rtw_get_oper_ch(padapter); 3090 DBG_871X("===========================================\n"); 3091 ODM_InbandNoise_Monitor(pDM_Odm, true, 0x1e, 100); 3092 DBG_871X("channel(%d), noise_a = %d, noise_b = %d , noise_all:%d\n", 3093 chan, pDM_Odm->noise_level.noise[ODM_RF_PATH_A], 3094 pDM_Odm->noise_level.noise[ODM_RF_PATH_B], 3095 pDM_Odm->noise_level.noise_all); 3096 DBG_871X("===========================================\n"); 3097 3098 } 3099 break; 3100 #endif 3101 case 0x23: 3102 { 3103 DBG_871X("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1)?"on":"off"); 3104 padapter->bNotifyChannelChange = extra_arg; 3105 break; 3106 } 3107 case 0x24: 3108 { 3109 break; 3110 } 3111 #ifdef CONFIG_GPIO_API 3112 case 0x25: /* Get GPIO register */ 3113 { 3114 /* 3115 * dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~7 3116 */ 3117 3118 int value; 3119 DBG_871X("Read GPIO Value extra_arg = %d\n", extra_arg); 3120 value = rtw_get_gpio(dev, extra_arg); 3121 DBG_871X("Read GPIO Value = %d\n", value); 3122 break; 3123 } 3124 case 0x26: /* Set GPIO direction */ 3125 { 3126 3127 /* dbg 0x7f26000x [y], Set gpio direction, 3128 * x: gpio_num, 4~7 y: indicate direction, 0~1 3129 */ 3130 3131 int value; 3132 DBG_871X("Set GPIO Direction! arg = %d , extra_arg =%d\n", arg , extra_arg); 3133 value = rtw_config_gpio(dev, arg, extra_arg); 3134 DBG_871X("Set GPIO Direction %s\n", (value ==-1)?"Fail!!!":"Success"); 3135 break; 3136 } 3137 case 0x27: /* Set GPIO output direction value */ 3138 { 3139 /* 3140 * dbg 0x7f27000x [y], Set gpio output direction value, 3141 * x: gpio_num, 4~7 y: indicate direction, 0~1 3142 */ 3143 3144 int value; 3145 DBG_871X("Set GPIO Value! arg = %d , extra_arg =%d\n", arg , extra_arg); 3146 value = rtw_set_gpio_output_value(dev, arg, extra_arg); 3147 DBG_871X("Set GPIO Value %s\n", (value ==-1)?"Fail!!!":"Success"); 3148 break; 3149 } 3150 #endif 3151 case 0xaa: 3152 { 3153 if ((extra_arg & 0x7F)> 0x3F) extra_arg = 0xFF; 3154 DBG_871X("chang data rate to :0x%02x\n", extra_arg); 3155 padapter->fix_rate = extra_arg; 3156 } 3157 break; 3158 case 0xdd:/* registers dump , 0 for mac reg, 1 for bb reg, 2 for rf reg */ 3159 { 3160 if (extra_arg == 0) 3161 mac_reg_dump(RTW_DBGDUMP, padapter); 3162 else if (extra_arg == 1) 3163 bb_reg_dump(RTW_DBGDUMP, padapter); 3164 else if (extra_arg ==2) 3165 rf_reg_dump(RTW_DBGDUMP, padapter); 3166 } 3167 break; 3168 3169 case 0xee:/* turn on/off dynamic funcs */ 3170 { 3171 u32 odm_flag; 3172 3173 if (0xf ==extra_arg) { 3174 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag); 3175 DBG_871X(" === DMFlag(0x%08x) ===\n", odm_flag); 3176 DBG_871X("extra_arg = 0 - disable all dynamic func\n"); 3177 DBG_871X("extra_arg = 1 - disable DIG- BIT(0)\n"); 3178 DBG_871X("extra_arg = 2 - disable High power - BIT(1)\n"); 3179 DBG_871X("extra_arg = 3 - disable tx power tracking - BIT(2)\n"); 3180 DBG_871X("extra_arg = 4 - disable BT coexistence - BIT(3)\n"); 3181 DBG_871X("extra_arg = 5 - disable antenna diversity - BIT(4)\n"); 3182 DBG_871X("extra_arg = 6 - enable all dynamic func\n"); 3183 } else { 3184 /*extra_arg = 0 - disable all dynamic func 3185 extra_arg = 1 - disable DIG 3186 extra_arg = 2 - disable tx power tracking 3187 extra_arg = 3 - turn on all dynamic func 3188 */ 3189 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg)); 3190 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag); 3191 DBG_871X(" === DMFlag(0x%08x) ===\n", odm_flag); 3192 } 3193 } 3194 break; 3195 3196 case 0xfd: 3197 rtw_write8(padapter, 0xc50, arg); 3198 DBG_871X("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50)); 3199 rtw_write8(padapter, 0xc58, arg); 3200 DBG_871X("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58)); 3201 break; 3202 case 0xfe: 3203 DBG_871X("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50)); 3204 DBG_871X("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58)); 3205 break; 3206 case 0xff: 3207 { 3208 DBG_871X("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210)); 3209 DBG_871X("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608)); 3210 DBG_871X("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280)); 3211 DBG_871X("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284)); 3212 DBG_871X("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288)); 3213 3214 DBG_871X("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664)); 3215 3216 3217 DBG_871X("\n"); 3218 3219 DBG_871X("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430)); 3220 DBG_871X("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438)); 3221 3222 DBG_871X("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440)); 3223 3224 DBG_871X("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458)); 3225 3226 DBG_871X("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484)); 3227 DBG_871X("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488)); 3228 3229 DBG_871X("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444)); 3230 DBG_871X("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448)); 3231 DBG_871X("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c)); 3232 DBG_871X("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450)); 3233 } 3234 break; 3235 } 3236 break; 3237 default: 3238 DBG_871X("error dbg cmd!\n"); 3239 break; 3240 } 3241 3242 3243 return 0; 3244 3245 } 3246 3247 static int wpa_set_param(struct net_device *dev, u8 name, u32 value) 3248 { 3249 uint ret = 0; 3250 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3251 3252 switch (name) { 3253 case IEEE_PARAM_WPA_ENABLED: 3254 3255 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */ 3256 3257 /* ret = ieee80211_wpa_enable(ieee, value); */ 3258 3259 switch ((value)&0xff) { 3260 case 1 : /* WPA */ 3261 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */ 3262 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; 3263 break; 3264 case 2: /* WPA2 */ 3265 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */ 3266 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; 3267 break; 3268 } 3269 3270 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter->securitypriv.ndisauthtype)); 3271 3272 break; 3273 3274 case IEEE_PARAM_TKIP_COUNTERMEASURES: 3275 /* ieee->tkip_countermeasures =value; */ 3276 break; 3277 3278 case IEEE_PARAM_DROP_UNENCRYPTED: 3279 { 3280 /* HACK: 3281 * 3282 * wpa_supplicant calls set_wpa_enabled when the driver 3283 * is loaded and unloaded, regardless of if WPA is being 3284 * used. No other calls are made which can be used to 3285 * determine if encryption will be used or not prior to 3286 * association being expected. If encryption is not being 3287 * used, drop_unencrypted is set to false, else true -- we 3288 * can use this to determine if the CAP_PRIVACY_ON bit should 3289 * be set. 3290 */ 3291 break; 3292 3293 } 3294 case IEEE_PARAM_PRIVACY_INVOKED: 3295 3296 /* ieee->privacy_invoked =value; */ 3297 3298 break; 3299 3300 case IEEE_PARAM_AUTH_ALGS: 3301 3302 ret = wpa_set_auth_algs(dev, value); 3303 3304 break; 3305 3306 case IEEE_PARAM_IEEE_802_1X: 3307 3308 /* ieee->ieee802_1x =value; */ 3309 3310 break; 3311 3312 case IEEE_PARAM_WPAX_SELECT: 3313 3314 /* added for WPA2 mixed mode */ 3315 /* DBG_871X(KERN_WARNING "------------------------>wpax value = %x\n", value); */ 3316 /* 3317 spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags); 3318 ieee->wpax_type_set = 1; 3319 ieee->wpax_type_notify = value; 3320 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags); 3321 */ 3322 3323 break; 3324 3325 default: 3326 3327 3328 3329 ret = -EOPNOTSUPP; 3330 3331 3332 break; 3333 3334 } 3335 3336 return ret; 3337 3338 } 3339 3340 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason) 3341 { 3342 int ret = 0; 3343 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3344 3345 switch (command) { 3346 case IEEE_MLME_STA_DEAUTH: 3347 3348 if (!rtw_set_802_11_disassociate(padapter)) 3349 ret = -1; 3350 3351 break; 3352 3353 case IEEE_MLME_STA_DISASSOC: 3354 3355 if (!rtw_set_802_11_disassociate(padapter)) 3356 ret = -1; 3357 3358 break; 3359 3360 default: 3361 ret = -EOPNOTSUPP; 3362 break; 3363 } 3364 3365 return ret; 3366 3367 } 3368 3369 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) 3370 { 3371 struct ieee_param *param; 3372 uint ret = 0; 3373 3374 /* down(&ieee->wx_sem); */ 3375 3376 if (p->length < sizeof(struct ieee_param) || !p->pointer) { 3377 ret = -EINVAL; 3378 goto out; 3379 } 3380 3381 param = rtw_malloc(p->length); 3382 if (param == NULL) { 3383 ret = -ENOMEM; 3384 goto out; 3385 } 3386 3387 if (copy_from_user(param, p->pointer, p->length)) { 3388 kfree(param); 3389 ret = -EFAULT; 3390 goto out; 3391 } 3392 3393 switch (param->cmd) { 3394 3395 case IEEE_CMD_SET_WPA_PARAM: 3396 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value); 3397 break; 3398 3399 case IEEE_CMD_SET_WPA_IE: 3400 /* ret = wpa_set_wpa_ie(dev, param, p->length); */ 3401 ret = rtw_set_wpa_ie((struct adapter *)rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len); 3402 break; 3403 3404 case IEEE_CMD_SET_ENCRYPTION: 3405 ret = wpa_set_encryption(dev, param, p->length); 3406 break; 3407 3408 case IEEE_CMD_MLME: 3409 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code); 3410 break; 3411 3412 default: 3413 DBG_871X("Unknown WPA supplicant request: %d\n", param->cmd); 3414 ret = -EOPNOTSUPP; 3415 break; 3416 3417 } 3418 3419 if (ret == 0 && copy_to_user(p->pointer, param, p->length)) 3420 ret = -EFAULT; 3421 3422 kfree(param); 3423 3424 out: 3425 3426 /* up(&ieee->wx_sem); */ 3427 3428 return ret; 3429 3430 } 3431 3432 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) 3433 { 3434 int ret = 0; 3435 u32 wep_key_idx, wep_key_len, wep_total_len; 3436 struct ndis_802_11_wep *pwep = NULL; 3437 struct sta_info *psta = NULL, *pbcmc_sta = NULL; 3438 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3439 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 3440 struct security_priv* psecuritypriv =&(padapter->securitypriv); 3441 struct sta_priv *pstapriv = &padapter->stapriv; 3442 3443 DBG_871X("%s\n", __func__); 3444 3445 param->u.crypt.err = 0; 3446 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; 3447 3448 /* sizeof(struct ieee_param) = 64 bytes; */ 3449 /* if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */ 3450 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) { 3451 ret = -EINVAL; 3452 goto exit; 3453 } 3454 3455 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 3456 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 3457 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3458 if (param->u.crypt.idx >= WEP_KEYS) { 3459 ret = -EINVAL; 3460 goto exit; 3461 } 3462 } else { 3463 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 3464 if (!psta) { 3465 /* ret = -EINVAL; */ 3466 DBG_871X("rtw_set_encryption(), sta has already been removed or never been added\n"); 3467 goto exit; 3468 } 3469 } 3470 3471 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) { 3472 /* todo:clear default encryption keys */ 3473 3474 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 3475 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled; 3476 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; 3477 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; 3478 3479 DBG_871X("clear default encryption keys, keyid =%d\n", param->u.crypt.idx); 3480 3481 goto exit; 3482 } 3483 3484 3485 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) { 3486 DBG_871X("r871x_set_encryption, crypt.alg = WEP\n"); 3487 3488 wep_key_idx = param->u.crypt.idx; 3489 wep_key_len = param->u.crypt.key_len; 3490 3491 DBG_871X("r871x_set_encryption, wep_key_idx =%d, len =%d\n", wep_key_idx, wep_key_len); 3492 3493 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len<= 0)) { 3494 ret = -EINVAL; 3495 goto exit; 3496 } 3497 3498 3499 if (wep_key_len > 0) { 3500 wep_key_len = wep_key_len <= 5 ? 5 : 13; 3501 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); 3502 pwep = kzalloc(wep_total_len, GFP_KERNEL); 3503 if (pwep == NULL) { 3504 DBG_871X(" r871x_set_encryption: pwep allocate fail !!!\n"); 3505 goto exit; 3506 } 3507 3508 pwep->KeyLength = wep_key_len; 3509 pwep->Length = wep_total_len; 3510 3511 } 3512 3513 pwep->KeyIndex = wep_key_idx; 3514 3515 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); 3516 3517 if (param->u.crypt.set_tx) { 3518 DBG_871X("wep, set_tx = 1\n"); 3519 3520 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; 3521 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; 3522 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; 3523 psecuritypriv->dot118021XGrpPrivacy = _WEP40_; 3524 3525 if (pwep->KeyLength == 13) { 3526 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; 3527 psecuritypriv->dot118021XGrpPrivacy = _WEP104_; 3528 } 3529 3530 3531 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; 3532 3533 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); 3534 3535 psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength; 3536 3537 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1); 3538 } else { 3539 DBG_871X("wep, set_tx = 0\n"); 3540 3541 /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */ 3542 /* psecuritypriv->dot11PrivacyKeyIndex =keyid", but can rtw_set_key to cam */ 3543 3544 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); 3545 3546 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; 3547 3548 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0); 3549 } 3550 3551 goto exit; 3552 3553 } 3554 3555 3556 if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* group key */ 3557 if (param->u.crypt.set_tx == 1) { 3558 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 3559 DBG_871X("%s, set group_key, WEP\n", __func__); 3560 3561 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); 3562 3563 psecuritypriv->dot118021XGrpPrivacy = _WEP40_; 3564 if (param->u.crypt.key_len == 13) 3565 psecuritypriv->dot118021XGrpPrivacy = _WEP104_; 3566 3567 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 3568 DBG_871X("%s, set group_key, TKIP\n", __func__); 3569 3570 psecuritypriv->dot118021XGrpPrivacy = _TKIP_; 3571 3572 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); 3573 3574 /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ 3575 /* set mic key */ 3576 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); 3577 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); 3578 3579 psecuritypriv->busetkipkey = true; 3580 3581 } 3582 else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 3583 DBG_871X("%s, set group_key, CCMP\n", __func__); 3584 3585 psecuritypriv->dot118021XGrpPrivacy = _AES_; 3586 3587 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); 3588 } else { 3589 DBG_871X("%s, set group_key, none\n", __func__); 3590 3591 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; 3592 } 3593 3594 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; 3595 3596 psecuritypriv->binstallGrpkey = true; 3597 3598 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* */ 3599 3600 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); 3601 3602 pbcmc_sta =rtw_get_bcmc_stainfo(padapter); 3603 if (pbcmc_sta) { 3604 pbcmc_sta->ieee8021x_blocked = false; 3605 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */ 3606 } 3607 } 3608 3609 goto exit; 3610 3611 } 3612 3613 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */ 3614 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 3615 if (param->u.crypt.set_tx == 1) { 3616 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); 3617 3618 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 3619 DBG_871X("%s, set pairwise key, WEP\n", __func__); 3620 3621 psta->dot118021XPrivacy = _WEP40_; 3622 if (param->u.crypt.key_len == 13) 3623 psta->dot118021XPrivacy = _WEP104_; 3624 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 3625 DBG_871X("%s, set pairwise key, TKIP\n", __func__); 3626 3627 psta->dot118021XPrivacy = _TKIP_; 3628 3629 /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ 3630 /* set mic key */ 3631 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); 3632 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); 3633 3634 psecuritypriv->busetkipkey = true; 3635 3636 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 3637 3638 DBG_871X("%s, set pairwise key, CCMP\n", __func__); 3639 3640 psta->dot118021XPrivacy = _AES_; 3641 } else { 3642 DBG_871X("%s, set pairwise key, none\n", __func__); 3643 3644 psta->dot118021XPrivacy = _NO_PRIVACY_; 3645 } 3646 3647 rtw_ap_set_pairwise_key(padapter, psta); 3648 3649 psta->ieee8021x_blocked = false; 3650 3651 } else { /* group key??? */ 3652 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 3653 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); 3654 3655 psecuritypriv->dot118021XGrpPrivacy = _WEP40_; 3656 if (param->u.crypt.key_len == 13) 3657 psecuritypriv->dot118021XGrpPrivacy = _WEP104_; 3658 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 3659 psecuritypriv->dot118021XGrpPrivacy = _TKIP_; 3660 3661 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); 3662 3663 /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ 3664 /* set mic key */ 3665 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); 3666 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); 3667 3668 psecuritypriv->busetkipkey = true; 3669 3670 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 3671 psecuritypriv->dot118021XGrpPrivacy = _AES_; 3672 3673 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); 3674 } else { 3675 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; 3676 } 3677 3678 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; 3679 3680 psecuritypriv->binstallGrpkey = true; 3681 3682 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* */ 3683 3684 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); 3685 3686 pbcmc_sta =rtw_get_bcmc_stainfo(padapter); 3687 if (pbcmc_sta) { 3688 pbcmc_sta->ieee8021x_blocked = false; 3689 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */ 3690 } 3691 } 3692 } 3693 } 3694 3695 exit: 3696 kfree(pwep); 3697 3698 return ret; 3699 3700 } 3701 3702 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len) 3703 { 3704 int ret = 0; 3705 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3706 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3707 struct sta_priv *pstapriv = &padapter->stapriv; 3708 unsigned char *pbuf = param->u.bcn_ie.buf; 3709 3710 3711 DBG_871X("%s, len =%d\n", __func__, len); 3712 3713 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 3714 return -EINVAL; 3715 3716 memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2); 3717 3718 if ((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<= 0)) 3719 pstapriv->max_num_sta = NUM_STA; 3720 3721 3722 if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS)/* 12 = param header, 2:no packed */ 3723 ret = 0; 3724 else 3725 ret = -EINVAL; 3726 3727 3728 return ret; 3729 3730 } 3731 3732 static void rtw_hostapd_sta_flush(struct net_device *dev) 3733 { 3734 /* _irqL irqL; */ 3735 /* struct list_head *phead, *plist; */ 3736 /* struct sta_info *psta = NULL; */ 3737 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3738 /* struct sta_priv *pstapriv = &padapter->stapriv; */ 3739 3740 DBG_871X("%s\n", __func__); 3741 3742 flush_all_cam_entry(padapter); /* clear CAM */ 3743 3744 rtw_sta_flush(padapter); 3745 } 3746 3747 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) 3748 { 3749 int ret = 0; 3750 struct sta_info *psta = NULL; 3751 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3752 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3753 struct sta_priv *pstapriv = &padapter->stapriv; 3754 3755 DBG_871X("rtw_add_sta(aid =%d) =" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr)); 3756 3757 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 3758 return -EINVAL; 3759 3760 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 3761 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 3762 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3763 return -EINVAL; 3764 } 3765 3766 /* 3767 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 3768 if (psta) 3769 { 3770 DBG_871X("rtw_add_sta(), free has been added psta =%p\n", psta); 3771 spin_lock_bh(&(pstapriv->sta_hash_lock)); 3772 rtw_free_stainfo(padapter, psta); 3773 spin_unlock_bh(&(pstapriv->sta_hash_lock)); 3774 3775 psta = NULL; 3776 } 3777 */ 3778 /* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */ 3779 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 3780 if (psta) { 3781 int flags = param->u.add_sta.flags; 3782 3783 /* DBG_871X("rtw_add_sta(), init sta's variables, psta =%p\n", psta); */ 3784 3785 psta->aid = param->u.add_sta.aid;/* aid = 1~2007 */ 3786 3787 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16); 3788 3789 3790 /* check wmm cap. */ 3791 if (WLAN_STA_WME&flags) 3792 psta->qos_option = 1; 3793 else 3794 psta->qos_option = 0; 3795 3796 if (pmlmepriv->qospriv.qos_option == 0) 3797 psta->qos_option = 0; 3798 3799 /* chec 802.11n ht cap. */ 3800 if (WLAN_STA_HT&flags) { 3801 psta->htpriv.ht_option = true; 3802 psta->qos_option = 1; 3803 memcpy((void *)&psta->htpriv.ht_cap, (void *)¶m->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap)); 3804 } else { 3805 psta->htpriv.ht_option = false; 3806 } 3807 3808 if (pmlmepriv->htpriv.ht_option == false) 3809 psta->htpriv.ht_option = false; 3810 3811 update_sta_info_apmode(padapter, psta); 3812 3813 3814 } else { 3815 ret = -ENOMEM; 3816 } 3817 3818 return ret; 3819 3820 } 3821 3822 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) 3823 { 3824 int ret = 0; 3825 struct sta_info *psta = NULL; 3826 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3827 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3828 struct sta_priv *pstapriv = &padapter->stapriv; 3829 3830 DBG_871X("rtw_del_sta =" MAC_FMT "\n", MAC_ARG(param->sta_addr)); 3831 3832 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 3833 return -EINVAL; 3834 3835 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 3836 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 3837 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3838 return -EINVAL; 3839 } 3840 3841 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 3842 if (psta) { 3843 u8 updated =false; 3844 3845 /* DBG_871X("free psta =%p, aid =%d\n", psta, psta->aid); */ 3846 3847 spin_lock_bh(&pstapriv->asoc_list_lock); 3848 if (list_empty(&psta->asoc_list) ==false) { 3849 list_del_init(&psta->asoc_list); 3850 pstapriv->asoc_list_cnt--; 3851 updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); 3852 3853 } 3854 spin_unlock_bh(&pstapriv->asoc_list_lock); 3855 3856 associated_clients_update(padapter, updated); 3857 3858 psta = NULL; 3859 3860 } else { 3861 DBG_871X("rtw_del_sta(), sta has already been removed or never been added\n"); 3862 3863 /* ret = -1; */ 3864 } 3865 3866 3867 return ret; 3868 3869 } 3870 3871 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len) 3872 { 3873 int ret = 0; 3874 struct sta_info *psta = NULL; 3875 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3876 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3877 struct sta_priv *pstapriv = &padapter->stapriv; 3878 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param; 3879 struct sta_data *psta_data = (struct sta_data *)param_ex->data; 3880 3881 DBG_871X("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr)); 3882 3883 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 3884 return -EINVAL; 3885 3886 if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff && 3887 param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff && 3888 param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) { 3889 return -EINVAL; 3890 } 3891 3892 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr); 3893 if (psta) { 3894 psta_data->aid = (u16)psta->aid; 3895 psta_data->capability = psta->capability; 3896 psta_data->flags = psta->flags; 3897 3898 /* 3899 nonerp_set : BIT(0) 3900 no_short_slot_time_set : BIT(1) 3901 no_short_preamble_set : BIT(2) 3902 no_ht_gf_set : BIT(3) 3903 no_ht_set : BIT(4) 3904 ht_20mhz_set : BIT(5) 3905 */ 3906 3907 psta_data->sta_set =((psta->nonerp_set) | 3908 (psta->no_short_slot_time_set <<1) | 3909 (psta->no_short_preamble_set <<2) | 3910 (psta->no_ht_gf_set <<3) | 3911 (psta->no_ht_set <<4) | 3912 (psta->ht_20mhz_set <<5)); 3913 3914 psta_data->tx_supp_rates_len = psta->bssratelen; 3915 memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen); 3916 memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap)); 3917 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts; 3918 psta_data->rx_bytes = psta->sta_stats.rx_bytes; 3919 psta_data->rx_drops = psta->sta_stats.rx_drops; 3920 3921 psta_data->tx_pkts = psta->sta_stats.tx_pkts; 3922 psta_data->tx_bytes = psta->sta_stats.tx_bytes; 3923 psta_data->tx_drops = psta->sta_stats.tx_drops; 3924 3925 3926 } else { 3927 ret = -1; 3928 } 3929 3930 return ret; 3931 3932 } 3933 3934 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param) 3935 { 3936 int ret = 0; 3937 struct sta_info *psta = NULL; 3938 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3939 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3940 struct sta_priv *pstapriv = &padapter->stapriv; 3941 3942 DBG_871X("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr)); 3943 3944 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 3945 return -EINVAL; 3946 3947 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 3948 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 3949 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3950 return -EINVAL; 3951 } 3952 3953 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 3954 if (psta) { 3955 if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) { 3956 int wpa_ie_len; 3957 int copy_len; 3958 3959 wpa_ie_len = psta->wpa_ie[1]; 3960 3961 copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2); 3962 3963 param->u.wpa_ie.len = copy_len; 3964 3965 memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len); 3966 } else { 3967 /* ret = -1; */ 3968 DBG_871X("sta's wpa_ie is NONE\n"); 3969 } 3970 } else { 3971 ret = -1; 3972 } 3973 3974 return ret; 3975 3976 } 3977 3978 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len) 3979 { 3980 int ret = 0; 3981 unsigned char wps_oui[4]={0x0, 0x50, 0xf2, 0x04}; 3982 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3983 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3984 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3985 int ie_len; 3986 3987 DBG_871X("%s, len =%d\n", __func__, len); 3988 3989 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 3990 return -EINVAL; 3991 3992 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 3993 3994 3995 kfree(pmlmepriv->wps_beacon_ie); 3996 pmlmepriv->wps_beacon_ie = NULL; 3997 3998 if (ie_len>0) { 3999 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len); 4000 pmlmepriv->wps_beacon_ie_len = ie_len; 4001 if (pmlmepriv->wps_beacon_ie == NULL) { 4002 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__); 4003 return -EINVAL; 4004 } 4005 4006 memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len); 4007 4008 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true); 4009 4010 pmlmeext->bstart_bss = true; 4011 } 4012 4013 4014 return ret; 4015 4016 } 4017 4018 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len) 4019 { 4020 int ret = 0; 4021 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 4022 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 4023 int ie_len; 4024 4025 DBG_871X("%s, len =%d\n", __func__, len); 4026 4027 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 4028 return -EINVAL; 4029 4030 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 4031 4032 4033 kfree(pmlmepriv->wps_probe_resp_ie); 4034 pmlmepriv->wps_probe_resp_ie = NULL; 4035 4036 if (ie_len>0) { 4037 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len); 4038 pmlmepriv->wps_probe_resp_ie_len = ie_len; 4039 if (pmlmepriv->wps_probe_resp_ie == NULL) { 4040 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__); 4041 return -EINVAL; 4042 } 4043 memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len); 4044 } 4045 4046 4047 return ret; 4048 4049 } 4050 4051 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len) 4052 { 4053 int ret = 0; 4054 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 4055 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 4056 int ie_len; 4057 4058 DBG_871X("%s, len =%d\n", __func__, len); 4059 4060 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 4061 return -EINVAL; 4062 4063 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 4064 4065 4066 kfree(pmlmepriv->wps_assoc_resp_ie); 4067 pmlmepriv->wps_assoc_resp_ie = NULL; 4068 4069 if (ie_len>0) { 4070 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); 4071 pmlmepriv->wps_assoc_resp_ie_len = ie_len; 4072 if (pmlmepriv->wps_assoc_resp_ie == NULL) { 4073 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__); 4074 return -EINVAL; 4075 } 4076 4077 memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len); 4078 } 4079 4080 4081 return ret; 4082 4083 } 4084 4085 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len) 4086 { 4087 int ret = 0; 4088 struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); 4089 struct mlme_priv *mlmepriv = &(adapter->mlmepriv); 4090 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); 4091 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info); 4092 int ie_len; 4093 u8 *ssid_ie; 4094 char ssid[NDIS_802_11_LENGTH_SSID + 1]; 4095 sint ssid_len; 4096 u8 ignore_broadcast_ssid; 4097 4098 if (check_fwstate(mlmepriv, WIFI_AP_STATE) != true) 4099 return -EPERM; 4100 4101 if (param->u.bcn_ie.reserved[0] != 0xea) 4102 return -EINVAL; 4103 4104 mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1]; 4105 4106 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 4107 ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len); 4108 4109 if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) { 4110 struct wlan_bssid_ex *pbss_network = &mlmepriv->cur_network.network; 4111 struct wlan_bssid_ex *pbss_network_ext = &mlmeinfo->network; 4112 4113 memcpy(ssid, ssid_ie+2, ssid_len); 4114 ssid[ssid_len] = 0x0; 4115 4116 if (0) 4117 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter), 4118 ssid, ssid_len, 4119 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength, 4120 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength); 4121 4122 memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len); 4123 pbss_network->Ssid.SsidLength = ssid_len; 4124 memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len); 4125 pbss_network_ext->Ssid.SsidLength = ssid_len; 4126 4127 if (0) 4128 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter), 4129 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength, 4130 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength); 4131 } 4132 4133 DBG_871X(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter), 4134 ignore_broadcast_ssid, ssid, ssid_len); 4135 4136 return ret; 4137 } 4138 4139 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len) 4140 { 4141 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 4142 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 4143 4144 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 4145 return -EINVAL; 4146 4147 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 4148 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 4149 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 4150 return -EINVAL; 4151 } 4152 4153 rtw_acl_remove_sta(padapter, param->sta_addr); 4154 return 0; 4155 4156 } 4157 4158 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len) 4159 { 4160 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 4161 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 4162 4163 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 4164 return -EINVAL; 4165 4166 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 4167 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 4168 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 4169 return -EINVAL; 4170 } 4171 4172 return rtw_acl_add_sta(padapter, param->sta_addr); 4173 4174 } 4175 4176 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len) 4177 { 4178 int ret = 0; 4179 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 4180 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 4181 4182 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 4183 return -EINVAL; 4184 4185 rtw_set_macaddr_acl(padapter, param->u.mlme.command); 4186 4187 return ret; 4188 } 4189 4190 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p) 4191 { 4192 struct ieee_param *param; 4193 int ret = 0; 4194 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 4195 4196 /* DBG_871X("%s\n", __func__); */ 4197 4198 /* 4199 * this function is expect to call in master mode, which allows no power saving 4200 * so, we just check hw_init_completed 4201 */ 4202 4203 if (!padapter->hw_init_completed) { 4204 ret = -EPERM; 4205 goto out; 4206 } 4207 4208 4209 /* if (p->length < sizeof(struct ieee_param) || !p->pointer) { */ 4210 if (!p->pointer) { 4211 ret = -EINVAL; 4212 goto out; 4213 } 4214 4215 param = rtw_malloc(p->length); 4216 if (param == NULL) { 4217 ret = -ENOMEM; 4218 goto out; 4219 } 4220 4221 if (copy_from_user(param, p->pointer, p->length)) { 4222 kfree(param); 4223 ret = -EFAULT; 4224 goto out; 4225 } 4226 4227 /* DBG_871X("%s, cmd =%d\n", __func__, param->cmd); */ 4228 4229 switch (param->cmd) { 4230 case RTL871X_HOSTAPD_FLUSH: 4231 4232 rtw_hostapd_sta_flush(dev); 4233 4234 break; 4235 4236 case RTL871X_HOSTAPD_ADD_STA: 4237 4238 ret = rtw_add_sta(dev, param); 4239 4240 break; 4241 4242 case RTL871X_HOSTAPD_REMOVE_STA: 4243 4244 ret = rtw_del_sta(dev, param); 4245 4246 break; 4247 4248 case RTL871X_HOSTAPD_SET_BEACON: 4249 4250 ret = rtw_set_beacon(dev, param, p->length); 4251 4252 break; 4253 4254 case RTL871X_SET_ENCRYPTION: 4255 4256 ret = rtw_set_encryption(dev, param, p->length); 4257 4258 break; 4259 4260 case RTL871X_HOSTAPD_GET_WPAIE_STA: 4261 4262 ret = rtw_get_sta_wpaie(dev, param); 4263 4264 break; 4265 4266 case RTL871X_HOSTAPD_SET_WPS_BEACON: 4267 4268 ret = rtw_set_wps_beacon(dev, param, p->length); 4269 4270 break; 4271 4272 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP: 4273 4274 ret = rtw_set_wps_probe_resp(dev, param, p->length); 4275 4276 break; 4277 4278 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP: 4279 4280 ret = rtw_set_wps_assoc_resp(dev, param, p->length); 4281 4282 break; 4283 4284 case RTL871X_HOSTAPD_SET_HIDDEN_SSID: 4285 4286 ret = rtw_set_hidden_ssid(dev, param, p->length); 4287 4288 break; 4289 4290 case RTL871X_HOSTAPD_GET_INFO_STA: 4291 4292 ret = rtw_ioctl_get_sta_data(dev, param, p->length); 4293 4294 break; 4295 4296 case RTL871X_HOSTAPD_SET_MACADDR_ACL: 4297 4298 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length); 4299 4300 break; 4301 4302 case RTL871X_HOSTAPD_ACL_ADD_STA: 4303 4304 ret = rtw_ioctl_acl_add_sta(dev, param, p->length); 4305 4306 break; 4307 4308 case RTL871X_HOSTAPD_ACL_REMOVE_STA: 4309 4310 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length); 4311 4312 break; 4313 4314 default: 4315 DBG_871X("Unknown hostapd request: %d\n", param->cmd); 4316 ret = -EOPNOTSUPP; 4317 break; 4318 4319 } 4320 4321 if (ret == 0 && copy_to_user(p->pointer, param, p->length)) 4322 ret = -EFAULT; 4323 4324 4325 kfree(param); 4326 4327 out: 4328 4329 return ret; 4330 4331 } 4332 4333 static int rtw_wx_set_priv(struct net_device *dev, 4334 struct iw_request_info *info, 4335 union iwreq_data *awrq, 4336 char *extra) 4337 { 4338 4339 #ifdef DEBUG_RTW_WX_SET_PRIV 4340 char *ext_dbg; 4341 #endif 4342 4343 int ret = 0; 4344 int len = 0; 4345 char *ext; 4346 4347 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 4348 struct iw_point *dwrq = (struct iw_point *)awrq; 4349 4350 /* RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, ("+rtw_wx_set_priv\n")); */ 4351 if (dwrq->length == 0) 4352 return -EFAULT; 4353 4354 len = dwrq->length; 4355 if (!(ext = vmalloc(len))) 4356 return -ENOMEM; 4357 4358 if (copy_from_user(ext, dwrq->pointer, len)) { 4359 vfree(ext); 4360 return -EFAULT; 4361 } 4362 4363 4364 /* RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, */ 4365 /* ("rtw_wx_set_priv: %s req =%s\n", */ 4366 /* dev->name, ext)); */ 4367 4368 #ifdef DEBUG_RTW_WX_SET_PRIV 4369 if (!(ext_dbg = vmalloc(len))) { 4370 vfree(ext, len); 4371 return -ENOMEM; 4372 } 4373 4374 memcpy(ext_dbg, ext, len); 4375 #endif 4376 4377 /* added for wps2.0 @20110524 */ 4378 if (dwrq->flags == 0x8766 && len > 8) { 4379 u32 cp_sz; 4380 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 4381 u8 *probereq_wpsie = ext; 4382 int probereq_wpsie_len = len; 4383 u8 wps_oui[4]={0x0, 0x50, 0xf2, 0x04}; 4384 4385 if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) && 4386 (!memcmp(&probereq_wpsie[2], wps_oui, 4))) { 4387 cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len; 4388 4389 if (pmlmepriv->wps_probe_req_ie) { 4390 pmlmepriv->wps_probe_req_ie_len = 0; 4391 kfree(pmlmepriv->wps_probe_req_ie); 4392 pmlmepriv->wps_probe_req_ie = NULL; 4393 } 4394 4395 pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz); 4396 if (pmlmepriv->wps_probe_req_ie == NULL) { 4397 printk("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__); 4398 ret = -EINVAL; 4399 goto FREE_EXT; 4400 4401 } 4402 4403 memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz); 4404 pmlmepriv->wps_probe_req_ie_len = cp_sz; 4405 4406 } 4407 4408 goto FREE_EXT; 4409 4410 } 4411 4412 if (len >= WEXT_CSCAN_HEADER_SIZE 4413 && !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) { 4414 ret = rtw_wx_set_scan(dev, info, awrq, ext); 4415 goto FREE_EXT; 4416 } 4417 4418 FREE_EXT: 4419 4420 vfree(ext); 4421 #ifdef DEBUG_RTW_WX_SET_PRIV 4422 vfree(ext_dbg); 4423 #endif 4424 4425 /* DBG_871X("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret =%d\n", */ 4426 /* dev->name, ret); */ 4427 4428 return ret; 4429 4430 } 4431 4432 static int rtw_pm_set(struct net_device *dev, 4433 struct iw_request_info *info, 4434 union iwreq_data *wrqu, char *extra) 4435 { 4436 int ret = 0; 4437 unsigned mode = 0; 4438 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 4439 4440 DBG_871X("[%s] extra = %s\n", __func__, extra); 4441 4442 if (!memcmp(extra, "lps =", 4)) { 4443 sscanf(extra+4, "%u", &mode); 4444 ret = rtw_pm_set_lps(padapter, mode); 4445 } else if (!memcmp(extra, "ips =", 4)) { 4446 sscanf(extra+4, "%u", &mode); 4447 ret = rtw_pm_set_ips(padapter, mode); 4448 } else { 4449 ret = -EINVAL; 4450 } 4451 4452 return ret; 4453 } 4454 4455 static int rtw_test( 4456 struct net_device *dev, 4457 struct iw_request_info *info, 4458 union iwreq_data *wrqu, char *extra) 4459 { 4460 u32 len; 4461 u8 *pbuf, *pch; 4462 char *ptmp; 4463 u8 *delim = ","; 4464 struct adapter *padapter = rtw_netdev_priv(dev); 4465 4466 4467 DBG_871X("+%s\n", __func__); 4468 len = wrqu->data.length; 4469 4470 pbuf = rtw_zmalloc(len); 4471 if (pbuf == NULL) { 4472 DBG_871X("%s: no memory!\n", __func__); 4473 return -ENOMEM; 4474 } 4475 4476 if (copy_from_user(pbuf, wrqu->data.pointer, len)) { 4477 kfree(pbuf); 4478 DBG_871X("%s: copy from user fail!\n", __func__); 4479 return -EFAULT; 4480 } 4481 DBG_871X("%s: string =\"%s\"\n", __func__, pbuf); 4482 4483 ptmp = (char *)pbuf; 4484 pch = strsep(&ptmp, delim); 4485 if ((pch == NULL) || (strlen(pch) == 0)) { 4486 kfree(pbuf); 4487 DBG_871X("%s: parameter error(level 1)!\n", __func__); 4488 return -EFAULT; 4489 } 4490 4491 if (strcmp(pch, "bton") == 0) 4492 hal_btcoex_SetManualControl(padapter, false); 4493 4494 if (strcmp(pch, "btoff") == 0) 4495 hal_btcoex_SetManualControl(padapter, true); 4496 4497 if (strcmp(pch, "h2c") == 0) { 4498 u8 param[8]; 4499 u8 count = 0; 4500 u32 tmp; 4501 u8 i; 4502 u32 pos; 4503 s32 ret; 4504 4505 4506 do { 4507 pch = strsep(&ptmp, delim); 4508 if ((pch == NULL) || (strlen(pch) == 0)) 4509 break; 4510 4511 sscanf(pch, "%x", &tmp); 4512 param[count++] = (u8)tmp; 4513 } while (count < 8); 4514 4515 if (count == 0) { 4516 kfree(pbuf); 4517 DBG_871X("%s: parameter error(level 2)!\n", __func__); 4518 return -EFAULT; 4519 } 4520 4521 ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, ¶m[1]); 4522 4523 pos = sprintf(extra, "H2C ID = 0x%02x content =", param[0]); 4524 for (i = 1; i<count; i++) 4525 pos += sprintf(extra+pos, "%02x,", param[i]); 4526 extra[pos] = 0; 4527 pos--; 4528 pos += sprintf(extra+pos, " %s", ret == _FAIL?"FAIL":"OK"); 4529 4530 wrqu->data.length = strlen(extra) + 1; 4531 } 4532 4533 kfree(pbuf); 4534 return 0; 4535 } 4536 4537 static iw_handler rtw_handlers[] = { 4538 NULL, /* SIOCSIWCOMMIT */ 4539 rtw_wx_get_name, /* SIOCGIWNAME */ 4540 dummy, /* SIOCSIWNWID */ 4541 dummy, /* SIOCGIWNWID */ 4542 rtw_wx_set_freq, /* SIOCSIWFREQ */ 4543 rtw_wx_get_freq, /* SIOCGIWFREQ */ 4544 rtw_wx_set_mode, /* SIOCSIWMODE */ 4545 rtw_wx_get_mode, /* SIOCGIWMODE */ 4546 dummy, /* SIOCSIWSENS */ 4547 rtw_wx_get_sens, /* SIOCGIWSENS */ 4548 NULL, /* SIOCSIWRANGE */ 4549 rtw_wx_get_range, /* SIOCGIWRANGE */ 4550 rtw_wx_set_priv, /* SIOCSIWPRIV */ 4551 NULL, /* SIOCGIWPRIV */ 4552 NULL, /* SIOCSIWSTATS */ 4553 NULL, /* SIOCGIWSTATS */ 4554 dummy, /* SIOCSIWSPY */ 4555 dummy, /* SIOCGIWSPY */ 4556 NULL, /* SIOCGIWTHRSPY */ 4557 NULL, /* SIOCWIWTHRSPY */ 4558 rtw_wx_set_wap, /* SIOCSIWAP */ 4559 rtw_wx_get_wap, /* SIOCGIWAP */ 4560 rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */ 4561 dummy, /* SIOCGIWAPLIST -- depricated */ 4562 rtw_wx_set_scan, /* SIOCSIWSCAN */ 4563 rtw_wx_get_scan, /* SIOCGIWSCAN */ 4564 rtw_wx_set_essid, /* SIOCSIWESSID */ 4565 rtw_wx_get_essid, /* SIOCGIWESSID */ 4566 dummy, /* SIOCSIWNICKN */ 4567 rtw_wx_get_nick, /* SIOCGIWNICKN */ 4568 NULL, /* -- hole -- */ 4569 NULL, /* -- hole -- */ 4570 rtw_wx_set_rate, /* SIOCSIWRATE */ 4571 rtw_wx_get_rate, /* SIOCGIWRATE */ 4572 rtw_wx_set_rts, /* SIOCSIWRTS */ 4573 rtw_wx_get_rts, /* SIOCGIWRTS */ 4574 rtw_wx_set_frag, /* SIOCSIWFRAG */ 4575 rtw_wx_get_frag, /* SIOCGIWFRAG */ 4576 dummy, /* SIOCSIWTXPOW */ 4577 dummy, /* SIOCGIWTXPOW */ 4578 dummy, /* SIOCSIWRETRY */ 4579 rtw_wx_get_retry, /* SIOCGIWRETRY */ 4580 rtw_wx_set_enc, /* SIOCSIWENCODE */ 4581 rtw_wx_get_enc, /* SIOCGIWENCODE */ 4582 dummy, /* SIOCSIWPOWER */ 4583 rtw_wx_get_power, /* SIOCGIWPOWER */ 4584 NULL, /*---hole---*/ 4585 NULL, /*---hole---*/ 4586 rtw_wx_set_gen_ie, /* SIOCSIWGENIE */ 4587 NULL, /* SIOCGWGENIE */ 4588 rtw_wx_set_auth, /* SIOCSIWAUTH */ 4589 NULL, /* SIOCGIWAUTH */ 4590 rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ 4591 NULL, /* SIOCGIWENCODEEXT */ 4592 rtw_wx_set_pmkid, /* SIOCSIWPMKSA */ 4593 NULL, /*---hole---*/ 4594 }; 4595 4596 static const struct iw_priv_args rtw_private_args[] = { 4597 { 4598 SIOCIWFIRSTPRIV + 0x0, 4599 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write" 4600 }, 4601 { 4602 SIOCIWFIRSTPRIV + 0x1, 4603 IW_PRIV_TYPE_CHAR | 0x7FF, 4604 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read" 4605 }, 4606 { 4607 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext" 4608 }, 4609 { 4610 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl" 4611 }, 4612 { 4613 SIOCIWFIRSTPRIV + 0x4, 4614 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" 4615 }, 4616 { 4617 SIOCIWFIRSTPRIV + 0x5, 4618 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid" 4619 }, 4620 { 4621 SIOCIWFIRSTPRIV + 0x6, 4622 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start" 4623 }, 4624 /* for PLATFORM_MT53XX */ 4625 { 4626 SIOCIWFIRSTPRIV + 0x7, 4627 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity" 4628 }, 4629 { 4630 SIOCIWFIRSTPRIV + 0x8, 4631 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie" 4632 }, 4633 { 4634 SIOCIWFIRSTPRIV + 0x9, 4635 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie" 4636 }, 4637 4638 /* for RTK_DMP_PLATFORM */ 4639 { 4640 SIOCIWFIRSTPRIV + 0xA, 4641 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan" 4642 }, 4643 4644 { 4645 SIOCIWFIRSTPRIV + 0xB, 4646 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg" 4647 }, 4648 { 4649 SIOCIWFIRSTPRIV + 0xC, 4650 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw" 4651 }, 4652 { 4653 SIOCIWFIRSTPRIV + 0xD, 4654 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr" 4655 }, 4656 { 4657 SIOCIWFIRSTPRIV + 0x10, 4658 IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set" 4659 }, 4660 { 4661 SIOCIWFIRSTPRIV + 0x11, 4662 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get" 4663 }, 4664 { 4665 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL" 4666 }, 4667 { 4668 SIOCIWFIRSTPRIV + 0x13, 4669 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2" 4670 }, 4671 { 4672 SIOCIWFIRSTPRIV + 0x14, 4673 IW_PRIV_TYPE_CHAR | 64, 0, "tdls" 4674 }, 4675 { 4676 SIOCIWFIRSTPRIV + 0x15, 4677 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get" 4678 }, 4679 { 4680 SIOCIWFIRSTPRIV + 0x16, 4681 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set" 4682 }, 4683 4684 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"}, 4685 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"}, 4686 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"}, 4687 { 4688 SIOCIWFIRSTPRIV + 0x1D, 4689 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test" 4690 }, 4691 4692 #ifdef CONFIG_WOWLAN 4693 { MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" }, /* set */ 4694 #endif 4695 #ifdef CONFIG_AP_WOWLAN 4696 { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, /* set */ 4697 #endif 4698 }; 4699 4700 static iw_handler rtw_private_handler[] = { 4701 rtw_wx_write32, /* 0x00 */ 4702 rtw_wx_read32, /* 0x01 */ 4703 rtw_drvext_hdl, /* 0x02 */ 4704 NULL, /* 0x03 */ 4705 4706 /* for MM DTV platform */ 4707 rtw_get_ap_info, /* 0x04 */ 4708 4709 rtw_set_pid, /* 0x05 */ 4710 rtw_wps_start, /* 0x06 */ 4711 4712 /* for PLATFORM_MT53XX */ 4713 rtw_wx_get_sensitivity, /* 0x07 */ 4714 rtw_wx_set_mtk_wps_probe_ie, /* 0x08 */ 4715 rtw_wx_set_mtk_wps_ie, /* 0x09 */ 4716 4717 /* for RTK_DMP_PLATFORM */ 4718 /* Set Channel depend on the country code */ 4719 rtw_wx_set_channel_plan, /* 0x0A */ 4720 4721 rtw_dbg_port, /* 0x0B */ 4722 rtw_wx_write_rf, /* 0x0C */ 4723 rtw_wx_read_rf, /* 0x0D */ 4724 rtw_wx_priv_null, /* 0x0E */ 4725 rtw_wx_priv_null, /* 0x0F */ 4726 rtw_p2p_set, /* 0x10 */ 4727 rtw_p2p_get, /* 0x11 */ 4728 NULL, /* 0x12 */ 4729 rtw_p2p_get2, /* 0x13 */ 4730 4731 NULL, /* 0x14 */ 4732 NULL, /* 0x15 */ 4733 4734 rtw_pm_set, /* 0x16 */ 4735 rtw_wx_priv_null, /* 0x17 */ 4736 rtw_rereg_nd_name, /* 0x18 */ 4737 rtw_wx_priv_null, /* 0x19 */ 4738 NULL, /* 0x1A */ 4739 NULL, /* 0x1B */ 4740 NULL, /* 0x1C is reserved for hostapd */ 4741 rtw_test, /* 0x1D */ 4742 }; 4743 4744 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) 4745 { 4746 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 4747 struct iw_statistics *piwstats =&padapter->iwstats; 4748 int tmp_level = 0; 4749 int tmp_qual = 0; 4750 int tmp_noise = 0; 4751 4752 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) { 4753 piwstats->qual.qual = 0; 4754 piwstats->qual.level = 0; 4755 piwstats->qual.noise = 0; 4756 /* DBG_871X("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); */ 4757 } else { 4758 #ifdef CONFIG_SIGNAL_DISPLAY_DBM 4759 tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength); 4760 #else 4761 #ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING 4762 { 4763 /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */ 4764 4765 struct hal_com_data *pHal = GET_HAL_DATA(padapter); 4766 4767 tmp_level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, padapter->recvpriv.signal_strength); 4768 } 4769 #else 4770 tmp_level = padapter->recvpriv.signal_strength; 4771 #endif 4772 #endif 4773 4774 tmp_qual = padapter->recvpriv.signal_qual; 4775 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) 4776 if (rtw_linked_check(padapter)) { 4777 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4778 struct noise_info info; 4779 info.bPauseDIG = true; 4780 info.IGIValue = 0x1e; 4781 info.max_time = 100;/* ms */ 4782 info.chan = pmlmeext->cur_channel ;/* rtw_get_oper_ch(padapter); */ 4783 rtw_ps_deny(padapter, PS_DENY_IOCTL); 4784 LeaveAllPowerSaveModeDirect(padapter); 4785 4786 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&info, false); 4787 /* ODM_InbandNoise_Monitor(podmpriv, true, 0x20, 100); */ 4788 rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL); 4789 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(info.chan), &(padapter->recvpriv.noise)); 4790 DBG_871X("chan:%d, noise_level:%d\n", info.chan, padapter->recvpriv.noise); 4791 } 4792 #endif 4793 tmp_noise = padapter->recvpriv.noise; 4794 DBG_871X("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise, padapter->recvpriv.rssi); 4795 4796 piwstats->qual.level = tmp_level; 4797 piwstats->qual.qual = tmp_qual; 4798 piwstats->qual.noise = tmp_noise; 4799 } 4800 piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;/* IW_QUAL_DBM; */ 4801 4802 #ifdef CONFIG_SIGNAL_DISPLAY_DBM 4803 piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM; 4804 #endif 4805 4806 return &padapter->iwstats; 4807 } 4808 4809 struct iw_handler_def rtw_handlers_def = { 4810 .standard = rtw_handlers, 4811 .num_standard = ARRAY_SIZE(rtw_handlers), 4812 #if defined(CONFIG_WEXT_PRIV) 4813 .private = rtw_private_handler, 4814 .private_args = (struct iw_priv_args *)rtw_private_args, 4815 .num_private = ARRAY_SIZE(rtw_private_handler), 4816 .num_private_args = ARRAY_SIZE(rtw_private_args), 4817 #endif 4818 .get_wireless_stats = rtw_get_wireless_stats, 4819 }; 4820 4821 /* copy from net/wireless/wext.c start */ 4822 /* ---------------------------------------------------------------- */ 4823 /* 4824 * Calculate size of private arguments 4825 */ 4826 static const char iw_priv_type_size[] = { 4827 0, /* IW_PRIV_TYPE_NONE */ 4828 1, /* IW_PRIV_TYPE_BYTE */ 4829 1, /* IW_PRIV_TYPE_CHAR */ 4830 0, /* Not defined */ 4831 sizeof(__u32), /* IW_PRIV_TYPE_INT */ 4832 sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */ 4833 sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */ 4834 0, /* Not defined */ 4835 }; 4836 4837 static int get_priv_size(__u16 args) 4838 { 4839 int num = args & IW_PRIV_SIZE_MASK; 4840 int type = (args & IW_PRIV_TYPE_MASK) >> 12; 4841 4842 return num * iw_priv_type_size[type]; 4843 } 4844 /* copy from net/wireless/wext.c end */ 4845 4846 static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data) 4847 { 4848 int err = 0; 4849 u8 *input = NULL; 4850 u32 input_len = 0; 4851 const char delim[] = " "; 4852 u8 *output = NULL; 4853 u32 output_len = 0; 4854 u32 count = 0; 4855 u8 *buffer = NULL; 4856 u32 buffer_len = 0; 4857 char *ptr = NULL; 4858 u8 cmdname[17] = {0}; /* IFNAMSIZ+1 */ 4859 u32 cmdlen; 4860 s32 len; 4861 u8 *extra = NULL; 4862 u32 extra_size = 0; 4863 4864 s32 k; 4865 const iw_handler *priv; /* Private ioctl */ 4866 const struct iw_priv_args *priv_args; /* Private ioctl description */ 4867 u32 num_priv_args; /* Number of descriptions */ 4868 iw_handler handler; 4869 int temp; 4870 int subcmd = 0; /* sub-ioctl index */ 4871 int offset = 0; /* Space for sub-ioctl index */ 4872 4873 union iwreq_data wdata; 4874 4875 4876 memcpy(&wdata, wrq_data, sizeof(wdata)); 4877 4878 input_len = 2048; 4879 input = rtw_zmalloc(input_len); 4880 if (NULL == input) 4881 return -ENOMEM; 4882 if (copy_from_user(input, wdata.data.pointer, input_len)) { 4883 err = -EFAULT; 4884 goto exit; 4885 } 4886 ptr = input; 4887 len = strlen(input); 4888 4889 sscanf(ptr, "%16s", cmdname); 4890 cmdlen = strlen(cmdname); 4891 DBG_8192C("%s: cmd =%s\n", __func__, cmdname); 4892 4893 /* skip command string */ 4894 if (cmdlen > 0) 4895 cmdlen += 1; /* skip one space */ 4896 ptr += cmdlen; 4897 len -= cmdlen; 4898 DBG_8192C("%s: parameters =%s\n", __func__, ptr); 4899 4900 priv = rtw_private_handler; 4901 priv_args = rtw_private_args; 4902 num_priv_args = ARRAY_SIZE(rtw_private_args); 4903 4904 if (num_priv_args == 0) { 4905 err = -EOPNOTSUPP; 4906 goto exit; 4907 } 4908 4909 /* Search the correct ioctl */ 4910 k = -1; 4911 while ((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname)); 4912 4913 /* If not found... */ 4914 if (k == num_priv_args) { 4915 err = -EOPNOTSUPP; 4916 goto exit; 4917 } 4918 4919 /* Watch out for sub-ioctls ! */ 4920 if (priv_args[k].cmd < SIOCDEVPRIVATE) { 4921 int j = -1; 4922 4923 /* Find the matching *real* ioctl */ 4924 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') || 4925 (priv_args[j].set_args != priv_args[k].set_args) || 4926 (priv_args[j].get_args != priv_args[k].get_args))); 4927 4928 /* If not found... */ 4929 if (j == num_priv_args) { 4930 err = -EINVAL; 4931 goto exit; 4932 } 4933 4934 /* Save sub-ioctl number */ 4935 subcmd = priv_args[k].cmd; 4936 /* Reserve one int (simplify alignment issues) */ 4937 offset = sizeof(__u32); 4938 /* Use real ioctl definition from now on */ 4939 k = j; 4940 } 4941 4942 buffer = rtw_zmalloc(4096); 4943 if (NULL == buffer) { 4944 err = -ENOMEM; 4945 goto exit; 4946 } 4947 4948 /* If we have to set some data */ 4949 if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) && 4950 (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) { 4951 u8 *str; 4952 4953 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) { 4954 case IW_PRIV_TYPE_BYTE: 4955 /* Fetch args */ 4956 count = 0; 4957 do { 4958 str = strsep(&ptr, delim); 4959 if (NULL == str) break; 4960 sscanf(str, "%i", &temp); 4961 buffer[count++] = (u8)temp; 4962 } while (1); 4963 buffer_len = count; 4964 4965 /* Number of args to fetch */ 4966 wdata.data.length = count; 4967 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) 4968 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK; 4969 4970 break; 4971 4972 case IW_PRIV_TYPE_INT: 4973 /* Fetch args */ 4974 count = 0; 4975 do { 4976 str = strsep(&ptr, delim); 4977 if (NULL == str) break; 4978 sscanf(str, "%i", &temp); 4979 ((s32 *)buffer)[count++] = (s32)temp; 4980 } while (1); 4981 buffer_len = count * sizeof(s32); 4982 4983 /* Number of args to fetch */ 4984 wdata.data.length = count; 4985 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) 4986 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK; 4987 4988 break; 4989 4990 case IW_PRIV_TYPE_CHAR: 4991 if (len > 0) { 4992 /* Size of the string to fetch */ 4993 wdata.data.length = len; 4994 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) 4995 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK; 4996 4997 /* Fetch string */ 4998 memcpy(buffer, ptr, wdata.data.length); 4999 } else { 5000 wdata.data.length = 1; 5001 buffer[0] = '\0'; 5002 } 5003 buffer_len = wdata.data.length; 5004 break; 5005 5006 default: 5007 DBG_8192C("%s: Not yet implemented...\n", __func__); 5008 err = -1; 5009 goto exit; 5010 } 5011 5012 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) && 5013 (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) { 5014 DBG_8192C("%s: The command %s needs exactly %d argument(s)...\n", 5015 __func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK); 5016 err = -EINVAL; 5017 goto exit; 5018 } 5019 } else { /* if args to set */ 5020 wdata.data.length = 0L; 5021 } 5022 5023 /* Those two tests are important. They define how the driver 5024 * will have to handle the data */ 5025 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) && 5026 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) { 5027 /* First case : all SET args fit within wrq */ 5028 if (offset) 5029 wdata.mode = subcmd; 5030 memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset); 5031 } else { 5032 if ((priv_args[k].set_args == 0) && 5033 (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) && 5034 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) { 5035 /* Second case : no SET args, GET args fit within wrq */ 5036 if (offset) 5037 wdata.mode = subcmd; 5038 } else { 5039 /* Third case : args won't fit in wrq, or variable number of args */ 5040 if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) { 5041 err = -EFAULT; 5042 goto exit; 5043 } 5044 wdata.data.flags = subcmd; 5045 } 5046 } 5047 5048 kfree(input); 5049 input = NULL; 5050 5051 extra_size = 0; 5052 if (IW_IS_SET(priv_args[k].cmd)) { 5053 /* Size of set arguments */ 5054 extra_size = get_priv_size(priv_args[k].set_args); 5055 5056 /* Does it fits in iwr ? */ 5057 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) && 5058 ((extra_size + offset) <= IFNAMSIZ)) 5059 extra_size = 0; 5060 } else { 5061 /* Size of get arguments */ 5062 extra_size = get_priv_size(priv_args[k].get_args); 5063 5064 /* Does it fits in iwr ? */ 5065 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) && 5066 (extra_size <= IFNAMSIZ)) 5067 extra_size = 0; 5068 } 5069 5070 if (extra_size == 0) { 5071 extra = (u8 *)&wdata; 5072 kfree(buffer); 5073 buffer = NULL; 5074 } else 5075 extra = buffer; 5076 5077 handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV]; 5078 err = handler(dev, NULL, &wdata, extra); 5079 5080 /* If we have to get some data */ 5081 if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) && 5082 (priv_args[k].get_args & IW_PRIV_SIZE_MASK)) { 5083 int j; 5084 int n = 0; /* number of args */ 5085 u8 str[20] = {0}; 5086 5087 /* Check where is the returned data */ 5088 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) && 5089 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) 5090 n = priv_args[k].get_args & IW_PRIV_SIZE_MASK; 5091 else 5092 n = wdata.data.length; 5093 5094 output = rtw_zmalloc(4096); 5095 if (NULL == output) { 5096 err = -ENOMEM; 5097 goto exit; 5098 } 5099 5100 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) { 5101 case IW_PRIV_TYPE_BYTE: 5102 /* Display args */ 5103 for (j = 0; j < n; j++) { 5104 sprintf(str, "%d ", extra[j]); 5105 len = strlen(str); 5106 output_len = strlen(output); 5107 if ((output_len + len + 1) > 4096) { 5108 err = -E2BIG; 5109 goto exit; 5110 } 5111 memcpy(output+output_len, str, len); 5112 } 5113 break; 5114 5115 case IW_PRIV_TYPE_INT: 5116 /* Display args */ 5117 for (j = 0; j < n; j++) { 5118 sprintf(str, "%d ", ((__s32 *)extra)[j]); 5119 len = strlen(str); 5120 output_len = strlen(output); 5121 if ((output_len + len + 1) > 4096) { 5122 err = -E2BIG; 5123 goto exit; 5124 } 5125 memcpy(output+output_len, str, len); 5126 } 5127 break; 5128 5129 case IW_PRIV_TYPE_CHAR: 5130 /* Display args */ 5131 memcpy(output, extra, n); 5132 break; 5133 5134 default: 5135 DBG_8192C("%s: Not yet implemented...\n", __func__); 5136 err = -1; 5137 goto exit; 5138 } 5139 5140 output_len = strlen(output) + 1; 5141 wrq_data->data.length = output_len; 5142 if (copy_to_user(wrq_data->data.pointer, output, output_len)) { 5143 err = -EFAULT; 5144 goto exit; 5145 } 5146 } else { /* if args to set */ 5147 wrq_data->data.length = 0; 5148 } 5149 5150 exit: 5151 kfree(input); 5152 kfree(buffer); 5153 kfree(output); 5154 5155 return err; 5156 } 5157 5158 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 5159 { 5160 struct iwreq *wrq = (struct iwreq *)rq; 5161 int ret = 0; 5162 5163 switch (cmd) { 5164 case RTL_IOCTL_WPA_SUPPLICANT: 5165 ret = wpa_supplicant_ioctl(dev, &wrq->u.data); 5166 break; 5167 case RTL_IOCTL_HOSTAPD: 5168 ret = rtw_hostapd_ioctl(dev, &wrq->u.data); 5169 break; 5170 case SIOCDEVPRIVATE: 5171 ret = rtw_ioctl_wext_private(dev, &wrq->u); 5172 break; 5173 default: 5174 ret = -EOPNOTSUPP; 5175 break; 5176 } 5177 5178 return ret; 5179 } 5180