1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 8 #include <drv_types.h> 9 #include <rtw_debug.h> 10 11 u8 rtw_validate_bssid(u8 *bssid) 12 { 13 u8 ret = true; 14 15 if (is_zero_mac_addr(bssid) 16 || is_broadcast_mac_addr(bssid) 17 || is_multicast_mac_addr(bssid) 18 ) { 19 ret = false; 20 } 21 22 return ret; 23 } 24 25 u8 rtw_validate_ssid(struct ndis_802_11_ssid *ssid) 26 { 27 u8 ret = true; 28 29 if (ssid->ssid_length > 32) { 30 ret = false; 31 goto exit; 32 } 33 34 exit: 35 return ret; 36 } 37 38 u8 rtw_do_join(struct adapter *padapter) 39 { 40 struct list_head *plist, *phead; 41 u8 *pibss = NULL; 42 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 43 struct __queue *queue = &(pmlmepriv->scanned_queue); 44 u8 ret = _SUCCESS; 45 46 spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); 47 phead = get_list_head(queue); 48 plist = get_next(phead); 49 50 pmlmepriv->cur_network.join_res = -2; 51 52 set_fwstate(pmlmepriv, _FW_UNDER_LINKING); 53 54 pmlmepriv->pscanned = plist; 55 56 pmlmepriv->to_join = true; 57 58 if (list_empty(&queue->queue)) { 59 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 60 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 61 62 /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */ 63 /* we try to issue sitesurvey firstly */ 64 65 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == false 66 || rtw_to_roam(padapter) > 0 67 ) { 68 /* submit site_survey_cmd */ 69 ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0); 70 if (ret != _SUCCESS) 71 pmlmepriv->to_join = false; 72 73 } else { 74 pmlmepriv->to_join = false; 75 ret = _FAIL; 76 } 77 78 goto exit; 79 } else { 80 int select_ret; 81 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 82 select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); 83 if (select_ret == _SUCCESS) { 84 pmlmepriv->to_join = false; 85 _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); 86 } else { 87 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) { 88 /* submit createbss_cmd to change to a ADHOC_MASTER */ 89 90 /* pmlmepriv->lock has been acquired by caller... */ 91 struct wlan_bssid_ex *pdev_network = &(padapter->registrypriv.dev_network); 92 93 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; 94 95 pibss = padapter->registrypriv.dev_network.mac_address; 96 97 memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); 98 99 rtw_update_registrypriv_dev_network(padapter); 100 101 rtw_generate_random_ibss(pibss); 102 103 if (rtw_createbss_cmd(padapter) != _SUCCESS) { 104 ret = false; 105 goto exit; 106 } 107 108 pmlmepriv->to_join = false; 109 110 } else { 111 /* can't associate ; reset under-linking */ 112 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 113 114 /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */ 115 /* we try to issue sitesurvey firstly */ 116 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == false 117 || rtw_to_roam(padapter) > 0 118 ) { 119 ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0); 120 if (ret != _SUCCESS) 121 pmlmepriv->to_join = false; 122 123 } else { 124 ret = _FAIL; 125 pmlmepriv->to_join = false; 126 } 127 } 128 129 } 130 131 } 132 133 exit: 134 return ret; 135 } 136 137 u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) 138 { 139 u8 status = _SUCCESS; 140 141 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 142 struct wlan_network *pnetwork = &pmlmepriv->cur_network; 143 144 netdev_dbg(padapter->pnetdev, "set ssid [%s] fw_state = 0x%08x\n", 145 ssid->ssid, get_fwstate(pmlmepriv)); 146 147 if (padapter->hw_init_completed == false) { 148 status = _FAIL; 149 goto exit; 150 } 151 152 spin_lock_bh(&pmlmepriv->lock); 153 154 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) 155 goto handle_tkip_countermeasure; 156 else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) 157 goto release_mlme_lock; 158 159 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) { 160 if ((pmlmepriv->assoc_ssid.ssid_length == ssid->ssid_length) && 161 (!memcmp(&pmlmepriv->assoc_ssid.ssid, ssid->ssid, ssid->ssid_length))) { 162 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)) { 163 if (rtw_is_same_ibss(padapter, pnetwork) == false) { 164 /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */ 165 rtw_disassoc_cmd(padapter, 0, true); 166 167 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) 168 rtw_indicate_disconnect(padapter); 169 170 rtw_free_assoc_resources(padapter, 1); 171 172 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) { 173 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); 174 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); 175 } 176 } else { 177 goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */ 178 } 179 } else { 180 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1); 181 } 182 } else { 183 rtw_disassoc_cmd(padapter, 0, true); 184 185 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) 186 rtw_indicate_disconnect(padapter); 187 188 rtw_free_assoc_resources(padapter, 1); 189 190 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) { 191 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); 192 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); 193 } 194 } 195 } 196 197 handle_tkip_countermeasure: 198 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) { 199 status = _FAIL; 200 goto release_mlme_lock; 201 } 202 203 if (rtw_validate_ssid(ssid) == false) { 204 status = _FAIL; 205 goto release_mlme_lock; 206 } 207 208 memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid)); 209 pmlmepriv->assoc_by_bssid = false; 210 211 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) 212 pmlmepriv->to_join = true; 213 else 214 status = rtw_do_join(padapter); 215 216 release_mlme_lock: 217 spin_unlock_bh(&pmlmepriv->lock); 218 219 exit: 220 221 return status; 222 } 223 224 u8 rtw_set_802_11_connect(struct adapter *padapter, u8 *bssid, struct ndis_802_11_ssid *ssid) 225 { 226 u8 status = _SUCCESS; 227 bool bssid_valid = true; 228 bool ssid_valid = true; 229 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 230 231 if (!ssid || rtw_validate_ssid(ssid) == false) 232 ssid_valid = false; 233 234 if (!bssid || rtw_validate_bssid(bssid) == false) 235 bssid_valid = false; 236 237 if (!ssid_valid && !bssid_valid) { 238 status = _FAIL; 239 goto exit; 240 } 241 242 if (padapter->hw_init_completed == false) { 243 status = _FAIL; 244 goto exit; 245 } 246 247 spin_lock_bh(&pmlmepriv->lock); 248 249 netdev_dbg(padapter->pnetdev, FUNC_ADPT_FMT " fw_state = 0x%08x\n", 250 FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); 251 252 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) 253 goto handle_tkip_countermeasure; 254 else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) 255 goto release_mlme_lock; 256 257 handle_tkip_countermeasure: 258 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) { 259 status = _FAIL; 260 goto release_mlme_lock; 261 } 262 263 if (ssid && ssid_valid) 264 memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid)); 265 else 266 memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid)); 267 268 if (bssid && bssid_valid) { 269 memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); 270 pmlmepriv->assoc_by_bssid = true; 271 } else { 272 pmlmepriv->assoc_by_bssid = false; 273 } 274 275 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) 276 pmlmepriv->to_join = true; 277 else 278 status = rtw_do_join(padapter); 279 280 release_mlme_lock: 281 spin_unlock_bh(&pmlmepriv->lock); 282 283 exit: 284 return status; 285 } 286 287 u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter, 288 enum ndis_802_11_network_infrastructure networktype) 289 { 290 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 291 struct wlan_network *cur_network = &pmlmepriv->cur_network; 292 enum ndis_802_11_network_infrastructure *pold_state = &(cur_network->network.infrastructure_mode); 293 294 if (*pold_state != networktype) { 295 if (*pold_state == Ndis802_11APMode) { 296 /* change to other mode from Ndis802_11APMode */ 297 cur_network->join_res = -1; 298 299 stop_ap_mode(padapter); 300 } 301 302 spin_lock_bh(&pmlmepriv->lock); 303 304 if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) || (*pold_state == Ndis802_11IBSS)) 305 rtw_disassoc_cmd(padapter, 0, true); 306 307 if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) || 308 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) 309 rtw_free_assoc_resources(padapter, 1); 310 311 if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) { 312 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) 313 rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have checked whether issue dis-assoc_cmd or not */ 314 } 315 316 *pold_state = networktype; 317 318 _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE); 319 320 switch (networktype) { 321 case Ndis802_11IBSS: 322 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); 323 break; 324 325 case Ndis802_11Infrastructure: 326 set_fwstate(pmlmepriv, WIFI_STATION_STATE); 327 break; 328 329 case Ndis802_11APMode: 330 set_fwstate(pmlmepriv, WIFI_AP_STATE); 331 start_ap_mode(padapter); 332 /* rtw_indicate_connect(padapter); */ 333 334 break; 335 336 case Ndis802_11AutoUnknown: 337 case Ndis802_11InfrastructureMax: 338 break; 339 } 340 341 /* SecClearAllKeys(adapter); */ 342 343 spin_unlock_bh(&pmlmepriv->lock); 344 } 345 return true; 346 } 347 348 349 u8 rtw_set_802_11_disassociate(struct adapter *padapter) 350 { 351 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 352 353 spin_lock_bh(&pmlmepriv->lock); 354 355 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { 356 rtw_disassoc_cmd(padapter, 0, true); 357 rtw_indicate_disconnect(padapter); 358 /* modify for CONFIG_IEEE80211W, none 11w can use it */ 359 rtw_free_assoc_resources_cmd(padapter); 360 rtw_pwr_wakeup(padapter); 361 } 362 363 spin_unlock_bh(&pmlmepriv->lock); 364 365 return true; 366 } 367 368 u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num) 369 { 370 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 371 u8 res = true; 372 373 if (!padapter) { 374 res = false; 375 goto exit; 376 } 377 if (padapter->hw_init_completed == false) { 378 res = false; 379 goto exit; 380 } 381 382 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) || 383 (pmlmepriv->LinkDetectInfo.bBusyTraffic == true)) { 384 /* Scan or linking is in progress, do nothing. */ 385 res = true; 386 387 } else { 388 if (rtw_is_scan_deny(padapter)) 389 return _SUCCESS; 390 391 spin_lock_bh(&pmlmepriv->lock); 392 393 res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0); 394 395 spin_unlock_bh(&pmlmepriv->lock); 396 } 397 exit: 398 399 return res; 400 } 401 402 u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11_authentication_mode authmode) 403 { 404 struct security_priv *psecuritypriv = &padapter->securitypriv; 405 int res; 406 u8 ret; 407 408 psecuritypriv->ndisauthtype = authmode; 409 410 if (psecuritypriv->ndisauthtype > 3) 411 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; 412 413 res = rtw_set_auth(padapter, psecuritypriv); 414 415 if (res == _SUCCESS) 416 ret = true; 417 else 418 ret = false; 419 420 return ret; 421 } 422 423 u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep) 424 { 425 426 signed int keyid, res; 427 struct security_priv *psecuritypriv = &(padapter->securitypriv); 428 u8 ret = _SUCCESS; 429 430 keyid = wep->key_index & 0x3fffffff; 431 432 if (keyid >= 4) { 433 ret = false; 434 goto exit; 435 } 436 437 switch (wep->key_length) { 438 case 5: 439 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; 440 break; 441 case 13: 442 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; 443 break; 444 default: 445 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; 446 break; 447 } 448 449 memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->key_material), wep->key_length); 450 451 psecuritypriv->dot11DefKeylen[keyid] = wep->key_length; 452 453 psecuritypriv->dot11PrivacyKeyIndex = keyid; 454 455 res = rtw_set_key(padapter, psecuritypriv, keyid, 1, true); 456 457 if (res == _FAIL) 458 ret = false; 459 exit: 460 461 return ret; 462 } 463 464 /* 465 * rtw_get_cur_max_rate - 466 * @adapter: pointer to struct adapter structure 467 * 468 * Return 0 or 100Kbps 469 */ 470 u16 rtw_get_cur_max_rate(struct adapter *adapter) 471 { 472 int i = 0; 473 u16 rate = 0, max_rate = 0; 474 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 475 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 476 struct sta_info *psta = NULL; 477 u8 short_GI = 0; 478 479 if ((check_fwstate(pmlmepriv, _FW_LINKED) != true) 480 && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != true)) 481 return 0; 482 483 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv)); 484 if (!psta) 485 return 0; 486 487 short_GI = query_ra_short_GI(psta); 488 489 if (is_supported_ht(psta->wireless_mode)) { 490 max_rate = rtw_mcs_rate(psta->bw_mode == CHANNEL_WIDTH_40 ? 1 : 0, 491 short_GI, 492 psta->htpriv.ht_cap.mcs.rx_mask); 493 } else { 494 while ((pcur_bss->supported_rates[i] != 0) && (pcur_bss->supported_rates[i] != 0xFF)) { 495 rate = pcur_bss->supported_rates[i]&0x7F; 496 if (rate > max_rate) 497 max_rate = rate; 498 i++; 499 } 500 501 max_rate = max_rate*10/2; 502 } 503 504 return max_rate; 505 } 506