ioctl_linux.c revision 6609ed9a3313f1d1ad66de4c265c25a35c175d2a
1/****************************************************************************** 2 * 3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 17 * 18 * 19 ******************************************************************************/ 20#define _IOCTL_LINUX_C_ 21 22#include <osdep_service.h> 23#include <drv_types.h> 24#include <wlan_bssdef.h> 25#include <rtw_debug.h> 26#include <wifi.h> 27#include <rtw_mlme.h> 28#include <rtw_mlme_ext.h> 29#include <rtw_ioctl.h> 30#include <rtw_ioctl_set.h> 31#include <rtl8188e_hal.h> 32 33#include <rtw_mp.h> 34#include <rtw_iol.h> 35#include <linux/vmalloc.h> 36 37#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30) 38 39#define SCAN_ITEM_SIZE 768 40#define MAX_CUSTOM_LEN 64 41#define RATE_COUNT 4 42 43/* combo scan */ 44#define WEXT_CSCAN_AMOUNT 9 45#define WEXT_CSCAN_BUF_LEN 360 46#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00" 47#define WEXT_CSCAN_HEADER_SIZE 12 48#define WEXT_CSCAN_SSID_SECTION 'S' 49#define WEXT_CSCAN_CHANNEL_SECTION 'C' 50#define WEXT_CSCAN_NPROBE_SECTION 'N' 51#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A' 52#define WEXT_CSCAN_PASV_DWELL_SECTION 'P' 53#define WEXT_CSCAN_HOME_DWELL_SECTION 'H' 54#define WEXT_CSCAN_TYPE_SECTION 'T' 55 56static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000, 57 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 58 48000000, 54000000}; 59 60static const char * const iw_operation_mode[] = { 61 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", 62 "Secondary", "Monitor" 63}; 64 65void indicate_wx_scan_complete_event(struct adapter *padapter) 66{ 67 union iwreq_data wrqu; 68 69 memset(&wrqu, 0, sizeof(union iwreq_data)); 70 wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL); 71} 72 73void rtw_indicate_wx_assoc_event(struct adapter *padapter) 74{ 75 union iwreq_data wrqu; 76 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 77 78 memset(&wrqu, 0, sizeof(union iwreq_data)); 79 80 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 81 82 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN); 83 84 DBG_88E_LEVEL(_drv_always_, "assoc success\n"); 85 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); 86} 87 88void rtw_indicate_wx_disassoc_event(struct adapter *padapter) 89{ 90 union iwreq_data wrqu; 91 92 memset(&wrqu, 0, sizeof(union iwreq_data)); 93 94 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 95 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 96 97 DBG_88E_LEVEL(_drv_always_, "indicate disassoc\n"); 98 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); 99} 100 101static char *translate_scan(struct adapter *padapter, 102 struct iw_request_info *info, 103 struct wlan_network *pnetwork, 104 char *start, char *stop) 105{ 106 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 107 struct iw_event iwe; 108 u16 cap; 109 __le16 le_tmp; 110 u32 ht_ielen = 0; 111 char custom[MAX_CUSTOM_LEN]; 112 char *p; 113 u16 max_rate = 0, rate, ht_cap = false; 114 u32 i = 0; 115 u8 bw_40MHz = 0, short_GI = 0; 116 u16 mcs_rate = 0; 117 u8 ss, sq; 118#ifdef CONFIG_88EU_P2P 119 struct wifidirect_info *pwdinfo = &padapter->wdinfo; 120 121 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { 122 u32 blnGotP2PIE = false; 123 124 /* User is doing the P2P device discovery */ 125 /* The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */ 126 /* If not, the driver should ignore this AP and go to the next AP. */ 127 128 /* Verifying the SSID */ 129 if (!memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) { 130 u32 p2pielen = 0; 131 132 if (pnetwork->network.Reserved[0] == 2) {/* Probe Request */ 133 /* Verifying the P2P IE */ 134 if (rtw_get_p2p_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &p2pielen)) 135 blnGotP2PIE = true; 136 } else {/* Beacon or Probe Respones */ 137 /* Verifying the P2P IE */ 138 if (rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) 139 blnGotP2PIE = true; 140 } 141 } 142 143 if (!blnGotP2PIE) 144 return start; 145 } 146#endif /* CONFIG_88EU_P2P */ 147 148 /* AP MAC address */ 149 iwe.cmd = SIOCGIWAP; 150 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 151 152 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN); 153 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); 154 155 /* Add the ESSID */ 156 iwe.cmd = SIOCGIWESSID; 157 iwe.u.data.flags = 1; 158 iwe.u.data.length = min_t(u16, pnetwork->network.Ssid.SsidLength, 32); 159 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); 160 161 /* parsing HT_CAP_IE */ 162 p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-12); 163 164 if (p && ht_ielen > 0) { 165 struct rtw_ieee80211_ht_cap *pht_capie; 166 ht_cap = true; 167 pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2); 168 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2); 169 bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0; 170 short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; 171 } 172 173 /* Add the protocol name */ 174 iwe.cmd = SIOCGIWNAME; 175 if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates))) { 176 if (ht_cap) 177 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn"); 178 else 179 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b"); 180 } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates))) { 181 if (ht_cap) 182 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn"); 183 else 184 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg"); 185 } else { 186 if (pnetwork->network.Configuration.DSConfig > 14) { 187 if (ht_cap) 188 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an"); 189 else 190 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a"); 191 } else { 192 if (ht_cap) 193 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn"); 194 else 195 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g"); 196 } 197 } 198 199 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN); 200 201 /* Add mode */ 202 iwe.cmd = SIOCGIWMODE; 203 memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); 204 205 cap = le16_to_cpu(le_tmp); 206 207 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) { 208 if (cap & WLAN_CAPABILITY_BSS) 209 iwe.u.mode = IW_MODE_MASTER; 210 else 211 iwe.u.mode = IW_MODE_ADHOC; 212 213 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN); 214 } 215 216 if (pnetwork->network.Configuration.DSConfig < 1) 217 pnetwork->network.Configuration.DSConfig = 1; 218 219 /* Add frequency/channel */ 220 iwe.cmd = SIOCGIWFREQ; 221 iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000; 222 iwe.u.freq.e = 1; 223 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig; 224 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN); 225 226 /* Add encryption capability */ 227 iwe.cmd = SIOCGIWENCODE; 228 if (cap & WLAN_CAPABILITY_PRIVACY) 229 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 230 else 231 iwe.u.data.flags = IW_ENCODE_DISABLED; 232 iwe.u.data.length = 0; 233 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); 234 235 /*Add basic and extended rates */ 236 max_rate = 0; 237 p = custom; 238 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); 239 while (pnetwork->network.SupportedRates[i] != 0) { 240 rate = pnetwork->network.SupportedRates[i]&0x7F; 241 if (rate > max_rate) 242 max_rate = rate; 243 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), 244 "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); 245 i++; 246 } 247 248 if (ht_cap) { 249 if (mcs_rate&0x8000)/* MCS15 */ 250 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130); 251 else if (mcs_rate&0x0080)/* MCS7 */ 252 ; 253 else/* default MCS7 */ 254 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65); 255 256 max_rate = max_rate*2;/* Mbps/2; */ 257 } 258 259 iwe.cmd = SIOCGIWRATE; 260 iwe.u.bitrate.fixed = 0; 261 iwe.u.bitrate.disabled = 0; 262 iwe.u.bitrate.value = max_rate * 500000; 263 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN); 264 265 /* parsing WPA/WPA2 IE */ 266 { 267 u8 buf[MAX_WPA_IE_LEN]; 268 u8 wpa_ie[255], rsn_ie[255]; 269 u16 wpa_len = 0, rsn_len = 0; 270 u8 *p; 271 272 rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len); 273 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.Ssid.Ssid)); 274 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len, rsn_len)); 275 276 if (wpa_len > 0) { 277 p = buf; 278 memset(buf, 0, MAX_WPA_IE_LEN); 279 p += sprintf(p, "wpa_ie="); 280 for (i = 0; i < wpa_len; i++) 281 p += sprintf(p, "%02x", wpa_ie[i]); 282 283 memset(&iwe, 0, sizeof(iwe)); 284 iwe.cmd = IWEVCUSTOM; 285 iwe.u.data.length = strlen(buf); 286 start = iwe_stream_add_point(info, start, stop, &iwe, buf); 287 288 memset(&iwe, 0, sizeof(iwe)); 289 iwe.cmd = IWEVGENIE; 290 iwe.u.data.length = wpa_len; 291 start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie); 292 } 293 if (rsn_len > 0) { 294 p = buf; 295 memset(buf, 0, MAX_WPA_IE_LEN); 296 p += sprintf(p, "rsn_ie="); 297 for (i = 0; i < rsn_len; i++) 298 p += sprintf(p, "%02x", rsn_ie[i]); 299 memset(&iwe, 0, sizeof(iwe)); 300 iwe.cmd = IWEVCUSTOM; 301 iwe.u.data.length = strlen(buf); 302 start = iwe_stream_add_point(info, start, stop, &iwe, buf); 303 304 memset(&iwe, 0, sizeof(iwe)); 305 iwe.cmd = IWEVGENIE; 306 iwe.u.data.length = rsn_len; 307 start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie); 308 } 309 } 310 311 {/* parsing WPS IE */ 312 uint cnt = 0, total_ielen; 313 u8 *wpsie_ptr = NULL; 314 uint wps_ielen = 0; 315 316 u8 *ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_; 317 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_; 318 319 while (cnt < total_ielen) { 320 if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) { 321 wpsie_ptr = &ie_ptr[cnt]; 322 iwe.cmd = IWEVGENIE; 323 iwe.u.data.length = (u16)wps_ielen; 324 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr); 325 } 326 cnt += ie_ptr[cnt+1]+2; /* goto next */ 327 } 328 } 329 330 /* Add quality statistics */ 331 iwe.cmd = IWEVQUAL; 332 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; 333 334 if (check_fwstate(pmlmepriv, _FW_LINKED) == true && 335 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) { 336 ss = padapter->recvpriv.signal_strength; 337 sq = padapter->recvpriv.signal_qual; 338 } else { 339 ss = pnetwork->network.PhyInfo.SignalStrength; 340 sq = pnetwork->network.PhyInfo.SignalQuality; 341 } 342 343 iwe.u.qual.level = (u8)ss; 344 iwe.u.qual.qual = (u8)sq; /* signal quality */ 345 iwe.u.qual.noise = 0; /* noise level */ 346 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); 347 return start; 348} 349 350static int wpa_set_auth_algs(struct net_device *dev, u32 value) 351{ 352 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 353 int ret = 0; 354 355 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) { 356 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value); 357 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 358 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; 359 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; 360 } else if (value & AUTH_ALG_SHARED_KEY) { 361 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value); 362 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 363 364 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; 365 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; 366 } else if (value & AUTH_ALG_OPEN_SYSTEM) { 367 DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n"); 368 if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) { 369 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; 370 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 371 } 372 } else if (value & AUTH_ALG_LEAP) { 373 DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n"); 374 } else { 375 DBG_88E("wpa_set_auth_algs, error!\n"); 376 ret = -EINVAL; 377 } 378 return ret; 379} 380 381static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) 382{ 383 int ret = 0; 384 u32 wep_key_idx, wep_key_len, wep_total_len; 385 struct ndis_802_11_wep *pwep = NULL; 386 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 387 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 388 struct security_priv *psecuritypriv = &padapter->securitypriv; 389#ifdef CONFIG_88EU_P2P 390 struct wifidirect_info *pwdinfo = &padapter->wdinfo; 391#endif /* CONFIG_88EU_P2P */ 392 393 param->u.crypt.err = 0; 394 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; 395 396 if (param_len < (u32) ((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) { 397 ret = -EINVAL; 398 goto exit; 399 } 400 401 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 402 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 403 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 404 if (param->u.crypt.idx >= WEP_KEYS) { 405 ret = -EINVAL; 406 goto exit; 407 } 408 } else { 409 ret = -EINVAL; 410 goto exit; 411 } 412 413 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 414 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n")); 415 DBG_88E("wpa_set_encryption, crypt.alg = WEP\n"); 416 417 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 418 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; 419 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; 420 421 wep_key_idx = param->u.crypt.idx; 422 wep_key_len = param->u.crypt.key_len; 423 424 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(1)wep_key_idx =%d\n", wep_key_idx)); 425 DBG_88E("(1)wep_key_idx =%d\n", wep_key_idx); 426 427 if (wep_key_idx > WEP_KEYS) 428 return -EINVAL; 429 430 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(2)wep_key_idx =%d\n", wep_key_idx)); 431 432 if (wep_key_len > 0) { 433 wep_key_len = wep_key_len <= 5 ? 5 : 13; 434 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); 435 pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len); 436 if (pwep == NULL) { 437 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, (" wpa_set_encryption: pwep allocate fail !!!\n")); 438 goto exit; 439 } 440 memset(pwep, 0, wep_total_len); 441 pwep->KeyLength = wep_key_len; 442 pwep->Length = wep_total_len; 443 if (wep_key_len == 13) { 444 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; 445 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_; 446 } 447 } else { 448 ret = -EINVAL; 449 goto exit; 450 } 451 pwep->KeyIndex = wep_key_idx; 452 pwep->KeyIndex |= 0x80000000; 453 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); 454 if (param->u.crypt.set_tx) { 455 DBG_88E("wep, set_tx = 1\n"); 456 if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL) 457 ret = -EOPNOTSUPP; 458 } else { 459 DBG_88E("wep, set_tx = 0\n"); 460 if (wep_key_idx >= WEP_KEYS) { 461 ret = -EOPNOTSUPP; 462 goto exit; 463 } 464 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); 465 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; 466 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0); 467 } 468 goto exit; 469 } 470 471 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */ 472 struct sta_info *psta, *pbcmc_sta; 473 struct sta_priv *pstapriv = &padapter->stapriv; 474 475 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) { /* sta mode */ 476 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); 477 if (psta == NULL) { 478 ; 479 } else { 480 if (strcmp(param->u.crypt.alg, "none") != 0) 481 psta->ieee8021x_blocked = false; 482 483 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || 484 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) 485 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; 486 487 if (param->u.crypt.set_tx == 1) { /* pairwise key */ 488 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 489 490 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ 491 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); 492 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); 493 padapter->securitypriv.busetkipkey = false; 494 } 495 496 DBG_88E(" ~~~~set sta key:unicastkey\n"); 497 498 rtw_setstakey_cmd(padapter, (unsigned char *)psta, true); 499 } else { /* group key */ 500 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)); 501 memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); 502 memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); 503 padapter->securitypriv.binstallGrpkey = true; 504 DBG_88E(" ~~~~set sta key:groupkey\n"); 505 506 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; 507 508 rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1); 509#ifdef CONFIG_88EU_P2P 510 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) 511 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE); 512#endif /* CONFIG_88EU_P2P */ 513 } 514 } 515 pbcmc_sta = rtw_get_bcmc_stainfo(padapter); 516 if (pbcmc_sta == NULL) { 517 ; 518 } else { 519 /* Jeff: don't disable ieee8021x_blocked while clearing key */ 520 if (strcmp(param->u.crypt.alg, "none") != 0) 521 pbcmc_sta->ieee8021x_blocked = false; 522 523 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || 524 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) 525 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; 526 } 527 } 528 } 529 530exit: 531 532 kfree(pwep); 533 return ret; 534} 535 536static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen) 537{ 538 u8 *buf = NULL; 539 int group_cipher = 0, pairwise_cipher = 0; 540 int ret = 0; 541#ifdef CONFIG_88EU_P2P 542 struct wifidirect_info *pwdinfo = &padapter->wdinfo; 543#endif /* CONFIG_88EU_P2P */ 544 545 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) { 546 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); 547 if (pie == NULL) 548 return ret; 549 else 550 return -EINVAL; 551 } 552 553 if (ielen) { 554 buf = kzalloc(ielen, GFP_KERNEL); 555 if (buf == NULL) { 556 ret = -ENOMEM; 557 goto exit; 558 } 559 560 memcpy(buf, pie, ielen); 561 562 /* dump */ 563 { 564 int i; 565 DBG_88E("\n wpa_ie(length:%d):\n", ielen); 566 for (i = 0; i < ielen; i += 8) 567 DBG_88E("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]); 568 } 569 570 if (ielen < RSN_HEADER_LEN) { 571 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("Ie len too short %d\n", ielen)); 572 ret = -1; 573 goto exit; 574 } 575 576 if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { 577 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; 578 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; 579 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); 580 } 581 582 if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { 583 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; 584 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; 585 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); 586 } 587 588 switch (group_cipher) { 589 case WPA_CIPHER_NONE: 590 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; 591 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; 592 break; 593 case WPA_CIPHER_WEP40: 594 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; 595 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 596 break; 597 case WPA_CIPHER_TKIP: 598 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_; 599 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; 600 break; 601 case WPA_CIPHER_CCMP: 602 padapter->securitypriv.dot118021XGrpPrivacy = _AES_; 603 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; 604 break; 605 case WPA_CIPHER_WEP104: 606 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_; 607 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 608 break; 609 } 610 611 switch (pairwise_cipher) { 612 case WPA_CIPHER_NONE: 613 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 614 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; 615 break; 616 case WPA_CIPHER_WEP40: 617 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; 618 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 619 break; 620 case WPA_CIPHER_TKIP: 621 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_; 622 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; 623 break; 624 case WPA_CIPHER_CCMP: 625 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_; 626 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; 627 break; 628 case WPA_CIPHER_WEP104: 629 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; 630 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 631 break; 632 } 633 634 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); 635 {/* set wps_ie */ 636 u16 cnt = 0; 637 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; 638 639 while (cnt < ielen) { 640 eid = buf[cnt]; 641 if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt+2], wps_oui, 4))) { 642 DBG_88E("SET WPS_IE\n"); 643 644 padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < (MAX_WPA_IE_LEN<<2)) ? (buf[cnt+1]+2) : (MAX_WPA_IE_LEN<<2); 645 646 memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len); 647 648 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); 649#ifdef CONFIG_88EU_P2P 650 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) 651 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING); 652#endif /* CONFIG_88EU_P2P */ 653 cnt += buf[cnt+1]+2; 654 break; 655 } else { 656 cnt += buf[cnt+1]+2; /* goto next */ 657 } 658 } 659 } 660 } 661 662 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, 663 ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n", 664 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype)); 665exit: 666 kfree(buf); 667 return ret; 668} 669 670typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; 671 672static int rtw_wx_get_name(struct net_device *dev, 673 struct iw_request_info *info, 674 union iwreq_data *wrqu, char *extra) 675{ 676 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 677 u32 ht_ielen = 0; 678 char *p; 679 u8 ht_cap = false; 680 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 681 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 682 NDIS_802_11_RATES_EX *prates = NULL; 683 684 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("cmd_code =%x\n", info->cmd)); 685 686 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) { 687 /* parsing HT_CAP_IE */ 688 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12); 689 if (p && ht_ielen > 0) 690 ht_cap = true; 691 692 prates = &pcur_bss->SupportedRates; 693 694 if (rtw_is_cckratesonly_included((u8 *)prates) == true) { 695 if (ht_cap) 696 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn"); 697 else 698 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b"); 699 } else if ((rtw_is_cckrates_included((u8 *)prates)) == true) { 700 if (ht_cap) 701 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn"); 702 else 703 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg"); 704 } else { 705 if (pcur_bss->Configuration.DSConfig > 14) { 706 if (ht_cap) 707 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an"); 708 else 709 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a"); 710 } else { 711 if (ht_cap) 712 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn"); 713 else 714 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); 715 } 716 } 717 } else { 718 snprintf(wrqu->name, IFNAMSIZ, "unassociated"); 719 } 720 return 0; 721} 722 723static int rtw_wx_set_freq(struct net_device *dev, 724 struct iw_request_info *info, 725 union iwreq_data *wrqu, char *extra) 726{ 727 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n")); 728 return 0; 729} 730 731static int rtw_wx_get_freq(struct net_device *dev, 732 struct iw_request_info *info, 733 union iwreq_data *wrqu, char *extra) 734{ 735 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 736 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 737 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 738 739 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 740 /* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */ 741 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000; 742 wrqu->freq.e = 1; 743 wrqu->freq.i = pcur_bss->Configuration.DSConfig; 744 } else { 745 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000; 746 wrqu->freq.e = 1; 747 wrqu->freq.i = padapter->mlmeextpriv.cur_channel; 748 } 749 750 return 0; 751} 752 753static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, 754 union iwreq_data *wrqu, char *b) 755{ 756 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 757 enum ndis_802_11_network_infra networkType; 758 int ret = 0; 759 760 if (_FAIL == rtw_pwr_wakeup(padapter)) { 761 ret = -EPERM; 762 goto exit; 763 } 764 765 if (!padapter->hw_init_completed) { 766 ret = -EPERM; 767 goto exit; 768 } 769 770 switch (wrqu->mode) { 771 case IW_MODE_AUTO: 772 networkType = Ndis802_11AutoUnknown; 773 DBG_88E("set_mode = IW_MODE_AUTO\n"); 774 break; 775 case IW_MODE_ADHOC: 776 networkType = Ndis802_11IBSS; 777 DBG_88E("set_mode = IW_MODE_ADHOC\n"); 778 break; 779 case IW_MODE_MASTER: 780 networkType = Ndis802_11APMode; 781 DBG_88E("set_mode = IW_MODE_MASTER\n"); 782 break; 783 case IW_MODE_INFRA: 784 networkType = Ndis802_11Infrastructure; 785 DBG_88E("set_mode = IW_MODE_INFRA\n"); 786 break; 787 default: 788 ret = -EINVAL; 789 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("\n Mode: %s is not supported\n", iw_operation_mode[wrqu->mode])); 790 goto exit; 791 } 792 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == false) { 793 ret = -EPERM; 794 goto exit; 795 } 796 rtw_setopmode_cmd(padapter, networkType); 797exit: 798 return ret; 799} 800 801static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a, 802 union iwreq_data *wrqu, char *b) 803{ 804 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 805 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 806 807 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_get_mode\n")); 808 809 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) 810 wrqu->mode = IW_MODE_INFRA; 811 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) || 812 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) 813 wrqu->mode = IW_MODE_ADHOC; 814 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) 815 wrqu->mode = IW_MODE_MASTER; 816 else 817 wrqu->mode = IW_MODE_AUTO; 818 819 return 0; 820} 821 822static int rtw_wx_set_pmkid(struct net_device *dev, 823 struct iw_request_info *a, 824 union iwreq_data *wrqu, char *extra) 825{ 826 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 827 u8 j, blInserted = false; 828 int ret = false; 829 struct security_priv *psecuritypriv = &padapter->securitypriv; 830 struct iw_pmksa *pPMK = (struct iw_pmksa *)extra; 831 u8 strZeroMacAddress[ETH_ALEN] = {0x00}; 832 u8 strIssueBssid[ETH_ALEN] = {0x00}; 833 834 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); 835 if (pPMK->cmd == IW_PMKSA_ADD) { 836 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n"); 837 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN)) 838 return ret; 839 else 840 ret = true; 841 blInserted = false; 842 843 /* overwrite PMKID */ 844 for (j = 0; j < NUM_PMKID_CACHE; j++) { 845 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { 846 /* BSSID is matched, the same AP => rewrite with new PMKID. */ 847 DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n"); 848 memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); 849 psecuritypriv->PMKIDList[j].bUsed = true; 850 psecuritypriv->PMKIDIndex = j+1; 851 blInserted = true; 852 break; 853 } 854 } 855 856 if (!blInserted) { 857 /* Find a new entry */ 858 DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n", 859 psecuritypriv->PMKIDIndex); 860 861 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN); 862 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN); 863 864 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true; 865 psecuritypriv->PMKIDIndex++; 866 if (psecuritypriv->PMKIDIndex == 16) 867 psecuritypriv->PMKIDIndex = 0; 868 } 869 } else if (pPMK->cmd == IW_PMKSA_REMOVE) { 870 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n"); 871 ret = true; 872 for (j = 0; j < NUM_PMKID_CACHE; j++) { 873 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { 874 /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */ 875 memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN); 876 psecuritypriv->PMKIDList[j].bUsed = false; 877 break; 878 } 879 } 880 } else if (pPMK->cmd == IW_PMKSA_FLUSH) { 881 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n"); 882 memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); 883 psecuritypriv->PMKIDIndex = 0; 884 ret = true; 885 } 886 return ret; 887} 888 889static int rtw_wx_get_sens(struct net_device *dev, 890 struct iw_request_info *info, 891 union iwreq_data *wrqu, char *extra) 892{ 893 wrqu->sens.value = 0; 894 wrqu->sens.fixed = 0; /* no auto select */ 895 wrqu->sens.disabled = 1; 896 return 0; 897} 898 899static int rtw_wx_get_range(struct net_device *dev, 900 struct iw_request_info *info, 901 union iwreq_data *wrqu, char *extra) 902{ 903 struct iw_range *range = (struct iw_range *)extra; 904 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 905 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 906 907 u16 val; 908 int i; 909 910 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_range. cmd_code =%x\n", info->cmd)); 911 912 wrqu->data.length = sizeof(*range); 913 memset(range, 0, sizeof(*range)); 914 915 /* Let's try to keep this struct in the same order as in 916 * linux/include/wireless.h 917 */ 918 919 /* TODO: See what values we can set, and remove the ones we can't 920 * set, or fill them with some default data. 921 */ 922 923 /* ~5 Mb/s real (802.11b) */ 924 range->throughput = 5 * 1000 * 1000; 925 926 /* signal level threshold range */ 927 928 /* percent values between 0 and 100. */ 929 range->max_qual.qual = 100; 930 range->max_qual.level = 100; 931 range->max_qual.noise = 100; 932 range->max_qual.updated = 7; /* Updated all three */ 933 934 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ 935 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ 936 range->avg_qual.level = 178; /* -78 dBm */ 937 range->avg_qual.noise = 0; 938 range->avg_qual.updated = 7; /* Updated all three */ 939 940 range->num_bitrates = RATE_COUNT; 941 942 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) 943 range->bitrate[i] = rtw_rates[i]; 944 945 range->min_frag = MIN_FRAG_THRESHOLD; 946 range->max_frag = MAX_FRAG_THRESHOLD; 947 948 range->pm_capa = 0; 949 950 range->we_version_compiled = WIRELESS_EXT; 951 range->we_version_source = 16; 952 953 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) { 954 /* Include only legal frequencies for some countries */ 955 if (pmlmeext->channel_set[i].ChannelNum != 0) { 956 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum; 957 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000; 958 range->freq[val].e = 1; 959 val++; 960 } 961 962 if (val == IW_MAX_FREQUENCIES) 963 break; 964 } 965 966 range->num_channels = val; 967 range->num_frequency = val; 968 969/* The following code will proivde the security capability to network manager. */ 970/* If the driver doesn't provide this capability to network manager, */ 971/* the WPA/WPA2 routers can't be chosen in the network manager. */ 972 973/* 974#define IW_SCAN_CAPA_NONE 0x00 975#define IW_SCAN_CAPA_ESSID 0x01 976#define IW_SCAN_CAPA_BSSID 0x02 977#define IW_SCAN_CAPA_CHANNEL 0x04 978#define IW_SCAN_CAPA_MODE 0x08 979#define IW_SCAN_CAPA_RATE 0x10 980#define IW_SCAN_CAPA_TYPE 0x20 981#define IW_SCAN_CAPA_TIME 0x40 982*/ 983 984 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 985 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 986 987 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | 988 IW_SCAN_CAPA_BSSID | IW_SCAN_CAPA_CHANNEL | 989 IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE; 990 return 0; 991} 992 993/* set bssid flow */ 994/* s1. rtw_set_802_11_infrastructure_mode() */ 995/* s2. rtw_set_802_11_authentication_mode() */ 996/* s3. set_802_11_encryption_mode() */ 997/* s4. rtw_set_802_11_bssid() */ 998static int rtw_wx_set_wap(struct net_device *dev, 999 struct iw_request_info *info, 1000 union iwreq_data *awrq, 1001 char *extra) 1002{ 1003 uint ret = 0; 1004 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1005 struct sockaddr *temp = (struct sockaddr *)awrq; 1006 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1007 struct list_head *phead; 1008 u8 *dst_bssid, *src_bssid; 1009 struct __queue *queue = &(pmlmepriv->scanned_queue); 1010 struct wlan_network *pnetwork = NULL; 1011 enum ndis_802_11_auth_mode authmode; 1012 1013 if (_FAIL == rtw_pwr_wakeup(padapter)) { 1014 ret = -1; 1015 goto exit; 1016 } 1017 1018 if (!padapter->bup) { 1019 ret = -1; 1020 goto exit; 1021 } 1022 1023 if (temp->sa_family != ARPHRD_ETHER) { 1024 ret = -EINVAL; 1025 goto exit; 1026 } 1027 1028 authmode = padapter->securitypriv.ndisauthtype; 1029 spin_lock_bh(&queue->lock); 1030 phead = get_list_head(queue); 1031 pmlmepriv->pscanned = phead->next; 1032 1033 while (phead != pmlmepriv->pscanned) { 1034 pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list); 1035 1036 pmlmepriv->pscanned = pmlmepriv->pscanned->next; 1037 1038 dst_bssid = pnetwork->network.MacAddress; 1039 1040 src_bssid = temp->sa_data; 1041 1042 if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) { 1043 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) { 1044 ret = -1; 1045 spin_unlock_bh(&queue->lock); 1046 goto exit; 1047 } 1048 1049 break; 1050 } 1051 } 1052 spin_unlock_bh(&queue->lock); 1053 1054 rtw_set_802_11_authentication_mode(padapter, authmode); 1055 /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */ 1056 if (rtw_set_802_11_bssid(padapter, temp->sa_data) == false) { 1057 ret = -1; 1058 goto exit; 1059 } 1060 1061exit: 1062 1063 return ret; 1064} 1065 1066static int rtw_wx_get_wap(struct net_device *dev, 1067 struct iw_request_info *info, 1068 union iwreq_data *wrqu, char *extra) 1069{ 1070 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1071 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1072 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 1073 1074 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 1075 1076 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 1077 1078 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_wap\n")); 1079 1080 if (((check_fwstate(pmlmepriv, _FW_LINKED)) == true) || 1081 ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) || 1082 ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == true)) 1083 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN); 1084 else 1085 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 1086 return 0; 1087} 1088 1089static int rtw_wx_set_mlme(struct net_device *dev, 1090 struct iw_request_info *info, 1091 union iwreq_data *wrqu, char *extra) 1092{ 1093 int ret = 0; 1094 u16 reason; 1095 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1096 struct iw_mlme *mlme = (struct iw_mlme *)extra; 1097 1098 if (mlme == NULL) 1099 return -1; 1100 1101 DBG_88E("%s\n", __func__); 1102 1103 reason = mlme->reason_code; 1104 1105 DBG_88E("%s, cmd =%d, reason =%d\n", __func__, mlme->cmd, reason); 1106 1107 switch (mlme->cmd) { 1108 case IW_MLME_DEAUTH: 1109 if (!rtw_set_802_11_disassociate(padapter)) 1110 ret = -1; 1111 break; 1112 case IW_MLME_DISASSOC: 1113 if (!rtw_set_802_11_disassociate(padapter)) 1114 ret = -1; 1115 break; 1116 default: 1117 return -EOPNOTSUPP; 1118 } 1119 return ret; 1120} 1121 1122static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, 1123 union iwreq_data *wrqu, char *extra) 1124{ 1125 u8 _status = false; 1126 int ret = 0; 1127 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1128 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1129 struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; 1130#ifdef CONFIG_88EU_P2P 1131 struct wifidirect_info *pwdinfo = &(padapter->wdinfo); 1132#endif /* CONFIG_88EU_P2P */ 1133 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n")); 1134 1135 if (padapter->registrypriv.mp_mode == 1) { 1136 if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { 1137 ret = -1; 1138 goto exit; 1139 } 1140 } 1141 if (_FAIL == rtw_pwr_wakeup(padapter)) { 1142 ret = -1; 1143 goto exit; 1144 } 1145 1146 if (padapter->bDriverStopped) { 1147 DBG_88E("bDriverStopped =%d\n", padapter->bDriverStopped); 1148 ret = -1; 1149 goto exit; 1150 } 1151 1152 if (!padapter->bup) { 1153 ret = -1; 1154 goto exit; 1155 } 1156 1157 if (!padapter->hw_init_completed) { 1158 ret = -1; 1159 goto exit; 1160 } 1161 1162 /* When Busy Traffic, driver do not site survey. So driver return success. */ 1163 /* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */ 1164 /* modify by thomas 2011-02-22. */ 1165 if (pmlmepriv->LinkDetectInfo.bBusyTraffic) { 1166 indicate_wx_scan_complete_event(padapter); 1167 goto exit; 1168 } 1169 1170 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) { 1171 indicate_wx_scan_complete_event(padapter); 1172 goto exit; 1173 } 1174 1175/* For the DMP WiFi Display project, the driver won't to scan because */ 1176/* the pmlmepriv->scan_interval is always equal to 3. */ 1177/* So, the wpa_supplicant won't find out the WPS SoftAP. */ 1178 1179#ifdef CONFIG_88EU_P2P 1180 if (pwdinfo->p2p_state != P2P_STATE_NONE) { 1181 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); 1182 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); 1183 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL); 1184 rtw_free_network_queue(padapter, true); 1185 } 1186#endif /* CONFIG_88EU_P2P */ 1187 1188 memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT); 1189 1190 if (wrqu->data.length == sizeof(struct iw_scan_req)) { 1191 struct iw_scan_req *req = (struct iw_scan_req *)extra; 1192 1193 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 1194 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE); 1195 1196 memcpy(ssid[0].Ssid, req->essid, len); 1197 ssid[0].SsidLength = len; 1198 1199 DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len); 1200 1201 spin_lock_bh(&pmlmepriv->lock); 1202 1203 _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0); 1204 1205 spin_unlock_bh(&pmlmepriv->lock); 1206 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { 1207 DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n"); 1208 } 1209 } else { 1210 if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE && 1211 !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) { 1212 int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE; 1213 char *pos = extra+WEXT_CSCAN_HEADER_SIZE; 1214 char section; 1215 char sec_len; 1216 int ssid_index = 0; 1217 1218 while (len >= 1) { 1219 section = *(pos++); 1220 len -= 1; 1221 1222 switch (section) { 1223 case WEXT_CSCAN_SSID_SECTION: 1224 if (len < 1) { 1225 len = 0; 1226 break; 1227 } 1228 sec_len = *(pos++); len -= 1; 1229 if (sec_len > 0 && sec_len <= len) { 1230 ssid[ssid_index].SsidLength = sec_len; 1231 memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength); 1232 ssid_index++; 1233 } 1234 pos += sec_len; 1235 len -= sec_len; 1236 break; 1237 case WEXT_CSCAN_TYPE_SECTION: 1238 case WEXT_CSCAN_CHANNEL_SECTION: 1239 pos += 1; 1240 len -= 1; 1241 break; 1242 case WEXT_CSCAN_PASV_DWELL_SECTION: 1243 case WEXT_CSCAN_HOME_DWELL_SECTION: 1244 case WEXT_CSCAN_ACTV_DWELL_SECTION: 1245 pos += 2; 1246 len -= 2; 1247 break; 1248 default: 1249 len = 0; /* stop parsing */ 1250 } 1251 } 1252 1253 /* it has still some scan parameter to parse, we only do this now... */ 1254 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT); 1255 } else { 1256 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); 1257 } 1258 } 1259 1260 if (!_status) 1261 ret = -1; 1262 1263exit: 1264 1265 return ret; 1266} 1267 1268static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, 1269 union iwreq_data *wrqu, char *extra) 1270{ 1271 struct list_head *plist, *phead; 1272 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1273 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1274 struct __queue *queue = &(pmlmepriv->scanned_queue); 1275 struct wlan_network *pnetwork = NULL; 1276 char *ev = extra; 1277 char *stop = ev + wrqu->data.length; 1278 u32 ret = 0; 1279 u32 cnt = 0; 1280 u32 wait_for_surveydone; 1281 int wait_status; 1282#ifdef CONFIG_88EU_P2P 1283 struct wifidirect_info *pwdinfo = &padapter->wdinfo; 1284#endif /* CONFIG_88EU_P2P */ 1285 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n")); 1286 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n")); 1287 1288 if (padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) { 1289 ret = -EINVAL; 1290 goto exit; 1291 } 1292 1293#ifdef CONFIG_88EU_P2P 1294 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { 1295 /* P2P is enabled */ 1296 wait_for_surveydone = 200; 1297 } else { 1298 /* P2P is disabled */ 1299 wait_for_surveydone = 100; 1300 } 1301#else 1302 { 1303 wait_for_surveydone = 100; 1304 } 1305#endif /* CONFIG_88EU_P2P */ 1306 1307 wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING; 1308 1309 while (check_fwstate(pmlmepriv, wait_status)) { 1310 msleep(30); 1311 cnt++; 1312 if (cnt > wait_for_surveydone) 1313 break; 1314 } 1315 1316 spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); 1317 1318 phead = get_list_head(queue); 1319 plist = phead->next; 1320 1321 while (phead != plist) { 1322 if ((stop - ev) < SCAN_ITEM_SIZE) { 1323 ret = -E2BIG; 1324 break; 1325 } 1326 1327 pnetwork = container_of(plist, struct wlan_network, list); 1328 1329 /* report network only if the current channel set contains the channel to which this network belongs */ 1330 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0) 1331 ev = translate_scan(padapter, a, pnetwork, ev, stop); 1332 1333 plist = plist->next; 1334 } 1335 1336 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1337 1338 wrqu->data.length = ev-extra; 1339 wrqu->data.flags = 0; 1340 1341exit: 1342 return ret; 1343} 1344 1345/* set ssid flow */ 1346/* s1. rtw_set_802_11_infrastructure_mode() */ 1347/* s2. set_802_11_authenticaion_mode() */ 1348/* s3. set_802_11_encryption_mode() */ 1349/* s4. rtw_set_802_11_ssid() */ 1350static int rtw_wx_set_essid(struct net_device *dev, 1351 struct iw_request_info *a, 1352 union iwreq_data *wrqu, char *extra) 1353{ 1354 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1355 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1356 struct __queue *queue = &pmlmepriv->scanned_queue; 1357 struct list_head *phead; 1358 struct wlan_network *pnetwork = NULL; 1359 enum ndis_802_11_auth_mode authmode; 1360 struct ndis_802_11_ssid ndis_ssid; 1361 u8 *dst_ssid, *src_ssid; 1362 1363 uint ret = 0, len; 1364 1365 1366 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, 1367 ("+rtw_wx_set_essid: fw_state = 0x%08x\n", get_fwstate(pmlmepriv))); 1368 if (_FAIL == rtw_pwr_wakeup(padapter)) { 1369 ret = -1; 1370 goto exit; 1371 } 1372 1373 if (!padapter->bup) { 1374 ret = -1; 1375 goto exit; 1376 } 1377 1378 if (wrqu->essid.length > IW_ESSID_MAX_SIZE) { 1379 ret = -E2BIG; 1380 goto exit; 1381 } 1382 1383 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1384 ret = -1; 1385 goto exit; 1386 } 1387 1388 authmode = padapter->securitypriv.ndisauthtype; 1389 DBG_88E("=>%s\n", __func__); 1390 if (wrqu->essid.flags && wrqu->essid.length) { 1391 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE; 1392 1393 if (wrqu->essid.length != 33) 1394 DBG_88E("ssid =%s, len =%d\n", extra, wrqu->essid.length); 1395 1396 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid)); 1397 ndis_ssid.SsidLength = len; 1398 memcpy(ndis_ssid.Ssid, extra, len); 1399 src_ssid = ndis_ssid.Ssid; 1400 1401 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid =[%s]\n", src_ssid)); 1402 spin_lock_bh(&queue->lock); 1403 phead = get_list_head(queue); 1404 pmlmepriv->pscanned = phead->next; 1405 1406 while (phead != pmlmepriv->pscanned) { 1407 pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list); 1408 1409 pmlmepriv->pscanned = pmlmepriv->pscanned->next; 1410 1411 dst_ssid = pnetwork->network.Ssid.Ssid; 1412 1413 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, 1414 ("rtw_wx_set_essid: dst_ssid =%s\n", 1415 pnetwork->network.Ssid.Ssid)); 1416 1417 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) && 1418 (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) { 1419 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, 1420 ("rtw_wx_set_essid: find match, set infra mode\n")); 1421 1422 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) { 1423 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) 1424 continue; 1425 } 1426 1427 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) { 1428 ret = -1; 1429 spin_unlock_bh(&queue->lock); 1430 goto exit; 1431 } 1432 1433 break; 1434 } 1435 } 1436 spin_unlock_bh(&queue->lock); 1437 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, 1438 ("set ssid: set_802_11_auth. mode =%d\n", authmode)); 1439 rtw_set_802_11_authentication_mode(padapter, authmode); 1440 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == false) { 1441 ret = -1; 1442 goto exit; 1443 } 1444 } 1445 1446exit: 1447 1448 DBG_88E("<=%s, ret %d\n", __func__, ret); 1449 1450 1451 return ret; 1452} 1453 1454static int rtw_wx_get_essid(struct net_device *dev, 1455 struct iw_request_info *a, 1456 union iwreq_data *wrqu, char *extra) 1457{ 1458 u32 len, ret = 0; 1459 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1460 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1461 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 1462 1463 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_essid\n")); 1464 1465 1466 if ((check_fwstate(pmlmepriv, _FW_LINKED)) || 1467 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) { 1468 len = pcur_bss->Ssid.SsidLength; 1469 1470 wrqu->essid.length = len; 1471 1472 memcpy(extra, pcur_bss->Ssid.Ssid, len); 1473 1474 wrqu->essid.flags = 1; 1475 } else { 1476 ret = -1; 1477 goto exit; 1478 } 1479 1480exit: 1481 1482 1483 return ret; 1484} 1485 1486static int rtw_wx_set_rate(struct net_device *dev, 1487 struct iw_request_info *a, 1488 union iwreq_data *wrqu, char *extra) 1489{ 1490 int i, ret = 0; 1491 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1492 u8 datarates[NumRates]; 1493 u32 target_rate = wrqu->bitrate.value; 1494 u32 fixed = wrqu->bitrate.fixed; 1495 u32 ratevalue = 0; 1496 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; 1497 1498 1499 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_set_rate\n")); 1500 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("target_rate = %d, fixed = %d\n", target_rate, fixed)); 1501 1502 if (target_rate == -1) { 1503 ratevalue = 11; 1504 goto set_rate; 1505 } 1506 target_rate = target_rate/100000; 1507 1508 switch (target_rate) { 1509 case 10: 1510 ratevalue = 0; 1511 break; 1512 case 20: 1513 ratevalue = 1; 1514 break; 1515 case 55: 1516 ratevalue = 2; 1517 break; 1518 case 60: 1519 ratevalue = 3; 1520 break; 1521 case 90: 1522 ratevalue = 4; 1523 break; 1524 case 110: 1525 ratevalue = 5; 1526 break; 1527 case 120: 1528 ratevalue = 6; 1529 break; 1530 case 180: 1531 ratevalue = 7; 1532 break; 1533 case 240: 1534 ratevalue = 8; 1535 break; 1536 case 360: 1537 ratevalue = 9; 1538 break; 1539 case 480: 1540 ratevalue = 10; 1541 break; 1542 case 540: 1543 ratevalue = 11; 1544 break; 1545 default: 1546 ratevalue = 11; 1547 break; 1548 } 1549 1550set_rate: 1551 1552 for (i = 0; i < NumRates; i++) { 1553 if (ratevalue == mpdatarate[i]) { 1554 datarates[i] = mpdatarate[i]; 1555 if (fixed == 0) 1556 break; 1557 } else { 1558 datarates[i] = 0xff; 1559 } 1560 1561 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("datarate_inx =%d\n", datarates[i])); 1562 } 1563 1564 if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) { 1565 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("rtw_wx_set_rate Fail!!!\n")); 1566 ret = -1; 1567 } 1568 1569 1570 return ret; 1571} 1572 1573static int rtw_wx_get_rate(struct net_device *dev, 1574 struct iw_request_info *info, 1575 union iwreq_data *wrqu, char *extra) 1576{ 1577 u16 max_rate = 0; 1578 1579 max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev)); 1580 1581 if (max_rate == 0) 1582 return -EPERM; 1583 1584 wrqu->bitrate.fixed = 0; /* no auto select */ 1585 wrqu->bitrate.value = max_rate * 100000; 1586 1587 return 0; 1588} 1589 1590static int rtw_wx_set_rts(struct net_device *dev, 1591 struct iw_request_info *info, 1592 union iwreq_data *wrqu, char *extra) 1593{ 1594 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1595 1596 1597 if (wrqu->rts.disabled) { 1598 padapter->registrypriv.rts_thresh = 2347; 1599 } else { 1600 if (wrqu->rts.value < 0 || 1601 wrqu->rts.value > 2347) 1602 return -EINVAL; 1603 1604 padapter->registrypriv.rts_thresh = wrqu->rts.value; 1605 } 1606 1607 DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh); 1608 1609 1610 return 0; 1611} 1612 1613static int rtw_wx_get_rts(struct net_device *dev, 1614 struct iw_request_info *info, 1615 union iwreq_data *wrqu, char *extra) 1616{ 1617 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1618 1619 1620 DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh); 1621 1622 wrqu->rts.value = padapter->registrypriv.rts_thresh; 1623 wrqu->rts.fixed = 0; /* no auto select */ 1624 /* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */ 1625 1626 1627 return 0; 1628} 1629 1630static int rtw_wx_set_frag(struct net_device *dev, 1631 struct iw_request_info *info, 1632 union iwreq_data *wrqu, char *extra) 1633{ 1634 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1635 1636 1637 if (wrqu->frag.disabled) { 1638 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; 1639 } else { 1640 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 1641 wrqu->frag.value > MAX_FRAG_THRESHOLD) 1642 return -EINVAL; 1643 1644 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1; 1645 } 1646 1647 DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len); 1648 1649 1650 return 0; 1651} 1652 1653static int rtw_wx_get_frag(struct net_device *dev, 1654 struct iw_request_info *info, 1655 union iwreq_data *wrqu, char *extra) 1656{ 1657 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1658 1659 1660 DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len); 1661 1662 wrqu->frag.value = padapter->xmitpriv.frag_len; 1663 wrqu->frag.fixed = 0; /* no auto select */ 1664 1665 1666 return 0; 1667} 1668 1669static int rtw_wx_get_retry(struct net_device *dev, 1670 struct iw_request_info *info, 1671 union iwreq_data *wrqu, char *extra) 1672{ 1673 wrqu->retry.value = 7; 1674 wrqu->retry.fixed = 0; /* no auto select */ 1675 wrqu->retry.disabled = 1; 1676 1677 return 0; 1678} 1679 1680static int rtw_wx_set_enc(struct net_device *dev, 1681 struct iw_request_info *info, 1682 union iwreq_data *wrqu, char *keybuf) 1683{ 1684 u32 key, ret = 0; 1685 u32 keyindex_provided; 1686 struct ndis_802_11_wep wep; 1687 enum ndis_802_11_auth_mode authmode; 1688 1689 struct iw_point *erq = &(wrqu->encoding); 1690 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1691 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 1692 DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags); 1693 1694 memset(&wep, 0, sizeof(struct ndis_802_11_wep)); 1695 1696 key = erq->flags & IW_ENCODE_INDEX; 1697 1698 1699 if (erq->flags & IW_ENCODE_DISABLED) { 1700 DBG_88E("EncryptionDisabled\n"); 1701 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; 1702 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 1703 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; 1704 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ 1705 authmode = Ndis802_11AuthModeOpen; 1706 padapter->securitypriv.ndisauthtype = authmode; 1707 1708 goto exit; 1709 } 1710 1711 if (key) { 1712 if (key > WEP_KEYS) 1713 return -EINVAL; 1714 key--; 1715 keyindex_provided = 1; 1716 } else { 1717 keyindex_provided = 0; 1718 key = padapter->securitypriv.dot11PrivacyKeyIndex; 1719 DBG_88E("rtw_wx_set_enc, key =%d\n", key); 1720 } 1721 1722 /* set authentication mode */ 1723 if (erq->flags & IW_ENCODE_OPEN) { 1724 DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n"); 1725 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ 1726 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 1727 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 1728 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; 1729 authmode = Ndis802_11AuthModeOpen; 1730 padapter->securitypriv.ndisauthtype = authmode; 1731 } else if (erq->flags & IW_ENCODE_RESTRICTED) { 1732 DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n"); 1733 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; 1734 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; 1735 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; 1736 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; 1737 authmode = Ndis802_11AuthModeShared; 1738 padapter->securitypriv.ndisauthtype = authmode; 1739 } else { 1740 DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags); 1741 1742 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ 1743 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ 1744 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 1745 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; 1746 authmode = Ndis802_11AuthModeOpen; 1747 padapter->securitypriv.ndisauthtype = authmode; 1748 } 1749 1750 wep.KeyIndex = key; 1751 if (erq->length > 0) { 1752 wep.KeyLength = erq->length <= 5 ? 5 : 13; 1753 1754 wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); 1755 } else { 1756 wep.KeyLength = 0; 1757 1758 if (keyindex_provided == 1) { 1759 /* set key_id only, no given KeyMaterial(erq->length == 0). */ 1760 padapter->securitypriv.dot11PrivacyKeyIndex = key; 1761 1762 DBG_88E("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key, padapter->securitypriv.dot11DefKeylen[key]); 1763 1764 switch (padapter->securitypriv.dot11DefKeylen[key]) { 1765 case 5: 1766 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; 1767 break; 1768 case 13: 1769 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; 1770 break; 1771 default: 1772 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 1773 break; 1774 } 1775 1776 goto exit; 1777 } 1778 } 1779 1780 wep.KeyIndex |= 0x80000000; 1781 1782 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength); 1783 1784 if (rtw_set_802_11_add_wep(padapter, &wep) == false) { 1785 if (rf_on == pwrpriv->rf_pwrstate) 1786 ret = -EOPNOTSUPP; 1787 goto exit; 1788 } 1789 1790exit: 1791 1792 1793 return ret; 1794} 1795 1796static int rtw_wx_get_enc(struct net_device *dev, 1797 struct iw_request_info *info, 1798 union iwreq_data *wrqu, char *keybuf) 1799{ 1800 uint key, ret = 0; 1801 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1802 struct iw_point *erq = &(wrqu->encoding); 1803 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1804 1805 1806 if (check_fwstate(pmlmepriv, _FW_LINKED) != true) { 1807 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { 1808 erq->length = 0; 1809 erq->flags |= IW_ENCODE_DISABLED; 1810 return 0; 1811 } 1812 } 1813 1814 key = erq->flags & IW_ENCODE_INDEX; 1815 1816 if (key) { 1817 if (key > WEP_KEYS) 1818 return -EINVAL; 1819 key--; 1820 } else { 1821 key = padapter->securitypriv.dot11PrivacyKeyIndex; 1822 } 1823 1824 erq->flags = key + 1; 1825 1826 switch (padapter->securitypriv.ndisencryptstatus) { 1827 case Ndis802_11EncryptionNotSupported: 1828 case Ndis802_11EncryptionDisabled: 1829 erq->length = 0; 1830 erq->flags |= IW_ENCODE_DISABLED; 1831 break; 1832 case Ndis802_11Encryption1Enabled: 1833 erq->length = padapter->securitypriv.dot11DefKeylen[key]; 1834 if (erq->length) { 1835 memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]); 1836 1837 erq->flags |= IW_ENCODE_ENABLED; 1838 1839 if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) 1840 erq->flags |= IW_ENCODE_OPEN; 1841 else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared) 1842 erq->flags |= IW_ENCODE_RESTRICTED; 1843 } else { 1844 erq->length = 0; 1845 erq->flags |= IW_ENCODE_DISABLED; 1846 } 1847 break; 1848 case Ndis802_11Encryption2Enabled: 1849 case Ndis802_11Encryption3Enabled: 1850 erq->length = 16; 1851 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY); 1852 break; 1853 default: 1854 erq->length = 0; 1855 erq->flags |= IW_ENCODE_DISABLED; 1856 break; 1857 } 1858 1859 return ret; 1860} 1861 1862static int rtw_wx_get_power(struct net_device *dev, 1863 struct iw_request_info *info, 1864 union iwreq_data *wrqu, char *extra) 1865{ 1866 wrqu->power.value = 0; 1867 wrqu->power.fixed = 0; /* no auto select */ 1868 wrqu->power.disabled = 1; 1869 1870 return 0; 1871} 1872 1873static int rtw_wx_set_gen_ie(struct net_device *dev, 1874 struct iw_request_info *info, 1875 union iwreq_data *wrqu, char *extra) 1876{ 1877 int ret; 1878 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 1879 1880 ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length); 1881 return ret; 1882} 1883 1884static int rtw_wx_set_auth(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 struct iw_param *param = (struct iw_param *)&(wrqu->param); 1890 int ret = 0; 1891 1892 switch (param->flags & IW_AUTH_INDEX) { 1893 case IW_AUTH_WPA_VERSION: 1894 break; 1895 case IW_AUTH_CIPHER_PAIRWISE: 1896 1897 break; 1898 case IW_AUTH_CIPHER_GROUP: 1899 1900 break; 1901 case IW_AUTH_KEY_MGMT: 1902 /* 1903 * ??? does not use these parameters 1904 */ 1905 break; 1906 case IW_AUTH_TKIP_COUNTERMEASURES: 1907 if (param->value) { 1908 /* wpa_supplicant is enabling the tkip countermeasure. */ 1909 padapter->securitypriv.btkip_countermeasure = true; 1910 } else { 1911 /* wpa_supplicant is disabling the tkip countermeasure. */ 1912 padapter->securitypriv.btkip_countermeasure = false; 1913 } 1914 break; 1915 case IW_AUTH_DROP_UNENCRYPTED: 1916 /* HACK: 1917 * 1918 * wpa_supplicant calls set_wpa_enabled when the driver 1919 * is loaded and unloaded, regardless of if WPA is being 1920 * used. No other calls are made which can be used to 1921 * determine if encryption will be used or not prior to 1922 * association being expected. If encryption is not being 1923 * used, drop_unencrypted is set to false, else true -- we 1924 * can use this to determine if the CAP_PRIVACY_ON bit should 1925 * be set. 1926 */ 1927 1928 if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) 1929 break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */ 1930 /* then it needn't reset it; */ 1931 1932 if (param->value) { 1933 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; 1934 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; 1935 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; 1936 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ 1937 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; 1938 } 1939 1940 break; 1941 case IW_AUTH_80211_AUTH_ALG: 1942 /* 1943 * It's the starting point of a link layer connection using wpa_supplicant 1944 */ 1945 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { 1946 LeaveAllPowerSaveMode(padapter); 1947 rtw_disassoc_cmd(padapter, 500, false); 1948 DBG_88E("%s...call rtw_indicate_disconnect\n ", __func__); 1949 rtw_indicate_disconnect(padapter); 1950 rtw_free_assoc_resources(padapter, 1); 1951 } 1952 ret = wpa_set_auth_algs(dev, (u32)param->value); 1953 break; 1954 case IW_AUTH_WPA_ENABLED: 1955 break; 1956 case IW_AUTH_RX_UNENCRYPTED_EAPOL: 1957 break; 1958 case IW_AUTH_PRIVACY_INVOKED: 1959 break; 1960 default: 1961 return -EOPNOTSUPP; 1962 } 1963 1964 return ret; 1965} 1966 1967static int rtw_wx_set_enc_ext(struct net_device *dev, 1968 struct iw_request_info *info, 1969 union iwreq_data *wrqu, char *extra) 1970{ 1971 char *alg_name; 1972 u32 param_len; 1973 struct ieee_param *param = NULL; 1974 struct iw_point *pencoding = &wrqu->encoding; 1975 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra; 1976 int ret = 0; 1977 1978 param_len = sizeof(struct ieee_param) + pext->key_len; 1979 param = (struct ieee_param *)rtw_malloc(param_len); 1980 if (param == NULL) 1981 return -1; 1982 1983 memset(param, 0, param_len); 1984 1985 param->cmd = IEEE_CMD_SET_ENCRYPTION; 1986 memset(param->sta_addr, 0xff, ETH_ALEN); 1987 1988 switch (pext->alg) { 1989 case IW_ENCODE_ALG_NONE: 1990 /* todo: remove key */ 1991 /* remove = 1; */ 1992 alg_name = "none"; 1993 break; 1994 case IW_ENCODE_ALG_WEP: 1995 alg_name = "WEP"; 1996 break; 1997 case IW_ENCODE_ALG_TKIP: 1998 alg_name = "TKIP"; 1999 break; 2000 case IW_ENCODE_ALG_CCMP: 2001 alg_name = "CCMP"; 2002 break; 2003 default: 2004 ret = -1; 2005 goto exit; 2006 } 2007 2008 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); 2009 2010 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 2011 param->u.crypt.set_tx = 1; 2012 2013 /* cliW: WEP does not have group key 2014 * just not checking GROUP key setting 2015 */ 2016 if ((pext->alg != IW_ENCODE_ALG_WEP) && 2017 (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) 2018 param->u.crypt.set_tx = 0; 2019 2020 param->u.crypt.idx = (pencoding->flags&0x00FF) - 1; 2021 2022 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) 2023 memcpy(param->u.crypt.seq, pext->rx_seq, 8); 2024 2025 if (pext->key_len) { 2026 param->u.crypt.key_len = pext->key_len; 2027 memcpy(param->u.crypt.key, pext + 1, pext->key_len); 2028 } 2029 2030 ret = wpa_set_encryption(dev, param, param_len); 2031 2032exit: 2033 kfree(param); 2034 return ret; 2035} 2036 2037static int rtw_wx_get_nick(struct net_device *dev, 2038 struct iw_request_info *info, 2039 union iwreq_data *wrqu, char *extra) 2040{ 2041 if (extra) { 2042 wrqu->data.length = 14; 2043 wrqu->data.flags = 1; 2044 memcpy(extra, "<WIFI@REALTEK>", 14); 2045 } 2046 2047 /* dump debug info here */ 2048 return 0; 2049} 2050 2051static int dummy(struct net_device *dev, struct iw_request_info *a, 2052 union iwreq_data *wrqu, char *b) 2053{ 2054 return -1; 2055} 2056 2057static int wpa_set_param(struct net_device *dev, u8 name, u32 value) 2058{ 2059 uint ret = 0; 2060 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2061 2062 switch (name) { 2063 case IEEE_PARAM_WPA_ENABLED: 2064 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */ 2065 switch ((value)&0xff) { 2066 case 1: /* WPA */ 2067 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */ 2068 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; 2069 break; 2070 case 2: /* WPA2 */ 2071 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */ 2072 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; 2073 break; 2074 } 2075 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, 2076 ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter->securitypriv.ndisauthtype)); 2077 break; 2078 case IEEE_PARAM_TKIP_COUNTERMEASURES: 2079 break; 2080 case IEEE_PARAM_DROP_UNENCRYPTED: { 2081 /* HACK: 2082 * 2083 * wpa_supplicant calls set_wpa_enabled when the driver 2084 * is loaded and unloaded, regardless of if WPA is being 2085 * used. No other calls are made which can be used to 2086 * determine if encryption will be used or not prior to 2087 * association being expected. If encryption is not being 2088 * used, drop_unencrypted is set to false, else true -- we 2089 * can use this to determine if the CAP_PRIVACY_ON bit should 2090 * be set. 2091 */ 2092 2093 break; 2094 } 2095 case IEEE_PARAM_PRIVACY_INVOKED: 2096 break; 2097 2098 case IEEE_PARAM_AUTH_ALGS: 2099 ret = wpa_set_auth_algs(dev, value); 2100 break; 2101 case IEEE_PARAM_IEEE_802_1X: 2102 break; 2103 case IEEE_PARAM_WPAX_SELECT: 2104 break; 2105 default: 2106 ret = -EOPNOTSUPP; 2107 break; 2108 } 2109 return ret; 2110} 2111 2112static int wpa_mlme(struct net_device *dev, u32 command, u32 reason) 2113{ 2114 int ret = 0; 2115 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2116 2117 switch (command) { 2118 case IEEE_MLME_STA_DEAUTH: 2119 if (!rtw_set_802_11_disassociate(padapter)) 2120 ret = -1; 2121 break; 2122 case IEEE_MLME_STA_DISASSOC: 2123 if (!rtw_set_802_11_disassociate(padapter)) 2124 ret = -1; 2125 break; 2126 default: 2127 ret = -EOPNOTSUPP; 2128 break; 2129 } 2130 2131 return ret; 2132} 2133 2134static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) 2135{ 2136 struct ieee_param *param; 2137 uint ret = 0; 2138 2139 if (p->length < sizeof(struct ieee_param) || !p->pointer) { 2140 ret = -EINVAL; 2141 goto out; 2142 } 2143 2144 param = (struct ieee_param *)rtw_malloc(p->length); 2145 if (param == NULL) { 2146 ret = -ENOMEM; 2147 goto out; 2148 } 2149 2150 if (copy_from_user(param, p->pointer, p->length)) { 2151 kfree(param); 2152 ret = -EFAULT; 2153 goto out; 2154 } 2155 2156 switch (param->cmd) { 2157 case IEEE_CMD_SET_WPA_PARAM: 2158 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value); 2159 break; 2160 2161 case IEEE_CMD_SET_WPA_IE: 2162 ret = rtw_set_wpa_ie((struct adapter *)rtw_netdev_priv(dev), 2163 (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len); 2164 break; 2165 2166 case IEEE_CMD_SET_ENCRYPTION: 2167 ret = wpa_set_encryption(dev, param, p->length); 2168 break; 2169 2170 case IEEE_CMD_MLME: 2171 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code); 2172 break; 2173 2174 default: 2175 DBG_88E("Unknown WPA supplicant request: %d\n", param->cmd); 2176 ret = -EOPNOTSUPP; 2177 break; 2178 } 2179 2180 if (ret == 0 && copy_to_user(p->pointer, param, p->length)) 2181 ret = -EFAULT; 2182 2183 kfree(param); 2184 2185out: 2186 2187 return ret; 2188} 2189 2190#ifdef CONFIG_88EU_AP_MODE 2191static u8 set_pairwise_key(struct adapter *padapter, struct sta_info *psta) 2192{ 2193 struct cmd_obj *ph2c; 2194 struct set_stakey_parm *psetstakey_para; 2195 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 2196 u8 res = _SUCCESS; 2197 2198 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 2199 if (ph2c == NULL) { 2200 res = _FAIL; 2201 goto exit; 2202 } 2203 2204 psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL); 2205 if (psetstakey_para == NULL) { 2206 kfree(ph2c); 2207 res = _FAIL; 2208 goto exit; 2209 } 2210 2211 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); 2212 2213 psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy; 2214 2215 memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN); 2216 2217 memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16); 2218 2219 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 2220 2221exit: 2222 2223 return res; 2224} 2225 2226static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid) 2227{ 2228 u8 keylen; 2229 struct cmd_obj *pcmd; 2230 struct setkey_parm *psetkeyparm; 2231 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); 2232 int res = _SUCCESS; 2233 2234 DBG_88E("%s\n", __func__); 2235 2236 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 2237 if (pcmd == NULL) { 2238 res = _FAIL; 2239 goto exit; 2240 } 2241 psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL); 2242 if (psetkeyparm == NULL) { 2243 kfree(pcmd); 2244 res = _FAIL; 2245 goto exit; 2246 } 2247 2248 memset(psetkeyparm, 0, sizeof(struct setkey_parm)); 2249 2250 psetkeyparm->keyid = (u8)keyid; 2251 2252 psetkeyparm->algorithm = alg; 2253 2254 psetkeyparm->set_tx = 1; 2255 2256 switch (alg) { 2257 case _WEP40_: 2258 keylen = 5; 2259 break; 2260 case _WEP104_: 2261 keylen = 13; 2262 break; 2263 case _TKIP_: 2264 case _TKIP_WTMIC_: 2265 case _AES_: 2266 default: 2267 keylen = 16; 2268 } 2269 2270 memcpy(&(psetkeyparm->key[0]), key, keylen); 2271 2272 pcmd->cmdcode = _SetKey_CMD_; 2273 pcmd->parmbuf = (u8 *)psetkeyparm; 2274 pcmd->cmdsz = (sizeof(struct setkey_parm)); 2275 pcmd->rsp = NULL; 2276 pcmd->rspsz = 0; 2277 2278 INIT_LIST_HEAD(&pcmd->list); 2279 2280 res = rtw_enqueue_cmd(pcmdpriv, pcmd); 2281 2282exit: 2283 2284 return res; 2285} 2286 2287static int set_wep_key(struct adapter *padapter, u8 *key, u8 keylen, int keyid) 2288{ 2289 u8 alg; 2290 2291 switch (keylen) { 2292 case 5: 2293 alg = _WEP40_; 2294 break; 2295 case 13: 2296 alg = _WEP104_; 2297 break; 2298 default: 2299 alg = _NO_PRIVACY_; 2300 } 2301 2302 return set_group_key(padapter, key, alg, keyid); 2303} 2304 2305static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) 2306{ 2307 int ret = 0; 2308 u32 wep_key_idx, wep_key_len, wep_total_len; 2309 struct ndis_802_11_wep *pwep = NULL; 2310 struct sta_info *psta = NULL, *pbcmc_sta = NULL; 2311 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2312 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2313 struct security_priv *psecuritypriv = &(padapter->securitypriv); 2314 struct sta_priv *pstapriv = &padapter->stapriv; 2315 2316 DBG_88E("%s\n", __func__); 2317 param->u.crypt.err = 0; 2318 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; 2319 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) { 2320 ret = -EINVAL; 2321 goto exit; 2322 } 2323 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 2324 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 2325 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 2326 if (param->u.crypt.idx >= WEP_KEYS) { 2327 ret = -EINVAL; 2328 goto exit; 2329 } 2330 } else { 2331 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 2332 if (!psta) { 2333 DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n"); 2334 goto exit; 2335 } 2336 } 2337 2338 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) { 2339 /* todo:clear default encryption keys */ 2340 2341 DBG_88E("clear default encryption keys, keyid =%d\n", param->u.crypt.idx); 2342 goto exit; 2343 } 2344 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) { 2345 DBG_88E("r871x_set_encryption, crypt.alg = WEP\n"); 2346 wep_key_idx = param->u.crypt.idx; 2347 wep_key_len = param->u.crypt.key_len; 2348 DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len); 2349 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) { 2350 ret = -EINVAL; 2351 goto exit; 2352 } 2353 2354 if (wep_key_len > 0) { 2355 wep_key_len = wep_key_len <= 5 ? 5 : 13; 2356 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); 2357 pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len); 2358 if (pwep == NULL) { 2359 DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n"); 2360 goto exit; 2361 } 2362 2363 memset(pwep, 0, wep_total_len); 2364 2365 pwep->KeyLength = wep_key_len; 2366 pwep->Length = wep_total_len; 2367 } 2368 2369 pwep->KeyIndex = wep_key_idx; 2370 2371 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); 2372 2373 if (param->u.crypt.set_tx) { 2374 DBG_88E("wep, set_tx = 1\n"); 2375 2376 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; 2377 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; 2378 psecuritypriv->dot118021XGrpPrivacy = _WEP40_; 2379 2380 if (pwep->KeyLength == 13) { 2381 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; 2382 psecuritypriv->dot118021XGrpPrivacy = _WEP104_; 2383 } 2384 2385 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; 2386 2387 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); 2388 2389 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; 2390 2391 set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx); 2392 } else { 2393 DBG_88E("wep, set_tx = 0\n"); 2394 2395 /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */ 2396 /* psecuritypriv->dot11PrivacyKeyIndex = keyid", but can rtw_set_key to cam */ 2397 2398 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); 2399 2400 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; 2401 2402 set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx); 2403 } 2404 2405 goto exit; 2406 } 2407 2408 if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* group key */ 2409 if (param->u.crypt.set_tx == 1) { 2410 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 2411 DBG_88E("%s, set group_key, WEP\n", __func__); 2412 2413 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, 2414 param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 2415 2416 psecuritypriv->dot118021XGrpPrivacy = _WEP40_; 2417 if (param->u.crypt.key_len == 13) 2418 psecuritypriv->dot118021XGrpPrivacy = _WEP104_; 2419 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 2420 DBG_88E("%s, set group_key, TKIP\n", __func__); 2421 psecuritypriv->dot118021XGrpPrivacy = _TKIP_; 2422 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, 2423 param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 2424 /* set mic key */ 2425 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); 2426 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); 2427 2428 psecuritypriv->busetkipkey = true; 2429 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 2430 DBG_88E("%s, set group_key, CCMP\n", __func__); 2431 psecuritypriv->dot118021XGrpPrivacy = _AES_; 2432 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, 2433 param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 2434 } else { 2435 DBG_88E("%s, set group_key, none\n", __func__); 2436 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; 2437 } 2438 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; 2439 psecuritypriv->binstallGrpkey = true; 2440 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* */ 2441 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); 2442 pbcmc_sta = rtw_get_bcmc_stainfo(padapter); 2443 if (pbcmc_sta) { 2444 pbcmc_sta->ieee8021x_blocked = false; 2445 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */ 2446 } 2447 } 2448 goto exit; 2449 } 2450 2451 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */ 2452 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 2453 if (param->u.crypt.set_tx == 1) { 2454 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 2455 2456 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 2457 DBG_88E("%s, set pairwise key, WEP\n", __func__); 2458 2459 psta->dot118021XPrivacy = _WEP40_; 2460 if (param->u.crypt.key_len == 13) 2461 psta->dot118021XPrivacy = _WEP104_; 2462 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 2463 DBG_88E("%s, set pairwise key, TKIP\n", __func__); 2464 2465 psta->dot118021XPrivacy = _TKIP_; 2466 2467 /* set mic key */ 2468 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); 2469 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); 2470 2471 psecuritypriv->busetkipkey = true; 2472 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 2473 DBG_88E("%s, set pairwise key, CCMP\n", __func__); 2474 2475 psta->dot118021XPrivacy = _AES_; 2476 } else { 2477 DBG_88E("%s, set pairwise key, none\n", __func__); 2478 2479 psta->dot118021XPrivacy = _NO_PRIVACY_; 2480 } 2481 2482 set_pairwise_key(padapter, psta); 2483 2484 psta->ieee8021x_blocked = false; 2485 } else { /* group key??? */ 2486 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 2487 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, 2488 param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 2489 psecuritypriv->dot118021XGrpPrivacy = _WEP40_; 2490 if (param->u.crypt.key_len == 13) 2491 psecuritypriv->dot118021XGrpPrivacy = _WEP104_; 2492 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 2493 psecuritypriv->dot118021XGrpPrivacy = _TKIP_; 2494 2495 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, 2496 param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 2497 2498 /* set mic key */ 2499 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); 2500 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); 2501 2502 psecuritypriv->busetkipkey = true; 2503 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 2504 psecuritypriv->dot118021XGrpPrivacy = _AES_; 2505 2506 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, 2507 param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); 2508 } else { 2509 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; 2510 } 2511 2512 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; 2513 2514 psecuritypriv->binstallGrpkey = true; 2515 2516 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* */ 2517 2518 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); 2519 2520 pbcmc_sta = rtw_get_bcmc_stainfo(padapter); 2521 if (pbcmc_sta) { 2522 pbcmc_sta->ieee8021x_blocked = false; 2523 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */ 2524 } 2525 } 2526 } 2527 } 2528 2529exit: 2530 2531 kfree(pwep); 2532 2533 return ret; 2534} 2535 2536static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len) 2537{ 2538 int ret = 0; 2539 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2540 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2541 struct sta_priv *pstapriv = &padapter->stapriv; 2542 unsigned char *pbuf = param->u.bcn_ie.buf; 2543 2544 DBG_88E("%s, len =%d\n", __func__, len); 2545 2546 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 2547 return -EINVAL; 2548 2549 memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2); 2550 2551 if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0)) 2552 pstapriv->max_num_sta = NUM_STA; 2553 2554 if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS)/* 12 = param header, 2:no packed */ 2555 ret = 0; 2556 else 2557 ret = -EINVAL; 2558 2559 return ret; 2560} 2561 2562static int rtw_hostapd_sta_flush(struct net_device *dev) 2563{ 2564 int ret = 0; 2565 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2566 2567 DBG_88E("%s\n", __func__); 2568 2569 flush_all_cam_entry(padapter); /* clear CAM */ 2570 2571 ret = rtw_sta_flush(padapter); 2572 2573 return ret; 2574} 2575 2576static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) 2577{ 2578 int ret = 0; 2579 struct sta_info *psta = NULL; 2580 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2581 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2582 struct sta_priv *pstapriv = &padapter->stapriv; 2583 2584 DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr)); 2585 2586 if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) 2587 return -EINVAL; 2588 2589 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 2590 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 2591 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 2592 return -EINVAL; 2593 2594 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 2595 if (psta) { 2596 int flags = param->u.add_sta.flags; 2597 2598 psta->aid = param->u.add_sta.aid;/* aid = 1~2007 */ 2599 2600 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16); 2601 2602 /* check wmm cap. */ 2603 if (WLAN_STA_WME&flags) 2604 psta->qos_option = 1; 2605 else 2606 psta->qos_option = 0; 2607 2608 if (pmlmepriv->qospriv.qos_option == 0) 2609 psta->qos_option = 0; 2610 2611 /* chec 802.11n ht cap. */ 2612 if (WLAN_STA_HT&flags) { 2613 psta->htpriv.ht_option = true; 2614 psta->qos_option = 1; 2615 memcpy((void *)&psta->htpriv.ht_cap, (void *)¶m->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap)); 2616 } else { 2617 psta->htpriv.ht_option = false; 2618 } 2619 2620 if (pmlmepriv->htpriv.ht_option == false) 2621 psta->htpriv.ht_option = false; 2622 2623 update_sta_info_apmode(padapter, psta); 2624 } else { 2625 ret = -ENOMEM; 2626 } 2627 2628 return ret; 2629} 2630 2631static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) 2632{ 2633 int ret = 0; 2634 struct sta_info *psta = NULL; 2635 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2636 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2637 struct sta_priv *pstapriv = &padapter->stapriv; 2638 int updated = 0; 2639 2640 DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr)); 2641 2642 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 2643 return -EINVAL; 2644 2645 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 2646 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 2647 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 2648 return -EINVAL; 2649 2650 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 2651 if (psta) { 2652 spin_lock_bh(&pstapriv->asoc_list_lock); 2653 if (!list_empty(&psta->asoc_list)) { 2654 list_del_init(&psta->asoc_list); 2655 pstapriv->asoc_list_cnt--; 2656 updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); 2657 } 2658 spin_unlock_bh(&pstapriv->asoc_list_lock); 2659 associated_clients_update(padapter, updated); 2660 psta = NULL; 2661 } else { 2662 DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n"); 2663 } 2664 2665 return ret; 2666} 2667 2668static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len) 2669{ 2670 int ret = 0; 2671 struct sta_info *psta = NULL; 2672 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2673 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2674 struct sta_priv *pstapriv = &padapter->stapriv; 2675 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param; 2676 struct sta_data *psta_data = (struct sta_data *)param_ex->data; 2677 2678 DBG_88E("rtw_ioctl_get_sta_info, sta_addr: %pM\n", (param_ex->sta_addr)); 2679 2680 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 2681 return -EINVAL; 2682 2683 if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff && 2684 param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff && 2685 param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) 2686 return -EINVAL; 2687 2688 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr); 2689 if (psta) { 2690 psta_data->aid = (u16)psta->aid; 2691 psta_data->capability = psta->capability; 2692 psta_data->flags = psta->flags; 2693 2694/* 2695 nonerp_set : BIT(0) 2696 no_short_slot_time_set : BIT(1) 2697 no_short_preamble_set : BIT(2) 2698 no_ht_gf_set : BIT(3) 2699 no_ht_set : BIT(4) 2700 ht_20mhz_set : BIT(5) 2701*/ 2702 2703 psta_data->sta_set = ((psta->nonerp_set) | 2704 (psta->no_short_slot_time_set << 1) | 2705 (psta->no_short_preamble_set << 2) | 2706 (psta->no_ht_gf_set << 3) | 2707 (psta->no_ht_set << 4) | 2708 (psta->ht_20mhz_set << 5)); 2709 psta_data->tx_supp_rates_len = psta->bssratelen; 2710 memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen); 2711 memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap)); 2712 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts; 2713 psta_data->rx_bytes = psta->sta_stats.rx_bytes; 2714 psta_data->rx_drops = psta->sta_stats.rx_drops; 2715 psta_data->tx_pkts = psta->sta_stats.tx_pkts; 2716 psta_data->tx_bytes = psta->sta_stats.tx_bytes; 2717 psta_data->tx_drops = psta->sta_stats.tx_drops; 2718 } else { 2719 ret = -1; 2720 } 2721 2722 return ret; 2723} 2724 2725static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param) 2726{ 2727 int ret = 0; 2728 struct sta_info *psta = NULL; 2729 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2730 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2731 struct sta_priv *pstapriv = &padapter->stapriv; 2732 2733 DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr)); 2734 2735 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true) 2736 return -EINVAL; 2737 2738 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 2739 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 2740 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 2741 return -EINVAL; 2742 2743 psta = rtw_get_stainfo(pstapriv, param->sta_addr); 2744 if (psta) { 2745 if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) { 2746 int wpa_ie_len; 2747 int copy_len; 2748 2749 wpa_ie_len = psta->wpa_ie[1]; 2750 copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)) : (wpa_ie_len+2); 2751 param->u.wpa_ie.len = copy_len; 2752 memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len); 2753 } else { 2754 DBG_88E("sta's wpa_ie is NONE\n"); 2755 } 2756 } else { 2757 ret = -1; 2758 } 2759 2760 return ret; 2761} 2762 2763static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len) 2764{ 2765 int ret = 0; 2766 unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; 2767 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2768 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2769 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2770 int ie_len; 2771 2772 DBG_88E("%s, len =%d\n", __func__, len); 2773 2774 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 2775 return -EINVAL; 2776 2777 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 2778 2779 if (pmlmepriv->wps_beacon_ie) { 2780 kfree(pmlmepriv->wps_beacon_ie); 2781 pmlmepriv->wps_beacon_ie = NULL; 2782 } 2783 2784 if (ie_len > 0) { 2785 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len); 2786 pmlmepriv->wps_beacon_ie_len = ie_len; 2787 if (pmlmepriv->wps_beacon_ie == NULL) { 2788 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__); 2789 return -EINVAL; 2790 } 2791 2792 memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len); 2793 2794 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true); 2795 2796 pmlmeext->bstart_bss = true; 2797 } 2798 2799 return ret; 2800} 2801 2802static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len) 2803{ 2804 int ret = 0; 2805 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2806 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2807 int ie_len; 2808 2809 DBG_88E("%s, len =%d\n", __func__, len); 2810 2811 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 2812 return -EINVAL; 2813 2814 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 2815 2816 if (pmlmepriv->wps_probe_resp_ie) { 2817 kfree(pmlmepriv->wps_probe_resp_ie); 2818 pmlmepriv->wps_probe_resp_ie = NULL; 2819 } 2820 2821 if (ie_len > 0) { 2822 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len); 2823 pmlmepriv->wps_probe_resp_ie_len = ie_len; 2824 if (pmlmepriv->wps_probe_resp_ie == NULL) { 2825 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__); 2826 return -EINVAL; 2827 } 2828 memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len); 2829 } 2830 2831 return ret; 2832} 2833 2834static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len) 2835{ 2836 int ret = 0; 2837 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2838 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2839 int ie_len; 2840 2841 DBG_88E("%s, len =%d\n", __func__, len); 2842 2843 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 2844 return -EINVAL; 2845 2846 ie_len = len-12-2;/* 12 = param header, 2:no packed */ 2847 2848 if (pmlmepriv->wps_assoc_resp_ie) { 2849 kfree(pmlmepriv->wps_assoc_resp_ie); 2850 pmlmepriv->wps_assoc_resp_ie = NULL; 2851 } 2852 2853 if (ie_len > 0) { 2854 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); 2855 pmlmepriv->wps_assoc_resp_ie_len = ie_len; 2856 if (pmlmepriv->wps_assoc_resp_ie == NULL) { 2857 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__); 2858 return -EINVAL; 2859 } 2860 2861 memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len); 2862 } 2863 2864 return ret; 2865} 2866 2867static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len) 2868{ 2869 int ret = 0; 2870 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2871 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2872 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2873 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2874 2875 u8 value; 2876 2877 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 2878 return -EINVAL; 2879 2880 if (param->u.wpa_param.name != 0) /* dummy test... */ 2881 DBG_88E("%s name(%u) != 0\n", __func__, param->u.wpa_param.name); 2882 value = param->u.wpa_param.value; 2883 2884 /* use the same definition of hostapd's ignore_broadcast_ssid */ 2885 if (value != 1 && value != 2) 2886 value = 0; 2887 DBG_88E("%s value(%u)\n", __func__, value); 2888 pmlmeinfo->hidden_ssid_mode = value; 2889 return ret; 2890} 2891 2892static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len) 2893{ 2894 int ret = 0; 2895 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2896 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2897 2898 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 2899 return -EINVAL; 2900 2901 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 2902 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 2903 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 2904 return -EINVAL; 2905 ret = rtw_acl_remove_sta(padapter, param->sta_addr); 2906 return ret; 2907} 2908 2909static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len) 2910{ 2911 int ret = 0; 2912 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2913 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2914 2915 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 2916 return -EINVAL; 2917 2918 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 2919 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 2920 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 2921 return -EINVAL; 2922 ret = rtw_acl_add_sta(padapter, param->sta_addr); 2923 return ret; 2924} 2925 2926static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len) 2927{ 2928 int ret = 0; 2929 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2930 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2931 2932 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 2933 return -EINVAL; 2934 2935 rtw_set_macaddr_acl(padapter, param->u.mlme.command); 2936 2937 return ret; 2938} 2939 2940static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p) 2941{ 2942 struct ieee_param *param; 2943 int ret = 0; 2944 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 2945 2946 /* 2947 * this function is expect to call in master mode, which allows no power saving 2948 * so, we just check hw_init_completed 2949 */ 2950 2951 if (!padapter->hw_init_completed) { 2952 ret = -EPERM; 2953 goto out; 2954 } 2955 2956 if (!p->pointer) { 2957 ret = -EINVAL; 2958 goto out; 2959 } 2960 2961 param = (struct ieee_param *)rtw_malloc(p->length); 2962 if (param == NULL) { 2963 ret = -ENOMEM; 2964 goto out; 2965 } 2966 2967 if (copy_from_user(param, p->pointer, p->length)) { 2968 kfree(param); 2969 ret = -EFAULT; 2970 goto out; 2971 } 2972 2973 switch (param->cmd) { 2974 case RTL871X_HOSTAPD_FLUSH: 2975 ret = rtw_hostapd_sta_flush(dev); 2976 break; 2977 case RTL871X_HOSTAPD_ADD_STA: 2978 ret = rtw_add_sta(dev, param); 2979 break; 2980 case RTL871X_HOSTAPD_REMOVE_STA: 2981 ret = rtw_del_sta(dev, param); 2982 break; 2983 case RTL871X_HOSTAPD_SET_BEACON: 2984 ret = rtw_set_beacon(dev, param, p->length); 2985 break; 2986 case RTL871X_SET_ENCRYPTION: 2987 ret = rtw_set_encryption(dev, param, p->length); 2988 break; 2989 case RTL871X_HOSTAPD_GET_WPAIE_STA: 2990 ret = rtw_get_sta_wpaie(dev, param); 2991 break; 2992 case RTL871X_HOSTAPD_SET_WPS_BEACON: 2993 ret = rtw_set_wps_beacon(dev, param, p->length); 2994 break; 2995 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP: 2996 ret = rtw_set_wps_probe_resp(dev, param, p->length); 2997 break; 2998 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP: 2999 ret = rtw_set_wps_assoc_resp(dev, param, p->length); 3000 break; 3001 case RTL871X_HOSTAPD_SET_HIDDEN_SSID: 3002 ret = rtw_set_hidden_ssid(dev, param, p->length); 3003 break; 3004 case RTL871X_HOSTAPD_GET_INFO_STA: 3005 ret = rtw_ioctl_get_sta_data(dev, param, p->length); 3006 break; 3007 case RTL871X_HOSTAPD_SET_MACADDR_ACL: 3008 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length); 3009 break; 3010 case RTL871X_HOSTAPD_ACL_ADD_STA: 3011 ret = rtw_ioctl_acl_add_sta(dev, param, p->length); 3012 break; 3013 case RTL871X_HOSTAPD_ACL_REMOVE_STA: 3014 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length); 3015 break; 3016 default: 3017 DBG_88E("Unknown hostapd request: %d\n", param->cmd); 3018 ret = -EOPNOTSUPP; 3019 break; 3020 } 3021 3022 if (ret == 0 && copy_to_user(p->pointer, param, p->length)) 3023 ret = -EFAULT; 3024 kfree(param); 3025out: 3026 return ret; 3027} 3028#endif 3029 3030#include <rtw_android.h> 3031static int rtw_wx_set_priv(struct net_device *dev, 3032 struct iw_request_info *info, 3033 union iwreq_data *awrq, 3034 char *extra) 3035{ 3036 int ret = 0; 3037 int len = 0; 3038 char *ext; 3039 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3040 struct iw_point *dwrq = (struct iw_point *)awrq; 3041 3042 if (dwrq->length == 0) 3043 return -EFAULT; 3044 3045 len = dwrq->length; 3046 ext = vmalloc(len); 3047 if (!ext) 3048 return -ENOMEM; 3049 3050 if (copy_from_user(ext, dwrq->pointer, len)) { 3051 vfree(ext); 3052 return -EFAULT; 3053 } 3054 3055 /* added for wps2.0 @20110524 */ 3056 if (dwrq->flags == 0x8766 && len > 8) { 3057 u32 cp_sz; 3058 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3059 u8 *probereq_wpsie = ext; 3060 int probereq_wpsie_len = len; 3061 u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; 3062 3063 if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) && 3064 (!memcmp(&probereq_wpsie[2], wps_oui, 4))) { 3065 cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len; 3066 3067 pmlmepriv->wps_probe_req_ie_len = 0; 3068 kfree(pmlmepriv->wps_probe_req_ie); 3069 pmlmepriv->wps_probe_req_ie = NULL; 3070 3071 pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz); 3072 if (pmlmepriv->wps_probe_req_ie == NULL) { 3073 pr_info("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__); 3074 ret = -EINVAL; 3075 goto FREE_EXT; 3076 } 3077 memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz); 3078 pmlmepriv->wps_probe_req_ie_len = cp_sz; 3079 } 3080 goto FREE_EXT; 3081 } 3082 3083 if (len >= WEXT_CSCAN_HEADER_SIZE && 3084 !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) { 3085 ret = rtw_wx_set_scan(dev, info, awrq, ext); 3086 goto FREE_EXT; 3087 } 3088 3089FREE_EXT: 3090 3091 vfree(ext); 3092 3093 return ret; 3094} 3095 3096static iw_handler rtw_handlers[] = { 3097 NULL, /* SIOCSIWCOMMIT */ 3098 rtw_wx_get_name, /* SIOCGIWNAME */ 3099 dummy, /* SIOCSIWNWID */ 3100 dummy, /* SIOCGIWNWID */ 3101 rtw_wx_set_freq, /* SIOCSIWFREQ */ 3102 rtw_wx_get_freq, /* SIOCGIWFREQ */ 3103 rtw_wx_set_mode, /* SIOCSIWMODE */ 3104 rtw_wx_get_mode, /* SIOCGIWMODE */ 3105 dummy, /* SIOCSIWSENS */ 3106 rtw_wx_get_sens, /* SIOCGIWSENS */ 3107 NULL, /* SIOCSIWRANGE */ 3108 rtw_wx_get_range, /* SIOCGIWRANGE */ 3109 rtw_wx_set_priv, /* SIOCSIWPRIV */ 3110 NULL, /* SIOCGIWPRIV */ 3111 NULL, /* SIOCSIWSTATS */ 3112 NULL, /* SIOCGIWSTATS */ 3113 dummy, /* SIOCSIWSPY */ 3114 dummy, /* SIOCGIWSPY */ 3115 NULL, /* SIOCGIWTHRSPY */ 3116 NULL, /* SIOCWIWTHRSPY */ 3117 rtw_wx_set_wap, /* SIOCSIWAP */ 3118 rtw_wx_get_wap, /* SIOCGIWAP */ 3119 rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */ 3120 dummy, /* SIOCGIWAPLIST -- depricated */ 3121 rtw_wx_set_scan, /* SIOCSIWSCAN */ 3122 rtw_wx_get_scan, /* SIOCGIWSCAN */ 3123 rtw_wx_set_essid, /* SIOCSIWESSID */ 3124 rtw_wx_get_essid, /* SIOCGIWESSID */ 3125 dummy, /* SIOCSIWNICKN */ 3126 rtw_wx_get_nick, /* SIOCGIWNICKN */ 3127 NULL, /* -- hole -- */ 3128 NULL, /* -- hole -- */ 3129 rtw_wx_set_rate, /* SIOCSIWRATE */ 3130 rtw_wx_get_rate, /* SIOCGIWRATE */ 3131 rtw_wx_set_rts, /* SIOCSIWRTS */ 3132 rtw_wx_get_rts, /* SIOCGIWRTS */ 3133 rtw_wx_set_frag, /* SIOCSIWFRAG */ 3134 rtw_wx_get_frag, /* SIOCGIWFRAG */ 3135 dummy, /* SIOCSIWTXPOW */ 3136 dummy, /* SIOCGIWTXPOW */ 3137 dummy, /* SIOCSIWRETRY */ 3138 rtw_wx_get_retry, /* SIOCGIWRETRY */ 3139 rtw_wx_set_enc, /* SIOCSIWENCODE */ 3140 rtw_wx_get_enc, /* SIOCGIWENCODE */ 3141 dummy, /* SIOCSIWPOWER */ 3142 rtw_wx_get_power, /* SIOCGIWPOWER */ 3143 NULL, /*---hole---*/ 3144 NULL, /*---hole---*/ 3145 rtw_wx_set_gen_ie, /* SIOCSIWGENIE */ 3146 NULL, /* SIOCGWGENIE */ 3147 rtw_wx_set_auth, /* SIOCSIWAUTH */ 3148 NULL, /* SIOCGIWAUTH */ 3149 rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ 3150 NULL, /* SIOCGIWENCODEEXT */ 3151 rtw_wx_set_pmkid, /* SIOCSIWPMKSA */ 3152 NULL, /*---hole---*/ 3153}; 3154 3155static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) 3156{ 3157 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); 3158 struct iw_statistics *piwstats = &padapter->iwstats; 3159 int tmp_level = 0; 3160 int tmp_qual = 0; 3161 int tmp_noise = 0; 3162 3163 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { 3164 piwstats->qual.qual = 0; 3165 piwstats->qual.level = 0; 3166 piwstats->qual.noise = 0; 3167 } else { 3168 tmp_level = padapter->recvpriv.signal_strength; 3169 tmp_qual = padapter->recvpriv.signal_qual; 3170 tmp_noise = padapter->recvpriv.noise; 3171 3172 piwstats->qual.level = tmp_level; 3173 piwstats->qual.qual = tmp_qual; 3174 piwstats->qual.noise = tmp_noise; 3175 } 3176 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;/* IW_QUAL_DBM; */ 3177 return &padapter->iwstats; 3178} 3179 3180struct iw_handler_def rtw_handlers_def = { 3181 .standard = rtw_handlers, 3182 .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler), 3183 .get_wireless_stats = rtw_get_wireless_stats, 3184}; 3185 3186#include <rtw_android.h> 3187int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 3188{ 3189 struct iwreq *wrq = (struct iwreq *)rq; 3190 int ret = 0; 3191 3192 switch (cmd) { 3193 case RTL_IOCTL_WPA_SUPPLICANT: 3194 ret = wpa_supplicant_ioctl(dev, &wrq->u.data); 3195 break; 3196#ifdef CONFIG_88EU_AP_MODE 3197 case RTL_IOCTL_HOSTAPD: 3198 ret = rtw_hostapd_ioctl(dev, &wrq->u.data); 3199 break; 3200#endif /* CONFIG_88EU_AP_MODE */ 3201 case (SIOCDEVPRIVATE+1): 3202 ret = rtw_android_priv_cmd(dev, rq, cmd); 3203 break; 3204 default: 3205 ret = -EOPNOTSUPP; 3206 break; 3207 } 3208 return ret; 3209} 3210