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