1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wlan_hdd_assoc.c 22 * 23 * WLAN Host Device Driver implementation 24 * 25 */ 26 27 #include "wlan_hdd_includes.h" 28 #include <ani_global.h> 29 #include "dot11f.h" 30 #include "wlan_hdd_power.h" 31 #include "wlan_hdd_trace.h" 32 #include <linux/ieee80211.h> 33 #include <linux/wireless.h> 34 #include <linux/etherdevice.h> 35 #include <net/cfg80211.h> 36 #include "wlan_hdd_cfg80211.h" 37 #include "csr_inside_api.h" 38 #include "wlan_hdd_p2p.h" 39 #include "wlan_hdd_tdls.h" 40 #include "sme_api.h" 41 #include "wlan_hdd_hostapd.h" 42 #include <wlan_hdd_green_ap.h> 43 #include <wlan_hdd_ipa.h> 44 #include "wlan_hdd_lpass.h" 45 #include <wlan_logging_sock_svc.h> 46 #include <cds_sched.h> 47 #include "wlan_policy_mgr_api.h" 48 #include <cds_utils.h> 49 #include "sme_power_save_api.h" 50 #include "wlan_hdd_napi.h" 51 #include <cdp_txrx_cmn.h> 52 #include <cdp_txrx_flow_ctrl_legacy.h> 53 #include <cdp_txrx_peer_ops.h> 54 #include <cdp_txrx_misc.h> 55 #include <cdp_txrx_ctrl.h> 56 #include "ol_txrx.h" 57 #include <wlan_logging_sock_svc.h> 58 #include <wlan_hdd_object_manager.h> 59 #include <cdp_txrx_handle.h> 60 #include "wlan_pmo_ucfg_api.h" 61 #include "wlan_hdd_tsf.h" 62 #include "wlan_utility.h" 63 #include "wlan_p2p_ucfg_api.h" 64 #include "wlan_ipa_ucfg_api.h" 65 #include "wlan_hdd_stats.h" 66 #include "wlan_hdd_scan.h" 67 #include "wlan_crypto_global_api.h" 68 #include "wlan_hdd_bcn_recv.h" 69 #include "wlan_mlme_twt_ucfg_api.h" 70 71 #include <wlan_cfg80211_crypto.h> 72 #include <wlan_crypto_global_api.h> 73 #include "wlan_dlm_ucfg_api.h" 74 #include "wlan_hdd_sta_info.h" 75 #include "wlan_hdd_ftm_time_sync.h" 76 #include "wlan_cm_roam_api.h" 77 78 #include <ol_defines.h> 79 #include "wlan_pkt_capture_ucfg_api.h" 80 #include "wlan_if_mgr_ucfg_api.h" 81 #include "wlan_if_mgr_public_struct.h" 82 #include "wlan_cm_public_struct.h" 83 #include "osif_cm_util.h" 84 #include "wlan_hdd_cm_api.h" 85 #include "cm_utf.h" 86 87 #include "wlan_hdd_bootup_marker.h" 88 #include "wlan_roam_debug.h" 89 90 #include "wlan_hdd_twt.h" 91 #include "wlan_cm_roam_ucfg_api.h" 92 #include "wlan_hdd_son.h" 93 #include "wlan_dp_ucfg_api.h" 94 #include "wlan_cm_ucfg_api.h" 95 96 /* These are needed to recognize WPA and RSN suite types */ 97 #define HDD_WPA_OUI_SIZE 4 98 #define HDD_RSN_OUI_SIZE 4 99 uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 }; 100 uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 }; 101 uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 }; 102 uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 }; 103 uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 }; 104 uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 }; 105 106 #ifdef FEATURE_WLAN_ESE 107 /* CCKM */ 108 uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 }; 109 /* CCKM */ 110 uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 }; 111 #endif /* FEATURE_WLAN_ESE */ 112 113 /* group cipher */ 114 uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 }; 115 116 /* WEP-40 or RSN */ 117 uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 }; 118 119 /* TKIP or RSN-PSK */ 120 uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 }; 121 122 /* Reserved */ 123 uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 }; 124 125 /* AES-CCMP */ 126 uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 }; 127 128 /* WEP-104 */ 129 uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 }; 130 131 /* RSN-PSK-SHA256 */ 132 uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 }; 133 134 /* RSN-8021X-SHA256 */ 135 uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 }; 136 137 /* AES-GCMP-128 */ 138 uint8_t ccp_rsn_oui09[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x08 }; 139 140 /* AES-GCMP-256 */ 141 uint8_t ccp_rsn_oui0a[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x09 }; 142 #ifdef WLAN_FEATURE_FILS_SK 143 uint8_t ccp_rsn_oui_0e[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0E}; 144 uint8_t ccp_rsn_oui_0f[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0F}; 145 uint8_t ccp_rsn_oui_10[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x10}; 146 uint8_t ccp_rsn_oui_11[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x11}; 147 #endif 148 uint8_t ccp_rsn_oui_12[HDD_RSN_OUI_SIZE] = {0x50, 0x6F, 0x9A, 0x02}; 149 uint8_t ccp_rsn_oui_0b[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0B}; 150 uint8_t ccp_rsn_oui_0c[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0C}; 151 /* FT-SUITE-B AKM */ 152 uint8_t ccp_rsn_oui_0d[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0D}; 153 154 /* OWE https://tools.ietf.org/html/rfc8110 */ 155 uint8_t ccp_rsn_oui_18[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x12}; 156 157 #ifdef WLAN_FEATURE_SAE 158 /* SAE AKM */ 159 uint8_t ccp_rsn_oui_80[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x08}; 160 /* FT SAE AKM */ 161 uint8_t ccp_rsn_oui_90[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x09}; 162 #endif 163 static const 164 u8 ccp_rsn_oui_13[HDD_RSN_OUI_SIZE] = {0x50, 0x6F, 0x9A, 0x01}; 165 166 #ifdef FEATURE_WLAN_WAPI 167 #define HDD_WAPI_OUI_SIZE 4 168 /* WPI-SMS4 */ 169 uint8_t ccp_wapi_oui01[HDD_WAPI_OUI_SIZE] = { 0x00, 0x14, 0x72, 0x01 }; 170 /* WAI-PSK */ 171 uint8_t ccp_wapi_oui02[HDD_WAPI_OUI_SIZE] = { 0x00, 0x14, 0x72, 0x02 }; 172 #endif /* FEATURE_WLAN_WAPI */ 173 174 /* Offset where the EID-Len-IE, start. */ 175 #define ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */ 176 #define ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */ 177 178 /* 179 * beacon_filter_table - table of IEs used for beacon filtering 180 */ 181 static const int beacon_filter_table[] = { 182 WLAN_ELEMID_DSPARMS, 183 WLAN_ELEMID_ERP, 184 WLAN_ELEMID_EDCAPARMS, 185 WLAN_ELEMID_QOS_CAPABILITY, 186 WLAN_ELEMID_HTINFO_ANA, 187 WLAN_ELEMID_OP_MODE_NOTIFY, 188 WLAN_ELEMID_VHTOP, 189 WLAN_ELEMID_QUIET_CHANNEL, 190 WLAN_ELEMID_TWT, 191 #ifdef WLAN_FEATURE_11AX_BSS_COLOR 192 /* 193 * EID: 221 vendor IE is being used temporarily by 11AX 194 * bss-color-change IE till it gets any fixed number. This 195 * vendor EID needs to be replaced with bss-color-change IE 196 * number. 197 */ 198 WLAN_ELEMID_VENDOR, 199 #endif 200 }; 201 202 /* 203 * beacon_filter_extn_table - table of extn IEs used for beacon filtering 204 */ 205 static const int beacon_filter_extn_table[] = { 206 WLAN_EXTN_ELEMID_HEOP, 207 WLAN_EXTN_ELEMID_UORA, 208 WLAN_EXTN_ELEMID_MUEDCA, 209 #ifdef WLAN_FEATURE_11BE 210 WLAN_EXTN_ELEMID_EHTOP, 211 #endif 212 }; 213 214 /* HE operation BIT positins */ 215 #if defined(WLAN_FEATURE_11AX) 216 #define HE_OPERATION_DFLT_PE_DURATION_POS 0 217 #define HE_OPERATION_TWT_REQUIRED_POS 3 218 #define HE_OPERATION_RTS_THRESHOLD_POS 4 219 #define HE_OPERATION_VHT_OPER_POS 14 220 #define HE_OPERATION_CO_LOCATED_BSS_POS 15 221 #define HE_OPERATION_ER_SU_DISABLE_POS 16 222 #define HE_OPERATION_OPER_INFO_6G_POS 17 223 #define HE_OPERATION_RESERVED_POS 18 224 #define HE_OPERATION_BSS_COLOR_POS 24 225 #define HE_OPERATION_PARTIAL_BSS_COLOR_POS 30 226 #define HE_OPERATION_BSS_COL_DISABLED_POS 31 227 #endif 228 229 /* EHT operation BIT positins */ 230 #if defined(WLAN_FEATURE_11BE) 231 #define EHT_OPER_BASIC_RX_NSS_MCS_0_TO_7_POS 0 232 #define EHT_OPER_BASIC_TX_NSS_MCS_0_TO_7_POS 4 233 #define EHT_OPER_BASIC_RX_NSS_MCS_8_AND_9_POS 8 234 #define EHT_OPER_BASIC_TX_NSS_MCS_8_AND_9_POS 12 235 #define EHT_OPER_BASIC_RX_NSS_MCS_10_AND_11_POS 16 236 #define EHT_OPER_BASIC_TX_NSS_MCS_10_AND_11_POS 20 237 #define EHT_OPER_BASIC_RX_NSS_MCS_12_AND_13_POS 24 238 #define EHT_OPER_BASIC_TX_NSS_MCS_12_AND_13_POS 28 239 #endif 240 241 #if defined(WLAN_FEATURE_SAE) && \ 242 (defined(CFG80211_EXTERNAL_AUTH_SUPPORT) || \ 243 LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) 244 #if defined (CFG80211_SAE_AUTH_TA_ADDR_SUPPORT) 245 /** 246 * wlan_hdd_sae_copy_ta_addr() - Send TA address to supplicant 247 * @params: pointer to external auth params 248 * @link_info: Link info pointer in HDD adapter 249 * 250 * This API is used to copy TA address info in supplicant structure. 251 * 252 * Return: None 253 */ 254 static inline 255 void wlan_hdd_sae_copy_ta_addr(struct cfg80211_external_auth_params *params, 256 struct wlan_hdd_link_info *link_info) 257 { 258 struct qdf_mac_addr ta = QDF_MAC_ADDR_ZERO_INIT; 259 QDF_STATUS status = QDF_STATUS_SUCCESS; 260 uint8_t *link_addr; 261 262 status = ucfg_cm_get_sae_auth_ta(link_info->adapter->hdd_ctx->pdev, 263 link_info->vdev_id, 264 &ta); 265 if (QDF_IS_STATUS_SUCCESS(status)) 266 qdf_ether_addr_copy(params->tx_addr, ta.bytes); 267 else if (wlan_vdev_mlme_is_mlo_vdev(link_info->vdev)) { 268 link_addr = wlan_vdev_mlme_get_linkaddr(link_info->vdev); 269 qdf_ether_addr_copy(params->tx_addr, link_addr); 270 } 271 272 hdd_debug("status:%d ta:" QDF_MAC_ADDR_FMT, status, 273 QDF_MAC_ADDR_REF(params->tx_addr)); 274 275 } 276 #else 277 static inline 278 void wlan_hdd_sae_copy_ta_addr(struct cfg80211_external_auth_params *params, 279 struct wlan_hdd_link_info *link_info) 280 { 281 } 282 #endif 283 284 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_EXTERNAL_AUTH_MLO_SUPPORT) 285 /** 286 * wlan_hdd_sae_update_mld_addr() - Send mld address to supplicant 287 * @params: pointer to external auth params 288 * @link_info: Link info pointer in HDD adapter 289 * 290 * This API is used to copy MLD address info in supplicant structure. 291 * 292 * Return: QDF_STATUS 293 */ 294 static inline QDF_STATUS 295 wlan_hdd_sae_update_mld_addr(struct cfg80211_external_auth_params *params, 296 struct wlan_hdd_link_info *link_info) 297 { 298 struct qdf_mac_addr mld_addr; 299 struct qdf_mac_addr *mld_roaming_addr; 300 QDF_STATUS status = QDF_STATUS_SUCCESS; 301 struct wlan_objmgr_vdev *vdev; 302 303 if (!link_info->vdev) 304 return QDF_STATUS_E_INVAL; 305 306 vdev = link_info->vdev; 307 wlan_objmgr_vdev_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR); 308 309 if (!ucfg_cm_is_sae_auth_addr_conversion_required(vdev)) 310 goto end; 311 312 if (ucfg_cm_is_vdev_roaming(vdev)) { 313 /* 314 * while roaming, peer is not created yet till authentication 315 * So retrieving the MLD address which is cached from the 316 * scan entry. 317 */ 318 mld_roaming_addr = ucfg_cm_roaming_get_peer_mld_addr(vdev); 319 if (!mld_roaming_addr) { 320 status = QDF_STATUS_E_INVAL; 321 goto end; 322 } 323 mld_addr = *mld_roaming_addr; 324 } else { 325 status = wlan_vdev_get_bss_peer_mld_mac(vdev, &mld_addr); 326 if (QDF_IS_STATUS_ERROR(status)) { 327 status = QDF_STATUS_E_INVAL; 328 goto end; 329 } 330 } 331 332 qdf_mem_copy(params->mld_addr, mld_addr.bytes, QDF_MAC_ADDR_SIZE); 333 hdd_debug("Sending MLD:" QDF_MAC_ADDR_FMT" to userspace", 334 QDF_MAC_ADDR_REF(mld_addr.bytes)); 335 336 end: 337 wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); 338 return status; 339 } 340 #else 341 static inline QDF_STATUS 342 wlan_hdd_sae_update_mld_addr(struct cfg80211_external_auth_params *params, 343 struct wlan_hdd_link_info *link_info) 344 { 345 return QDF_STATUS_SUCCESS; 346 } 347 #endif 348 349 /** 350 * wlan_hdd_get_keymgmt_for_sae_akm() - Get the keymgmt OUI 351 * corresponding to the SAE AKM type 352 * @akm: AKM type 353 * 354 * This API is used to get the keymgmt OUI for the SAE AKM type. 355 * Return: keymgmt OUI 356 */ 357 static uint32_t 358 wlan_hdd_get_keymgmt_for_sae_akm(uint32_t akm) 359 { 360 if (akm == WLAN_AKM_SAE) 361 return WLAN_AKM_SUITE_SAE; 362 else if (akm == WLAN_AKM_FT_SAE) 363 return WLAN_AKM_SUITE_FT_OVER_SAE; 364 else if (akm == WLAN_AKM_SAE_EXT_KEY) 365 return WLAN_AKM_SUITE_SAE_EXT_KEY; 366 else if (akm == WLAN_AKM_FT_SAE_EXT_KEY) 367 return WLAN_AKM_SUITE_FT_SAE_EXT_KEY; 368 /** 369 * Legacy FW doesn't support SAE-EXK-KEY or 370 * Cross-SAE_AKM roaming. In such cases, send 371 * SAE for both SAE and FT-SAE AKMs. The supplicant 372 * has backward compatibility to handle this case. 373 */ 374 else 375 return WLAN_AKM_SUITE_SAE; 376 } 377 378 /** 379 * wlan_hdd_sae_callback() - Sends SAE info to supplicant 380 * @link_info: Link info pointer in HDD adapter 381 * @roam_info: pointer to roam info 382 * 383 * This API is used to send required SAE info to trigger SAE in supplicant. 384 * 385 * Return: None 386 */ 387 static void wlan_hdd_sae_callback(struct wlan_hdd_link_info *link_info, 388 struct csr_roam_info *roam_info) 389 { 390 struct hdd_adapter *adapter = link_info->adapter; 391 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 392 int flags; 393 struct sir_sae_info *sae_info = roam_info->sae_info; 394 struct cfg80211_external_auth_params params = {0}; 395 QDF_STATUS status; 396 397 if (wlan_hdd_validate_context(hdd_ctx)) 398 return; 399 400 if (!sae_info) { 401 hdd_err("SAE info in NULL"); 402 return; 403 } 404 405 flags = cds_get_gfp_flags(); 406 407 params.key_mgmt_suite = 408 wlan_hdd_get_keymgmt_for_sae_akm(sae_info->akm); 409 410 params.action = NL80211_EXTERNAL_AUTH_START; 411 qdf_ether_addr_copy(params.bssid, sae_info->peer_mac_addr.bytes); 412 wlan_hdd_sae_copy_ta_addr(¶ms, link_info); 413 status = wlan_hdd_sae_update_mld_addr(¶ms, link_info); 414 if (QDF_IS_STATUS_ERROR(status)) 415 return; 416 417 qdf_mem_copy(params.ssid.ssid, sae_info->ssid.ssId, 418 sae_info->ssid.length); 419 params.ssid.ssid_len = sae_info->ssid.length; 420 cfg80211_external_auth_request(adapter->dev, ¶ms, flags); 421 hdd_debug("SAE: sent cmd"); 422 } 423 #else 424 static inline void wlan_hdd_sae_callback(struct wlan_hdd_link_info *link_info, 425 struct csr_roam_info *roam_info) 426 { } 427 #endif 428 429 /** 430 * hdd_start_powersave_timer_on_associated() - Start auto powersave timer 431 * after associated 432 * @link_info: Link info pointer in HDD adapter 433 * 434 * This function will start auto powersave timer for STA/P2P Client. 435 * 436 * Return: none 437 */ 438 static void 439 hdd_start_powersave_timer_on_associated(struct wlan_hdd_link_info *link_info) 440 { 441 uint32_t timeout; 442 uint32_t auto_bmps_timer_val; 443 struct hdd_adapter *adapter = link_info->adapter; 444 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 445 446 if (adapter->device_mode != QDF_STA_MODE && 447 adapter->device_mode != QDF_P2P_CLIENT_MODE) 448 return; 449 450 ucfg_mlme_get_auto_bmps_timer_value(hdd_ctx->psoc, 451 &auto_bmps_timer_val); 452 timeout = hdd_cm_is_vdev_roaming(link_info) ? 453 AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE : 454 (auto_bmps_timer_val * 1000); 455 sme_ps_enable_auto_ps_timer(hdd_ctx->mac_handle, 456 link_info->vdev_id, 457 timeout); 458 } 459 460 void hdd_conn_set_authenticated(struct wlan_hdd_link_info *link_info, 461 uint8_t auth_state) 462 { 463 struct hdd_station_ctx *sta_ctx; 464 struct wlan_objmgr_vdev *vdev; 465 char *auth_time; 466 uint32_t time_buffer_size; 467 468 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 469 /* save the new connection state */ 470 hdd_debug("Authenticated state Changed from oldState:%d to State:%d", 471 sta_ctx->conn_info.is_authenticated, auth_state); 472 sta_ctx->conn_info.is_authenticated = auth_state; 473 474 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID); 475 if (vdev) { 476 ucfg_dp_conn_info_set_peer_authenticate(vdev, auth_state); 477 hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID); 478 } 479 480 auth_time = sta_ctx->conn_info.auth_time; 481 time_buffer_size = sizeof(sta_ctx->conn_info.auth_time); 482 483 if (auth_state) 484 qdf_get_time_of_the_day_in_hr_min_sec_usec(auth_time, 485 time_buffer_size); 486 else 487 qdf_mem_zero(auth_time, time_buffer_size); 488 if (auth_state && 489 (sta_ctx->conn_info.ptk_installed || 490 sta_ctx->conn_info.uc_encrypt_type == eCSR_ENCRYPT_TYPE_NONE)) 491 hdd_start_powersave_timer_on_associated(link_info); 492 } 493 494 void hdd_conn_set_connection_state(struct hdd_adapter *adapter, 495 eConnectionState conn_state) 496 { 497 struct hdd_station_ctx *hdd_sta_ctx = 498 WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink); 499 500 /* save the new connection state */ 501 if (conn_state == hdd_sta_ctx->conn_info.conn_state) 502 return; 503 504 hdd_nofl_debug("connection state changed %d --> %d for dev %s (vdev %d)", 505 hdd_sta_ctx->conn_info.conn_state, conn_state, 506 adapter->dev->name, adapter->deflink->vdev_id); 507 508 hdd_sta_ctx->conn_info.conn_state = conn_state; 509 } 510 511 enum band_info hdd_conn_get_connected_band(struct wlan_hdd_link_info *link_info) 512 { 513 struct hdd_station_ctx *sta_ctx; 514 uint32_t sta_freq = 0; 515 516 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 517 if (hdd_cm_is_vdev_associated(link_info)) 518 sta_freq = sta_ctx->conn_info.chan_freq; 519 520 if (wlan_reg_is_24ghz_ch_freq(sta_freq)) 521 return BAND_2G; 522 else if (wlan_reg_is_5ghz_ch_freq(sta_freq) || 523 wlan_reg_is_6ghz_chan_freq(sta_freq)) 524 return BAND_5G; 525 else /* If station is not connected return as BAND_ALL */ 526 return BAND_ALL; 527 } 528 529 /** 530 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type 531 * @link_info: Link info pointer in HDD adapter. 532 * @sta_ctx: pointer to global HDD Station context 533 * @pConnectedCipherAlgo: pointer to connected cipher algo 534 * 535 * Return: false if any errors encountered, true otherwise 536 */ 537 static inline bool 538 hdd_conn_get_connected_cipher_algo(struct wlan_hdd_link_info *link_info, 539 struct hdd_station_ctx *sta_ctx, 540 eCsrEncryptionType *pConnectedCipherAlgo) 541 { 542 bool connected; 543 544 connected = hdd_cm_is_vdev_associated(link_info); 545 if (pConnectedCipherAlgo) 546 *pConnectedCipherAlgo = sta_ctx->conn_info.uc_encrypt_type; 547 548 return connected; 549 } 550 551 struct wlan_hdd_link_info * 552 hdd_get_sta_connection_in_progress(struct hdd_context *hdd_ctx) 553 { 554 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 555 wlan_net_dev_ref_dbgid dbgid = 556 NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS; 557 struct wlan_hdd_link_info *link_info; 558 559 if (!hdd_ctx) { 560 hdd_err("HDD context is NULL"); 561 return NULL; 562 } 563 564 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 565 dbgid) { 566 if ((QDF_STA_MODE == adapter->device_mode) || 567 (QDF_P2P_CLIENT_MODE == adapter->device_mode) || 568 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) { 569 hdd_adapter_for_each_active_link_info(adapter, 570 link_info) { 571 if (!hdd_cm_is_connecting(link_info)) 572 continue; 573 574 hdd_debug("vdev_id %d: Connection is in progress", 575 link_info->vdev_id); 576 hdd_adapter_dev_put_debug(adapter, dbgid); 577 if (next_adapter) 578 hdd_adapter_dev_put_debug(next_adapter, 579 dbgid); 580 return link_info; 581 } 582 } 583 hdd_adapter_dev_put_debug(adapter, dbgid); 584 } 585 return NULL; 586 } 587 588 void hdd_abort_ongoing_sta_connection(struct hdd_context *hdd_ctx) 589 { 590 struct wlan_hdd_link_info *link_info; 591 592 link_info = hdd_get_sta_connection_in_progress(hdd_ctx); 593 if (link_info && 594 !wlan_vdev_mlme_is_mlo_link_switch_in_progress(link_info->vdev)) 595 wlan_hdd_cm_issue_disconnect(link_info, 596 REASON_UNSPEC_FAILURE, false); 597 } 598 599 void hdd_abort_ongoing_sta_sae_connection(struct hdd_context *hdd_ctx) 600 { 601 struct wlan_hdd_link_info *link_info; 602 struct wlan_objmgr_vdev *vdev; 603 int32_t key_mgmt; 604 605 link_info = hdd_get_sta_connection_in_progress(hdd_ctx); 606 if (!link_info || 607 wlan_vdev_mlme_is_mlo_link_switch_in_progress(link_info->vdev)) 608 return; 609 610 vdev = hdd_objmgr_get_vdev_by_user(link_info->adapter->deflink, 611 WLAN_OSIF_ID); 612 if (!vdev) 613 return; 614 615 key_mgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); 616 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 617 618 if (key_mgmt < 0) { 619 hdd_debug_rl("Invalid key_mgmt: %d", key_mgmt); 620 return; 621 } 622 623 if (QDF_HAS_PARAM(key_mgmt, WLAN_CRYPTO_KEY_MGMT_SAE) || 624 QDF_HAS_PARAM(key_mgmt, WLAN_CRYPTO_KEY_MGMT_FT_SAE) || 625 QDF_HAS_PARAM(key_mgmt, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY) || 626 QDF_HAS_PARAM(key_mgmt, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY)) 627 wlan_hdd_cm_issue_disconnect(link_info->adapter->deflink, 628 REASON_DISASSOC_NETWORK_LEAVING, 629 false); 630 } 631 632 QDF_STATUS hdd_get_first_connected_sta_vdev_id(struct hdd_context *hdd_ctx, 633 uint32_t *vdev_id) 634 { 635 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 636 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_STA_CONNECTED; 637 struct wlan_hdd_link_info *link_info; 638 639 if (!hdd_ctx) { 640 hdd_err("HDD context is NULL"); 641 return QDF_STATUS_E_INVAL; 642 } 643 644 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 645 dbgid) { 646 if (adapter->device_mode == QDF_STA_MODE || 647 adapter->device_mode == QDF_P2P_CLIENT_MODE) { 648 hdd_adapter_for_each_active_link_info(adapter, 649 link_info) { 650 if (!hdd_cm_is_vdev_connected(link_info)) 651 continue; 652 653 *vdev_id = link_info->vdev_id; 654 hdd_adapter_dev_put_debug(adapter, dbgid); 655 if (next_adapter) 656 hdd_adapter_dev_put_debug(next_adapter, 657 dbgid); 658 return QDF_STATUS_SUCCESS; 659 } 660 } 661 hdd_adapter_dev_put_debug(adapter, dbgid); 662 } 663 return QDF_STATUS_E_FAILURE; 664 } 665 666 bool hdd_is_any_sta_connected(struct hdd_context *hdd_ctx) 667 { 668 QDF_STATUS status; 669 uint32_t vdev_id; 670 671 status = hdd_get_first_connected_sta_vdev_id(hdd_ctx, &vdev_id); 672 return QDF_IS_STATUS_ERROR(status) ? false : true; 673 } 674 675 /** 676 * hdd_remove_beacon_filter() - remove beacon filter 677 * @adapter: Pointer to the hdd adapter 678 * 679 * Return: 0 on success and errno on failure 680 */ 681 int hdd_remove_beacon_filter(struct hdd_adapter *adapter) 682 { 683 QDF_STATUS status; 684 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 685 686 status = sme_remove_beacon_filter(hdd_ctx->mac_handle, 687 adapter->deflink->vdev_id); 688 if (!QDF_IS_STATUS_SUCCESS(status)) { 689 hdd_err("sme_remove_beacon_filter() failed"); 690 return -EFAULT; 691 } 692 693 return 0; 694 } 695 696 int hdd_add_beacon_filter(struct hdd_adapter *adapter) 697 { 698 int i; 699 uint32_t ie_map[SIR_BCN_FLT_MAX_ELEMS_IE_LIST] = {0}; 700 QDF_STATUS status; 701 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 702 703 for (i = 0; i < ARRAY_SIZE(beacon_filter_table); i++) 704 qdf_set_bit(beacon_filter_table[i], 705 (unsigned long *)ie_map); 706 707 for (i = 0; i < ARRAY_SIZE(beacon_filter_extn_table); i++) 708 qdf_set_bit(beacon_filter_extn_table[i] + WLAN_ELEMID_EXTN_ELEM, 709 (unsigned long *)ie_map); 710 711 status = sme_add_beacon_filter(hdd_ctx->mac_handle, 712 adapter->deflink->vdev_id, ie_map); 713 if (!QDF_IS_STATUS_SUCCESS(status)) { 714 hdd_err("sme_add_beacon_filter() failed"); 715 return -EFAULT; 716 } 717 return 0; 718 } 719 720 void hdd_copy_ht_caps(struct ieee80211_ht_cap *hdd_ht_cap, 721 tDot11fIEHTCaps *roam_ht_cap) 722 723 { 724 uint32_t i, temp_ht_cap; 725 726 qdf_mem_zero(hdd_ht_cap, sizeof(struct ieee80211_ht_cap)); 727 728 if (roam_ht_cap->advCodingCap) 729 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LDPC_CODING; 730 if (roam_ht_cap->supportedChannelWidthSet) 731 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 732 temp_ht_cap = roam_ht_cap->mimoPowerSave & 733 (IEEE80211_HT_CAP_SM_PS >> IEEE80211_HT_CAP_SM_PS_SHIFT); 734 if (temp_ht_cap) 735 hdd_ht_cap->cap_info |= 736 temp_ht_cap << IEEE80211_HT_CAP_SM_PS_SHIFT; 737 if (roam_ht_cap->greenField) 738 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_GRN_FLD; 739 if (roam_ht_cap->shortGI20MHz) 740 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_20; 741 if (roam_ht_cap->shortGI40MHz) 742 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_40; 743 if (roam_ht_cap->txSTBC) 744 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_TX_STBC; 745 temp_ht_cap = roam_ht_cap->rxSTBC & (IEEE80211_HT_CAP_RX_STBC >> 746 IEEE80211_HT_CAP_RX_STBC_SHIFT); 747 if (temp_ht_cap) 748 hdd_ht_cap->cap_info |= 749 temp_ht_cap << IEEE80211_HT_CAP_RX_STBC_SHIFT; 750 if (roam_ht_cap->delayedBA) 751 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DELAY_BA; 752 if (roam_ht_cap->maximalAMSDUsize) 753 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_MAX_AMSDU; 754 if (roam_ht_cap->dsssCckMode40MHz) 755 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DSSSCCK40; 756 if (roam_ht_cap->psmp) 757 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_RESERVED; 758 if (roam_ht_cap->stbcControlFrame) 759 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_40MHZ_INTOLERANT; 760 if (roam_ht_cap->lsigTXOPProtection) 761 hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LSIG_TXOP_PROT; 762 763 /* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ 764 if (roam_ht_cap->maxRxAMPDUFactor) 765 hdd_ht_cap->ampdu_params_info |= 766 IEEE80211_HT_AMPDU_PARM_FACTOR; 767 temp_ht_cap = roam_ht_cap->mpduDensity & 768 (IEEE80211_HT_AMPDU_PARM_DENSITY >> 769 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); 770 if (temp_ht_cap) 771 hdd_ht_cap->ampdu_params_info |= 772 temp_ht_cap << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT; 773 774 /* 802.11n HT extended capabilities masks */ 775 if (roam_ht_cap->pco) 776 hdd_ht_cap->extended_ht_cap_info |= 777 IEEE80211_HT_EXT_CAP_PCO; 778 temp_ht_cap = roam_ht_cap->transitionTime & 779 (IEEE80211_HT_EXT_CAP_PCO_TIME >> 780 IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT); 781 if (temp_ht_cap) 782 hdd_ht_cap->extended_ht_cap_info |= 783 temp_ht_cap << IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT; 784 temp_ht_cap = roam_ht_cap->mcsFeedback & 785 (IEEE80211_HT_EXT_CAP_MCS_FB >> IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT); 786 if (temp_ht_cap) 787 hdd_ht_cap->extended_ht_cap_info |= 788 temp_ht_cap << IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT; 789 790 /* tx_bf_cap_info capabilities */ 791 if (roam_ht_cap->txBF) 792 hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_BF; 793 if (roam_ht_cap->rxStaggeredSounding) 794 hdd_ht_cap->tx_BF_cap_info |= 795 TX_BF_CAP_INFO_RX_STAG_RED_SOUNDING; 796 if (roam_ht_cap->txStaggeredSounding) 797 hdd_ht_cap->tx_BF_cap_info |= 798 TX_BF_CAP_INFO_TX_STAG_RED_SOUNDING; 799 if (roam_ht_cap->rxZLF) 800 hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_RX_ZFL; 801 if (roam_ht_cap->txZLF) 802 hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_ZFL; 803 if (roam_ht_cap->implicitTxBF) 804 hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_IMP_TX_BF; 805 temp_ht_cap = roam_ht_cap->calibration & 806 (TX_BF_CAP_INFO_CALIBRATION >> TX_BF_CAP_INFO_CALIBRATION_SHIFT); 807 if (temp_ht_cap) 808 hdd_ht_cap->tx_BF_cap_info |= 809 temp_ht_cap << TX_BF_CAP_INFO_CALIBRATION_SHIFT; 810 if (roam_ht_cap->explicitCSITxBF) 811 hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_EXP_CSIT_BF; 812 if (roam_ht_cap->explicitUncompressedSteeringMatrix) 813 hdd_ht_cap->tx_BF_cap_info |= 814 TX_BF_CAP_INFO_EXP_UNCOMP_STEER_MAT; 815 temp_ht_cap = roam_ht_cap->explicitBFCSIFeedback & 816 (TX_BF_CAP_INFO_EXP_BF_CSI_FB >> 817 TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT); 818 if (temp_ht_cap) 819 hdd_ht_cap->tx_BF_cap_info |= 820 temp_ht_cap << TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT; 821 temp_ht_cap = 822 roam_ht_cap->explicitUncompressedSteeringMatrixFeedback & 823 (TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT >> 824 TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT); 825 if (temp_ht_cap) 826 hdd_ht_cap->tx_BF_cap_info |= 827 temp_ht_cap << 828 TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT; 829 temp_ht_cap = 830 roam_ht_cap->explicitCompressedSteeringMatrixFeedback & 831 (TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB >> 832 TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT); 833 if (temp_ht_cap) 834 hdd_ht_cap->tx_BF_cap_info |= 835 temp_ht_cap << 836 TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT; 837 temp_ht_cap = roam_ht_cap->csiNumBFAntennae & 838 (TX_BF_CAP_INFO_CSI_NUM_BF_ANT >> 839 TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT); 840 if (temp_ht_cap) 841 hdd_ht_cap->tx_BF_cap_info |= 842 temp_ht_cap << TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT; 843 temp_ht_cap = roam_ht_cap->uncompressedSteeringMatrixBFAntennae & 844 (TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT >> 845 TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT); 846 if (temp_ht_cap) 847 hdd_ht_cap->tx_BF_cap_info |= 848 temp_ht_cap << 849 TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT; 850 temp_ht_cap = roam_ht_cap->compressedSteeringMatrixBFAntennae & 851 (TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT >> 852 TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT); 853 if (temp_ht_cap) 854 hdd_ht_cap->tx_BF_cap_info |= 855 temp_ht_cap << 856 TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT; 857 858 /* antenna selection */ 859 if (roam_ht_cap->antennaSelection) 860 hdd_ht_cap->antenna_selection_info |= ANTENNA_SEL_INFO; 861 if (roam_ht_cap->explicitCSIFeedbackTx) 862 hdd_ht_cap->antenna_selection_info |= 863 ANTENNA_SEL_INFO_EXP_CSI_FB_TX; 864 if (roam_ht_cap->antennaIndicesFeedbackTx) 865 hdd_ht_cap->antenna_selection_info |= 866 ANTENNA_SEL_INFO_ANT_ID_FB_TX; 867 if (roam_ht_cap->explicitCSIFeedback) 868 hdd_ht_cap->antenna_selection_info |= 869 ANTENNA_SEL_INFO_EXP_CSI_FB; 870 if (roam_ht_cap->antennaIndicesFeedback) 871 hdd_ht_cap->antenna_selection_info |= 872 ANTENNA_SEL_INFO_ANT_ID_FB; 873 if (roam_ht_cap->rxAS) 874 hdd_ht_cap->antenna_selection_info |= 875 ANTENNA_SEL_INFO_RX_AS; 876 if (roam_ht_cap->txSoundingPPDUs) 877 hdd_ht_cap->antenna_selection_info |= 878 ANTENNA_SEL_INFO_TX_SOUNDING_PPDU; 879 880 /* mcs data rate */ 881 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; ++i) 882 hdd_ht_cap->mcs.rx_mask[i] = 883 roam_ht_cap->supportedMCSSet[i]; 884 hdd_ht_cap->mcs.rx_highest = 885 ((short) (roam_ht_cap->supportedMCSSet[11]) << 8) | 886 ((short) (roam_ht_cap->supportedMCSSet[10])); 887 hdd_ht_cap->mcs.tx_params = 888 roam_ht_cap->supportedMCSSet[12]; 889 } 890 891 #define VHT_CAP_MAX_MPDU_LENGTH_MASK 0x00000003 892 #define VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT 2 893 #define VHT_CAP_RXSTBC_MASK_SHIFT 8 894 #define VHT_CAP_BEAMFORMEE_STS_SHIFT 13 895 #define VHT_CAP_BEAMFORMEE_STS_MASK \ 896 (0x0000e000 >> VHT_CAP_BEAMFORMEE_STS_SHIFT) 897 #define VHT_CAP_SOUNDING_DIMENSIONS_SHIFT 16 898 #define VHT_CAP_SOUNDING_DIMENSIONS_MASK \ 899 (0x00070000 >> VHT_CAP_SOUNDING_DIMENSIONS_SHIFT) 900 #define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT 23 901 #define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \ 902 (0x03800000 >> VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT) 903 #define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT 26 904 905 void hdd_copy_vht_caps(struct ieee80211_vht_cap *hdd_vht_cap, 906 tDot11fIEVHTCaps *roam_vht_cap) 907 { 908 uint32_t temp_vht_cap; 909 910 qdf_mem_zero(hdd_vht_cap, sizeof(struct ieee80211_vht_cap)); 911 912 temp_vht_cap = roam_vht_cap->maxMPDULen & VHT_CAP_MAX_MPDU_LENGTH_MASK; 913 hdd_vht_cap->vht_cap_info |= temp_vht_cap; 914 temp_vht_cap = roam_vht_cap->supportedChannelWidthSet & 915 (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK >> 916 VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT); 917 if (temp_vht_cap) { 918 if (roam_vht_cap->supportedChannelWidthSet & 919 (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ >> 920 VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT)) 921 hdd_vht_cap->vht_cap_info |= 922 temp_vht_cap << 923 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; 924 if (roam_vht_cap->supportedChannelWidthSet & 925 (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ >> 926 VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT)) 927 hdd_vht_cap->vht_cap_info |= 928 temp_vht_cap << 929 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; 930 } 931 if (roam_vht_cap->ldpcCodingCap) 932 hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_RXLDPC; 933 if (roam_vht_cap->shortGI80MHz) 934 hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_80; 935 if (roam_vht_cap->shortGI160and80plus80MHz) 936 hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_160; 937 if (roam_vht_cap->txSTBC) 938 hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_TXSTBC; 939 temp_vht_cap = roam_vht_cap->rxSTBC & (IEEE80211_VHT_CAP_RXSTBC_MASK >> 940 VHT_CAP_RXSTBC_MASK_SHIFT); 941 if (temp_vht_cap) 942 hdd_vht_cap->vht_cap_info |= 943 temp_vht_cap << VHT_CAP_RXSTBC_MASK_SHIFT; 944 if (roam_vht_cap->suBeamFormerCap) 945 hdd_vht_cap->vht_cap_info |= 946 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; 947 if (roam_vht_cap->suBeamformeeCap) 948 hdd_vht_cap->vht_cap_info |= 949 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; 950 temp_vht_cap = roam_vht_cap->csnofBeamformerAntSup & 951 (VHT_CAP_BEAMFORMEE_STS_MASK); 952 if (temp_vht_cap) 953 hdd_vht_cap->vht_cap_info |= 954 temp_vht_cap << VHT_CAP_BEAMFORMEE_STS_SHIFT; 955 temp_vht_cap = roam_vht_cap->numSoundingDim & 956 (VHT_CAP_SOUNDING_DIMENSIONS_MASK); 957 if (temp_vht_cap) 958 hdd_vht_cap->vht_cap_info |= 959 temp_vht_cap << VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; 960 if (roam_vht_cap->muBeamformerCap) 961 hdd_vht_cap->vht_cap_info |= 962 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; 963 if (roam_vht_cap->muBeamformeeCap) 964 hdd_vht_cap->vht_cap_info |= 965 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; 966 if (roam_vht_cap->vhtTXOPPS) 967 hdd_vht_cap->vht_cap_info |= 968 IEEE80211_VHT_CAP_VHT_TXOP_PS; 969 if (roam_vht_cap->htcVHTCap) 970 hdd_vht_cap->vht_cap_info |= 971 IEEE80211_VHT_CAP_HTC_VHT; 972 temp_vht_cap = roam_vht_cap->maxAMPDULenExp & 973 (VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK); 974 if (temp_vht_cap) 975 hdd_vht_cap->vht_cap_info |= 976 temp_vht_cap << 977 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT; 978 temp_vht_cap = roam_vht_cap->vhtLinkAdaptCap & 979 (IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB >> 980 VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT); 981 if (temp_vht_cap) 982 hdd_vht_cap->vht_cap_info |= temp_vht_cap << 983 VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT; 984 if (roam_vht_cap->rxAntPattern) 985 hdd_vht_cap->vht_cap_info |= 986 IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN; 987 if (roam_vht_cap->txAntPattern) 988 hdd_vht_cap->vht_cap_info |= 989 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; 990 hdd_vht_cap->supp_mcs.rx_mcs_map = roam_vht_cap->rxMCSMap; 991 hdd_vht_cap->supp_mcs.rx_highest = 992 ((uint16_t)roam_vht_cap->rxHighSupDataRate); 993 hdd_vht_cap->supp_mcs.tx_mcs_map = roam_vht_cap->txMCSMap; 994 hdd_vht_cap->supp_mcs.tx_highest = 995 ((uint16_t)roam_vht_cap->txSupDataRate); 996 } 997 998 /* ht param */ 999 #define HT_PARAM_CONTROLLED_ACCESS_ONLY 0x10 1000 #define HT_PARAM_SERVICE_INT_GRAN 0xe0 1001 #define HT_PARAM_SERVICE_INT_GRAN_SHIFT 5 1002 1003 /* operatinon mode */ 1004 #define HT_OP_MODE_TX_BURST_LIMIT 0x0008 1005 1006 /* stbc_param */ 1007 #define HT_STBC_PARAM_MCS 0x007f 1008 1009 void hdd_copy_ht_operation(struct hdd_station_ctx *hdd_sta_ctx, 1010 tDot11fIEHTInfo *ht_ops) 1011 { 1012 struct ieee80211_ht_operation *hdd_ht_ops = 1013 &hdd_sta_ctx->conn_info.ht_operation; 1014 uint32_t i, temp_ht_ops; 1015 1016 qdf_mem_zero(hdd_ht_ops, sizeof(struct ieee80211_ht_operation)); 1017 1018 hdd_ht_ops->primary_chan = ht_ops->primaryChannel; 1019 1020 /* HT_PARAMS */ 1021 temp_ht_ops = ht_ops->secondaryChannelOffset & 1022 IEEE80211_HT_PARAM_CHA_SEC_OFFSET; 1023 if (temp_ht_ops) 1024 hdd_ht_ops->ht_param |= temp_ht_ops; 1025 else 1026 hdd_ht_ops->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; 1027 if (ht_ops->recommendedTxWidthSet) 1028 hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; 1029 if (ht_ops->rifsMode) 1030 hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_RIFS_MODE; 1031 if (ht_ops->controlledAccessOnly) 1032 hdd_ht_ops->ht_param |= HT_PARAM_CONTROLLED_ACCESS_ONLY; 1033 temp_ht_ops = ht_ops->serviceIntervalGranularity & 1034 (HT_PARAM_SERVICE_INT_GRAN >> HT_PARAM_SERVICE_INT_GRAN_SHIFT); 1035 if (temp_ht_ops) 1036 hdd_ht_ops->ht_param |= temp_ht_ops << 1037 HT_PARAM_SERVICE_INT_GRAN_SHIFT; 1038 1039 /* operation mode */ 1040 temp_ht_ops = ht_ops->opMode & 1041 IEEE80211_HT_OP_MODE_PROTECTION; 1042 switch (temp_ht_ops) { 1043 case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER: 1044 hdd_ht_ops->operation_mode |= 1045 IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER; 1046 break; 1047 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: 1048 hdd_ht_ops->operation_mode |= 1049 IEEE80211_HT_OP_MODE_PROTECTION_20MHZ; 1050 break; 1051 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED: 1052 hdd_ht_ops->operation_mode |= 1053 IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED; 1054 break; 1055 case IEEE80211_HT_OP_MODE_PROTECTION_NONE: 1056 default: 1057 hdd_ht_ops->operation_mode |= 1058 IEEE80211_HT_OP_MODE_PROTECTION_NONE; 1059 } 1060 if (ht_ops->nonGFDevicesPresent) 1061 hdd_ht_ops->operation_mode |= 1062 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT; 1063 if (ht_ops->transmitBurstLimit) 1064 hdd_ht_ops->operation_mode |= 1065 HT_OP_MODE_TX_BURST_LIMIT; 1066 if (ht_ops->obssNonHTStaPresent) 1067 hdd_ht_ops->operation_mode |= 1068 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT; 1069 1070 if (ht_ops->chan_center_freq_seg2) 1071 hdd_ht_ops->operation_mode |= 1072 (ht_ops->chan_center_freq_seg2 << IEEE80211_HT_OP_MODE_CCFS2_SHIFT); 1073 /* stbc_param */ 1074 temp_ht_ops = ht_ops->basicSTBCMCS & 1075 HT_STBC_PARAM_MCS; 1076 if (temp_ht_ops) 1077 hdd_ht_ops->stbc_param |= temp_ht_ops; 1078 if (ht_ops->dualCTSProtection) 1079 hdd_ht_ops->stbc_param |= 1080 IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT; 1081 if (ht_ops->secondaryBeacon) 1082 hdd_ht_ops->stbc_param |= 1083 IEEE80211_HT_STBC_PARAM_STBC_BEACON; 1084 if (ht_ops->lsigTXOPProtectionFullSupport) 1085 hdd_ht_ops->stbc_param |= 1086 IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT; 1087 if (ht_ops->pcoActive) 1088 hdd_ht_ops->stbc_param |= 1089 IEEE80211_HT_STBC_PARAM_PCO_ACTIVE; 1090 if (ht_ops->pcoPhase) 1091 hdd_ht_ops->stbc_param |= 1092 IEEE80211_HT_STBC_PARAM_PCO_PHASE; 1093 1094 /* basic MCs set */ 1095 for (i = 0; i < 16; ++i) 1096 hdd_ht_ops->basic_set[i] = 1097 ht_ops->basicMCSSet[i]; 1098 } 1099 1100 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) 1101 static void hdd_copy_vht_center_freq(struct ieee80211_vht_operation *ieee_ops, 1102 tDot11fIEVHTOperation *roam_ops) 1103 { 1104 ieee_ops->center_freq_seg0_idx = roam_ops->chan_center_freq_seg0; 1105 ieee_ops->center_freq_seg1_idx = roam_ops->chan_center_freq_seg1; 1106 } 1107 #else 1108 static void hdd_copy_vht_center_freq(struct ieee80211_vht_operation *ieee_ops, 1109 tDot11fIEVHTOperation *roam_ops) 1110 { 1111 ieee_ops->center_freq_seg1_idx = roam_ops->chan_center_freq_seg0; 1112 ieee_ops->center_freq_seg2_idx = roam_ops->chan_center_freq_seg1; 1113 } 1114 #endif /* KERNEL_VERSION(4, 12, 0) */ 1115 1116 void hdd_copy_vht_operation(struct hdd_station_ctx *hdd_sta_ctx, 1117 tDot11fIEVHTOperation *vht_ops) 1118 { 1119 struct ieee80211_vht_operation *hdd_vht_ops = 1120 &hdd_sta_ctx->conn_info.vht_operation; 1121 1122 qdf_mem_zero(hdd_vht_ops, sizeof(struct ieee80211_vht_operation)); 1123 1124 hdd_vht_ops->chan_width = vht_ops->chanWidth; 1125 hdd_copy_vht_center_freq(hdd_vht_ops, vht_ops); 1126 hdd_vht_ops->basic_mcs_set = vht_ops->basicMCSSet; 1127 } 1128 1129 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0)) && \ 1130 defined(WLAN_FEATURE_11BE) 1131 void hdd_copy_eht_operation(struct hdd_station_ctx *hdd_sta_ctx, 1132 tDot11fIEeht_op *eht_ops) 1133 { 1134 struct ieee80211_eht_operation *hdd_eht_ops = 1135 &hdd_sta_ctx->conn_info.eht_operation; 1136 struct ieee80211_eht_mcs_nss_supp_20mhz_only mcs_param; 1137 uint32_t filled = 0, len = 0; 1138 1139 qdf_mem_zero(hdd_eht_ops, sizeof(struct ieee80211_eht_operation)); 1140 1141 if (!eht_ops->eht_op_information_present) 1142 return; 1143 1144 /* Min length if op_info_present */ 1145 len += 3; 1146 1147 hdd_eht_ops->params |= IEEE80211_EHT_OPER_INFO_PRESENT; 1148 1149 if (eht_ops->eht_default_pe_duration) 1150 hdd_eht_ops->params |= 1151 IEEE80211_EHT_OPER_EHT_DEF_PE_DURATION; 1152 if (eht_ops->group_addr_bu_indication_limit) 1153 hdd_eht_ops->params |= 1154 IEEE80211_EHT_OPER_GROUP_ADDRESSED_BU_IND_LIMIT; 1155 if (eht_ops->group_addr_bu_indication_exponent) 1156 hdd_eht_ops->params |= 1157 IEEE80211_EHT_OPER_GROUP_ADDRESSED_BU_IND_EXP_MASK; 1158 1159 mcs_param.rx_tx_mcs7_max_nss = 1160 eht_ops->basic_rx_max_nss_for_mcs_0_to_7 << 1161 EHT_OPER_BASIC_RX_NSS_MCS_0_TO_7_POS; 1162 mcs_param.rx_tx_mcs7_max_nss |= 1163 eht_ops->basic_tx_max_nss_for_mcs_0_to_7 << 1164 EHT_OPER_BASIC_TX_NSS_MCS_0_TO_7_POS; 1165 mcs_param.rx_tx_mcs9_max_nss = 1166 eht_ops->basic_rx_max_nss_for_mcs_8_and_9 << 1167 EHT_OPER_BASIC_RX_NSS_MCS_8_AND_9_POS; 1168 mcs_param.rx_tx_mcs9_max_nss |= 1169 eht_ops->basic_tx_max_nss_for_mcs_8_and_9 << 1170 EHT_OPER_BASIC_TX_NSS_MCS_8_AND_9_POS; 1171 mcs_param.rx_tx_mcs11_max_nss = 1172 eht_ops->basic_rx_max_nss_for_mcs_10_and_11 << 1173 EHT_OPER_BASIC_RX_NSS_MCS_10_AND_11_POS; 1174 mcs_param.rx_tx_mcs11_max_nss |= 1175 eht_ops->basic_tx_max_nss_for_mcs_10_and_11 << 1176 EHT_OPER_BASIC_TX_NSS_MCS_10_AND_11_POS; 1177 mcs_param.rx_tx_mcs13_max_nss = 1178 eht_ops->basic_rx_max_nss_for_mcs_12_and_13 << 1179 EHT_OPER_BASIC_RX_NSS_MCS_12_AND_13_POS; 1180 mcs_param.rx_tx_mcs13_max_nss |= 1181 eht_ops->basic_tx_max_nss_for_mcs_12_and_13 << 1182 EHT_OPER_BASIC_TX_NSS_MCS_12_AND_13_POS; 1183 1184 hdd_eht_ops->basic_mcs_nss = mcs_param; 1185 hdd_eht_ops->optional[filled++] = eht_ops->channel_width; 1186 hdd_eht_ops->optional[filled++] = eht_ops->ccfs0; 1187 hdd_eht_ops->optional[filled++] = eht_ops->ccfs1; 1188 1189 if (eht_ops->disabled_sub_chan_bitmap_present) { 1190 hdd_eht_ops->params |= 1191 IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT; 1192 len += 2; 1193 hdd_eht_ops->optional[filled++] = 1194 eht_ops->disabled_sub_chan_bitmap[0][0]; 1195 hdd_eht_ops->optional[filled++] = 1196 eht_ops->disabled_sub_chan_bitmap[0][1]; 1197 } 1198 hdd_sta_ctx->conn_info.eht_oper_len = 1199 sizeof(struct ieee80211_eht_operation) + len; 1200 } 1201 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) && \ 1202 defined(WLAN_FEATURE_11BE) 1203 void hdd_copy_eht_operation(struct hdd_station_ctx *hdd_sta_ctx, 1204 tDot11fIEeht_op *eht_ops) 1205 { 1206 struct ieee80211_eht_operation *hdd_eht_ops = 1207 &hdd_sta_ctx->conn_info.eht_operation; 1208 uint32_t mcs_param = 0, filled = 0, len = 0; 1209 1210 qdf_mem_zero(hdd_eht_ops, sizeof(struct ieee80211_eht_operation)); 1211 1212 if (!eht_ops->eht_op_information_present) 1213 return; 1214 1215 /* Min length if op_info_present */ 1216 len += 3; 1217 1218 hdd_eht_ops->params |= IEEE80211_EHT_OPER_INFO_PRESENT; 1219 1220 if (eht_ops->eht_default_pe_duration) 1221 hdd_eht_ops->params |= 1222 IEEE80211_EHT_OPER_EHT_DEF_PE_DURATION; 1223 if (eht_ops->group_addr_bu_indication_limit) 1224 hdd_eht_ops->params |= 1225 IEEE80211_EHT_OPER_GROUP_ADDRESSED_BU_IND_LIMIT; 1226 if (eht_ops->group_addr_bu_indication_exponent) 1227 hdd_eht_ops->params |= 1228 IEEE80211_EHT_OPER_GROUP_ADDRESSED_BU_IND_EXP_MASK; 1229 1230 mcs_param |= eht_ops->basic_rx_max_nss_for_mcs_0_to_7 << 1231 EHT_OPER_BASIC_RX_NSS_MCS_0_TO_7_POS; 1232 mcs_param |= eht_ops->basic_tx_max_nss_for_mcs_0_to_7 << 1233 EHT_OPER_BASIC_TX_NSS_MCS_0_TO_7_POS; 1234 mcs_param |= eht_ops->basic_rx_max_nss_for_mcs_8_and_9 << 1235 EHT_OPER_BASIC_RX_NSS_MCS_8_AND_9_POS; 1236 mcs_param |= eht_ops->basic_tx_max_nss_for_mcs_8_and_9 << 1237 EHT_OPER_BASIC_TX_NSS_MCS_8_AND_9_POS; 1238 mcs_param |= eht_ops->basic_rx_max_nss_for_mcs_10_and_11 << 1239 EHT_OPER_BASIC_RX_NSS_MCS_10_AND_11_POS; 1240 mcs_param |= eht_ops->basic_tx_max_nss_for_mcs_10_and_11 << 1241 EHT_OPER_BASIC_TX_NSS_MCS_10_AND_11_POS; 1242 mcs_param |= eht_ops->basic_rx_max_nss_for_mcs_12_and_13 << 1243 EHT_OPER_BASIC_RX_NSS_MCS_12_AND_13_POS; 1244 mcs_param |= eht_ops->basic_tx_max_nss_for_mcs_12_and_13 << 1245 EHT_OPER_BASIC_TX_NSS_MCS_12_AND_13_POS; 1246 1247 hdd_eht_ops->basic_mcs_nss = mcs_param; 1248 hdd_eht_ops->optional[filled++] = eht_ops->channel_width; 1249 hdd_eht_ops->optional[filled++] = eht_ops->ccfs0; 1250 hdd_eht_ops->optional[filled++] = eht_ops->ccfs1; 1251 1252 if (eht_ops->disabled_sub_chan_bitmap_present) { 1253 hdd_eht_ops->params |= 1254 IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT; 1255 len += 2; 1256 hdd_eht_ops->optional[filled++] = 1257 eht_ops->disabled_sub_chan_bitmap[0][0]; 1258 hdd_eht_ops->optional[filled++] = 1259 eht_ops->disabled_sub_chan_bitmap[0][1]; 1260 } 1261 hdd_sta_ctx->conn_info.eht_oper_len = 1262 sizeof(struct ieee80211_eht_operation) + len; 1263 } 1264 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)) && \ 1265 defined(WLAN_FEATURE_11BE) 1266 void hdd_copy_eht_operation(struct hdd_station_ctx *hdd_sta_ctx, 1267 tDot11fIEeht_op *eht_ops) 1268 { 1269 struct ieee80211_eht_operation *hdd_eht_ops = 1270 &hdd_sta_ctx->conn_info.eht_operation; 1271 uint32_t filled = 0, len = 0; 1272 1273 qdf_mem_zero(hdd_eht_ops, sizeof(struct ieee80211_eht_operation)); 1274 1275 if (!eht_ops->eht_op_information_present) 1276 return; 1277 1278 hdd_eht_ops->chan_width = eht_ops->channel_width; 1279 hdd_eht_ops->ccfs = eht_ops->ccfs0; 1280 hdd_eht_ops->present_bm = eht_ops->disabled_sub_chan_bitmap_present; 1281 1282 if (eht_ops->disabled_sub_chan_bitmap_present) { 1283 hdd_eht_ops->disable_subchannel_bitmap[filled++] = 1284 eht_ops->disabled_sub_chan_bitmap[0][0]; 1285 hdd_eht_ops->disable_subchannel_bitmap[filled++] = 1286 eht_ops->disabled_sub_chan_bitmap[0][1]; 1287 len += 2; 1288 } 1289 hdd_sta_ctx->conn_info.eht_oper_len = 1290 sizeof(struct ieee80211_eht_operation) + len; 1291 } 1292 #endif 1293 1294 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \ 1295 defined(WLAN_FEATURE_11AX) 1296 void hdd_copy_he_operation(struct hdd_station_ctx *hdd_sta_ctx, 1297 tDot11fIEhe_op *he_operation) 1298 { 1299 struct ieee80211_he_operation *hdd_he_operation; 1300 uint32_t he_oper_params = 0; 1301 uint32_t len = 0, filled = 0; 1302 uint8_t he_oper_6g_params = 0; 1303 uint32_t he_oper_len; 1304 1305 if (!he_operation->present) 1306 return; 1307 if (he_operation->vht_oper_present) 1308 len += 3; 1309 if (he_operation->co_located_bss) 1310 len += 1; 1311 if (he_operation->oper_info_6g_present) 1312 len += 5; 1313 1314 he_oper_len = sizeof(struct ieee80211_he_operation) + len; 1315 1316 hdd_he_operation = qdf_mem_malloc(he_oper_len); 1317 if (!hdd_he_operation) 1318 return; 1319 1320 /* Fill he_oper_params */ 1321 he_oper_params |= he_operation->default_pe << 1322 HE_OPERATION_DFLT_PE_DURATION_POS; 1323 he_oper_params |= he_operation->twt_required << 1324 HE_OPERATION_TWT_REQUIRED_POS; 1325 he_oper_params |= he_operation->txop_rts_threshold << 1326 HE_OPERATION_RTS_THRESHOLD_POS; 1327 he_oper_params |= he_operation->vht_oper_present << 1328 HE_OPERATION_VHT_OPER_POS; 1329 he_oper_params |= he_operation->co_located_bss << 1330 HE_OPERATION_CO_LOCATED_BSS_POS; 1331 he_oper_params |= he_operation->er_su_disable << 1332 HE_OPERATION_ER_SU_DISABLE_POS; 1333 he_oper_params |= he_operation->oper_info_6g_present << 1334 HE_OPERATION_OPER_INFO_6G_POS; 1335 he_oper_params |= he_operation->reserved2 << 1336 HE_OPERATION_RESERVED_POS; 1337 he_oper_params |= he_operation->bss_color << 1338 HE_OPERATION_BSS_COLOR_POS; 1339 he_oper_params |= he_operation->partial_bss_col << 1340 HE_OPERATION_PARTIAL_BSS_COLOR_POS; 1341 he_oper_params |= he_operation->bss_col_disabled << 1342 HE_OPERATION_BSS_COL_DISABLED_POS; 1343 1344 hdd_he_operation->he_oper_params = he_oper_params; 1345 1346 /* Fill he_mcs_nss set */ 1347 qdf_mem_copy(&hdd_he_operation->he_mcs_nss_set, 1348 he_operation->basic_mcs_nss, 1349 sizeof(hdd_he_operation->he_mcs_nss_set)); 1350 1351 /* Fill he_params_optional fields */ 1352 1353 if (he_operation->vht_oper_present) { 1354 hdd_he_operation->optional[filled++] = 1355 he_operation->vht_oper.info.chan_width; 1356 hdd_he_operation->optional[filled++] = 1357 he_operation->vht_oper.info.center_freq_seg0; 1358 hdd_he_operation->optional[filled++] = 1359 he_operation->vht_oper.info.center_freq_seg1; 1360 } 1361 if (he_operation->co_located_bss) 1362 hdd_he_operation->optional[filled++] = 1363 he_operation->maxbssid_ind.info.data; 1364 1365 if (he_operation->oper_info_6g_present) { 1366 hdd_he_operation->optional[filled++] = 1367 he_operation->oper_info_6g.info.primary_ch; 1368 he_oper_6g_params |= 1369 he_operation->oper_info_6g.info.ch_width << 0; 1370 he_oper_6g_params |= 1371 he_operation->oper_info_6g.info.dup_bcon << 2; 1372 he_oper_6g_params |= 1373 he_operation->oper_info_6g.info.reserved << 3; 1374 1375 hdd_he_operation->optional[filled++] = he_oper_6g_params; 1376 hdd_he_operation->optional[filled++] = 1377 he_operation->oper_info_6g.info.center_freq_seg0; 1378 hdd_he_operation->optional[filled++] = 1379 he_operation->oper_info_6g.info.center_freq_seg1; 1380 hdd_he_operation->optional[filled] = 1381 he_operation->oper_info_6g.info.min_rate; 1382 } 1383 1384 if (hdd_sta_ctx->cache_conn_info.he_operation) { 1385 qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation); 1386 hdd_sta_ctx->cache_conn_info.he_operation = NULL; 1387 } 1388 1389 hdd_sta_ctx->cache_conn_info.he_oper_len = he_oper_len; 1390 1391 hdd_sta_ctx->cache_conn_info.he_operation = hdd_he_operation; 1392 } 1393 #endif 1394 1395 bool hdd_is_roam_sync_in_progress(struct hdd_context *hdd_ctx, uint8_t vdev_id) 1396 { 1397 return wlan_cm_is_roam_sync_in_progress(hdd_ctx->psoc, vdev_id); 1398 } 1399 1400 void hdd_conn_remove_connect_info(struct hdd_station_ctx *sta_ctx) 1401 { 1402 /* Remove bssid and peer_macaddr */ 1403 qdf_mem_zero(&sta_ctx->conn_info.bssid, QDF_MAC_ADDR_SIZE); 1404 qdf_mem_zero(&sta_ctx->conn_info.peer_macaddr[0], 1405 QDF_MAC_ADDR_SIZE); 1406 1407 /* Clear all security settings */ 1408 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM; 1409 sta_ctx->conn_info.uc_encrypt_type = eCSR_ENCRYPT_TYPE_NONE; 1410 1411 sta_ctx->conn_info.proxy_arp_service = 0; 1412 1413 qdf_mem_zero(&sta_ctx->conn_info.ssid, sizeof(tCsrSSIDInfo)); 1414 1415 /* 1416 * Reset the ptk, gtk status flags to avoid using current connection 1417 * status in further connections. 1418 */ 1419 sta_ctx->conn_info.gtk_installed = false; 1420 sta_ctx->conn_info.ptk_installed = false; 1421 } 1422 1423 void hdd_clear_roam_profile_ie(struct hdd_adapter *adapter) 1424 { 1425 hdd_enter(); 1426 1427 #ifdef FEATURE_WLAN_WAPI 1428 adapter->wapi_info.wapi_auth_mode = WAPI_AUTH_MODE_OPEN; 1429 adapter->wapi_info.wapi_mode = false; 1430 #endif 1431 1432 hdd_exit(); 1433 } 1434 1435 #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) 1436 static inline void hdd_set_unpause_queue(void *soc, uint8_t vdev_id) 1437 { 1438 cdp_fc_vdev_unpause(soc, vdev_id, 1439 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED, 0); 1440 } 1441 #else 1442 static inline void hdd_set_unpause_queue(void *soc, uint8_t vdev_id) 1443 { 1444 } 1445 #endif 1446 1447 #ifdef FEATURE_WDS 1448 /** 1449 * hdd_config_wds_repeater_mode() - configures vdev for wds repeater mode 1450 * @link_info: Link info pointer in HDD adapter 1451 * @peer_addr: peer mac address 1452 * 1453 * Configure dp vdev to detect and drop multicast echo packets and enable 1454 * 4 address frame format in fw. 1455 * 1456 * Return: None 1457 */ 1458 static void hdd_config_wds_repeater_mode(struct wlan_hdd_link_info *link_info, 1459 uint8_t *peer_addr) 1460 { 1461 cdp_config_param_type vdev_param; 1462 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 1463 1464 vdev_param.cdp_vdev_param_mec = true; 1465 if (cdp_txrx_set_vdev_param(soc, link_info->vdev_id, 1466 CDP_ENABLE_MEC, vdev_param)) 1467 hdd_debug("Failed to set MEC param on DP vdev"); 1468 1469 hdd_nofl_info("Turn on 4 address for peer: " QDF_MAC_ADDR_FMT, 1470 QDF_MAC_ADDR_REF(peer_addr)); 1471 if (sme_set_peer_param(peer_addr, WMI_HOST_PEER_USE_4ADDR, true, 1472 link_info->vdev_id)) 1473 hdd_err("Failed to enable WDS on vdev"); 1474 } 1475 #else 1476 static inline void 1477 hdd_config_wds_repeater_mode(struct wlan_hdd_link_info *link_info, 1478 uint8_t *peer_addr) 1479 { 1480 } 1481 #endif 1482 1483 QDF_STATUS hdd_change_peer_state(struct wlan_hdd_link_info *link_info, 1484 uint8_t *peer_mac, 1485 enum ol_txrx_peer_state sta_state) 1486 { 1487 QDF_STATUS err; 1488 struct hdd_adapter *adapter = link_info->adapter; 1489 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1490 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 1491 1492 err = cdp_peer_state_update(soc, peer_mac, sta_state); 1493 if (err != QDF_STATUS_SUCCESS) { 1494 hdd_err("peer state update failed"); 1495 return QDF_STATUS_E_FAULT; 1496 } 1497 1498 if (hdd_is_roam_sync_in_progress(hdd_ctx, link_info->vdev_id)) { 1499 if (adapter->device_mode == QDF_STA_MODE && 1500 (wlan_mlme_get_wds_mode(hdd_ctx->psoc) == 1501 WLAN_WDS_MODE_REPEATER)) 1502 hdd_config_wds_repeater_mode(link_info, peer_mac); 1503 1504 hdd_son_deliver_peer_authorize_event(link_info, peer_mac); 1505 return QDF_STATUS_SUCCESS; 1506 } 1507 1508 if (sta_state == OL_TXRX_PEER_STATE_AUTH) { 1509 /* Reset scan reject params on successful set key */ 1510 hdd_debug("Reset scan reject params"); 1511 hdd_init_scan_reject_params(hdd_ctx); 1512 1513 err = sme_set_peer_authorized(peer_mac, link_info->vdev_id); 1514 if (err != QDF_STATUS_SUCCESS) { 1515 hdd_err("Failed to set the peer state to authorized"); 1516 return QDF_STATUS_E_FAULT; 1517 } 1518 1519 if (adapter->device_mode == QDF_STA_MODE || 1520 adapter->device_mode == QDF_P2P_CLIENT_MODE) { 1521 hdd_set_unpause_queue(soc, link_info->vdev_id); 1522 } 1523 1524 if (adapter->device_mode == QDF_STA_MODE && 1525 (wlan_mlme_get_wds_mode(hdd_ctx->psoc) == 1526 WLAN_WDS_MODE_REPEATER)) 1527 hdd_config_wds_repeater_mode(link_info, peer_mac); 1528 1529 hdd_son_deliver_peer_authorize_event(link_info, peer_mac); 1530 } 1531 return QDF_STATUS_SUCCESS; 1532 } 1533 1534 QDF_STATUS hdd_update_dp_vdev_flags(void *cbk_data, 1535 uint8_t vdev_id, 1536 uint32_t vdev_param, 1537 bool is_link_up) 1538 { 1539 QDF_STATUS status = QDF_STATUS_SUCCESS; 1540 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 1541 struct hdd_context *hdd_ctx; 1542 struct wlan_objmgr_psoc **psoc; 1543 cdp_config_param_type val; 1544 1545 if (!cbk_data) 1546 return status; 1547 1548 psoc = cbk_data; 1549 1550 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 1551 if (!hdd_ctx) 1552 return QDF_STATUS_E_INVAL; 1553 1554 if (!hdd_ctx->tdls_nap_active) 1555 return status; 1556 1557 if (vdev_id == WLAN_INVALID_VDEV_ID) { 1558 status = QDF_STATUS_E_FAILURE; 1559 return status; 1560 } 1561 1562 val.cdp_vdev_param_tdls_flags = is_link_up; 1563 cdp_txrx_set_vdev_param(soc, vdev_id, vdev_param, val); 1564 1565 return status; 1566 } 1567 1568 QDF_STATUS hdd_roam_register_sta(struct wlan_hdd_link_info *link_info, 1569 struct qdf_mac_addr *bssid, 1570 bool is_auth_required) 1571 { 1572 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 1573 struct ol_txrx_desc_type txrx_desc = {0}; 1574 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 1575 enum phy_ch_width ch_width; 1576 enum wlan_phymode phymode; 1577 struct wlan_objmgr_vdev *vdev; 1578 struct hdd_adapter *adapter = link_info->adapter; 1579 1580 /* Get the Station ID from the one saved during the association */ 1581 if (!QDF_IS_ADDR_BROADCAST(bssid->bytes)) 1582 WLAN_ADDR_COPY(txrx_desc.peer_addr.bytes, 1583 bssid->bytes); 1584 else 1585 WLAN_ADDR_COPY(txrx_desc.peer_addr.bytes, 1586 adapter->mac_addr.bytes); 1587 1588 /* set the QoS field appropriately */ 1589 if (hdd_wmm_is_active(adapter)) 1590 txrx_desc.is_qos_enabled = 1; 1591 else 1592 txrx_desc.is_qos_enabled = 0; 1593 1594 #ifdef FEATURE_WLAN_WAPI 1595 hdd_debug("WAPI STA Registered: %d", 1596 adapter->wapi_info.is_wapi_sta); 1597 if (adapter->wapi_info.is_wapi_sta) 1598 txrx_desc.is_wapi_supported = 1; 1599 else 1600 txrx_desc.is_wapi_supported = 0; 1601 #endif /* FEATURE_WLAN_WAPI */ 1602 1603 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID); 1604 if (!vdev) 1605 return QDF_STATUS_E_INVAL; 1606 1607 qdf_status = ucfg_dp_sta_register_txrx_ops(vdev); 1608 hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID); 1609 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1610 hdd_err("DP tx/rx ops register failed Status: %d", qdf_status); 1611 return qdf_status; 1612 } 1613 1614 if (adapter->device_mode == QDF_NDI_MODE) { 1615 phymode = ucfg_mlme_get_vdev_phy_mode( 1616 adapter->hdd_ctx->psoc, 1617 link_info->vdev_id); 1618 ch_width = ucfg_mlme_get_ch_width_from_phymode(phymode); 1619 } else { 1620 ch_width = ucfg_mlme_get_peer_ch_width(adapter->hdd_ctx->psoc, 1621 txrx_desc.peer_addr.bytes); 1622 } 1623 txrx_desc.bw = hdd_convert_ch_width_to_cdp_peer_bw(ch_width); 1624 qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc); 1625 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1626 hdd_err("cdp_peer_register() failed Status: %d [0x%08X]", 1627 qdf_status, qdf_status); 1628 return qdf_status; 1629 } 1630 1631 hdd_cm_set_peer_authenticate(link_info, &txrx_desc.peer_addr, 1632 is_auth_required); 1633 1634 return qdf_status; 1635 } 1636 1637 /** 1638 * hdd_change_sta_state_authenticated()- 1639 * This function changes STA state to authenticated 1640 * @link_info: Link info pointer in HDD adapter 1641 * @roaminfo: pointer to the RoamInfo structure. 1642 * 1643 * This is called from hdd_RoamSetKeyCompleteHandler 1644 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw. 1645 * 1646 * Return: 0 on success and errno on failure 1647 */ 1648 static int 1649 hdd_change_sta_state_authenticated(struct wlan_hdd_link_info *link_info, 1650 struct csr_roam_info *roaminfo) 1651 { 1652 uint8_t *mac_addr; 1653 struct hdd_station_ctx *sta_ctx; 1654 struct hdd_adapter *adapter = link_info->adapter; 1655 struct hdd_context *hdd_ctx; 1656 QDF_STATUS status; 1657 bool alt_pipe; 1658 1659 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 1660 1661 mac_addr = sta_ctx->conn_info.bssid.bytes; 1662 1663 if (ucfg_ipa_is_enabled() && !sta_ctx->conn_info.is_authenticated && 1664 adapter->device_mode == QDF_STA_MODE && 1665 sta_ctx->conn_info.auth_type != eCSR_AUTH_TYPE_NONE && 1666 sta_ctx->conn_info.auth_type != eCSR_AUTH_TYPE_OPEN_SYSTEM && 1667 sta_ctx->conn_info.auth_type != eCSR_AUTH_TYPE_SHARED_KEY) { 1668 1669 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1670 status = hdd_ipa_get_tx_pipe(hdd_ctx, link_info, &alt_pipe); 1671 if (!QDF_IS_STATUS_SUCCESS(status)) { 1672 hdd_debug("Failed to get alternate pipe for vdev %d", 1673 link_info->vdev_id); 1674 alt_pipe = false; 1675 } 1676 1677 ucfg_ipa_wlan_evt(adapter->hdd_ctx->pdev, adapter->dev, 1678 adapter->device_mode, 1679 link_info->vdev_id, 1680 WLAN_IPA_STA_CONNECT, mac_addr, 1681 alt_pipe); 1682 } 1683 1684 hdd_cm_set_peer_authenticate(link_info, 1685 &sta_ctx->conn_info.bssid, false); 1686 1687 return 0; 1688 } 1689 1690 /** 1691 * hdd_change_peer_state_after_set_key() - change the peer state on set key 1692 * complete 1693 * @link_info: Link info pointer in HDD adapter 1694 * @roaminfo: pointer to roam info 1695 * @roam_result: roam result 1696 * 1697 * Peer state will be OL_TXRX_PEER_STATE_CONN until set key is complete. 1698 * This function checks for the successful set key completion and update 1699 * the peer state to OL_TXRX_PEER_STATE_AUTH. 1700 * 1701 * Return: None 1702 */ 1703 static void 1704 hdd_change_peer_state_after_set_key(struct wlan_hdd_link_info *link_info, 1705 struct csr_roam_info *roaminfo, 1706 eCsrRoamResult roam_result) 1707 { 1708 struct hdd_station_ctx *hdd_sta_ctx; 1709 eCsrEncryptionType encr_type; 1710 struct hdd_adapter *adapter = link_info->adapter; 1711 1712 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 1713 encr_type = hdd_sta_ctx->conn_info.uc_encrypt_type; 1714 1715 if (eCSR_ROAM_RESULT_AUTHENTICATED == roam_result) { 1716 hdd_sta_ctx->conn_info.gtk_installed = true; 1717 /* 1718 * PTK exchange happens in preauthentication itself if key_mgmt 1719 * is FT-PSK, ptk_installed was false as there is no set PTK 1720 * after roaming. STA TL state moves to authenticated only if 1721 * ptk_installed is true. So, make ptk_installed to true in 1722 * case of 11R roaming. 1723 */ 1724 if (sme_neighbor_roam_is11r_assoc(adapter->hdd_ctx->mac_handle, 1725 link_info->vdev_id)) 1726 hdd_sta_ctx->conn_info.ptk_installed = true; 1727 } else { 1728 hdd_sta_ctx->conn_info.ptk_installed = true; 1729 } 1730 1731 /* In WPA case move STA to authenticated when ptk is installed. Earlier 1732 * in WEP case STA was moved to AUTHENTICATED prior to setting the 1733 * unicast key and it was resulting in sending few un-encrypted packet. 1734 * Now in WEP case STA state will be moved to AUTHENTICATED after we 1735 * set the unicast and broadcast key. 1736 */ 1737 if ((encr_type == eCSR_ENCRYPT_TYPE_WEP40) || 1738 (encr_type == eCSR_ENCRYPT_TYPE_WEP104) || 1739 (encr_type == eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) || 1740 (encr_type == eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) { 1741 if (hdd_sta_ctx->conn_info.gtk_installed && 1742 hdd_sta_ctx->conn_info.ptk_installed) 1743 hdd_change_sta_state_authenticated(link_info, roaminfo); 1744 } else if (hdd_sta_ctx->conn_info.ptk_installed) { 1745 hdd_change_sta_state_authenticated(link_info, roaminfo); 1746 } 1747 1748 if (hdd_sta_ctx->conn_info.gtk_installed && 1749 hdd_sta_ctx->conn_info.ptk_installed) { 1750 hdd_sta_ctx->conn_info.gtk_installed = false; 1751 hdd_sta_ctx->conn_info.ptk_installed = false; 1752 } 1753 } 1754 1755 /** 1756 * hdd_roam_set_key_complete_handler() - Update the security parameters 1757 * @link_info: Link info pointer in HDD adapter 1758 * @roam_info: pointer to roam info 1759 * @roam_status: roam status 1760 * @roam_result: roam result 1761 * 1762 * Return: QDF_STATUS enumeration 1763 */ 1764 static QDF_STATUS 1765 hdd_roam_set_key_complete_handler(struct wlan_hdd_link_info *link_info, 1766 struct csr_roam_info *roam_info, 1767 eRoamCmdStatus roam_status, 1768 eCsrRoamResult roam_result) 1769 { 1770 eCsrEncryptionType algorithm; 1771 bool connected; 1772 struct hdd_station_ctx *sta_ctx; 1773 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 1774 1775 hdd_enter(); 1776 1777 if (!roam_info) { 1778 hdd_err("roam_info is NULL"); 1779 return QDF_STATUS_E_FAILURE; 1780 } 1781 1782 if (!hdd_ctx || !hdd_ctx->psoc) { 1783 hdd_err("hdd_ctx or psoc is NULL"); 1784 return QDF_STATUS_E_FAILURE; 1785 } 1786 1787 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 1788 /* 1789 * if (WPA), tell TL to go to 'authenticated' after the keys are set. 1790 * then go to 'authenticated'. For all other authentication types 1791 * (those that do not require upper layer authentication) we can put TL 1792 * directly into 'authenticated' state. 1793 */ 1794 hdd_debug("Set Key completion roam_status =%d roam_result=%d " 1795 QDF_MAC_ADDR_FMT, roam_status, roam_result, 1796 QDF_MAC_ADDR_REF(roam_info->peerMac.bytes)); 1797 1798 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 1799 connected = hdd_conn_get_connected_cipher_algo(link_info, sta_ctx, 1800 &algorithm); 1801 if (connected) { 1802 hdd_change_peer_state_after_set_key(link_info, 1803 roam_info, roam_result); 1804 } 1805 1806 policy_mgr_restart_opportunistic_timer(hdd_ctx->psoc, false); 1807 1808 hdd_exit(); 1809 return QDF_STATUS_SUCCESS; 1810 } 1811 1812 bool hdd_save_peer(struct hdd_station_ctx *sta_ctx, 1813 struct qdf_mac_addr *peer_mac_addr) 1814 { 1815 int idx; 1816 struct qdf_mac_addr *mac_addr; 1817 1818 for (idx = 0; idx < MAX_PEERS; idx++) { 1819 mac_addr = &sta_ctx->conn_info.peer_macaddr[idx]; 1820 if (qdf_is_macaddr_zero(mac_addr)) { 1821 hdd_debug("adding peer: "QDF_MAC_ADDR_FMT" at idx: %d", 1822 QDF_MAC_ADDR_REF(peer_mac_addr->bytes), idx); 1823 qdf_copy_macaddr(mac_addr, peer_mac_addr); 1824 return true; 1825 } 1826 } 1827 1828 return false; 1829 } 1830 1831 void hdd_delete_peer(struct hdd_station_ctx *sta_ctx, 1832 struct qdf_mac_addr *peer_mac_addr) 1833 { 1834 int i; 1835 struct qdf_mac_addr *mac_addr; 1836 1837 for (i = 0; i < MAX_PEERS; i++) { 1838 mac_addr = &sta_ctx->conn_info.peer_macaddr[i]; 1839 if (qdf_is_macaddr_equal(mac_addr, peer_mac_addr)) { 1840 qdf_zero_macaddr(mac_addr); 1841 return; 1842 } 1843 } 1844 } 1845 1846 bool hdd_any_valid_peer_present(struct wlan_hdd_link_info *link_info) 1847 { 1848 struct hdd_station_ctx *sta_ctx; 1849 int i; 1850 struct qdf_mac_addr *mac_addr; 1851 1852 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 1853 for (i = 0; i < MAX_PEERS; i++) { 1854 mac_addr = &sta_ctx->conn_info.peer_macaddr[i]; 1855 if (!qdf_is_macaddr_zero(mac_addr) && 1856 !qdf_is_macaddr_broadcast(mac_addr)) { 1857 hdd_debug("peer: index: %u " QDF_MAC_ADDR_FMT, i, 1858 QDF_MAC_ADDR_REF(mac_addr->bytes)); 1859 return true; 1860 } 1861 } 1862 1863 return false; 1864 } 1865 1866 /** 1867 * hdd_roam_mic_error_indication_handler() - MIC error indication handler 1868 * @link_info: Link info pointer in HDD adapter 1869 * @roam_info: pointer to roam info 1870 * 1871 * This function indicates the Mic failure to the supplicant 1872 * 1873 * Return: None 1874 */ 1875 static void 1876 hdd_roam_mic_error_indication_handler(struct wlan_hdd_link_info *link_info, 1877 struct csr_roam_info *roam_info) 1878 { 1879 struct hdd_adapter *adapter = link_info->adapter; 1880 tSirMicFailureInfo *mic_failure_info; 1881 1882 if (!hdd_cm_is_vdev_associated(link_info)) 1883 return; 1884 1885 mic_failure_info = roam_info->u.pMICFailureInfo; 1886 cfg80211_michael_mic_failure(adapter->dev, 1887 mic_failure_info->taMacAddr, 1888 mic_failure_info->multicast ? 1889 NL80211_KEYTYPE_GROUP : 1890 NL80211_KEYTYPE_PAIRWISE, 1891 mic_failure_info->keyId, 1892 mic_failure_info->TSC, 1893 GFP_KERNEL); 1894 } 1895 1896 #ifdef FEATURE_WLAN_TDLS 1897 QDF_STATUS hdd_roam_register_tdlssta(struct hdd_adapter *adapter, 1898 const uint8_t *peerMac, uint8_t qos) 1899 { 1900 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 1901 struct ol_txrx_desc_type txrx_desc = { 0 }; 1902 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 1903 enum phy_ch_width ch_width; 1904 struct wlan_objmgr_vdev *vdev; 1905 1906 /* 1907 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should 1908 * be peer MAC, here we are working on direct Link 1909 */ 1910 WLAN_ADDR_COPY(txrx_desc.peer_addr.bytes, peerMac); 1911 1912 /* set the QoS field appropriately .. */ 1913 txrx_desc.is_qos_enabled = qos; 1914 1915 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_DP_ID); 1916 if (!vdev) 1917 return QDF_STATUS_E_INVAL; 1918 1919 qdf_status = ucfg_dp_tdlsta_register_txrx_ops(vdev); 1920 hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID); 1921 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1922 hdd_err("DP tx/rx ops register failed Status: %d", qdf_status); 1923 return qdf_status; 1924 } 1925 1926 ch_width = ucfg_mlme_get_peer_ch_width(adapter->hdd_ctx->psoc, 1927 txrx_desc.peer_addr.bytes); 1928 txrx_desc.bw = hdd_convert_ch_width_to_cdp_peer_bw(ch_width); 1929 /* Register the Station with TL... */ 1930 qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc); 1931 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1932 hdd_err("cdp_peer_register() failed Status: %d [0x%08X]", 1933 qdf_status, qdf_status); 1934 return qdf_status; 1935 } 1936 1937 return qdf_status; 1938 } 1939 1940 #endif 1941 1942 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 1943 1944 static void hdd_rx_unprot_disassoc(struct net_device *dev, 1945 const u8 *buf, size_t len) 1946 { 1947 cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); 1948 } 1949 1950 static void hdd_rx_unprot_deauth(struct net_device *dev, 1951 const u8 *buf, size_t len) 1952 { 1953 cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); 1954 } 1955 1956 #else 1957 1958 static void hdd_rx_unprot_disassoc(struct net_device *dev, 1959 const u8 *buf, size_t len) 1960 { 1961 cfg80211_send_unprot_disassoc(dev, buf, len); 1962 } 1963 1964 static void hdd_rx_unprot_deauth(struct net_device *dev, 1965 const u8 *buf, size_t len) 1966 { 1967 cfg80211_send_unprot_deauth(dev, buf, len); 1968 } 1969 1970 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) */ 1971 1972 /** 1973 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame 1974 * @link_info: Link info pointer in HDD adapter 1975 * @frame_length: Length of the unprotected frame being passed 1976 * @frame: Pointer to the frame buffer 1977 * @frame_type: 802.11 frame type 1978 * 1979 * This function forwards the unprotected management frame to the supplicant. 1980 * 1981 * Return: nothing 1982 */ 1983 static void 1984 hdd_indicate_unprot_mgmt_frame(struct wlan_hdd_link_info *link_info, 1985 uint32_t frame_length, uint8_t *frame, 1986 uint8_t frame_type) 1987 { 1988 uint8_t type, subtype; 1989 struct hdd_stats *hdd_stats; 1990 struct hdd_adapter *adapter = link_info->adapter; 1991 1992 hdd_debug("Frame Type = %d Frame Length = %d", 1993 frame_type, frame_length); 1994 1995 if (hdd_validate_adapter(adapter)) 1996 return; 1997 1998 if (!frame_length) { 1999 hdd_err("Frame Length is Invalid ZERO"); 2000 return; 2001 } 2002 2003 if (!frame) { 2004 hdd_err("frame is NULL"); 2005 return; 2006 } 2007 2008 type = WLAN_HDD_GET_TYPE_FRM_FC(frame[0]); 2009 if (type != SIR_MAC_MGMT_FRAME) { 2010 hdd_warn("Unexpected frame type %d", type); 2011 return; 2012 } 2013 2014 hdd_stats = &link_info->hdd_stats; 2015 subtype = WLAN_HDD_GET_SUBTYPE_FRM_FC(frame[0]); 2016 switch (subtype) { 2017 case SIR_MAC_MGMT_DISASSOC: 2018 hdd_rx_unprot_disassoc(adapter->dev, frame, frame_length); 2019 hdd_stats->hdd_pmf_stats.num_unprot_disassoc_rx++; 2020 break; 2021 case SIR_MAC_MGMT_DEAUTH: 2022 hdd_rx_unprot_deauth(adapter->dev, frame, frame_length); 2023 hdd_stats->hdd_pmf_stats.num_unprot_deauth_rx++; 2024 break; 2025 default: 2026 hdd_warn("Unexpected frame subtype %d", subtype); 2027 break; 2028 } 2029 } 2030 2031 #ifdef FEATURE_WLAN_ESE 2032 /** 2033 * hdd_indicate_tsm_ie() - send traffic stream metrics ie 2034 * @adapter: pointer to adapter 2035 * @tid: traffic identifier 2036 * @state: state 2037 * @measInterval: measurement interval 2038 * 2039 * This function sends traffic stream metrics IE information to 2040 * the supplicant via wireless event. 2041 * 2042 * Return: none 2043 */ 2044 static void 2045 hdd_indicate_tsm_ie(struct hdd_adapter *adapter, uint8_t tid, 2046 uint8_t state, uint16_t measInterval) 2047 { 2048 union iwreq_data wrqu; 2049 char buf[IW_CUSTOM_MAX + 1]; 2050 int nBytes = 0; 2051 2052 if (!adapter) 2053 return; 2054 2055 /* create the event */ 2056 memset(&wrqu, '\0', sizeof(wrqu)); 2057 memset(buf, '\0', sizeof(buf)); 2058 2059 hdd_debug("TSM Ind tid(%d) state(%d) MeasInt(%d)", 2060 tid, state, measInterval); 2061 2062 nBytes = 2063 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state, 2064 measInterval); 2065 2066 wrqu.data.pointer = buf; 2067 wrqu.data.length = nBytes; 2068 /* send the event */ 2069 hdd_wext_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buf); 2070 } 2071 2072 /** 2073 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication 2074 * @adapter: pointer to adapter 2075 * @roam_info: pointer to roam info 2076 * 2077 * Return: none 2078 */ 2079 static void 2080 hdd_indicate_ese_adj_ap_rep_ind(struct hdd_adapter *adapter, 2081 struct csr_roam_info *roam_info) 2082 { 2083 union iwreq_data wrqu; 2084 char buf[IW_CUSTOM_MAX + 1]; 2085 int nBytes = 0; 2086 2087 if ((!adapter) || (!roam_info)) 2088 return; 2089 2090 /* create the event */ 2091 memset(&wrqu, '\0', sizeof(wrqu)); 2092 memset(buf, '\0', sizeof(buf)); 2093 2094 hdd_debug("CCXADJAPREP=%u", roam_info->tsmRoamDelay); 2095 2096 nBytes = 2097 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u", 2098 roam_info->tsmRoamDelay); 2099 2100 wrqu.data.pointer = buf; 2101 wrqu.data.length = nBytes; 2102 2103 /* send the event */ 2104 hdd_wext_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buf); 2105 } 2106 2107 /** 2108 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results 2109 * @adapter: pointer to adapter 2110 * @measurementToken: measurement token 2111 * @flag: flag 2112 * @numBss: number of bss 2113 * 2114 * If the measurement is none and no scan results found, 2115 * indicate the supplicant about measurement done. 2116 * 2117 * Return: none 2118 */ 2119 void 2120 hdd_indicate_ese_bcn_report_no_results(const struct hdd_adapter *adapter, 2121 const uint16_t measurementToken, 2122 const bool flag, const uint8_t numBss) 2123 { 2124 union iwreq_data wrqu; 2125 char buf[IW_CUSTOM_MAX]; 2126 char *pos = buf; 2127 int nBytes = 0, freeBytes = IW_CUSTOM_MAX; 2128 2129 memset(&wrqu, '\0', sizeof(wrqu)); 2130 memset(buf, '\0', sizeof(buf)); 2131 2132 hdd_debug("CCXBCNREP=%d %d %d", measurementToken, 2133 flag, numBss); 2134 2135 nBytes = 2136 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken, 2137 flag, numBss); 2138 2139 wrqu.data.pointer = buf; 2140 wrqu.data.length = nBytes; 2141 /* send the event */ 2142 hdd_wext_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buf); 2143 } 2144 2145 /** 2146 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication 2147 * @adapter: pointer to adapter 2148 * @roam_info: pointer to roam info 2149 * 2150 * If the measurement is none and no scan results found, 2151 * indicate the supplicant about measurement done. 2152 * 2153 * Return: none 2154 */ 2155 static void 2156 hdd_indicate_ese_bcn_report_ind(const struct hdd_adapter *adapter, 2157 const struct csr_roam_info *roam_info) 2158 { 2159 union iwreq_data wrqu; 2160 char buf[IW_CUSTOM_MAX]; 2161 char *pos = buf; 2162 int nBytes = 0, freeBytes = IW_CUSTOM_MAX; 2163 uint8_t i = 0, len = 0; 2164 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */ 2165 uint8_t lastSent = 0, sendBss = 0; 2166 int bcnRepFieldSize = 2167 sizeof(roam_info->pEseBcnReportRsp->bcnRepBssInfo[0]. 2168 bcnReportFields); 2169 uint8_t ieLenByte = 1; 2170 /* 2171 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes 2172 */ 2173 #define ESEBCNREPHEADER_LEN (18) 2174 2175 if ((!adapter) || (!roam_info)) 2176 return; 2177 2178 /* 2179 * Custom event can pass maximum of 256 bytes of data, 2180 * based on the IE len we need to identify how many BSS info can 2181 * be filled in to custom event data. 2182 */ 2183 /* 2184 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data 2185 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces 2186 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes 2187 */ 2188 2189 if ((roam_info->pEseBcnReportRsp->flag >> 1) 2190 && (!roam_info->pEseBcnReportRsp->numBss)) { 2191 hdd_debug("Measurement Done but no scan results"); 2192 /* If the measurement is none and no scan results found, 2193 * indicate the supplicant about measurement done 2194 */ 2195 hdd_indicate_ese_bcn_report_no_results( 2196 adapter, 2197 roam_info->pEseBcnReportRsp-> 2198 measurementToken, 2199 roam_info->pEseBcnReportRsp->flag, 2200 roam_info->pEseBcnReportRsp->numBss); 2201 } else { 2202 while (lastSent < roam_info->pEseBcnReportRsp->numBss) { 2203 memset(&wrqu, '\0', sizeof(wrqu)); 2204 memset(buf, '\0', sizeof(buf)); 2205 tot_bcn_ieLen = 0; 2206 sendBss = 0; 2207 pos = buf; 2208 freeBytes = IW_CUSTOM_MAX; 2209 2210 for (i = lastSent; 2211 i < roam_info->pEseBcnReportRsp->numBss; i++) { 2212 len = 2213 bcnRepFieldSize + ieLenByte + 2214 roam_info->pEseBcnReportRsp-> 2215 bcnRepBssInfo[i].ieLen; 2216 if ((len + tot_bcn_ieLen) > 2217 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) { 2218 break; 2219 } 2220 tot_bcn_ieLen += len; 2221 sendBss++; 2222 hdd_debug("i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)", 2223 i, bcnRepFieldSize, 1, 2224 roam_info->pEseBcnReportRsp-> 2225 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen); 2226 } 2227 2228 hdd_debug("Sending %d BSS Info", sendBss); 2229 hdd_debug("CCXBCNREP=%d %d %d %d", 2230 roam_info->pEseBcnReportRsp->measurementToken, 2231 roam_info->pEseBcnReportRsp->flag, sendBss, 2232 tot_bcn_ieLen); 2233 2234 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ", 2235 roam_info->pEseBcnReportRsp-> 2236 measurementToken, 2237 roam_info->pEseBcnReportRsp->flag, 2238 sendBss); 2239 pos += nBytes; 2240 freeBytes -= nBytes; 2241 2242 /* Copy total Beacon report data length */ 2243 qdf_mem_copy(pos, (char *)&tot_bcn_ieLen, 2244 sizeof(tot_bcn_ieLen)); 2245 pos += sizeof(tot_bcn_ieLen); 2246 freeBytes -= sizeof(tot_bcn_ieLen); 2247 2248 for (i = 0; i < sendBss; i++) { 2249 hdd_debug("ChanNum(%d) Spare(%d) MeasDuration(%d)" 2250 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)" 2251 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)" 2252 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)", 2253 roam_info->pEseBcnReportRsp-> 2254 bcnRepBssInfo[i + 2255 lastSent].bcnReportFields. 2256 ChanNum, 2257 roam_info->pEseBcnReportRsp-> 2258 bcnRepBssInfo[i + 2259 lastSent].bcnReportFields. 2260 Spare, 2261 roam_info->pEseBcnReportRsp-> 2262 bcnRepBssInfo[i + 2263 lastSent].bcnReportFields. 2264 MeasDuration, 2265 roam_info->pEseBcnReportRsp-> 2266 bcnRepBssInfo[i + 2267 lastSent].bcnReportFields. 2268 PhyType, 2269 roam_info->pEseBcnReportRsp-> 2270 bcnRepBssInfo[i + 2271 lastSent].bcnReportFields. 2272 RecvSigPower, 2273 roam_info->pEseBcnReportRsp-> 2274 bcnRepBssInfo[i + 2275 lastSent].bcnReportFields. 2276 ParentTsf, 2277 roam_info->pEseBcnReportRsp-> 2278 bcnRepBssInfo[i + 2279 lastSent].bcnReportFields. 2280 TargetTsf[0], 2281 roam_info->pEseBcnReportRsp-> 2282 bcnRepBssInfo[i + 2283 lastSent].bcnReportFields. 2284 TargetTsf[1], 2285 roam_info->pEseBcnReportRsp-> 2286 bcnRepBssInfo[i + 2287 lastSent].bcnReportFields. 2288 BcnInterval, 2289 roam_info->pEseBcnReportRsp-> 2290 bcnRepBssInfo[i + 2291 lastSent].bcnReportFields. 2292 CapabilityInfo, 2293 roam_info->pEseBcnReportRsp-> 2294 bcnRepBssInfo[i + 2295 lastSent].bcnReportFields. 2296 Bssid[0], 2297 roam_info->pEseBcnReportRsp-> 2298 bcnRepBssInfo[i + 2299 lastSent].bcnReportFields. 2300 Bssid[1], 2301 roam_info->pEseBcnReportRsp-> 2302 bcnRepBssInfo[i + 2303 lastSent].bcnReportFields. 2304 Bssid[2], 2305 roam_info->pEseBcnReportRsp-> 2306 bcnRepBssInfo[i + 2307 lastSent].bcnReportFields. 2308 Bssid[3], 2309 roam_info->pEseBcnReportRsp-> 2310 bcnRepBssInfo[i + 2311 lastSent].bcnReportFields. 2312 Bssid[4], 2313 roam_info->pEseBcnReportRsp-> 2314 bcnRepBssInfo[i + 2315 lastSent].bcnReportFields. 2316 Bssid[5]); 2317 2318 /* bcn report fields are copied */ 2319 len = 2320 sizeof(roam_info->pEseBcnReportRsp-> 2321 bcnRepBssInfo[i + 2322 lastSent]. 2323 bcnReportFields); 2324 qdf_mem_copy(pos, 2325 (char *)&roam_info-> 2326 pEseBcnReportRsp->bcnRepBssInfo[i + 2327 lastSent]. 2328 bcnReportFields, len); 2329 pos += len; 2330 freeBytes -= len; 2331 2332 /* Add 1 byte of ie len */ 2333 len = 2334 roam_info->pEseBcnReportRsp-> 2335 bcnRepBssInfo[i + lastSent].ieLen; 2336 qdf_mem_copy(pos, (char *)&len, sizeof(len)); 2337 pos += sizeof(len); 2338 freeBytes -= sizeof(len); 2339 2340 /* copy IE from scan results */ 2341 qdf_mem_copy(pos, 2342 (char *)roam_info-> 2343 pEseBcnReportRsp->bcnRepBssInfo[i + 2344 lastSent]. 2345 pBuf, len); 2346 pos += len; 2347 freeBytes -= len; 2348 } 2349 2350 wrqu.data.pointer = buf; 2351 wrqu.data.length = IW_CUSTOM_MAX - freeBytes; 2352 2353 /* send the event */ 2354 hdd_wext_send_event(adapter->dev, IWEVCUSTOM, &wrqu, 2355 buf); 2356 lastSent += sendBss; 2357 } 2358 } 2359 } 2360 2361 #endif /* FEATURE_WLAN_ESE */ 2362 2363 /* 2364 * hdd_roam_channel_switch_handler() - hdd channel switch handler 2365 * @link_info: Link info pointer in HDD adapter 2366 * @roam_info: Pointer to roam info 2367 * 2368 * Return: None 2369 */ 2370 static void 2371 hdd_roam_channel_switch_handler(struct wlan_hdd_link_info *link_info, 2372 struct csr_roam_info *roam_info) 2373 { 2374 struct hdd_chan_change_params chan_change = {0}; 2375 QDF_STATUS status; 2376 struct hdd_adapter *adapter = link_info->adapter; 2377 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 2378 mac_handle_t mac_handle; 2379 struct hdd_station_ctx *sta_ctx; 2380 uint8_t connected_vdev; 2381 bool notify = true, is_sap_go_moved_before_sta = false; 2382 struct wlan_objmgr_vdev *vdev; 2383 2384 mac_handle = hdd_adapter_get_mac_handle(adapter); 2385 if (!mac_handle) 2386 return; 2387 2388 /* Enable Roaming on STA interface which was disabled before CSA */ 2389 if (adapter->device_mode == QDF_STA_MODE) 2390 sme_start_roaming(mac_handle, link_info->vdev_id, 2391 REASON_VDEV_RESTART_FROM_HOST, 2392 RSO_CHANNEL_SWITCH); 2393 2394 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 2395 if (sta_ctx) { 2396 sta_ctx->conn_info.chan_freq = roam_info->chan_info.mhz; 2397 sta_ctx->conn_info.ch_width = roam_info->chan_info.ch_width; 2398 } 2399 2400 chan_change.chan_freq = roam_info->chan_info.mhz; 2401 chan_change.chan_params.ch_width = 2402 roam_info->chan_info.ch_width; 2403 chan_change.chan_params.sec_ch_offset = 2404 roam_info->chan_info.sec_ch_offset; 2405 chan_change.chan_params.mhz_freq_seg0 = 2406 roam_info->chan_info.band_center_freq1; 2407 chan_change.chan_params.mhz_freq_seg1 = 2408 roam_info->chan_info.band_center_freq2; 2409 2410 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID); 2411 if (!vdev) { 2412 hdd_err("Invalid vdev"); 2413 return; 2414 } 2415 2416 if ((adapter->device_mode == QDF_STA_MODE || 2417 adapter->device_mode == QDF_P2P_CLIENT_MODE)) { 2418 if (!wlan_get_connected_vdev_by_bssid( 2419 hdd_ctx->pdev, sta_ctx->conn_info.bssid.bytes, 2420 &connected_vdev)) 2421 notify = false; 2422 else if (link_info->vdev_id != connected_vdev || 2423 !ucfg_cm_is_vdev_active(vdev)) 2424 notify = false; 2425 } 2426 if (notify) { 2427 qdf_sched_work(0, &link_info->chan_change_notify_work); 2428 } else { 2429 hdd_err("BSS "QDF_MAC_ADDR_FMT" no connected with vdev %d (%d)", 2430 QDF_MAC_ADDR_REF(sta_ctx->conn_info.bssid.bytes), 2431 link_info->vdev_id, connected_vdev); 2432 } 2433 status = policy_mgr_set_hw_mode_on_channel_switch(hdd_ctx->psoc, 2434 link_info->vdev_id); 2435 if (QDF_IS_STATUS_ERROR(status)) 2436 hdd_debug("set hw mode change not done"); 2437 2438 is_sap_go_moved_before_sta = 2439 wlan_vdev_mlme_is_sap_go_move_before_sta(vdev); 2440 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 2441 2442 if (!is_sap_go_moved_before_sta) 2443 policy_mgr_check_concurrent_intf_and_restart_sap( 2444 hdd_ctx->psoc, 2445 !!link_info->session.ap.sap_config.acs_cfg.acs_mode); 2446 2447 wlan_twt_concurrency_update(hdd_ctx); 2448 if (adapter->device_mode == QDF_STA_MODE || 2449 adapter->device_mode == QDF_P2P_CLIENT_MODE) { 2450 vdev = hdd_objmgr_get_vdev_by_user(link_info, 2451 WLAN_OSIF_ID); 2452 if (!vdev) 2453 return; 2454 2455 status = ucfg_if_mgr_deliver_event( 2456 vdev, WLAN_IF_MGR_EV_STA_CSA_COMPLETE, NULL); 2457 if (QDF_IS_STATUS_ERROR(status)) 2458 hdd_debug("Failed to deliver CSA complete evt"); 2459 2460 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 2461 } 2462 } 2463 2464 #ifdef WLAN_FEATURE_HOST_ROAM 2465 void wlan_hdd_ft_set_key_delay(struct wlan_objmgr_vdev *vdev) 2466 { 2467 int errno = 0; 2468 2469 if (ucfg_cm_ft_key_ready_for_install(vdev)) 2470 errno = 2471 wlan_cfg80211_crypto_add_key(vdev, 2472 WLAN_CRYPTO_KEY_TYPE_UNICAST, 2473 0, false); 2474 if (errno) 2475 hdd_err("ft set key failed"); 2476 } 2477 #endif 2478 2479 QDF_STATUS hdd_sme_roam_callback(void *context, 2480 struct csr_roam_info *roam_info, 2481 eRoamCmdStatus roam_status, 2482 eCsrRoamResult roam_result) 2483 { 2484 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS; 2485 struct wlan_hdd_link_info *link_info = context; 2486 struct hdd_adapter *adapter = link_info->adapter; 2487 struct hdd_station_ctx *sta_ctx = NULL; 2488 struct hdd_context *hdd_ctx; 2489 2490 hdd_debug("CSR Callback: status=%s (%d) result= %s (%d)", 2491 get_e_roam_cmd_status_str(roam_status), roam_status, 2492 get_e_csr_roam_result_str(roam_result), roam_result); 2493 2494 /* Sanity check */ 2495 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) { 2496 hdd_err("Invalid adapter or adapter has invalid magic"); 2497 return QDF_STATUS_E_FAILURE; 2498 } 2499 2500 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 2501 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 2502 2503 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG, 2504 link_info->vdev_id, roam_status)); 2505 2506 switch (roam_status) { 2507 case eCSR_ROAM_MIC_ERROR_IND: 2508 hdd_roam_mic_error_indication_handler(link_info, roam_info); 2509 break; 2510 2511 case eCSR_ROAM_SET_KEY_COMPLETE: 2512 { 2513 qdf_ret_status = 2514 hdd_roam_set_key_complete_handler(link_info, roam_info, 2515 roam_status, 2516 roam_result); 2517 if (eCSR_ROAM_RESULT_AUTHENTICATED == roam_result) 2518 hdd_debug("set key complete, session: %d", 2519 link_info->vdev_id); 2520 } 2521 break; 2522 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND: 2523 if (roam_info) 2524 hdd_indicate_unprot_mgmt_frame(link_info, 2525 roam_info->nFrameLength, 2526 roam_info->pbFrames, 2527 roam_info->frameType); 2528 break; 2529 #ifdef FEATURE_WLAN_ESE 2530 case eCSR_ROAM_TSM_IE_IND: 2531 if (roam_info) 2532 hdd_indicate_tsm_ie(adapter, 2533 roam_info->tsm_ie.tsid, 2534 roam_info->tsm_ie.state, 2535 roam_info->tsm_ie.msmt_interval); 2536 break; 2537 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND: 2538 { 2539 hdd_indicate_ese_adj_ap_rep_ind(adapter, roam_info); 2540 break; 2541 } 2542 2543 case eCSR_ROAM_ESE_BCN_REPORT_IND: 2544 { 2545 hdd_indicate_ese_bcn_report_ind(adapter, roam_info); 2546 break; 2547 } 2548 #endif /* FEATURE_WLAN_ESE */ 2549 case eCSR_ROAM_STA_CHANNEL_SWITCH: 2550 hdd_roam_channel_switch_handler(link_info, roam_info); 2551 break; 2552 2553 case eCSR_ROAM_NDP_STATUS_UPDATE: 2554 hdd_ndp_event_handler(link_info, roam_info, 2555 roam_status, roam_result); 2556 break; 2557 case eCSR_ROAM_SAE_COMPUTE: 2558 if (roam_info) 2559 wlan_hdd_sae_callback(link_info, roam_info); 2560 break; 2561 default: 2562 break; 2563 } 2564 return qdf_ret_status; 2565 } 2566 2567 #ifdef WLAN_FEATURE_FILS_SK 2568 /** 2569 * hdd_translate_fils_rsn_to_csr_auth() - Translate FILS RSN to CSR auth type 2570 * @auth_suite: auth suite 2571 * @auth_type: pointer to enum csr_akm_type 2572 * 2573 * Return: None 2574 */ 2575 static void hdd_translate_fils_rsn_to_csr_auth(int8_t auth_suite[4], 2576 enum csr_akm_type *auth_type) 2577 { 2578 if (!memcmp(auth_suite, ccp_rsn_oui_0e, 4)) 2579 *auth_type = eCSR_AUTH_TYPE_FILS_SHA256; 2580 else if (!memcmp(auth_suite, ccp_rsn_oui_0f, 4)) 2581 *auth_type = eCSR_AUTH_TYPE_FILS_SHA384; 2582 else if (!memcmp(auth_suite, ccp_rsn_oui_10, 4)) 2583 *auth_type = eCSR_AUTH_TYPE_FT_FILS_SHA256; 2584 else if (!memcmp(auth_suite, ccp_rsn_oui_11, 4)) 2585 *auth_type = eCSR_AUTH_TYPE_FT_FILS_SHA384; 2586 } 2587 #else 2588 static inline void hdd_translate_fils_rsn_to_csr_auth(int8_t auth_suite[4], 2589 enum csr_akm_type *auth_type) 2590 { 2591 } 2592 #endif 2593 2594 #ifdef WLAN_FEATURE_SAE 2595 /** 2596 * hdd_translate_sae_rsn_to_csr_auth() - Translate SAE RSN to CSR auth type 2597 * @auth_suite: auth suite 2598 * @auth_type: pointer to enum csr_akm_type 2599 * 2600 * Return: None 2601 */ 2602 static void hdd_translate_sae_rsn_to_csr_auth(int8_t auth_suite[4], 2603 enum csr_akm_type *auth_type) 2604 { 2605 if (qdf_mem_cmp(auth_suite, ccp_rsn_oui_80, 4) == 0) 2606 *auth_type = eCSR_AUTH_TYPE_SAE; 2607 else if (qdf_mem_cmp(auth_suite, ccp_rsn_oui_90, 4) == 0) 2608 *auth_type = eCSR_AUTH_TYPE_FT_SAE; 2609 2610 } 2611 #else 2612 static inline void hdd_translate_sae_rsn_to_csr_auth(int8_t auth_suite[4], 2613 enum csr_akm_type *auth_type) 2614 { 2615 } 2616 #endif 2617 2618 void *hdd_filter_ft_info(const uint8_t *frame, size_t len, 2619 uint32_t *ft_info_len) 2620 { 2621 uint32_t ft_ie_len, md_ie_len, rsn_ie_len, ie_len; 2622 const uint8_t *rsn_ie, *md_ie, *ft_ie; 2623 void *ft_info; 2624 2625 ft_ie_len = 0; 2626 md_ie_len = 0; 2627 rsn_ie_len = 0; 2628 ie_len = len - DOT11F_FF_CAPABILITIES_LEN - DOT11F_FF_STATUS_LEN 2629 - DOT11F_IE_AID_MAX_LEN - sizeof(tSirMacMgmtHdr); 2630 rsn_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_RSN, frame, ie_len); 2631 2632 if (rsn_ie) { 2633 rsn_ie_len = rsn_ie[1] + 2; 2634 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, 2635 (void *)rsn_ie, rsn_ie_len); 2636 } 2637 md_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_MOBILITYDOMAIN, 2638 frame, ie_len); 2639 if (md_ie) { 2640 md_ie_len = md_ie[1] + 2; 2641 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, 2642 (void *)md_ie, md_ie_len); 2643 } 2644 ft_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_FTINFO, frame, ie_len); 2645 if (ft_ie) 2646 ft_ie_len = ft_ie[1] + 2; 2647 2648 *ft_info_len = rsn_ie_len + md_ie_len + ft_ie_len; 2649 ft_info = qdf_mem_malloc(*ft_info_len); 2650 if (!ft_info) 2651 return NULL; 2652 if (rsn_ie_len) 2653 qdf_mem_copy(ft_info, rsn_ie, rsn_ie_len); 2654 if (md_ie_len) 2655 qdf_mem_copy(ft_info + rsn_ie_len, md_ie, md_ie_len); 2656 if (ft_ie_len) 2657 qdf_mem_copy(ft_info + rsn_ie_len + md_ie_len, 2658 ft_ie, ft_ie_len); 2659 return ft_info; 2660 } 2661 2662 /** 2663 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type 2664 * @auth_suite: auth suite 2665 * 2666 * Return: enum csr_akm_type enumeration 2667 */ 2668 enum csr_akm_type hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4]) 2669 { 2670 enum csr_akm_type auth_type = eCSR_AUTH_TYPE_UNKNOWN; 2671 /* is the auth type supported? */ 2672 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) { 2673 auth_type = eCSR_AUTH_TYPE_RSN; 2674 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) { 2675 auth_type = eCSR_AUTH_TYPE_RSN_PSK; 2676 } else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) { 2677 /* Check for 11r FT Authentication with PSK */ 2678 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK; 2679 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) { 2680 /* Check for 11R FT Authentication with 802.1X */ 2681 auth_type = eCSR_AUTH_TYPE_FT_RSN; 2682 } else 2683 #ifdef FEATURE_WLAN_ESE 2684 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) { 2685 auth_type = eCSR_AUTH_TYPE_CCKM_RSN; 2686 } else 2687 #endif /* FEATURE_WLAN_ESE */ 2688 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) { 2689 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256; 2690 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) { 2691 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256; 2692 } else if (memcmp(auth_suite, ccp_rsn_oui_18, 4) == 0) { 2693 auth_type = eCSR_AUTH_TYPE_OWE; 2694 } else if (memcmp(auth_suite, ccp_rsn_oui_12, 4) == 0) { 2695 auth_type = eCSR_AUTH_TYPE_DPP_RSN; 2696 } else if (memcmp(auth_suite, ccp_rsn_oui_0b, 4) == 0) { 2697 /* Check for Suite B EAP 256 */ 2698 auth_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256; 2699 } else if (memcmp(auth_suite, ccp_rsn_oui_0c, 4) == 0) { 2700 /* Check for Suite B EAP 384 */ 2701 auth_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384; 2702 } else if (memcmp(auth_suite, ccp_rsn_oui_0d, 4) == 0) { 2703 /* Check for FT Suite B EAP 384 */ 2704 auth_type = eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384; 2705 } else if (memcmp(auth_suite, ccp_rsn_oui_13, 4) == 0) { 2706 auth_type = eCSR_AUTH_TYPE_OSEN; 2707 } else { 2708 hdd_translate_fils_rsn_to_csr_auth(auth_suite, &auth_type); 2709 hdd_translate_sae_rsn_to_csr_auth(auth_suite, &auth_type); 2710 } 2711 2712 return auth_type; 2713 } 2714 2715 /** 2716 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type 2717 * @auth_suite: auth suite 2718 * 2719 * Return: enum csr_akm_type enumeration 2720 */ 2721 enum csr_akm_type hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4]) 2722 { 2723 enum csr_akm_type auth_type = eCSR_AUTH_TYPE_UNKNOWN; 2724 /* is the auth type supported? */ 2725 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) { 2726 auth_type = eCSR_AUTH_TYPE_WPA; 2727 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) { 2728 auth_type = eCSR_AUTH_TYPE_WPA_PSK; 2729 } else 2730 #ifdef FEATURE_WLAN_ESE 2731 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) { 2732 auth_type = eCSR_AUTH_TYPE_CCKM_WPA; 2733 } else 2734 #endif /* FEATURE_WLAN_ESE */ 2735 { 2736 hdd_translate_fils_rsn_to_csr_auth(auth_suite, &auth_type); 2737 } 2738 2739 return auth_type; 2740 } 2741 2742 /** 2743 * hdd_translate_rsn_to_csr_encryption_type() - 2744 * Translate RSN to CSR encryption type 2745 * @cipher_suite: cipher suite 2746 * 2747 * Return: eCsrEncryptionType enumeration 2748 */ 2749 eCsrEncryptionType 2750 hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4]) 2751 { 2752 eCsrEncryptionType cipher_type; 2753 2754 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0) 2755 cipher_type = eCSR_ENCRYPT_TYPE_AES; 2756 else if (memcmp(cipher_suite, ccp_rsn_oui09, 4) == 0) 2757 cipher_type = eCSR_ENCRYPT_TYPE_AES_GCMP; 2758 else if (memcmp(cipher_suite, ccp_rsn_oui0a, 4) == 0) 2759 cipher_type = eCSR_ENCRYPT_TYPE_AES_GCMP_256; 2760 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0) 2761 cipher_type = eCSR_ENCRYPT_TYPE_TKIP; 2762 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0) 2763 cipher_type = eCSR_ENCRYPT_TYPE_NONE; 2764 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0) 2765 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; 2766 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0) 2767 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; 2768 else 2769 cipher_type = eCSR_ENCRYPT_TYPE_FAILED; 2770 2771 return cipher_type; 2772 } 2773 2774 /** 2775 * hdd_translate_wpa_to_csr_encryption_type() - 2776 * Translate WPA to CSR encryption type 2777 * @cipher_suite: cipher suite 2778 * 2779 * Return: eCsrEncryptionType enumeration 2780 */ 2781 eCsrEncryptionType 2782 hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4]) 2783 { 2784 eCsrEncryptionType cipher_type; 2785 2786 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0) 2787 cipher_type = eCSR_ENCRYPT_TYPE_AES; 2788 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0) 2789 cipher_type = eCSR_ENCRYPT_TYPE_TKIP; 2790 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0) 2791 cipher_type = eCSR_ENCRYPT_TYPE_NONE; 2792 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0) 2793 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; 2794 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0) 2795 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; 2796 else 2797 cipher_type = eCSR_ENCRYPT_TYPE_FAILED; 2798 2799 return cipher_type; 2800 } 2801 2802 #ifdef FEATURE_WLAN_WAPI 2803 enum csr_akm_type hdd_translate_wapi_to_csr_auth_type(uint8_t auth_suite[4]) 2804 { 2805 enum csr_akm_type auth_type; 2806 2807 if (memcmp(auth_suite, ccp_wapi_oui01, 4) == 0) 2808 auth_type = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE; 2809 else if (memcmp(auth_suite, ccp_wapi_oui02, 4) == 0) 2810 auth_type = eCSR_AUTH_TYPE_WAPI_WAI_PSK; 2811 else 2812 auth_type = eCSR_AUTH_TYPE_UNKNOWN; 2813 2814 return auth_type; 2815 } 2816 2817 eCsrEncryptionType 2818 hdd_translate_wapi_to_csr_encryption_type(uint8_t cipher_suite[4]) 2819 { 2820 eCsrEncryptionType cipher_type; 2821 2822 if (memcmp(cipher_suite, ccp_wapi_oui01, 4) == 0 || 2823 memcmp(cipher_suite, ccp_wapi_oui02, 4) == 0) 2824 cipher_type = eCSR_ENCRYPT_TYPE_WPI; 2825 else 2826 cipher_type = eCSR_ENCRYPT_TYPE_FAILED; 2827 2828 return cipher_type; 2829 } 2830 #endif /* FEATURE_WLAN_WAPI */ 2831 2832 enum cdp_peer_bw 2833 hdd_convert_ch_width_to_cdp_peer_bw(enum phy_ch_width ch_width) 2834 { 2835 switch (ch_width) { 2836 case CH_WIDTH_20MHZ: 2837 return CDP_20_MHZ; 2838 case CH_WIDTH_40MHZ: 2839 return CDP_40_MHZ; 2840 case CH_WIDTH_80MHZ: 2841 return CDP_80_MHZ; 2842 case CH_WIDTH_160MHZ: 2843 return CDP_160_MHZ; 2844 case CH_WIDTH_80P80MHZ: 2845 return CDP_80P80_MHZ; 2846 case CH_WIDTH_5MHZ: 2847 return CDP_5_MHZ; 2848 case CH_WIDTH_10MHZ: 2849 return CDP_10_MHZ; 2850 case CH_WIDTH_320MHZ: 2851 return CDP_320_MHZ; 2852 default: 2853 return CDP_BW_INVALID; 2854 } 2855 2856 return CDP_BW_INVALID; 2857 } 2858 2859 #ifdef WLAN_FEATURE_FILS_SK 2860 bool hdd_is_fils_connection(struct hdd_context *hdd_ctx, 2861 struct hdd_adapter *adapter) 2862 { 2863 struct wlan_fils_connection_info *fils_info; 2864 2865 fils_info = wlan_cm_get_fils_connection_info(hdd_ctx->psoc, 2866 adapter->deflink->vdev_id); 2867 if (fils_info) 2868 return fils_info->is_fils_connection; 2869 2870 return false; 2871 } 2872 #else 2873 bool hdd_is_fils_connection(struct hdd_context *hdd_ctx, 2874 struct hdd_adapter *adapter) 2875 { 2876 return false; 2877 } 2878 #endif 2879 2880 void hdd_roam_profile_init(struct wlan_hdd_link_info *link_info) 2881 { 2882 struct csr_roam_profile *roam_profile; 2883 struct hdd_station_ctx *sta_ctx; 2884 2885 hdd_enter(); 2886 2887 roam_profile = hdd_roam_profile(link_info); 2888 qdf_mem_zero(roam_profile, sizeof(*roam_profile)); 2889 2890 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 2891 2892 /* Configure the roaming profile links to SSID and bssid. */ 2893 roam_profile->SSIDs.numOfSSIDs = 0; 2894 roam_profile->SSIDs.SSIDList = &sta_ctx->conn_info.ssid; 2895 2896 roam_profile->BSSIDs.numOfBSSIDs = 0; 2897 roam_profile->BSSIDs.bssid = &sta_ctx->conn_info.bssid; 2898 2899 /* Set the numOfChannels to zero to scan all the channels */ 2900 roam_profile->ChannelInfo.numOfChannels = 0; 2901 roam_profile->ChannelInfo.freq_list = NULL; 2902 2903 roam_profile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; 2904 2905 roam_profile->phyMode = eCSR_DOT11_MODE_AUTO; 2906 2907 /* Set the default scan mode */ 2908 link_info->adapter->scan_info.scan_mode = eSIR_ACTIVE_SCAN; 2909 2910 hdd_clear_roam_profile_ie(link_info->adapter); 2911 hdd_exit(); 2912 } 2913 2914 struct osif_cm_ops osif_ops = { 2915 .connect_complete_cb = hdd_cm_connect_complete, 2916 .disconnect_complete_cb = hdd_cm_disconnect_complete, 2917 .netif_queue_control_cb = hdd_cm_netif_queue_control, 2918 .napi_serialize_control_cb = hdd_cm_napi_serialize_control, 2919 .save_gtk_cb = hdd_cm_save_gtk, 2920 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 2921 .roam_rt_stats_event_cb = wlan_hdd_cfg80211_roam_events_callback, 2922 #endif 2923 #ifdef WLAN_FEATURE_FILS_SK 2924 .set_hlp_data_cb = hdd_cm_set_hlp_data, 2925 #endif 2926 #ifdef WLAN_FEATURE_PREAUTH_ENABLE 2927 .ft_preauth_complete_cb = hdd_cm_ft_preauth_complete, 2928 #ifdef FEATURE_WLAN_ESE 2929 .cckm_preauth_complete_cb = hdd_cm_cckm_preauth_complete, 2930 #endif 2931 #endif 2932 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 2933 .vendor_handoff_params_cb = hdd_cm_get_vendor_handoff_params, 2934 #endif 2935 .send_vdev_keys_cb = hdd_cm_send_vdev_keys, 2936 .get_scan_ie_params_cb = hdd_cm_get_scan_ie_params, 2937 #ifdef WLAN_BOOST_CPU_FREQ_IN_ROAM 2938 .perfd_set_cpufreq_cb = hdd_cm_perfd_set_cpufreq, 2939 #endif 2940 }; 2941 2942 QDF_STATUS hdd_cm_register_cb(void) 2943 { 2944 QDF_STATUS status; 2945 osif_cm_set_legacy_cb(&osif_ops); 2946 2947 status = osif_cm_register_cb(); 2948 if (QDF_IS_STATUS_ERROR(status)) 2949 return status; 2950 2951 /* Overwrite with UTF cb if UTF enabled */ 2952 return cm_utf_register_os_if_cb(); 2953 } 2954 2955 void hdd_cm_unregister_cb(void) 2956 { 2957 osif_cm_reset_legacy_cb(); 2958 } 2959