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 any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /** 19 * DOC: hdd_cm_connect.c 20 * 21 * WLAN Host Device Driver connect APIs implementation 22 * 23 */ 24 25 #include "wlan_hdd_main.h" 26 #include <wlan_hdd_mlo.h> 27 #include "wlan_hdd_cm_api.h" 28 #include "wlan_hdd_trace.h" 29 #include "wlan_hdd_object_manager.h" 30 #include "wlan_hdd_power.h" 31 #include "wlan_hdd_connectivity_logging.h" 32 #include <osif_cm_req.h> 33 #include <wlan_logging_sock_svc.h> 34 #include <wlan_hdd_green_ap.h> 35 #include <wlan_hdd_p2p.h> 36 #include <wlan_p2p_ucfg_api.h> 37 #include <wlan_pkt_capture_ucfg_api.h> 38 #include <wlan_hdd_ipa.h> 39 #include <wlan_ipa_ucfg_api.h> 40 #include <wlan_hdd_ftm_time_sync.h> 41 #include "wlan_crypto_global_api.h" 42 #include "wlan_vdev_mgr_ucfg_api.h" 43 #include "wlan_hdd_bootup_marker.h" 44 #include "sme_qos_internal.h" 45 #include "wlan_dlm_ucfg_api.h" 46 #include "wlan_hdd_scan.h" 47 #include "wlan_osif_priv.h" 48 #include <enet.h> 49 #include <wlan_mlme_twt_ucfg_api.h> 50 #include "wlan_roam_debug.h" 51 #include <wlan_hdd_regulatory.h> 52 #include "wlan_hdd_hostapd.h" 53 #include <wlan_twt_ucfg_ext_api.h> 54 #include <osif_twt_internal.h> 55 #include "wlan_osif_features.h" 56 #include "wlan_osif_request_manager.h" 57 #include <wlan_dp_ucfg_api.h> 58 #include "wlan_psoc_mlme_ucfg_api.h" 59 #include "wlan_action_oui_ucfg_api.h" 60 61 bool hdd_cm_is_vdev_associated(struct wlan_hdd_link_info *link_info) 62 { 63 struct wlan_objmgr_vdev *vdev; 64 bool is_vdev_active; 65 enum QDF_OPMODE opmode; 66 struct hdd_station_ctx *sta_ctx; 67 68 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 69 if (link_info->adapter->device_mode == QDF_NDI_MODE) 70 return (sta_ctx->conn_info.conn_state == 71 eConnectionState_NdiConnected); 72 73 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID); 74 if (!vdev) 75 return false; 76 77 opmode = wlan_vdev_mlme_get_opmode(vdev); 78 if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) { 79 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 80 return false; 81 } 82 is_vdev_active = ucfg_cm_is_vdev_active(vdev); 83 84 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 85 86 return is_vdev_active; 87 } 88 89 bool hdd_cm_is_vdev_connected(struct wlan_hdd_link_info *link_info) 90 { 91 struct wlan_objmgr_vdev *vdev; 92 bool is_vdev_connected; 93 struct hdd_station_ctx *sta_ctx; 94 enum QDF_OPMODE opmode = link_info->adapter->device_mode; 95 96 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 97 if (opmode == QDF_NDI_MODE) 98 return (sta_ctx->conn_info.conn_state == 99 eConnectionState_NdiConnected); 100 101 if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) 102 return false; 103 104 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID); 105 if (!vdev) 106 return false; 107 108 is_vdev_connected = ucfg_cm_is_vdev_connected(vdev); 109 110 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 111 112 return is_vdev_connected; 113 } 114 115 bool hdd_cm_is_connecting(struct wlan_hdd_link_info *link_info) 116 { 117 struct wlan_objmgr_vdev *vdev; 118 bool is_vdev_connecting; 119 enum QDF_OPMODE opmode; 120 121 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID); 122 if (!vdev) 123 return false; 124 125 opmode = wlan_vdev_mlme_get_opmode(vdev); 126 if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) { 127 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 128 return false; 129 } 130 is_vdev_connecting = ucfg_cm_is_vdev_connecting(vdev); 131 132 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 133 134 return is_vdev_connecting; 135 } 136 137 bool hdd_cm_is_disconnected(struct wlan_hdd_link_info *link_info) 138 { 139 struct wlan_objmgr_vdev *vdev; 140 bool is_vdev_disconnected; 141 enum QDF_OPMODE opmode; 142 143 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID); 144 if (!vdev) 145 return false; 146 147 opmode = wlan_vdev_mlme_get_opmode(vdev); 148 if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) { 149 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 150 return false; 151 } 152 is_vdev_disconnected = ucfg_cm_is_vdev_disconnected(vdev); 153 154 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 155 156 return is_vdev_disconnected; 157 } 158 159 bool hdd_cm_is_vdev_roaming(struct wlan_hdd_link_info *link_info) 160 { 161 struct wlan_objmgr_vdev *vdev; 162 bool is_vdev_roaming; 163 enum QDF_OPMODE opmode; 164 165 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID); 166 if (!vdev) 167 return false; 168 169 opmode = wlan_vdev_mlme_get_opmode(vdev); 170 if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) { 171 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 172 return false; 173 } 174 is_vdev_roaming = ucfg_cm_is_vdev_roaming(vdev); 175 176 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 177 178 return is_vdev_roaming; 179 } 180 181 void hdd_cm_set_peer_authenticate(struct wlan_hdd_link_info *link_info, 182 struct qdf_mac_addr *bssid, 183 bool is_auth_required) 184 { 185 hdd_debug("sta: " QDF_MAC_ADDR_FMT "Changing TL state to %s", 186 QDF_MAC_ADDR_REF(bssid->bytes), 187 is_auth_required ? "CONNECTED" : "AUTHENTICATED"); 188 189 hdd_change_peer_state(link_info, bssid->bytes, 190 is_auth_required ? 191 OL_TXRX_PEER_STATE_CONN : 192 OL_TXRX_PEER_STATE_AUTH); 193 hdd_conn_set_authenticated(link_info, !is_auth_required); 194 hdd_objmgr_set_peer_mlme_auth_state(link_info->vdev, 195 !is_auth_required); 196 } 197 198 void hdd_cm_update_rssi_snr_by_bssid(struct wlan_hdd_link_info *link_info) 199 { 200 struct hdd_station_ctx *sta_ctx; 201 int8_t snr = 0; 202 struct hdd_adapter *adapter = link_info->adapter; 203 mac_handle_t mac_handle; 204 205 if (!adapter) { 206 hdd_err_rl("null hdd_adapter pointer"); 207 return; 208 } 209 210 mac_handle = hdd_adapter_get_mac_handle(adapter); 211 212 if (!mac_handle) { 213 hdd_err_rl("null mac_handle pointer"); 214 return; 215 } 216 217 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 218 hdd_get_rssi_snr_by_bssid(mac_handle, 219 sta_ctx->conn_info.bssid.bytes, 220 &link_info->rssi, &snr); 221 222 /* If RSSi is reported as positive then it is invalid */ 223 if (link_info->rssi > 0) { 224 hdd_debug_rl("RSSI invalid %d", link_info->rssi); 225 link_info->rssi = 0; 226 } 227 228 hdd_debug("snr: %d, rssi: %d", snr, link_info->rssi); 229 230 sta_ctx->conn_info.signal = link_info->rssi; 231 sta_ctx->conn_info.noise = sta_ctx->conn_info.signal - snr; 232 sta_ctx->cache_conn_info.signal = sta_ctx->conn_info.signal; 233 sta_ctx->cache_conn_info.noise = sta_ctx->conn_info.noise; 234 } 235 236 void hdd_cm_handle_assoc_event(struct wlan_objmgr_vdev *vdev, uint8_t *peer_mac) 237 { 238 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 239 struct wlan_hdd_link_info *link_info; 240 struct hdd_station_ctx *sta_ctx; 241 int ret; 242 243 if (!hdd_ctx) { 244 hdd_err("hdd_ctx is NULL"); 245 return; 246 } 247 248 link_info = hdd_get_link_info_by_vdev(hdd_ctx, wlan_vdev_get_id(vdev)); 249 if (!link_info) { 250 hdd_err("adapter is NULL for vdev %d", wlan_vdev_get_id(vdev)); 251 return; 252 } 253 254 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 255 ret = hdd_objmgr_set_peer_mlme_state(link_info->vdev, 256 WLAN_ASSOC_STATE); 257 if (ret) 258 hdd_err("Peer object " QDF_MAC_ADDR_FMT " fail to set associated state", 259 QDF_MAC_ADDR_REF(peer_mac)); 260 ucfg_dp_add_latency_critical_client(vdev, 261 hdd_convert_cfgdot11mode_to_80211mode( 262 sta_ctx->conn_info.dot11mode)); 263 264 ucfg_dp_bus_bw_compute_prev_txrx_stats(vdev); 265 ucfg_dp_bus_bw_compute_timer_start(hdd_ctx->psoc); 266 267 if (ucfg_pkt_capture_get_pktcap_mode(hdd_ctx->psoc)) 268 ucfg_pkt_capture_record_channel(link_info->vdev); 269 } 270 271 /** 272 * hdd_cm_netif_features_update_required() - Check if feature update 273 * is required 274 * @adapter: pointer to the adapter structure 275 * Returns: true if the connection is legacy and TSO and Checksum offload 276 * enabled or if the connection is not latency and TSO and Checksum 277 * offload are not enabled, false otherwise 278 */ 279 static bool hdd_cm_netif_features_update_required(struct hdd_adapter *adapter) 280 { 281 bool is_legacy_connection = hdd_is_legacy_connection(adapter->deflink); 282 283 hdd_debug("Legacy Connection: %d, TSO_CSUM Feature Enabled:%d", 284 is_legacy_connection, adapter->tso_csum_feature_enabled); 285 286 if (adapter->tso_csum_feature_enabled && is_legacy_connection) 287 return true; 288 289 if (!adapter->tso_csum_feature_enabled && !is_legacy_connection) 290 return true; 291 292 return false; 293 } 294 295 void hdd_cm_netif_queue_enable(struct hdd_adapter *adapter) 296 { 297 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 298 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 299 300 if (cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload) && 301 hdd_cm_netif_features_update_required(adapter)) { 302 hdd_adapter_ops_record_event(hdd_ctx, 303 WLAN_HDD_ADAPTER_OPS_WORK_POST, 304 adapter->deflink->vdev_id); 305 qdf_queue_work(0, hdd_ctx->adapter_ops_wq, 306 &adapter->netdev_features_update_work); 307 } 308 309 wlan_hdd_netif_queue_control(adapter, 310 WLAN_WAKE_ALL_NETIF_QUEUE, 311 WLAN_CONTROL_PATH); 312 } 313 314 void hdd_cm_clear_pmf_stats(struct hdd_adapter *adapter) 315 { 316 qdf_mem_zero(&adapter->deflink->hdd_stats.hdd_pmf_stats, 317 sizeof(adapter->deflink->hdd_stats.hdd_pmf_stats)); 318 } 319 320 void hdd_cm_save_connect_status(struct wlan_hdd_link_info *link_info, 321 uint32_t reason_code) 322 { 323 struct hdd_station_ctx *hdd_sta_ctx; 324 325 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 326 link_info->adapter->connect_req_status = reason_code; 327 hdd_sta_ctx->conn_info.assoc_status_code = reason_code; 328 hdd_sta_ctx->cache_conn_info.assoc_status_code = reason_code; 329 } 330 331 #ifdef WLAN_FEATURE_11BE_MLO 332 QDF_STATUS hdd_cm_save_connected_links_info(struct qdf_mac_addr *self_mac, 333 struct qdf_mac_addr *bssid, 334 int32_t link_id) 335 { 336 struct hdd_context *hdd_ctx; 337 struct wlan_hdd_link_info *link_info; 338 struct hdd_station_ctx *sta_ctx; 339 340 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 341 if (!hdd_ctx) { 342 hdd_err("HDD context NULL"); 343 return QDF_STATUS_E_INVAL; 344 } 345 346 link_info = hdd_get_link_info_by_link_addr(hdd_ctx, self_mac); 347 if (!link_info) { 348 hdd_err("No link info with MAC: " QDF_MAC_ADDR_FMT, 349 QDF_MAC_ADDR_REF(self_mac->bytes)); 350 return QDF_STATUS_E_INVAL; 351 } 352 353 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 354 hdd_cm_set_ieee_link_id(link_info, link_id); 355 qdf_copy_macaddr(&sta_ctx->conn_info.bssid, bssid); 356 return QDF_STATUS_SUCCESS; 357 } 358 359 void 360 hdd_cm_set_ieee_link_id(struct wlan_hdd_link_info *link_info, uint8_t link_id) 361 { 362 struct hdd_station_ctx *sta_ctx = 363 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 364 365 hdd_debug("old_link_id:%d new_link_id:%d", 366 sta_ctx->conn_info.ieee_link_id, link_id); 367 sta_ctx->conn_info.ieee_link_id = link_id; 368 } 369 370 void 371 hdd_cm_clear_ieee_link_id(struct wlan_hdd_link_info *link_info) 372 { 373 struct hdd_station_ctx *sta_ctx = 374 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 375 376 hdd_debug("clear link id:%d", sta_ctx->conn_info.ieee_link_id); 377 sta_ctx->conn_info.ieee_link_id = WLAN_INVALID_LINK_ID; 378 } 379 #endif 380 381 #ifdef FEATURE_WLAN_WAPI 382 static bool hdd_cm_is_wapi_sta(enum csr_akm_type auth_type) 383 { 384 if (auth_type == eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE || 385 auth_type == eCSR_AUTH_TYPE_WAPI_WAI_PSK) 386 return true; 387 else 388 return false; 389 } 390 #else 391 static inline bool hdd_cm_is_wapi_sta(enum csr_akm_type auth_type) 392 { 393 return false; 394 } 395 #endif 396 397 static void hdd_update_scan_ie_for_connect(struct hdd_adapter *adapter, 398 struct osif_connect_params *params) 399 { 400 if (adapter->device_mode == QDF_P2P_CLIENT_MODE) { 401 params->scan_ie.ptr = 402 &adapter->scan_info.scan_add_ie.addIEdata[0]; 403 params->scan_ie.len = adapter->scan_info.scan_add_ie.length; 404 } else if (adapter->scan_info.default_scan_ies) { 405 params->scan_ie.ptr = adapter->scan_info.default_scan_ies; 406 params->scan_ie.len = adapter->scan_info.default_scan_ies_len; 407 } else if (adapter->scan_info.scan_add_ie.length) { 408 params->scan_ie.ptr = adapter->scan_info.scan_add_ie.addIEdata; 409 params->scan_ie.len = adapter->scan_info.scan_add_ie.length; 410 } 411 } 412 413 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)) || \ 414 defined(CFG80211_11BE_BASIC)) && \ 415 defined(WLAN_FEATURE_11BE) 416 /** 417 * hdd_update_action_oui_for_connect() - Update Action OUI for 802.11be AP 418 * @hdd_ctx: hdd context 419 * @req: connect request parameter 420 * 421 * If user sets flag ASSOC_REQ_DISABLE_EHT in connect request, driver 422 * will send action oui "ffffff 00 01" to host mlme and also firmware 423 * for action id ACTION_OUI_11BE_OUI_ALLOW, so that all the AP will 424 * be not matched with this OUI and 802.11be mode will not be allowed, 425 * possibly downgrade to 11ax will happen. 426 * If user doesn't set ASSOC_REQ_DISABLE_EHT, driver/firmware will 427 * recover to default INI setting. 428 * 429 * Returns: void 430 */ 431 static void 432 hdd_update_action_oui_for_connect(struct hdd_context *hdd_ctx, 433 struct cfg80211_connect_params *req) 434 { 435 QDF_STATUS status; 436 uint8_t *str; 437 bool usr_disable_eht; 438 439 if (!ucfg_action_oui_enabled(hdd_ctx->psoc)) 440 return; 441 442 usr_disable_eht = ucfg_mlme_get_usr_disable_sta_eht(hdd_ctx->psoc); 443 if (req->flags & ASSOC_REQ_DISABLE_EHT || 444 !(req->flags & CONNECT_REQ_MLO_SUPPORT)) { 445 if (usr_disable_eht) { 446 hdd_debug("user eht is disabled already"); 447 return; 448 } 449 status = ucfg_action_oui_cleanup( 450 hdd_ctx->psoc, ACTION_OUI_11BE_OUI_ALLOW); 451 if (!QDF_IS_STATUS_SUCCESS(status)) { 452 hdd_err("Failed to cleanup oui id %d", 453 ACTION_OUI_11BE_OUI_ALLOW); 454 return; 455 } 456 status = ucfg_action_oui_parse(hdd_ctx->psoc, 457 ACTION_OUI_INVALID, 458 ACTION_OUI_11BE_OUI_ALLOW); 459 if (!QDF_IS_STATUS_SUCCESS(status)) { 460 hdd_err("Failed to parse action_oui str for id %d", 461 ACTION_OUI_11BE_OUI_ALLOW); 462 return; 463 } 464 } else { 465 if (!usr_disable_eht) { 466 hdd_debug("user eht is enabled already"); 467 return; 468 } 469 status = ucfg_action_oui_cleanup(hdd_ctx->psoc, 470 ACTION_OUI_11BE_OUI_ALLOW); 471 if (!QDF_IS_STATUS_SUCCESS(status)) { 472 hdd_err("Failed to cleanup oui id %d", 473 ACTION_OUI_11BE_OUI_ALLOW); 474 return; 475 } 476 str = ucfg_action_oui_get_config(hdd_ctx->psoc, 477 ACTION_OUI_11BE_OUI_ALLOW); 478 if (!qdf_str_len(str)) 479 goto send_oui; 480 481 status = ucfg_action_oui_parse(hdd_ctx->psoc, 482 str, ACTION_OUI_11BE_OUI_ALLOW); 483 if (!QDF_IS_STATUS_SUCCESS(status)) { 484 hdd_err("Failed to parse action_oui str for id %d", 485 ACTION_OUI_11BE_OUI_ALLOW); 486 return; 487 } 488 } 489 490 send_oui: 491 status = ucfg_action_oui_send_by_id(hdd_ctx->psoc, 492 ACTION_OUI_11BE_OUI_ALLOW); 493 if (!QDF_IS_STATUS_SUCCESS(status)) { 494 hdd_err("Failed to send oui id %d", ACTION_OUI_11BE_OUI_ALLOW); 495 return; 496 } 497 ucfg_mlme_set_usr_disable_sta_eht(hdd_ctx->psoc, !usr_disable_eht); 498 } 499 #else 500 static void 501 hdd_update_action_oui_for_connect(struct hdd_context *hdd_ctx, 502 struct cfg80211_connect_params *req) 503 { 504 } 505 #endif 506 507 #ifdef WLAN_FEATURE_11BE 508 static inline bool 509 hdd_config_is_dot11mode_11be_only(struct hdd_config *config) 510 { 511 if (config->dot11Mode == eHDD_DOT11_MODE_11be_ONLY) 512 return true; 513 else 514 return false; 515 } 516 #else 517 static inline bool 518 hdd_config_is_dot11mode_11be_only(struct hdd_config *config) 519 { 520 return false; 521 } 522 #endif 523 524 /** 525 * hdd_get_dot11mode_filter() - Get dot11 mode filter 526 * @hdd_ctx: HDD context 527 * 528 * This function is used to get the dot11 mode filter 529 * 530 * Context: Any Context. 531 * Return: dot11_mode_filter 532 */ 533 static enum dot11_mode_filter 534 hdd_get_dot11mode_filter(struct hdd_context *hdd_ctx) 535 { 536 struct hdd_config *config = hdd_ctx->config; 537 538 if (config->dot11Mode == eHDD_DOT11_MODE_11n_ONLY) 539 return ALLOW_11N_ONLY; 540 else if (config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) 541 return ALLOW_11AC_ONLY; 542 else if (config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) 543 return ALLOW_11AX_ONLY; 544 else if (hdd_config_is_dot11mode_11be_only(config)) 545 return ALLOW_11BE_ONLY; 546 else 547 return ALLOW_ALL; 548 } 549 550 /** 551 * hdd_get_sap_adapter_of_dfs - Get sap adapter on dfs channel 552 * @hdd_ctx: HDD context 553 * 554 * This function is used to get the sap adapter on dfs channel. 555 * 556 * Return: pointer to adapter or null 557 */ 558 static struct hdd_adapter * 559 hdd_get_sap_adapter_of_dfs(struct hdd_context *hdd_ctx) 560 { 561 struct hdd_adapter *adapter, *next_adapter = NULL; 562 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 563 struct wlan_channel *chan; 564 struct ch_params ch_params = {0}; 565 struct wlan_hdd_link_info *link_info; 566 567 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 568 dbgid) { 569 if (adapter->device_mode != QDF_SAP_MODE) 570 goto loop_next; 571 572 hdd_adapter_for_each_active_link_info(adapter, link_info) { 573 if (wlan_hdd_validate_vdev_id(link_info->vdev_id)) 574 continue; 575 576 /* 577 * sap is not in started state and also not under doing 578 * CAC, so it is fine to go ahead with sta. 579 */ 580 if (!test_bit(SOFTAP_BSS_STARTED, 581 &link_info->link_flags) && 582 hdd_ctx->dev_dfs_cac_status != DFS_CAC_IN_PROGRESS) 583 continue; 584 585 wlan_objmgr_vdev_get_ref(link_info->vdev, 586 WLAN_HDD_ID_OBJ_MGR); 587 chan = wlan_vdev_get_active_channel(link_info->vdev); 588 if (!chan) { 589 hdd_debug("Can not get active channel"); 590 wlan_objmgr_vdev_release_ref(link_info->vdev, 591 WLAN_HDD_ID_OBJ_MGR); 592 continue; 593 } 594 595 wlan_objmgr_vdev_release_ref(link_info->vdev, 596 WLAN_HDD_ID_OBJ_MGR); 597 598 if (!wlan_reg_is_5ghz_ch_freq(chan->ch_freq)) 599 continue; 600 601 ch_params.ch_width = chan->ch_width; 602 if (ch_params.ch_width == CH_WIDTH_160MHZ) 603 wlan_reg_set_create_punc_bitmap(&ch_params, 604 true); 605 606 if (wlan_reg_get_5g_bonded_channel_state_for_pwrmode( 607 hdd_ctx->pdev, 608 chan->ch_freq, 609 &ch_params, 610 REG_CURRENT_PWR_MODE) == 611 CHANNEL_STATE_DFS) { 612 hdd_adapter_dev_put_debug(adapter, dbgid); 613 if (next_adapter) 614 hdd_adapter_dev_put_debug(next_adapter, 615 dbgid); 616 617 return adapter; 618 } 619 } 620 loop_next: 621 hdd_adapter_dev_put_debug(adapter, dbgid); 622 } 623 624 return NULL; 625 } 626 627 /** 628 * wlan_hdd_cm_handle_sap_sta_dfs_conc() - to handle SAP STA DFS conc 629 * @hdd_ctx: hdd_ctx 630 * @req: connect req 631 * 632 * This routine will move SAP from dfs to non-dfs, if sta is coming up. 633 * 634 * Return: false if sta-sap conc is not allowed, else return true 635 */ 636 static 637 bool wlan_hdd_cm_handle_sap_sta_dfs_conc(struct hdd_context *hdd_ctx, 638 struct cfg80211_connect_params *req) 639 { 640 struct hdd_adapter *ap_adapter; 641 struct hdd_ap_ctx *hdd_ap_ctx; 642 struct hdd_hostapd_state *hostapd_state; 643 QDF_STATUS status; 644 qdf_freq_t ch_freq = 0; 645 enum phy_ch_width ch_bw; 646 enum channel_state ch_state; 647 struct scan_filter *scan_filter; 648 qdf_list_t *list = NULL; 649 qdf_list_node_t *cur_lst = NULL; 650 struct scan_cache_node *cur_node = NULL; 651 bool is_6ghz_cap = false; 652 653 ap_adapter = hdd_get_sap_adapter_of_dfs(hdd_ctx); 654 /* probably no dfs sap running, no handling required */ 655 if (!ap_adapter) 656 return true; 657 658 /* if sap is currently doing CAC then don't allow sta to go further */ 659 if (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS) { 660 hdd_err("Concurrent SAP is in CAC state, STA is not allowed"); 661 return false; 662 } 663 664 /* 665 * log and return error, if we allow STA to go through, we don't 666 * know what is going to happen better stop sta connection 667 */ 668 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink); 669 if (!hdd_ap_ctx) { 670 hdd_err("AP context not found"); 671 return false; 672 } 673 674 if (req->channel && req->channel->center_freq) { 675 ch_freq = req->channel->center_freq; 676 goto def_chan; 677 } 678 /* 679 * find out by looking in to scan cache where sta is going to 680 * connect by passing its ssid amd bssid. 681 */ 682 scan_filter = qdf_mem_malloc(sizeof(*scan_filter)); 683 if (!scan_filter) 684 goto def_chan; 685 686 if (req->bssid) { 687 scan_filter->num_of_bssid = 1; 688 qdf_mem_copy(scan_filter->bssid_list[0].bytes, req->bssid, 689 QDF_MAC_ADDR_SIZE); 690 } 691 if (req->ssid_len > WLAN_SSID_MAX_LEN) { 692 scan_filter->num_of_ssid = 0; 693 hdd_err("req ssid len invalid %zu", req->ssid_len); 694 } else { 695 scan_filter->num_of_ssid = 1; 696 scan_filter->ssid_list[0].length = req->ssid_len; 697 qdf_mem_copy(scan_filter->ssid_list[0].ssid, req->ssid, 698 scan_filter->ssid_list[0].length); 699 } 700 scan_filter->ignore_auth_enc_type = true; 701 list = ucfg_scan_get_result(hdd_ctx->pdev, scan_filter); 702 qdf_mem_free(scan_filter); 703 704 if (!list || (list && !qdf_list_size(list))) { 705 hdd_debug("scan list empty"); 706 goto purge_list; 707 } 708 qdf_list_peek_front(list, &cur_lst); 709 if (!cur_lst) 710 goto purge_list; 711 712 cur_node = qdf_container_of(cur_lst, struct scan_cache_node, node); 713 ch_freq = cur_node->entry->channel.chan_freq; 714 purge_list: 715 if (list) 716 ucfg_scan_purge_results(list); 717 def_chan: 718 /* 719 * If the STA's channel is 2.4 GHz, then set pcl with only 2.4 GHz 720 * channels for roaming case. 721 */ 722 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { 723 hdd_info("sap is on dfs, new sta conn on 2.4 is allowed"); 724 return true; 725 } 726 727 if (policy_mgr_is_hw_sbs_capable(hdd_ctx->psoc) && 728 ch_freq && 729 policy_mgr_are_sbs_chan(hdd_ctx->psoc, 730 ch_freq, 731 hdd_ap_ctx->operating_chan_freq)) { 732 hdd_debug("sta freq %d sap freq %d in sbs mode is allowed", 733 ch_freq, hdd_ap_ctx->operating_chan_freq); 734 return true; 735 } 736 737 /* 738 * If channel is 0 or DFS or LTE unsafe then better to call pcl and 739 * find out the best channel. If channel is non-dfs 5 GHz then 740 * better move SAP to STA's channel to make scc, so we have room 741 * for 3port MCC scenario. 742 */ 743 ch_bw = hdd_ap_ctx->sap_config.ch_width_orig; 744 if (ch_freq) 745 is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(hdd_ctx->psoc, 746 ap_adapter->deflink->vdev_id, 747 NULL); 748 749 if (!ch_freq || wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, ch_freq) || 750 !policy_mgr_is_safe_channel(hdd_ctx->psoc, ch_freq) || 751 wlan_reg_is_passive_for_freq(hdd_ctx->pdev, ch_freq) || 752 (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) && !is_6ghz_cap)) 753 ch_freq = policy_mgr_get_nondfs_preferred_channel( 754 hdd_ctx->psoc, PM_SAP_MODE, 755 true, ap_adapter->deflink->vdev_id); 756 757 if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && 758 ch_bw > CH_WIDTH_20MHZ) { 759 struct ch_params ch_params; 760 761 qdf_mem_zero(&ch_params, sizeof(ch_params)); 762 ch_params.ch_width = ch_bw; 763 ch_state = 764 wlan_reg_get_5g_bonded_channel_state_for_pwrmode( 765 hdd_ctx->pdev, ch_freq, &ch_params, 766 REG_CURRENT_PWR_MODE); 767 while (ch_bw > CH_WIDTH_20MHZ && 768 ch_state != CHANNEL_STATE_ENABLE) { 769 ch_bw = 770 wlan_reg_get_next_lower_bandwidth(ch_bw); 771 ch_params.ch_width = ch_bw; 772 ch_state = 773 wlan_reg_get_5g_bonded_channel_state_for_pwrmode 774 (hdd_ctx->pdev, ch_freq, &ch_params, 775 REG_CURRENT_PWR_MODE); 776 } 777 hdd_debug("bw change from %d to %d", 778 hdd_ap_ctx->sap_config.ch_width_orig, 779 ch_bw); 780 } 781 782 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink); 783 qdf_event_reset(&hostapd_state->qdf_event); 784 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, ap_adapter->deflink->vdev_id, 785 CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS); 786 787 status = wlansap_set_channel_change_with_csa( 788 WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter->deflink), ch_freq, 789 ch_bw, false); 790 791 if (QDF_STATUS_SUCCESS != status) { 792 hdd_err("Set channel with CSA IE failed, can't allow STA"); 793 return false; 794 } 795 796 /* 797 * wait here for SAP to finish the channel switch. When channel 798 * switch happens, SAP sends few beacons with CSA_IE. After 799 * successfully Transmission of those beacons, it will move its 800 * state from started to disconnected and move to new channel. 801 * once it moves to new channel, sap again moves its state 802 * machine from disconnected to started and set this event. 803 * wait for 10 secs to finish this. 804 */ 805 status = qdf_wait_for_event_completion(&hostapd_state->qdf_event, 806 10000); 807 if (!QDF_IS_STATUS_SUCCESS(status)) { 808 hdd_err("wait for qdf_event failed, STA not allowed!!"); 809 return false; 810 } 811 812 return true; 813 } 814 815 int wlan_hdd_cm_connect(struct wiphy *wiphy, 816 struct net_device *ndev, 817 struct cfg80211_connect_params *req) 818 { 819 int status; 820 struct wlan_objmgr_vdev *vdev; 821 struct osif_connect_params params; 822 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); 823 struct hdd_context *hdd_ctx; 824 struct hdd_station_ctx *hdd_sta_ctx; 825 qdf_freq_t ch_freq = 0; 826 827 hdd_enter(); 828 829 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 830 hdd_err("Command not allowed in FTM mode"); 831 return -EINVAL; 832 } 833 834 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 835 return -EINVAL; 836 837 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, 838 TRACE_CODE_HDD_CFG80211_CONNECT, 839 adapter->deflink->vdev_id, adapter->device_mode); 840 841 if (adapter->device_mode != QDF_STA_MODE && 842 adapter->device_mode != QDF_P2P_CLIENT_MODE) { 843 hdd_err("Device_mode %s(%d) is not supported", 844 qdf_opmode_str(adapter->device_mode), 845 adapter->device_mode); 846 return -EINVAL; 847 } 848 849 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 850 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink); 851 852 status = wlan_hdd_validate_context(hdd_ctx); 853 if (status) 854 return status; 855 856 hdd_reg_wait_for_country_change(hdd_ctx); 857 858 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) && 859 !wlan_hdd_cm_handle_sap_sta_dfs_conc(hdd_ctx, req)) { 860 hdd_err("sap-sta conc will fail, can't allow sta"); 861 return -EINVAL; 862 } 863 864 if (req->channel && req->channel->center_freq) 865 ch_freq = req->channel->center_freq; 866 867 if (ch_freq && wlan_reg_is_6ghz_chan_freq(ch_freq) && 868 !wlan_reg_is_6ghz_band_set(hdd_ctx->pdev)) { 869 hdd_err("6 GHz band disabled"); 870 return -EINVAL; 871 } 872 873 qdf_mem_zero(¶ms, sizeof(params)); 874 ucfg_dlm_dump_deny_list_ap(hdd_ctx->pdev); 875 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_CM_ID); 876 if (!vdev) 877 return -EINVAL; 878 879 ucfg_pmo_flush_gtk_offload_req(vdev); 880 qdf_mem_zero(&hdd_sta_ctx->conn_info.conn_flag, 881 sizeof(hdd_sta_ctx->conn_info.conn_flag)); 882 883 /* 884 * Reset the ptk, gtk status flags to avoid using old/previous 885 * connection status. 886 */ 887 hdd_sta_ctx->conn_info.gtk_installed = false; 888 hdd_sta_ctx->conn_info.ptk_installed = false; 889 adapter->last_disconnect_reason = 0; 890 891 qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.connect); 892 hdd_prevent_suspend_timeout(HDD_WAKELOCK_CONNECT_COMPLETE, 893 WIFI_POWER_EVENT_WAKELOCK_CONNECT); 894 895 params.force_rsne_override = hdd_ctx->force_rsne_override; 896 params.dot11mode_filter = hdd_get_dot11mode_filter(hdd_ctx); 897 898 hdd_update_scan_ie_for_connect(adapter, ¶ms); 899 hdd_update_action_oui_for_connect(hdd_ctx, req); 900 901 if (!hdd_cm_is_vdev_associated(adapter->deflink)) { 902 /* 903 * Clear user/wpa_supplicant disabled_roaming flag for new 904 * connection 905 */ 906 ucfg_clear_user_disabled_roaming(hdd_ctx->psoc, 907 adapter->deflink->vdev_id); 908 } 909 status = osif_cm_connect(ndev, vdev, req, ¶ms); 910 911 if (status || ucfg_cm_is_vdev_roaming(vdev)) { 912 /* Release suspend and wake lock for failure or roam invoke */ 913 if (status) 914 hdd_err("Vdev %d connect failed status %d", 915 adapter->deflink->vdev_id, status); 916 else 917 hdd_debug("Vdev %d: connect lead to roam invoke", 918 adapter->deflink->vdev_id); 919 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect); 920 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT); 921 } 922 923 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 924 return status; 925 } 926 927 static void hdd_cm_rec_connect_info(struct wlan_cm_connect_resp *rsp) 928 { 929 if (rsp->is_reassoc) 930 wlan_rec_conn_info(rsp->vdev_id, DEBUG_CONN_ROAMED_IND, 931 rsp->bssid.bytes, rsp->cm_id, 0); 932 else 933 wlan_rec_conn_info(rsp->vdev_id, DEBUG_CONN_CONNECT_RESULT, 934 rsp->bssid.bytes, rsp->cm_id << 16 | 935 rsp->reason, 936 rsp->status_code); 937 } 938 939 static void 940 hdd_cm_connect_failure_pre_user_update(struct wlan_objmgr_vdev *vdev, 941 struct wlan_cm_connect_resp *rsp) 942 { 943 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 944 struct hdd_adapter *adapter; 945 struct hdd_station_ctx *hdd_sta_ctx; 946 uint32_t time_buffer_size; 947 struct wlan_hdd_link_info *link_info; 948 bool is_link_switch = 949 wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev); 950 951 if (!hdd_ctx) { 952 hdd_err("hdd_ctx is NULL"); 953 return; 954 } 955 956 link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id); 957 if (!link_info) { 958 hdd_err("adapter is NULL vdev %d", rsp->vdev_id); 959 return; 960 } 961 962 adapter = link_info->adapter; 963 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 964 time_buffer_size = sizeof(hdd_sta_ctx->conn_info.connect_time); 965 qdf_mem_zero(hdd_sta_ctx->conn_info.connect_time, time_buffer_size); 966 hdd_init_scan_reject_params(hdd_ctx); 967 hdd_cm_save_connect_status(link_info, rsp->status_code); 968 if (!is_link_switch) { 969 /* For link switch connection failure, do not clear existing 970 * connection info in OSIF. 971 */ 972 hdd_conn_remove_connect_info(hdd_sta_ctx); 973 hdd_adapter_reset_station_ctx(adapter); 974 } 975 976 ucfg_dp_remove_conn_info(vdev); 977 hdd_cm_update_rssi_snr_by_bssid(link_info); 978 hdd_cm_rec_connect_info(rsp); 979 hdd_debug("Invoking packetdump deregistration API"); 980 wlan_deregister_txrx_packetdump(OL_TXRX_PDEV_ID); 981 } 982 983 static void 984 hdd_cm_connect_failure_post_user_update(struct wlan_objmgr_vdev *vdev, 985 struct wlan_cm_connect_resp *rsp) 986 { 987 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 988 struct hdd_adapter *adapter; 989 struct wlan_hdd_link_info *link_info; 990 bool is_roam = rsp->is_reassoc; 991 992 if (!hdd_ctx) { 993 hdd_err("hdd_ctx is NULL"); 994 return; 995 } 996 997 link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id); 998 if (!link_info) { 999 hdd_err("adapter is NULL for vdev %d", rsp->vdev_id); 1000 return; 1001 } 1002 if (!is_roam) { 1003 /* call only for connect */ 1004 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect); 1005 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT); 1006 } 1007 1008 adapter = link_info->adapter; 1009 wlan_hdd_connectivity_fail_event(vdev, rsp); 1010 hdd_clear_roam_profile_ie(adapter); 1011 ucfg_cm_reset_key(hdd_ctx->pdev, link_info->vdev_id); 1012 hdd_wmm_dscp_initial_state(adapter); 1013 1014 /* 1015 * If connect failure is due to link switch, do not disable the 1016 * netdev queues as it will lead to data stall/NUD failure. 1017 */ 1018 if (!(rsp->cm_id & CM_ID_LSWITCH_BIT)) { 1019 hdd_debug("Disabling queues"); 1020 wlan_hdd_netif_queue_control(adapter, 1021 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 1022 WLAN_CONTROL_PATH); 1023 } 1024 1025 ucfg_dp_periodic_sta_stats_start(vdev); 1026 wlan_twt_concurrency_update(hdd_ctx); 1027 } 1028 1029 static void hdd_cm_connect_failure(struct wlan_objmgr_vdev *vdev, 1030 struct wlan_cm_connect_resp *rsp, 1031 enum osif_cb_type type) 1032 { 1033 switch (type) { 1034 case OSIF_PRE_USERSPACE_UPDATE: 1035 hdd_cm_connect_failure_pre_user_update(vdev, rsp); 1036 break; 1037 case OSIF_POST_USERSPACE_UPDATE: 1038 hdd_cm_connect_failure_post_user_update(vdev, rsp); 1039 break; 1040 default: 1041 hdd_cm_connect_failure_pre_user_update(vdev, rsp); 1042 hdd_cm_connect_failure_post_user_update(vdev, rsp); 1043 } 1044 } 1045 1046 /** 1047 * hdd_cm_update_prev_ap_ie() - Update the connected AP IEs 1048 * @hdd_sta_ctx: Station context. 1049 * @rsp: Connect response 1050 * 1051 * This API updates the connected ap beacon IEs to station context connection 1052 * info. 1053 * 1054 * Return: None 1055 */ 1056 static void hdd_cm_update_prev_ap_ie(struct hdd_station_ctx *hdd_sta_ctx, 1057 struct wlan_cm_connect_resp *rsp) 1058 { 1059 struct element_info *bcn_probe_rsp = &rsp->connect_ies.bcn_probe_rsp; 1060 struct element_info *bcn_ie; 1061 uint32_t len; 1062 1063 bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie; 1064 if (bcn_ie->ptr) { 1065 qdf_mem_free(bcn_ie->ptr); 1066 bcn_ie->ptr = NULL; 1067 bcn_ie->len = 0; 1068 } 1069 1070 if (bcn_probe_rsp->ptr && 1071 bcn_probe_rsp->len > sizeof(struct wlan_frame_hdr)) { 1072 len = bcn_probe_rsp->len - sizeof(struct wlan_frame_hdr); 1073 bcn_ie->ptr = qdf_mem_malloc(len); 1074 if (!bcn_ie->ptr) { 1075 bcn_ie->len = 0; 1076 return; 1077 } 1078 qdf_mem_copy(bcn_ie->ptr, bcn_probe_rsp->ptr + 1079 sizeof(struct wlan_frame_hdr), len); 1080 bcn_ie->len = len; 1081 } 1082 } 1083 1084 static void hdd_cm_save_bss_info(struct wlan_hdd_link_info *link_info, 1085 struct wlan_cm_connect_resp *rsp) 1086 { 1087 struct hdd_context *hdd_ctx; 1088 struct hdd_station_ctx *hdd_sta_ctx; 1089 QDF_STATUS status; 1090 struct hdd_adapter *adapter = link_info->adapter; 1091 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 1092 struct sDot11fAssocResponse *assoc_resp; 1093 1094 if (!mac_handle) { 1095 hdd_err("mac handle is null"); 1096 return; 1097 } 1098 1099 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1100 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 1101 1102 assoc_resp = qdf_mem_malloc(sizeof(struct sDot11fAssocResponse)); 1103 if (!assoc_resp) 1104 return; 1105 1106 qdf_mem_zero(&hdd_sta_ctx->conn_info.hs20vendor_ie, 1107 sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie)); 1108 if (rsp->connect_ies.bcn_probe_rsp.ptr) 1109 sme_get_hs20vendor_ie(mac_handle, 1110 rsp->connect_ies.bcn_probe_rsp.ptr, 1111 rsp->connect_ies.bcn_probe_rsp.len, 1112 &hdd_sta_ctx->conn_info.hs20vendor_ie); 1113 1114 status = sme_unpack_assoc_rsp(mac_handle, rsp, assoc_resp); 1115 if (QDF_IS_STATUS_ERROR(status)) { 1116 hdd_err("could not parse assoc response"); 1117 qdf_mem_free(assoc_resp); 1118 return; 1119 } 1120 1121 if (assoc_resp->VHTCaps.present) { 1122 hdd_sta_ctx->conn_info.conn_flag.vht_present = true; 1123 hdd_copy_vht_caps(&hdd_sta_ctx->conn_info.vht_caps, 1124 &assoc_resp->VHTCaps); 1125 } else { 1126 hdd_sta_ctx->conn_info.conn_flag.vht_present = false; 1127 } 1128 if (assoc_resp->HTCaps.present) { 1129 hdd_sta_ctx->conn_info.conn_flag.ht_present = true; 1130 hdd_copy_ht_caps(&hdd_sta_ctx->conn_info.ht_caps, 1131 &assoc_resp->HTCaps); 1132 } else { 1133 hdd_sta_ctx->conn_info.conn_flag.ht_present = false; 1134 } 1135 if (rsp->is_reassoc) 1136 hdd_sta_ctx->conn_info.roam_count++; 1137 1138 if (assoc_resp->HTInfo.present) { 1139 hdd_sta_ctx->conn_info.conn_flag.ht_op_present = true; 1140 hdd_copy_ht_operation(hdd_sta_ctx, &assoc_resp->HTInfo); 1141 } else { 1142 hdd_sta_ctx->conn_info.conn_flag.ht_op_present = false; 1143 } 1144 if (assoc_resp->VHTOperation.present) { 1145 hdd_sta_ctx->conn_info.conn_flag.vht_op_present = true; 1146 hdd_copy_vht_operation(hdd_sta_ctx, &assoc_resp->VHTOperation); 1147 } else { 1148 hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false; 1149 } 1150 1151 if (assoc_resp->he_cap.present) 1152 hdd_sta_ctx->conn_info.conn_flag.he_present = true; 1153 else 1154 hdd_sta_ctx->conn_info.conn_flag.he_present = false; 1155 1156 if (assoc_resp->eht_cap.present) 1157 hdd_sta_ctx->conn_info.conn_flag.eht_present = true; 1158 else 1159 hdd_sta_ctx->conn_info.conn_flag.eht_present = false; 1160 1161 if (assoc_resp->eht_op.present) 1162 hdd_sta_ctx->conn_info.conn_flag.eht_op_present = true; 1163 else 1164 hdd_sta_ctx->conn_info.conn_flag.eht_op_present = false; 1165 1166 /* 1167 * Cache connection info only in case of station 1168 */ 1169 if (adapter->device_mode == QDF_STA_MODE) { 1170 /* Cleanup already existing he info */ 1171 hdd_cleanup_conn_info(link_info); 1172 1173 hdd_copy_eht_operation(hdd_sta_ctx, &assoc_resp->eht_op); 1174 /* Cache last connection info */ 1175 qdf_mem_copy(&hdd_sta_ctx->cache_conn_info, 1176 &hdd_sta_ctx->conn_info, 1177 sizeof(hdd_sta_ctx->cache_conn_info)); 1178 1179 hdd_copy_he_operation(hdd_sta_ctx, &assoc_resp->he_op); 1180 hdd_cm_update_prev_ap_ie(hdd_sta_ctx, rsp); 1181 } 1182 1183 qdf_mem_free(assoc_resp); 1184 } 1185 1186 #ifdef FEATURE_WLAN_ESE 1187 static bool hdd_is_ese_assoc(enum csr_akm_type auth_type, 1188 tDot11fBeaconIEs *bcn_ie, 1189 struct mac_context *mac_ctx) 1190 { 1191 if ((csr_is_auth_type_ese(auth_type) || 1192 (bcn_ie->ESEVersion.present && 1193 auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) && 1194 mac_ctx->mlme_cfg->lfr.ese_enabled) { 1195 return true; 1196 } 1197 1198 return false; 1199 } 1200 #else 1201 static bool hdd_is_ese_assoc(enum csr_akm_type auth_type, 1202 tDot11fBeaconIEs *bcn_ie, 1203 struct mac_context *mac_ctx) 1204 { 1205 return false; 1206 } 1207 #endif 1208 1209 static const uint8_t acm_mask_bit[WLAN_MAX_AC] = { 1210 0x4, /* SME_AC_BK */ 1211 0x8, /* SME_AC_BE */ 1212 0x2, /* SME_AC_VI */ 1213 0x1 /* SME_AC_VO */ 1214 }; 1215 1216 static void hdd_wmm_cm_connect(struct wlan_objmgr_vdev *vdev, 1217 struct hdd_adapter *adapter, 1218 tDot11fBeaconIEs *bcn_ie, 1219 enum csr_akm_type auth_type) 1220 { 1221 int ac; 1222 bool qap; 1223 bool qos_connection; 1224 uint8_t acm_mask = 0; 1225 struct vdev_mlme_obj *vdev_mlme; 1226 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 1227 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 1228 1229 if (!mac_handle) { 1230 hdd_err("mac handle is null"); 1231 return; 1232 } 1233 1234 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 1235 if (!vdev_mlme) { 1236 hdd_err("vdev component object is NULL"); 1237 return; 1238 } 1239 if (CSR_IS_QOS_BSS(bcn_ie) || bcn_ie->HTCaps.present) 1240 /* Some HT AP's dont send WMM IE so in that case we 1241 * assume all HT Ap's are Qos Enabled AP's 1242 */ 1243 qap = true; 1244 else 1245 qap = false; 1246 1247 qos_connection = vdev_mlme->ext_vdev_ptr->connect_info.qos_enabled; 1248 1249 acm_mask = sme_qos_get_acm_mask(mac_ctx, NULL, bcn_ie); 1250 1251 hdd_debug("qap is %d, qos_connection is %d, acm_mask is 0x%x", 1252 qap, qos_connection, acm_mask); 1253 1254 adapter->hdd_wmm_status.qap = qap; 1255 adapter->hdd_wmm_status.qos_connection = qos_connection; 1256 1257 if (acm_mask) 1258 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, 1259 (uint8_t *)acm_mask_bit, WLAN_MAX_AC); 1260 1261 for (ac = 0; ac < WLAN_MAX_AC; ac++) { 1262 if (qap && qos_connection && (acm_mask & acm_mask_bit[ac])) { 1263 1264 /* admission is required */ 1265 adapter->hdd_wmm_status.ac_status[ac]. 1266 is_access_required = true; 1267 adapter->hdd_wmm_status.ac_status[ac]. 1268 is_access_allowed = false; 1269 adapter->hdd_wmm_status.ac_status[ac]. 1270 was_access_granted = false; 1271 /* after reassoc if we have valid tspec, allow access */ 1272 if (adapter->hdd_wmm_status.ac_status[ac]. 1273 is_tspec_valid && 1274 (adapter->hdd_wmm_status.ac_status[ac]. 1275 tspec.ts_info.direction != 1276 SME_QOS_WMM_TS_DIR_DOWNLINK)) { 1277 adapter->hdd_wmm_status.ac_status[ac]. 1278 is_access_allowed = true; 1279 } 1280 if (!sme_neighbor_roam_is11r_assoc( 1281 mac_handle, 1282 adapter->deflink->vdev_id) && 1283 !hdd_is_ese_assoc(auth_type, bcn_ie, mac_ctx)) { 1284 adapter->hdd_wmm_status.ac_status[ac]. 1285 is_tspec_valid = false; 1286 adapter->hdd_wmm_status.ac_status[ac]. 1287 is_access_allowed = false; 1288 } 1289 } else { 1290 /* admission is not required so access is allowed */ 1291 adapter->hdd_wmm_status.ac_status[ac]. 1292 is_access_required = false; 1293 adapter->hdd_wmm_status.ac_status[ac]. 1294 is_access_allowed = true; 1295 } 1296 } 1297 } 1298 1299 static void hdd_cm_save_connect_info(struct wlan_hdd_link_info *link_info, 1300 struct wlan_cm_connect_resp *rsp) 1301 { 1302 struct hdd_station_ctx *sta_ctx; 1303 struct wlan_crypto_params *crypto_params; 1304 struct wlan_channel *des_chan; 1305 struct wlan_objmgr_vdev *vdev; 1306 uint8_t *ie_field; 1307 uint32_t ie_len, status; 1308 tDot11fBeaconIEs *bcn_ie; 1309 struct s_ext_cap *p_ext_cap = NULL; 1310 struct hdd_adapter *adapter = link_info->adapter; 1311 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 1312 uint32_t phymode; 1313 1314 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 1315 bcn_ie = qdf_mem_malloc(sizeof(*bcn_ie)); 1316 if (!bcn_ie) 1317 return; 1318 1319 qdf_copy_macaddr(&sta_ctx->conn_info.bssid, &rsp->bssid); 1320 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID); 1321 if (vdev) { 1322 ucfg_dp_conn_info_set_bssid(vdev, &rsp->bssid); 1323 hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID); 1324 } 1325 1326 phymode = wlan_reg_get_max_phymode(adapter->hdd_ctx->pdev, 1327 REG_PHYMODE_MAX, 1328 rsp->freq); 1329 1330 sta_ctx->reg_phymode = csr_convert_from_reg_phy_mode(phymode); 1331 1332 sta_ctx->conn_info.assoc_status_code = rsp->status_code; 1333 1334 crypto_params = 1335 wlan_crypto_vdev_get_crypto_params(link_info->vdev); 1336 1337 if (crypto_params) { 1338 sme_fill_enc_type(&sta_ctx->conn_info.uc_encrypt_type, 1339 crypto_params->ucastcipherset); 1340 1341 sme_fill_auth_type(&sta_ctx->conn_info.auth_type, 1342 crypto_params->authmodeset, 1343 crypto_params->key_mgmt, 1344 crypto_params->ucastcipherset); 1345 sta_ctx->conn_info.last_auth_type = 1346 sta_ctx->conn_info.auth_type; 1347 } 1348 des_chan = wlan_vdev_mlme_get_des_chan(link_info->vdev); 1349 1350 sta_ctx->conn_info.chan_freq = rsp->freq; 1351 1352 /* Save the ssid for the connection */ 1353 qdf_mem_copy(&sta_ctx->conn_info.ssid.SSID.ssId, 1354 &rsp->ssid.ssid, 1355 rsp->ssid.length); 1356 qdf_mem_copy(&sta_ctx->conn_info.last_ssid.SSID.ssId, 1357 &rsp->ssid.ssid, 1358 rsp->ssid.length); 1359 sta_ctx->conn_info.ssid.SSID.length = rsp->ssid.length; 1360 sta_ctx->conn_info.last_ssid.SSID.length = rsp->ssid.length; 1361 1362 sta_ctx->conn_info.dot11mode = 1363 sme_phy_mode_to_dot11mode(des_chan->ch_phymode); 1364 1365 sta_ctx->conn_info.ch_width = des_chan->ch_width; 1366 if (!rsp->connect_ies.bcn_probe_rsp.ptr || 1367 (rsp->connect_ies.bcn_probe_rsp.len < 1368 (sizeof(struct wlan_frame_hdr) + 1369 offsetof(struct wlan_bcn_frame, ie)))) { 1370 hdd_err("beacon len is invalid %d", 1371 rsp->connect_ies.bcn_probe_rsp.len); 1372 qdf_mem_free(bcn_ie); 1373 return; 1374 } 1375 1376 ie_len = (rsp->connect_ies.bcn_probe_rsp.len - 1377 sizeof(struct wlan_frame_hdr) - 1378 offsetof(struct wlan_bcn_frame, ie)); 1379 ie_field = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr + 1380 sizeof(struct wlan_frame_hdr) + 1381 offsetof(struct wlan_bcn_frame, ie)); 1382 1383 status = dot11f_unpack_beacon_i_es(MAC_CONTEXT(mac_handle), ie_field, 1384 ie_len, bcn_ie, false); 1385 1386 if (DOT11F_FAILED(status)) { 1387 hdd_err("Failed to parse beacon ie"); 1388 qdf_mem_free(bcn_ie); 1389 return; 1390 } 1391 if (bcn_ie->ExtCap.present) { 1392 p_ext_cap = (struct s_ext_cap *)bcn_ie->ExtCap.bytes; 1393 sta_ctx->conn_info.proxy_arp_service = 1394 p_ext_cap->proxy_arp_service; 1395 1396 } 1397 1398 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID); 1399 if (vdev) { 1400 sta_ctx->conn_info.nss = wlan_vdev_mlme_get_nss(vdev); 1401 ucfg_wlan_vdev_mgr_get_param(vdev, WLAN_MLME_CFG_RATE_FLAGS, 1402 &sta_ctx->conn_info.rate_flags); 1403 hdd_wmm_cm_connect(vdev, adapter, bcn_ie, 1404 sta_ctx->conn_info.auth_type); 1405 1406 if (p_ext_cap) 1407 ucfg_dp_conn_info_set_arp_service(vdev, 1408 p_ext_cap->proxy_arp_service); 1409 1410 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID); 1411 } 1412 qdf_mem_free(bcn_ie); 1413 1414 hdd_cm_save_bss_info(link_info, rsp); 1415 } 1416 1417 #ifdef WLAN_FEATURE_FILS_SK 1418 static bool hdd_cm_is_fils_connection(struct wlan_cm_connect_resp *rsp) 1419 { 1420 return rsp->is_fils_connection; 1421 } 1422 #else 1423 static inline 1424 bool hdd_cm_is_fils_connection(struct wlan_cm_connect_resp *rsp) 1425 { 1426 return false; 1427 } 1428 #endif 1429 1430 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 1431 static bool hdd_cm_is_roam_auth_required(struct hdd_station_ctx *sta_ctx, 1432 struct wlan_cm_connect_resp *rsp) 1433 { 1434 if (!rsp->roaming_info) 1435 return false; 1436 1437 if (rsp->roaming_info->auth_status == ROAM_AUTH_STATUS_AUTHENTICATED) 1438 return false; 1439 1440 return true; 1441 } 1442 #else 1443 static bool hdd_cm_is_roam_auth_required(struct hdd_station_ctx *sta_ctx, 1444 struct wlan_cm_connect_resp *rsp) 1445 { 1446 return true; 1447 } 1448 #endif 1449 1450 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 1451 #ifndef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 1452 struct hdd_adapter *hdd_get_assoc_link_adapter(struct hdd_adapter *ml_adapter) 1453 { 1454 int i; 1455 bool eht_capab; 1456 struct hdd_adapter *link_adapter; 1457 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ml_adapter); 1458 1459 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 1460 if (!eht_capab || hdd_adapter_is_sl_ml_adapter(ml_adapter)) 1461 return ml_adapter; 1462 1463 for (i = 0; i < WLAN_MAX_MLD; i++) { 1464 link_adapter = ml_adapter->mlo_adapter_info.link_adapter[i]; 1465 if (link_adapter) { 1466 if (hdd_adapter_is_associated_with_ml_adapter( 1467 link_adapter)) 1468 return link_adapter; 1469 } 1470 } 1471 1472 return NULL; 1473 } 1474 #endif 1475 1476 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 1477 static void hdd_set_immediate_power_save(struct hdd_adapter *adapter, 1478 bool is_immediate_powersave) 1479 { 1480 struct hdd_station_ctx *sta_ctx; 1481 struct wlan_hdd_link_info *link_info; 1482 1483 hdd_adapter_for_each_active_link_info(adapter, link_info) { 1484 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 1485 sta_ctx->ap_supports_immediate_power_save = 1486 is_immediate_powersave; 1487 } 1488 } 1489 #else 1490 static void hdd_set_immediate_power_save(struct hdd_adapter *adapter, 1491 bool is_immediate_powersave) 1492 { 1493 struct hdd_adapter *link_adapter; 1494 struct hdd_mlo_adapter_info *mlo_adapter_info; 1495 struct hdd_station_ctx *sta_ctx; 1496 int i; 1497 1498 if (!hdd_adapter_is_ml_adapter(adapter)) 1499 goto update_non_ml; 1500 1501 mlo_adapter_info = &adapter->mlo_adapter_info; 1502 for (i = 0; i < WLAN_MAX_MLD; i++) { 1503 link_adapter = mlo_adapter_info->link_adapter[i]; 1504 if (!link_adapter) 1505 continue; 1506 1507 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_adapter->deflink); 1508 sta_ctx->ap_supports_immediate_power_save = 1509 is_immediate_powersave; 1510 } 1511 1512 update_non_ml: 1513 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink); 1514 sta_ctx->ap_supports_immediate_power_save = is_immediate_powersave; 1515 } 1516 #endif 1517 #else 1518 static void hdd_set_immediate_power_save(struct hdd_adapter *adapter, 1519 bool is_immediate_powersave) 1520 { 1521 struct hdd_station_ctx *sta_ctx; 1522 1523 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink); 1524 sta_ctx->ap_supports_immediate_power_save = is_immediate_powersave; 1525 } 1526 #endif 1527 1528 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 1529 static QDF_STATUS 1530 hdd_cm_mlme_send_standby_link_chn_width(struct hdd_adapter *adapter, 1531 struct wlan_objmgr_vdev *vdev) 1532 { 1533 struct wlan_objmgr_psoc *psoc; 1534 struct wlan_hdd_link_info *link_info; 1535 struct hdd_station_ctx *sta_ctx; 1536 uint8_t link_id = wlan_vdev_get_link_id(vdev); 1537 uint8_t ch_width; 1538 enum phy_ch_width connection_ch_width = CH_WIDTH_INVALID; 1539 1540 psoc = wlan_vdev_get_psoc(vdev); 1541 if (!psoc) { 1542 hdd_err("Failed to get PSOC Object"); 1543 return QDF_STATUS_E_INVAL; 1544 } 1545 1546 link_info = hdd_get_link_info_by_ieee_link_id(adapter, link_id); 1547 if (!link_info) { 1548 hdd_err("Link info not found by linkid:%u", link_id); 1549 return QDF_STATUS_E_INVAL; 1550 } 1551 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 1552 ch_width = sta_ctx->user_cfg_chn_width; 1553 1554 wlan_mlme_get_sta_ch_width(vdev, &connection_ch_width); 1555 1556 if (ch_width == CH_WIDTH_INVALID) { 1557 hdd_debug("no cached bandwidth for the link %u", link_id); 1558 return QDF_STATUS_SUCCESS; 1559 } 1560 1561 if (ch_width == connection_ch_width) { 1562 hdd_debug("user config max bd same as connection ch bw:%u", 1563 ch_width); 1564 return QDF_STATUS_SUCCESS; 1565 } 1566 1567 hdd_debug("send vdev id:%u, chwidth:%u", link_info->vdev_id, 1568 ch_width); 1569 1570 wlan_mlme_send_ch_width_update_with_notify(psoc, vdev, 1571 link_info->vdev_id, 1572 ch_width); 1573 return QDF_STATUS_SUCCESS; 1574 } 1575 #else 1576 static QDF_STATUS 1577 hdd_cm_mlme_send_standby_link_chn_width(struct hdd_adapter *adapter, 1578 struct wlan_objmgr_vdev *vdev) 1579 { 1580 return QDF_STATUS_SUCCESS; 1581 } 1582 #endif 1583 1584 static void 1585 hdd_cm_connect_success_pre_user_update(struct wlan_objmgr_vdev *vdev, 1586 struct wlan_cm_connect_resp *rsp) 1587 { 1588 struct hdd_context *hdd_ctx; 1589 struct hdd_adapter *adapter; 1590 struct hdd_station_ctx *sta_ctx; 1591 struct vdev_mlme_obj *vdev_mlme; 1592 unsigned long rc; 1593 uint32_t ie_len; 1594 uint8_t *ie_field; 1595 mac_handle_t mac_handle; 1596 bool is_auth_required = true; 1597 bool is_roam_offload = false; 1598 bool is_roam = rsp->is_reassoc; 1599 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 1600 uint8_t uapsd_mask = 0; 1601 uint32_t time_buffer_size; 1602 struct hdd_adapter *assoc_link_adapter; 1603 bool is_immediate_power_save; 1604 struct wlan_hdd_link_info *link_info; 1605 QDF_STATUS status = QDF_STATUS_E_INVAL; 1606 bool alt_pipe; 1607 1608 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 1609 if (!hdd_ctx) { 1610 hdd_err("hdd_ctx is NULL"); 1611 return; 1612 } 1613 1614 link_info = hdd_get_link_info_by_vdev(hdd_ctx, wlan_vdev_get_id(vdev)); 1615 if (!link_info) { 1616 hdd_err("Invalid vdev"); 1617 return; 1618 } 1619 1620 adapter = link_info->adapter; 1621 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 1622 mac_handle = hdd_adapter_get_mac_handle(adapter); 1623 1624 wlan_hdd_ft_set_key_delay(vdev); 1625 hdd_cm_update_rssi_snr_by_bssid(link_info); 1626 hdd_cm_save_connect_status(link_info, rsp->status_code); 1627 1628 hdd_init_scan_reject_params(hdd_ctx); 1629 time_buffer_size = sizeof(sta_ctx->conn_info.connect_time); 1630 qdf_mem_zero(sta_ctx->conn_info.connect_time, time_buffer_size); 1631 qdf_get_time_of_the_day_in_hr_min_sec_usec(sta_ctx->conn_info.connect_time, 1632 time_buffer_size); 1633 hdd_start_tsf_sync(adapter); 1634 hdd_cm_rec_connect_info(rsp); 1635 1636 hdd_cm_save_connect_info(link_info, rsp); 1637 if (adapter->device_mode == QDF_STA_MODE && 1638 hdd_adapter_is_ml_adapter(adapter)) { 1639 /* Save connection info in assoc link adapter as well */ 1640 assoc_link_adapter = hdd_get_assoc_link_adapter(adapter); 1641 if (assoc_link_adapter) 1642 hdd_cm_save_connect_info(assoc_link_adapter->deflink, 1643 rsp); 1644 } 1645 if (hdd_add_beacon_filter(adapter) != 0) 1646 hdd_err("add beacon filter failed"); 1647 1648 adapter->wapi_info.is_wapi_sta = hdd_cm_is_wapi_sta( 1649 sta_ctx->conn_info.auth_type); 1650 if (adapter->device_mode == QDF_STA_MODE && 1651 rsp->connect_ies.bcn_probe_rsp.ptr && 1652 (rsp->connect_ies.bcn_probe_rsp.len > 1653 (sizeof(struct wlan_frame_hdr) + 1654 offsetof(struct wlan_bcn_frame, ie)))) { 1655 ie_len = (rsp->connect_ies.bcn_probe_rsp.len - 1656 sizeof(struct wlan_frame_hdr) - 1657 offsetof(struct wlan_bcn_frame, ie)); 1658 1659 ie_field = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr + 1660 sizeof(struct wlan_frame_hdr) + 1661 offsetof(struct wlan_bcn_frame, ie)); 1662 is_immediate_power_save = 1663 wlan_hdd_is_ap_supports_immediate_power_save( 1664 ie_field, ie_len); 1665 hdd_set_immediate_power_save(adapter, is_immediate_power_save); 1666 hdd_debug("ap_supports_immediate_power_save flag [%d]", 1667 sta_ctx->ap_supports_immediate_power_save); 1668 } 1669 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, true); 1670 1671 hdd_cm_handle_assoc_event(vdev, rsp->bssid.bytes); 1672 1673 if (ucfg_cm_is_link_switch_connect_resp(rsp)) { 1674 if (hdd_cm_mlme_send_standby_link_chn_width(adapter, vdev)) 1675 hdd_debug("send standby link chn width fail"); 1676 } 1677 1678 /* 1679 * check update hdd_send_update_beacon_ies_event, 1680 * hdd_send_ft_assoc_response, 1681 */ 1682 1683 wlan_hdd_set_tx_flow_info(); 1684 hdd_place_marker(adapter, "ASSOCIATION COMPLETE", NULL); 1685 1686 if (policy_mgr_is_mcc_in_24G(hdd_ctx->psoc)) { 1687 if (hdd_ctx->miracast_value) 1688 wlan_hdd_set_mas(adapter, hdd_ctx->miracast_value); 1689 } 1690 1691 if (!is_roam) { 1692 /* Initialize the Linkup event completion variable */ 1693 INIT_COMPLETION(adapter->linkup_event_var); 1694 1695 /* 1696 * Enable Linkup Event Servicing which allows the net 1697 * device notifier to set the linkup event variable. 1698 */ 1699 adapter->is_link_up_service_needed = true; 1700 1701 /* Switch on the Carrier to activate the device */ 1702 wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_CARRIER_ON, 1703 WLAN_CONTROL_PATH); 1704 1705 /* 1706 * Wait for the Link to up to ensure all the queues 1707 * are set properly by the kernel. 1708 */ 1709 rc = wait_for_completion_timeout( 1710 &adapter->linkup_event_var, 1711 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)); 1712 /* 1713 * Disable Linkup Event Servicing - no more service 1714 * required from the net device notifier call. 1715 */ 1716 adapter->is_link_up_service_needed = false; 1717 } 1718 1719 vdev_mlme = wlan_objmgr_vdev_get_comp_private_obj(vdev, 1720 WLAN_UMAC_COMP_MLME); 1721 if (vdev_mlme) 1722 uapsd_mask = 1723 vdev_mlme->ext_vdev_ptr->connect_info.uapsd_per_ac_bitmask; 1724 1725 cdp_hl_fc_set_td_limit(soc, link_info->vdev_id, 1726 sta_ctx->conn_info.chan_freq); 1727 hdd_wmm_assoc(adapter, false, uapsd_mask); 1728 1729 if (!rsp->is_wps_connection && 1730 !rsp->is_osen_connection && 1731 (sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_NONE || 1732 sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM || 1733 sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_SHARED_KEY || 1734 hdd_cm_is_fils_connection(rsp))) 1735 is_auth_required = false; 1736 1737 if (is_roam) 1738 /* If roaming is set check if FW roaming/LFR3 */ 1739 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &is_roam_offload); 1740 1741 if (is_roam_offload || !is_roam) { 1742 /* For FW_ROAM/LFR3 OR connect */ 1743 /* for LFR 3 get authenticated info from resp */ 1744 if (is_roam) { 1745 is_auth_required = 1746 hdd_cm_is_roam_auth_required(sta_ctx, rsp); 1747 if (is_auth_required) 1748 wlan_acquire_peer_key_wakelock(hdd_ctx->pdev, 1749 rsp->bssid.bytes); 1750 } 1751 hdd_debug("is_roam_offload %d, is_roam %d, is_auth_required %d", 1752 is_roam_offload, is_roam, is_auth_required); 1753 hdd_roam_register_sta(link_info, &rsp->bssid, is_auth_required); 1754 } else { 1755 /* for host roam/LFR2 */ 1756 hdd_cm_set_peer_authenticate(link_info, 1757 &rsp->bssid, is_auth_required); 1758 } 1759 1760 hdd_debug("Enabling queues"); 1761 hdd_cm_netif_queue_enable(adapter); 1762 1763 /* send peer status indication to oem app */ 1764 if (vdev_mlme) { 1765 hdd_send_peer_status_ind_to_app( 1766 &rsp->bssid, 1767 ePeerConnected, 1768 vdev_mlme->ext_vdev_ptr->connect_info.timing_meas_cap, 1769 link_info->vdev_id, 1770 &vdev_mlme->ext_vdev_ptr->connect_info.chan_info, 1771 adapter->device_mode); 1772 } 1773 1774 if (ucfg_ipa_is_enabled() && !is_auth_required) { 1775 status = hdd_ipa_get_tx_pipe(hdd_ctx, link_info, &alt_pipe); 1776 if (!QDF_IS_STATUS_SUCCESS(status)) { 1777 hdd_debug("Failed to get alternate pipe for vdev %d", 1778 link_info->vdev_id); 1779 alt_pipe = false; 1780 } 1781 1782 ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev, 1783 adapter->device_mode, 1784 link_info->vdev_id, 1785 WLAN_IPA_STA_CONNECT, 1786 rsp->bssid.bytes, 1787 alt_pipe); 1788 } 1789 1790 if (adapter->device_mode == QDF_STA_MODE) 1791 cdp_reset_rx_hw_ext_stats(soc); 1792 1793 wlan_hdd_auto_shutdown_enable(hdd_ctx, false); 1794 1795 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD, 1796 link_info->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID, 1797 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC)); 1798 1799 if (is_roam) 1800 ucfg_dp_nud_indicate_roam(vdev); 1801 /* hdd_objmgr_set_peer_mlme_auth_state */ 1802 1803 if (adapter->keep_alive_interval) 1804 hdd_vdev_send_sta_keep_alive_interval(link_info, hdd_ctx, 1805 adapter->keep_alive_interval); 1806 } 1807 1808 static void 1809 hdd_cm_connect_success_post_user_update(struct wlan_objmgr_vdev *vdev, 1810 struct wlan_cm_connect_resp *rsp) 1811 { 1812 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 1813 struct hdd_adapter *adapter; 1814 struct wlan_hdd_link_info *link_info; 1815 bool is_roam = rsp->is_reassoc; 1816 1817 if (!hdd_ctx) { 1818 hdd_err("hdd_ctx is NULL"); 1819 return; 1820 } 1821 1822 link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id); 1823 if (!link_info) { 1824 hdd_err("adapter is NULL for vdev %d", rsp->vdev_id); 1825 return; 1826 } 1827 1828 if (!is_roam) { 1829 /* call only for connect */ 1830 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect); 1831 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT); 1832 } 1833 1834 adapter = link_info->adapter; 1835 hdd_cm_clear_pmf_stats(adapter); 1836 1837 if (adapter->device_mode == QDF_STA_MODE) { 1838 /* Inform FTM TIME SYNC about the connection with AP */ 1839 hdd_ftm_time_sync_sta_state_notify(adapter, 1840 FTM_TIME_SYNC_STA_CONNECTED); 1841 ucfg_mlme_init_twt_context(hdd_ctx->psoc, 1842 &rsp->bssid, 1843 TWT_ALL_SESSIONS_DIALOG_ID); 1844 ucfg_twt_init_context(hdd_ctx->psoc, 1845 &rsp->bssid, 1846 TWT_ALL_SESSIONS_DIALOG_ID); 1847 } 1848 ucfg_dp_periodic_sta_stats_start(vdev); 1849 wlan_twt_concurrency_update(hdd_ctx); 1850 1851 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) 1852 hdd_send_ps_config_to_fw(adapter); 1853 } 1854 1855 static void hdd_cm_connect_success(struct wlan_objmgr_vdev *vdev, 1856 struct wlan_cm_connect_resp *rsp, 1857 enum osif_cb_type type) 1858 { 1859 switch (type) { 1860 case OSIF_PRE_USERSPACE_UPDATE: 1861 hdd_cm_connect_success_pre_user_update(vdev, rsp); 1862 break; 1863 case OSIF_POST_USERSPACE_UPDATE: 1864 hdd_cm_connect_success_post_user_update(vdev, rsp); 1865 break; 1866 default: 1867 hdd_cm_connect_success_pre_user_update(vdev, rsp); 1868 hdd_cm_connect_success_post_user_update(vdev, rsp); 1869 } 1870 } 1871 1872 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 1873 void hdd_cm_connect_active_notify(uint8_t vdev_id) 1874 { 1875 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 1876 struct wlan_hdd_link_info *link_info; 1877 1878 if (!hdd_ctx) { 1879 hdd_err("HDD context is NULL"); 1880 return; 1881 } 1882 1883 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 1884 if (!link_info) { 1885 hdd_err("Link info not found for vdev %d", vdev_id); 1886 return; 1887 } 1888 1889 if (hdd_adapter_restore_link_vdev_map(link_info->adapter, true)) 1890 hdd_adapter_update_mlo_mgr_mac_addr(link_info->adapter); 1891 } 1892 #endif 1893 1894 QDF_STATUS hdd_cm_connect_complete(struct wlan_objmgr_vdev *vdev, 1895 struct wlan_cm_connect_resp *rsp, 1896 enum osif_cb_type type) 1897 { 1898 if (QDF_IS_STATUS_ERROR(rsp->connect_status)) 1899 hdd_cm_connect_failure(vdev, rsp, type); 1900 else 1901 hdd_cm_connect_success(vdev, rsp, type); 1902 1903 return QDF_STATUS_SUCCESS; 1904 } 1905 1906 QDF_STATUS hdd_cm_send_vdev_keys(struct wlan_objmgr_vdev *vdev, 1907 u8 key_index, bool pairwise, 1908 enum wlan_crypto_cipher_type cipher_type) 1909 { 1910 return wlan_hdd_send_key_vdev(vdev, key_index, pairwise, cipher_type); 1911 } 1912 1913 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 1914 #define WLAN_WAIT_TIME_HANDOFF_PARAMS 1000 1915 QDF_STATUS hdd_cm_get_handoff_param(struct wlan_objmgr_psoc *psoc, 1916 uint8_t vdev_id, 1917 enum vendor_control_roam_param param_id) 1918 { 1919 QDF_STATUS status; 1920 int retval; 1921 void *vendor_handoff_context; 1922 struct osif_request *request; 1923 static const struct osif_request_params params = { 1924 .priv_size = 0, 1925 .timeout_ms = WLAN_WAIT_TIME_HANDOFF_PARAMS, 1926 }; 1927 1928 request = osif_request_alloc(¶ms); 1929 if (!request) { 1930 hdd_err("Request allocation failure"); 1931 status = QDF_STATUS_E_NOMEM; 1932 goto error; 1933 } 1934 1935 vendor_handoff_context = osif_request_cookie(request); 1936 1937 hdd_debug("sending vendor handoff param request for :0x%x", param_id); 1938 status = ucfg_cm_roam_send_vendor_handoff_param_req(psoc, vdev_id, 1939 param_id, 1940 vendor_handoff_context); 1941 if (QDF_IS_STATUS_ERROR(status)) { 1942 hdd_err("Unable to get vendor handoff param"); 1943 goto error; 1944 } 1945 1946 retval = osif_request_wait_for_response(request); 1947 if (retval) { 1948 hdd_err("Target response timed out"); 1949 status = qdf_status_from_os_return(retval); 1950 } 1951 error: 1952 if (request) 1953 osif_request_put(request); 1954 1955 return status; 1956 } 1957 1958 QDF_STATUS 1959 hdd_cm_get_vendor_handoff_params(struct wlan_objmgr_psoc *psoc, 1960 void *vendor_handoff_context) 1961 { 1962 struct osif_request *request; 1963 1964 hdd_debug("Received vendor handoff event from FW"); 1965 1966 request = osif_request_get(vendor_handoff_context); 1967 if (!request) { 1968 hdd_err("Invalid request"); 1969 return QDF_STATUS_E_FAILURE; 1970 } 1971 1972 osif_request_complete(request); 1973 osif_request_put(request); 1974 1975 hdd_exit(); 1976 1977 return QDF_STATUS_SUCCESS; 1978 } 1979 #endif 1980 1981 QDF_STATUS 1982 hdd_cm_get_scan_ie_params(struct wlan_objmgr_vdev *vdev, 1983 struct element_info *scan_ie, 1984 enum dot11_mode_filter *dot11mode_filter) 1985 { 1986 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 1987 struct wlan_hdd_link_info *link_info; 1988 struct hdd_scan_info *scan_info; 1989 1990 if (!hdd_ctx) { 1991 hdd_err("hdd_ctx is NULL"); 1992 return QDF_STATUS_E_INVAL; 1993 } 1994 1995 link_info = hdd_get_link_info_by_vdev(hdd_ctx, wlan_vdev_get_id(vdev)); 1996 if (!link_info) { 1997 hdd_err("adapter is NULL for vdev %d", wlan_vdev_get_id(vdev)); 1998 return QDF_STATUS_E_INVAL; 1999 } 2000 2001 scan_info = &link_info->adapter->scan_info; 2002 if (link_info->adapter->device_mode == QDF_P2P_CLIENT_MODE) { 2003 scan_ie->ptr = &scan_info->scan_add_ie.addIEdata[0]; 2004 scan_ie->len = scan_info->scan_add_ie.length; 2005 } else if (scan_info->default_scan_ies) { 2006 scan_ie->ptr = scan_info->default_scan_ies; 2007 scan_ie->len = scan_info->default_scan_ies_len; 2008 } else if (scan_info->scan_add_ie.length) { 2009 scan_ie->ptr = scan_info->scan_add_ie.addIEdata; 2010 scan_ie->len = scan_info->scan_add_ie.length; 2011 } 2012 2013 *dot11mode_filter = hdd_get_dot11mode_filter(hdd_ctx); 2014 2015 return QDF_STATUS_SUCCESS; 2016 } 2017 2018 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 2019 #ifdef WLAN_FEATURE_FILS_SK 2020 QDF_STATUS hdd_cm_save_gtk(struct wlan_objmgr_vdev *vdev, 2021 struct wlan_cm_connect_resp *rsp) 2022 { 2023 uint8_t *kek; 2024 uint32_t kek_len; 2025 uint8_t *kck = NULL; 2026 uint8_t kck_len = 0; 2027 uint8_t replay_ctr_def[REPLAY_CTR_LEN] = {0}; 2028 uint8_t *replay_ctr; 2029 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 2030 struct wlan_hdd_link_info *link_info; 2031 2032 if (!hdd_ctx) { 2033 hdd_err("hdd_ctx is NULL"); 2034 return QDF_STATUS_E_INVAL; 2035 } 2036 2037 link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id); 2038 if (!link_info) { 2039 hdd_err("adapter is NULL for vdev %d", rsp->vdev_id); 2040 return QDF_STATUS_E_INVAL; 2041 } 2042 2043 if (rsp->is_reassoc && rsp->roaming_info) { 2044 kek = rsp->roaming_info->kek; 2045 kek_len = rsp->roaming_info->kek_len; 2046 kck = rsp->roaming_info->kck; 2047 kck_len = rsp->roaming_info->kck_len; 2048 replay_ctr = rsp->roaming_info->replay_ctr; 2049 } else if (rsp->connect_ies.fils_ie) { 2050 kek = rsp->connect_ies.fils_ie->kek; 2051 kek_len = rsp->connect_ies.fils_ie->kek_len; 2052 replay_ctr = replay_ctr_def; 2053 } else { 2054 return QDF_STATUS_SUCCESS; 2055 } 2056 wlan_hdd_save_gtk_offload_params(link_info->adapter, kck, kck_len, 2057 kek, kek_len, replay_ctr, true); 2058 2059 return QDF_STATUS_SUCCESS; 2060 } 2061 #else 2062 QDF_STATUS hdd_cm_save_gtk(struct wlan_objmgr_vdev *vdev, 2063 struct wlan_cm_connect_resp *rsp) 2064 { 2065 uint8_t *kek; 2066 uint32_t kek_len; 2067 uint8_t *kck = NULL; 2068 uint8_t kck_len = 0; 2069 uint8_t *replay_ctr; 2070 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 2071 struct wlan_hdd_link_info *link_info; 2072 2073 if (!hdd_ctx) { 2074 hdd_err("hdd_ctx is NULL"); 2075 return QDF_STATUS_E_INVAL; 2076 } 2077 2078 link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id); 2079 if (!link_info) { 2080 hdd_err("adapter is NULL for vdev %d", rsp->vdev_id); 2081 return QDF_STATUS_E_INVAL; 2082 } 2083 2084 if (rsp->is_reassoc && rsp->roaming_info) { 2085 kek = rsp->roaming_info.kek; 2086 kek_len = rsp->roaming_info.kek_len; 2087 kck = rsp->roaming_info.kck; 2088 kck_len = rsp->roaming_info.kck_len; 2089 replay_ctr = rsp->roaming_info.replay_ctr; 2090 } else { 2091 return QDF_STATUS_SUCCESS; 2092 } 2093 wlan_hdd_save_gtk_offload_params(link_info->adapter, kck, kck_len, 2094 kek, kek_len, replay_ctr, true); 2095 2096 return QDF_STATUS_SUCCESS; 2097 } 2098 #endif /* WLAN_FEATURE_FILS_SK*/ 2099 #else 2100 QDF_STATUS hdd_cm_save_gtk(struct wlan_objmgr_vdev *vdev, 2101 struct wlan_cm_connect_resp *rsp) 2102 { 2103 return QDF_STATUS_SUCCESS; 2104 } 2105 #endif 2106 2107 #ifdef WLAN_FEATURE_FILS_SK 2108 static void hdd_update_hlp_info(struct net_device *dev, 2109 struct wlan_cm_connect_resp *rsp) 2110 { 2111 struct sk_buff *skb; 2112 uint16_t skb_len; 2113 struct llc_snap_hdr_t *llc_hdr; 2114 QDF_STATUS status; 2115 uint8_t *hlp_data; 2116 uint16_t hlp_data_len; 2117 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 2118 2119 if (!rsp || !rsp->connect_ies.fils_ie) { 2120 return; 2121 } 2122 2123 if (!rsp->connect_ies.fils_ie->hlp_data_len) { 2124 return; 2125 } 2126 2127 hlp_data = rsp->connect_ies.fils_ie->hlp_data; 2128 hlp_data_len = rsp->connect_ies.fils_ie->hlp_data_len; 2129 2130 /* Calculate skb length */ 2131 skb_len = (2 * ETH_ALEN) + hlp_data_len; 2132 skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false); 2133 if (!skb) { 2134 hdd_err("HLP packet nbuf alloc fails"); 2135 return; 2136 } 2137 2138 qdf_mem_copy(skb_put(skb, ETH_ALEN), 2139 rsp->connect_ies.fils_ie->dst_mac.bytes, 2140 QDF_MAC_ADDR_SIZE); 2141 qdf_mem_copy(skb_put(skb, ETH_ALEN), 2142 rsp->connect_ies.fils_ie->src_mac.bytes, 2143 QDF_MAC_ADDR_SIZE); 2144 2145 llc_hdr = (struct llc_snap_hdr_t *)hlp_data; 2146 if (IS_SNAP(llc_hdr)) { 2147 hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE; 2148 hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE; 2149 } 2150 2151 qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len); 2152 2153 /* 2154 * This HLP packet is formed from HLP info encapsulated 2155 * in assoc response frame which is AEAD encrypted. 2156 * Hence, this checksum validation can be set unnecessary. 2157 * i.e. network layer need not worry about checksum. 2158 */ 2159 skb->ip_summed = CHECKSUM_UNNECESSARY; 2160 2161 /* 2162 * adapter->deflink->vdev is directly dereferenced because in per packet 2163 * path usage of hdd_get_vdev_by_user is costly operation as it 2164 * involves lock access. And it is guaranteed during TX/RX operations 2165 * vdev will be active will not deleted. 2166 */ 2167 status = ucfg_dp_rx_packet_cbk(adapter->deflink->vdev, (qdf_nbuf_t)skb); 2168 if (QDF_IS_STATUS_ERROR(status)) { 2169 hdd_err("Sending HLP packet fails"); 2170 return; 2171 } 2172 hdd_debug("send HLP packet to netif successfully"); 2173 } 2174 2175 QDF_STATUS hdd_cm_set_hlp_data(struct net_device *dev, 2176 struct wlan_objmgr_vdev *vdev, 2177 struct wlan_cm_connect_resp *rsp) 2178 { 2179 hdd_update_hlp_info(dev, rsp); 2180 return QDF_STATUS_SUCCESS; 2181 } 2182 #endif 2183 2184 #ifdef WLAN_FEATURE_PREAUTH_ENABLE 2185 /** 2186 * hdd_cm_get_ft_preauth_response() - get ft preauth response 2187 * related information 2188 * @vdev: vdev pointer 2189 * @rsp: preauth response 2190 * @ft_ie: ft ie 2191 * @ft_ie_ip_len: ft ie ip length 2192 * @ft_ie_length: ft ies length 2193 * 2194 * This function is used to get ft ie related information 2195 * 2196 * Return: none 2197 */ 2198 static void 2199 hdd_cm_get_ft_preauth_response(struct wlan_objmgr_vdev *vdev, 2200 struct wlan_preauth_rsp *rsp, uint8_t *ft_ie, 2201 uint32_t ft_ie_ip_len, uint16_t *ft_ie_length) 2202 { 2203 struct mlme_legacy_priv *mlme_priv; 2204 2205 *ft_ie_length = 0; 2206 2207 if (!vdev) 2208 return; 2209 2210 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); 2211 if (!mlme_priv) 2212 return; 2213 2214 /* All or nothing - proceed only if both BSSID and FT IE fit */ 2215 if ((QDF_MAC_ADDR_SIZE + rsp->ft_ie_length) > ft_ie_ip_len) 2216 return; 2217 /* 2218 * hdd needs to pack the bssid also along with the 2219 * auth response to supplicant 2220 */ 2221 qdf_mem_copy(ft_ie, rsp->pre_auth_bssid.bytes, QDF_MAC_ADDR_SIZE); 2222 2223 /* Copy the auth resp FTIEs */ 2224 qdf_mem_copy(&ft_ie[QDF_MAC_ADDR_SIZE], 2225 rsp->ft_ie, rsp->ft_ie_length); 2226 2227 *ft_ie_length = QDF_MAC_ADDR_SIZE + rsp->ft_ie_length; 2228 2229 hdd_debug("Filled auth resp: %d", *ft_ie_length); 2230 } 2231 2232 #if defined(KERNEL_SUPPORT_11R_CFG80211) 2233 QDF_STATUS hdd_cm_ft_preauth_complete(struct wlan_objmgr_vdev *vdev, 2234 struct wlan_preauth_rsp *rsp) 2235 { 2236 mac_handle_t mac_handle; 2237 struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev); 2238 struct wireless_dev *wdev; 2239 uint16_t auth_resp_len = 0; 2240 uint32_t ric_ies_length = 0; 2241 struct cfg80211_ft_event_params ft_event = {0}; 2242 uint8_t ft_ie[DOT11F_IE_FTINFO_MAX_LEN] = {0}; 2243 uint8_t ric_ies[DOT11F_IE_RICDESCRIPTOR_MAX_LEN] = {0}; 2244 2245 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 2246 if (!mac_handle) { 2247 hdd_err("mac_handle is null"); 2248 return QDF_STATUS_E_INVAL; 2249 } 2250 2251 if (!osif_priv) { 2252 hdd_err("Invalid vdev osif priv"); 2253 return QDF_STATUS_E_INVAL; 2254 } 2255 2256 wdev = osif_priv->wdev; 2257 if (!wdev) { 2258 hdd_err("wdev is null"); 2259 return QDF_STATUS_E_INVAL; 2260 } 2261 2262 if (rsp->ric_ies_length && 2263 rsp->ric_ies_length <= DOT11F_IE_RICDESCRIPTOR_MAX_LEN) { 2264 qdf_mem_copy(ric_ies, rsp->ric_ies, rsp->ric_ies_length); 2265 ric_ies_length = rsp->ric_ies_length; 2266 } else { 2267 hdd_warn("Do not send RIC IEs as length is 0"); 2268 } 2269 2270 if (ric_ies_length) { 2271 ft_event.ric_ies = ric_ies; 2272 ft_event.ric_ies_len = ric_ies_length; 2273 } 2274 hdd_debug("RIC IEs is of length %d", ric_ies_length); 2275 2276 hdd_cm_get_ft_preauth_response(vdev, rsp, ft_ie, 2277 DOT11F_IE_FTINFO_MAX_LEN, 2278 &auth_resp_len); 2279 if (!auth_resp_len) { 2280 hdd_debug("AuthRsp FTIES is of length 0"); 2281 return QDF_STATUS_E_FAILURE; 2282 } 2283 2284 ucfg_cm_set_ft_pre_auth_state(vdev, true); 2285 2286 ft_event.target_ap = ft_ie; 2287 ft_event.ies = (u8 *)(ft_ie + QDF_MAC_ADDR_SIZE); 2288 ft_event.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE; 2289 2290 hdd_debug("ftEvent.ies_len %zu", ft_event.ies_len); 2291 hdd_debug("ftEvent.ric_ies_len %zu", ft_event.ric_ies_len); 2292 hdd_debug("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x", 2293 ft_event.target_ap[0], ft_event.target_ap[1], 2294 ft_event.target_ap[2], ft_event.target_ap[3], 2295 ft_event.target_ap[4], ft_event.target_ap[5]); 2296 2297 (void)cfg80211_ft_event(wdev->netdev, &ft_event); 2298 2299 return QDF_STATUS_SUCCESS; 2300 } 2301 #else 2302 QDF_STATUS hdd_cm_ft_preauth_complete(struct wlan_objmgr_vdev *vdev, 2303 struct wlan_preauth_rsp *rsp) 2304 { 2305 struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev); 2306 struct wireless_dev *wdev; 2307 uint16_t auth_resp_len = 0; 2308 uint32_t ric_ies_length = 0; 2309 char *buff; 2310 union iwreq_data wrqu; 2311 uint16_t str_len; 2312 2313 if (!osif_priv) { 2314 hdd_err("Invalid vdev osif priv"); 2315 return QDF_STATUS_E_INVAL; 2316 } 2317 2318 wdev = osif_priv->wdev; 2319 if (!wdev) { 2320 hdd_err("wdev is null"); 2321 return QDF_STATUS_E_INVAL; 2322 } 2323 2324 /* need to send the IEs to the supplicant */ 2325 buff = qdf_mem_malloc(IW_CUSTOM_MAX); 2326 if (!buff) 2327 return QDF_STATUS_E_NOMEM; 2328 2329 /* need to send the RIC IEs first */ 2330 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX); 2331 if (rsp->ric_ies_length && 2332 (rsp->ric_ies_length <= (IW_CUSTOM_MAX - str_len))) { 2333 qdf_mem_copy(&buff[str_len], rsp->ric_ies, 2334 rsp->ric_ies_length); 2335 ric_ies_length = rsp->ric_ies_length; 2336 wrqu.data.length = str_len + ric_ies_length; 2337 hdd_wext_send_event(wdev->netdev, IWEVCUSTOM, &wrqu, buff); 2338 } else { 2339 hdd_warn("Do not send RIC IEs as length is 0"); 2340 } 2341 2342 /* need to provide the Auth Resp */ 2343 qdf_mem_zero(buff, IW_CUSTOM_MAX); 2344 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX); 2345 hdd_cm_get_ft_preauth_response(vdev, rsp, &buff[str_len], 2346 (IW_CUSTOM_MAX - str_len), 2347 &auth_resp_len); 2348 if (!auth_resp_len) { 2349 qdf_mem_free(buff); 2350 hdd_debug("AuthRsp FTIES is of length 0"); 2351 return QDF_STATUS_E_FAILURE; 2352 } 2353 2354 wrqu.data.length = str_len + auth_resp_len; 2355 hdd_wext_send_event(wdev->netdev, IWEVCUSTOM, &wrqu, buff); 2356 2357 qdf_mem_free(buff); 2358 return QDF_STATUS_SUCCESS; 2359 } 2360 #endif 2361 2362 #ifdef FEATURE_WLAN_ESE 2363 QDF_STATUS hdd_cm_cckm_preauth_complete(struct wlan_objmgr_vdev *vdev, 2364 struct wlan_preauth_rsp *rsp) 2365 { 2366 struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev); 2367 struct wireless_dev *wdev; 2368 union iwreq_data wrqu; 2369 char buf[IW_CUSTOM_MAX + 1]; 2370 char *pos = buf; 2371 int nbytes = 0, freebytes = IW_CUSTOM_MAX; 2372 2373 if (!osif_priv) { 2374 hdd_err("Invalid vdev osif priv"); 2375 return QDF_STATUS_E_INVAL; 2376 } 2377 2378 wdev = osif_priv->wdev; 2379 if (!wdev) { 2380 hdd_err("wdev is null"); 2381 return QDF_STATUS_E_INVAL; 2382 } 2383 2384 /* create the event */ 2385 memset(&wrqu, '\0', sizeof(wrqu)); 2386 memset(buf, '\0', sizeof(buf)); 2387 2388 /* timestamp0 is lower 32 bits and timestamp1 is upper 32 bits */ 2389 hdd_debug("CCXPREAUTHNOTIFY=" QDF_MAC_ADDR_FMT " %d:%d", 2390 QDF_MAC_ADDR_REF(rsp->pre_auth_bssid.bytes), 2391 rsp->timestamp[0], rsp->timestamp[1]); 2392 2393 nbytes = snprintf(pos, freebytes, "CCXPREAUTHNOTIFY="); 2394 pos += nbytes; 2395 freebytes -= nbytes; 2396 2397 qdf_mem_copy(pos, rsp->pre_auth_bssid.bytes, QDF_MAC_ADDR_SIZE); 2398 pos += QDF_MAC_ADDR_SIZE; 2399 freebytes -= QDF_MAC_ADDR_SIZE; 2400 2401 nbytes = snprintf(pos, freebytes, " %u:%u", 2402 rsp->timestamp[0], rsp->timestamp[1]); 2403 freebytes -= nbytes; 2404 2405 wrqu.data.pointer = buf; 2406 wrqu.data.length = (IW_CUSTOM_MAX - freebytes); 2407 2408 /* send the event */ 2409 hdd_wext_send_event(wdev->netdev, IWEVCUSTOM, &wrqu, buf); 2410 2411 return QDF_STATUS_SUCCESS; 2412 } 2413 #endif /* FEATURE_WLAN_ESE */ 2414 #endif /* WLAN_FEATURE_PREAUTH_ENABLE */ 2415