From 594c30b7ec92a37e4178bf3cbfd3504cb343ce18 Mon Sep 17 00:00:00 2001 From: Krupali Dhanvijay Date: Mon, 13 Oct 2025 10:57:26 +0530 Subject: [PATCH 01/14] qcacld-3.0: Consider intersected AKM for association MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently host overwrites crypto AKM with candidate AP’s AKM. To choose the most secure AKM, host do sort of AKMs properly based on security to use for association and can choose the AKM which station do not advertise and results in Assoc failure. To fix this, consider intersection of crypto and candidate AP’s AKM for association instead of AKMs directly from AP config. CRs-Fixed: 4320132 Change-Id: Id1813fc9f7fe76ff5ae9daf4da051067bddfdce1 --- core/sme/src/csr/csr_util.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index f8c2f48b711c..ecd857bcd604 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -2451,6 +2451,7 @@ static void csr_update_key_mgmt_crypto_param(struct wlan_objmgr_vdev *vdev, { int32_t key_mgmt = 0; int32_t neg_akm; + int32_t ap_akm = 0; uint8_t i; neg_akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); @@ -2460,9 +2461,16 @@ static void csr_update_key_mgmt_crypto_param(struct wlan_objmgr_vdev *vdev, } for (i = 0; i < ap_rsn.akm_suite_cnt; i++) - SET_PARAM(neg_akm, + SET_PARAM(ap_akm, wlan_crypto_rsn_suite_to_keymgmt(ap_rsn.akm_suite[i])); + /* Intersect crypto AKM and candidate AP's AKM */ + neg_akm &= ap_akm; + if (neg_akm <= 0) { + sme_err("Invalid AKM suite"); + return; + } + /* * As there can be multiple AKM present select the most secured AKM * present @@ -2531,6 +2539,7 @@ static void csr_update_ucast_cipher_crypto_param(struct wlan_objmgr_vdev *vdev, { int32_t ucastcipherset = 0; int32_t neg_ucastcipher; + int32_t ap_ucastcipher = 0; uint8_t i; neg_ucastcipher = wlan_crypto_get_param(vdev, @@ -2541,9 +2550,16 @@ static void csr_update_ucast_cipher_crypto_param(struct wlan_objmgr_vdev *vdev, } for (i = 0; i < ap_rsn.pwise_cipher_suite_count; i++) - SET_PARAM(neg_ucastcipher, + SET_PARAM(ap_ucastcipher, wlan_crypto_rsn_suite_to_cipher(ap_rsn.pwise_cipher_suites[i])); + /* Intersect crypto cipherset and candidate AP's cipherset */ + neg_ucastcipher &= ap_ucastcipher; + if (neg_ucastcipher <= 0) { + sme_err("Invalid unicast cipherset"); + return; + } + /* * As there can be multiple ucastcipher present select the most secured * ucastcipher present. From b4d8fce29fbb75e7dc14575b0c3dd86086672ac3 Mon Sep 17 00:00:00 2001 From: jinbao liu Date: Mon, 15 Dec 2025 15:47:16 +0800 Subject: [PATCH 02/14] qcacld-3.0: Validate fse metadata before aggregation of FISA flow When aggregation of a flow is in progress, there can be case when the HW flow table entry match may fail for few packets. Such packets, even though belong to a flow already present in flow table, are routed independently to any RX ring. When software checks this rx ring ID, from the independently routed packet and compares the ring ID against the one which is assigned for the flow, there will be a mismatch leading to unwanted behaviour. Hence, always validate the fse_metadata before taking any action on the basis of rx ring ID mismatch. The non-matching packets, with invalid fse metadata can be submitted to network stack independently. Change-Id: Ia95f20ef1050bc981b2d22571b612fd2af6f6a65 CRs-Fixed: 3272353 --- core/dp/txrx3.0/dp_fisa_rx.c | 24 +++++++++++++++++++++--- core/dp/txrx3.0/dp_rx_fst.c | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/core/dp/txrx3.0/dp_fisa_rx.c b/core/dp/txrx3.0/dp_fisa_rx.c index d0d84e40a9ce..835f795e7736 100644 --- a/core/dp/txrx3.0/dp_fisa_rx.c +++ b/core/dp/txrx3.0/dp_fisa_rx.c @@ -1677,15 +1677,33 @@ static int dp_add_nbuf_to_fisa_flow(struct dp_rx_fst *fisa_hdl, fse_metadata = hal_rx_msdu_fse_metadata_get(hal_soc_hdl, rx_tlv_hdr); cce_match = hal_rx_msdu_cce_match_get(rx_tlv_hdr); - if (cce_match || (fisa_hdl->del_flow_count && - fse_metadata != fisa_flow->metadata)) { + /* + * For two cases the fse_metadata will not match the metadata + * from the fisa_flow_table entry + * 1) Flow has been evicted (lru deletion), and this packet is + * one of the few packets pending in the rx ring from the prev + * flow + * 2) HW flow table match fails for some packets in the + * currently active flow. + */ + if (cce_match) { dp_rx_fisa_release_ft_lock(fisa_hdl, napi_id); + DP_STATS_INC(fisa_hdl, reo_mismatch.allow_cce_match, + 1); + return FISA_AGGR_NOT_ELIGIBLE; + } + + if (fse_metadata != fisa_flow->metadata) { + dp_rx_fisa_release_ft_lock(fisa_hdl, napi_id); + DP_STATS_INC(fisa_hdl, + reo_mismatch.allow_fse_metdata_mismatch, + 1); return FISA_AGGR_NOT_ELIGIBLE; } dp_err("REO id mismatch flow: %pK napi_id: %u nbuf: %pK reo_id: %u", fisa_flow, fisa_flow->napi_id, nbuf, napi_id); - DP_STATS_INC(fisa_hdl, reo_mismatch, 1); + DP_STATS_INC(fisa_hdl, reo_mismatch.allow_non_aggr, 1); QDF_BUG(0); dp_rx_fisa_release_ft_lock(fisa_hdl, napi_id); return FISA_AGGR_NOT_ELIGIBLE; diff --git a/core/dp/txrx3.0/dp_rx_fst.c b/core/dp/txrx3.0/dp_rx_fst.c index 023729a53bf1..4d88045dedf1 100644 --- a/core/dp/txrx3.0/dp_rx_fst.c +++ b/core/dp/txrx3.0/dp_rx_fst.c @@ -63,6 +63,24 @@ void dp_rx_dump_fisa_table(struct dp_soc *soc) } } +void dp_print_fisa_stats(struct dp_soc *soc) +{ + struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx; + struct dp_rx_fst *fst = soc->rx_fst; + + /* Check if it is enabled in the INI */ + if (!wlan_cfg_is_rx_fisa_enabled(cfg)) + return; + + dp_info("invalid flow index: %u", fst->stats.invalid_flow_index); + dp_info("reo_mismatch: cce_match: %u", + fst->stats.reo_mismatch.allow_cce_match); + dp_info("reo_mismatch: allow_fse_metdata_mismatch: %u", + fst->stats.reo_mismatch.allow_fse_metdata_mismatch); + dp_info("reo_mismatch: allow_non_aggr: %u", + fst->stats.reo_mismatch.allow_non_aggr); +} + /** * dp_rx_flow_send_htt_operation_cmd() - Invalidate FSE cache on FT change * @pdev: handle to DP pdev From 1474e194976202f50a00293fab586605c538c980 Mon Sep 17 00:00:00 2001 From: Sanskar Jain Date: Tue, 25 Nov 2025 10:22:26 +0530 Subject: [PATCH 03/14] qcacld-3.0: Add buffer overflow check in wma_fill_rx_stats function The wma_fill_rx_stats function accesses wmi_rx array using index wmi_rx[i * WLAN_MAX_AC + k] without validating that wmi_rx buffer has sufficient elements. This can lead to buffer overflow when num_peer_ac_rx_stats * WLAN_MAX_AC exceeds the available num_rx_stats. Add validation check to ensure wmi_rx does not reach out of bound before accessing the array. CRs-Fixed: 4315163 Change-Id: I91cf41d8f931aef7d5666b2744fc5d8a167d43f3 --- core/wma/src/wma_utils.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 3f34979096b8..68bd4241fd04 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -1361,6 +1361,15 @@ wma_fill_rx_stats(struct sir_wifi_ll_ext_stats *ll_stats, wmi_peer_rx, wmi_rx, peer_stats); return QDF_STATUS_E_FAILURE; } + + /* Check if num_rx_stats is sufficient to avoid buffer overflow */ + if (param_buf->num_rx_stats < + fix_param->num_peer_ac_rx_stats * WLAN_MAX_AC) { + wma_err("Insufficient rx_stats buffer: available %d, required %d", + param_buf->num_rx_stats, + fix_param->num_peer_ac_rx_stats * WLAN_MAX_AC); + return QDF_STATUS_E_FAILURE; + } for (i = 0; i < fix_param->num_peer_ac_rx_stats; i++) { uint32_t peer_id = wmi_peer_rx[i].peer_id; struct sir_wifi_rx *ac; From f955beb16c6f31d8ca18cf688aa42ffd4df50076 Mon Sep 17 00:00:00 2001 From: Surya Prakash Sivaraj Date: Wed, 28 Jan 2026 16:51:15 +0530 Subject: [PATCH 04/14] qcacld-3.0: Add runtime pm lock during roaming Acquire the runtime pm lock when roam sync event is received and release after roam sync complete is sent. Change-Id: Ic56d353dd343f5fcbc228a8d7251e047177b9a9b CRs-Fixed: 3238723 --- core/wma/inc/wma.h | 5 +++-- core/wma/inc/wma_internal.h | 17 +++++++++++++++++ core/wma/src/wma_main.c | 3 +++ core/wma/src/wma_scan_roam.c | 15 +++++++++++---- core/wma/src/wma_utils.c | 16 ++++++++++++++++ 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 5474fe767d0f..787f5d3c3e6f 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -909,11 +909,11 @@ struct wma_wlm_stats_data { * @dynamic_nss_chains_update: per vdev nss, chains update * @ito_repeat_count: Indicates ito repeated count * @wma_fw_time_sync_timer: timer used for firmware time sync - * * @fw_therm_throt_support: FW Supports thermal throttling? + * @fw_therm_throt_support: FW Supports thermal throttling? + * @roam_sync_runtime_lock: roam sync runtime lock * * This structure is the global wma context. It contains global wma * module parameters and handles of other modules. - */ typedef struct { void *wmi_handle; @@ -1045,6 +1045,7 @@ typedef struct { qdf_mc_timer_t wma_fw_time_sync_timer; bool fw_therm_throt_support; bool enable_tx_compl_tsf64; + qdf_runtime_lock_t roam_sync_runtime_lock; } t_wma_handle, *tp_wma_handle; /** diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 1d7f88d5392c..45e2e678442b 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1587,6 +1587,23 @@ void wma_acquire_wakelock(qdf_wake_lock_t *wl, uint32_t msec); */ void wma_release_wakelock(qdf_wake_lock_t *wl); +/** + * wma_prevent_pm_during_roam_sync() - prevent runtime PM during roam sync + * @wma: a reference to the global WMA handle + * + * Return: None + */ +void wma_prevent_pm_during_roam_sync(t_wma_handle *wma); + +/** + * wma_allow_pm_after_roam_sync() - allow runtime PM after roam + * sync complete + * @wma: a reference to the global WMA handle + * + * Return: None + */ +void wma_allow_pm_after_roam_sync(t_wma_handle *wma); + /** * wma_send_vdev_stop_to_fw() - send the vdev stop command to firmware * @wma: a reference to the global WMA handle diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index b48b2729e9ae..6165e7fc31e2 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -3428,6 +3428,7 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, "wlan_fw_rsp_wakelock"); qdf_runtime_lock_init(&wma_handle->wmi_cmd_rsp_runtime_lock); qdf_runtime_lock_init(&wma_handle->sap_prevent_runtime_pm_lock); + qdf_runtime_lock_init(&wma_handle->roam_sync_runtime_lock); /* Register peer assoc conf event handler */ wmi_unified_register_event_handler(wma_handle->wmi_handle, @@ -3538,6 +3539,7 @@ err_dbglog_init: qdf_runtime_lock_deinit(&wma_handle->sap_prevent_runtime_pm_lock); qdf_runtime_lock_deinit(&wma_handle->wmi_cmd_rsp_runtime_lock); qdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock); + qdf_runtime_lock_deinit(&wma_handle->roam_sync_runtime_lock); err_event_init: wmi_unified_unregister_event_handler(wma_handle->wmi_handle, wmi_debug_print_event_id); @@ -4592,6 +4594,7 @@ QDF_STATUS wma_close(void) qdf_wake_lock_destroy(&wma_handle->wmi_cmd_rsp_wake_lock); qdf_runtime_lock_deinit(&wma_handle->sap_prevent_runtime_pm_lock); qdf_runtime_lock_deinit(&wma_handle->wmi_cmd_rsp_runtime_lock); + qdf_runtime_lock_deinit(&wma_handle->roam_sync_runtime_lock); qdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock); if (wma_handle->pGetRssiReq) { diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 702063ef6170..994e08c449d7 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -1617,21 +1617,23 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, return status; } + wma_prevent_pm_during_roam_sync(wma); + param_buf = (WMI_ROAM_SYNCH_EVENTID_param_tlvs *)event; if (!param_buf) { wma_err_rl("received null buf from target"); - return status; + goto fail; } synch_event = param_buf->fixed_param; if (!synch_event) { wma_err_rl("received null event data from target"); - return status; + goto fail; } if (synch_event->vdev_id >= wma->max_bssid) { wma_err_rl("received invalid vdev_id %d", synch_event->vdev_id); - return status; + goto fail; } iface = &wma->interfaces[synch_event->vdev_id]; @@ -1647,10 +1649,14 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, if (QDF_IS_STATUS_ERROR(qdf_status)) { wma_err("Failed to send the EV_ROAM"); wma_post_roam_sync_failure(wma, synch_event->vdev_id); - return status; + goto fail; } wma_debug("Posted EV_ROAM to VDEV SM"); return 0; + +fail: + wma_allow_pm_after_roam_sync(wma); + return status; } int wma_roam_auth_offload_event_handler(WMA_HANDLE handle, uint8_t *event, @@ -2833,6 +2839,7 @@ void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id) wma_info("LFR3: vdev[%d] Sent ROAM_SYNCH_COMPLETE", vdev_id); wlan_roam_debug_log(vdev_id, DEBUG_ROAM_SYNCH_CNF, DEBUG_INVALID_PEER_ID, NULL, NULL, 0, 0); + wma_allow_pm_after_roam_sync(wma_handle); } #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 68bd4241fd04..28c927fbcd41 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -3822,6 +3822,22 @@ void wma_release_wakelock(qdf_wake_lock_t *wl) qdf_runtime_pm_allow_suspend(&wma->wmi_cmd_rsp_runtime_lock); } +void wma_prevent_pm_during_roam_sync(t_wma_handle *wma) +{ + if (!wma) + return; + + qdf_runtime_pm_prevent_suspend(&wma->roam_sync_runtime_lock); +} + +void wma_allow_pm_after_roam_sync(t_wma_handle *wma) +{ + if (!wma) + return; + + qdf_runtime_pm_allow_suspend(&wma->roam_sync_runtime_lock); +} + QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id) { QDF_STATUS status = QDF_STATUS_E_FAILURE; From 3a3ead7c317c4912945cb787e2defb92006cce28 Mon Sep 17 00:00:00 2001 From: Surya Prakash Sivaraj Date: Wed, 28 Jan 2026 23:24:10 -0800 Subject: [PATCH 05/14] qcacld-3.0: Prevent ping loss due to runtime suspend Scenario: 1) FW sends roam start to the host, and host disables the netif queues. Therefore, the ping from the stack does not reach the driver. 3) The driver goes into runtime suspend, and the firmware aborts roaming due to pmf assoc retry. 4) After assoc comeback timeout, the firmware successfully roams. However, both roam abort and roam sync are not wakeable events. 5) Therefore, the host stays in runtime suspend until the timeout as part of the serialization command queued during roam start. 6) Netif queues are enabled back after roam start timeout and ping resumes. This results in a data loss for a longer time, eventhough the firmware has aborted the roaming. Currently, the host driver prevents runtime suspend only from roam sync event until roam sync completion. To fix this issue, prevent the runtime suspend from the roam start until roam sync completion/roam abort/roam ho-failure. Change-Id: I9d63dd6af09d17e90d7d2d6a63a8aaa59297a047 CRs-Fixed: 4413987 --- core/wma/inc/wma.h | 2 ++ core/wma/src/wma_main.c | 1 + core/wma/src/wma_scan_roam.c | 3 +++ core/wma/src/wma_utils.c | 8 ++++++++ 4 files changed, 14 insertions(+) diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 787f5d3c3e6f..99b2164e618a 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -911,6 +911,7 @@ struct wma_wlm_stats_data { * @wma_fw_time_sync_timer: timer used for firmware time sync * @fw_therm_throt_support: FW Supports thermal throttling? * @roam_sync_runtime_lock: roam sync runtime lock + * @is_roam_lock_acquired: Is roam_sync_runtime_lock acquired * * This structure is the global wma context. It contains global wma * module parameters and handles of other modules. @@ -1046,6 +1047,7 @@ typedef struct { bool fw_therm_throt_support; bool enable_tx_compl_tsf64; qdf_runtime_lock_t roam_sync_runtime_lock; + bool is_roam_lock_acquired; } t_wma_handle, *tp_wma_handle; /** diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 6165e7fc31e2..7021b8720fc3 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -3429,6 +3429,7 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, qdf_runtime_lock_init(&wma_handle->wmi_cmd_rsp_runtime_lock); qdf_runtime_lock_init(&wma_handle->sap_prevent_runtime_pm_lock); qdf_runtime_lock_init(&wma_handle->roam_sync_runtime_lock); + wma_handle->is_roam_lock_acquired = false; /* Register peer assoc conf event handler */ wmi_unified_register_event_handler(wma_handle->wmi_handle, diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 994e08c449d7..276f64af9cf8 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -4558,10 +4558,12 @@ static void wma_invalid_roam_reason_handler(tp_wma_handle wma_handle, if (notif == WMI_ROAM_NOTIF_ROAM_START) { wma_handle->interfaces[vdev_id].roaming_in_progress = true; op_code = SIR_ROAMING_START; + wma_prevent_pm_during_roam_sync(wma_handle); } else if (notif == WMI_ROAM_NOTIF_ROAM_ABORT) { wma_handle->interfaces[vdev_id].roaming_in_progress = false; op_code = SIR_ROAMING_ABORT; lim_sae_auth_cleanup_retry(wma_handle->mac_context, vdev_id); + wma_allow_pm_after_roam_sync(wma_handle); } else { wma_debug("Invalid notif %d", notif); return; @@ -4737,6 +4739,7 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf, = false; lim_sae_auth_cleanup_retry(wma_handle->mac_context, wmi_event->vdev_id); + wma_allow_pm_after_roam_sync(wma_handle); break; #endif case WMI_ROAM_REASON_INVALID: diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 28c927fbcd41..87c194ee45f0 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -3827,7 +3827,11 @@ void wma_prevent_pm_during_roam_sync(t_wma_handle *wma) if (!wma) return; + if (wma->is_roam_lock_acquired) + return; + qdf_runtime_pm_prevent_suspend(&wma->roam_sync_runtime_lock); + wma->is_roam_lock_acquired = true; } void wma_allow_pm_after_roam_sync(t_wma_handle *wma) @@ -3835,7 +3839,11 @@ void wma_allow_pm_after_roam_sync(t_wma_handle *wma) if (!wma) return; + if (!wma->is_roam_lock_acquired) + return; + qdf_runtime_pm_allow_suspend(&wma->roam_sync_runtime_lock); + wma->is_roam_lock_acquired = false; } QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id) From 083fef0100139b29bebe69b4b76c87671f04344e Mon Sep 17 00:00:00 2001 From: Ajit Vaishya Date: Tue, 20 Jan 2026 14:40:42 +0530 Subject: [PATCH 06/14] qcacld-3.0: Self rsn cap intersect with AP rsn cap currently self rsn cap intersect with AP rsn cap IE which is filed in bss desc, but while reading rsn cap IE from bss desc is getting all Zero's, due to which self cap also become Zero's. Fix is read AP rsn cap from negotiated rsn cap of bss desc which is populate properly and self rsn cap is filled correctly. Change-Id: Ia1d9c27e1f3a7528636ab78ebe973090a9ae6f1d CRs-Fixed: 4423830 --- core/mac/inc/sir_api.h | 1 + core/sme/src/csr/csr_api_scan.c | 1 + core/sme/src/csr/csr_util.c | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index f13d7eda15bc..1f1ff23d47b4 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -786,6 +786,7 @@ struct bss_description { #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) uint32_t is_single_pmk; #endif + uint16_t neg_rsn_caps; /* Please keep the structure 4 bytes aligned above the ieFields */ uint32_t ieFields[1]; }; diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 8ba4ef61b6a1..5ce7d5345138 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -2256,6 +2256,7 @@ static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx, bss_desc->beaconInterval = scan_entry->bcn_int; bss_desc->capabilityInfo = scan_entry->cap_info.value; + bss_desc->neg_rsn_caps = scan_entry->neg_sec_info.rsn_caps; if (WLAN_REG_IS_5GHZ_CH_FREQ(scan_entry->channel.chan_freq) || WLAN_REG_IS_6GHZ_CHAN_FREQ(scan_entry->channel.chan_freq)) diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index ecd857bcd604..a92dee201977 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -2603,8 +2603,6 @@ uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId, (mac, pSirBssDesc, &local_ap_ie)))) return ie_len; - /* get AP RSN cap */ - qdf_mem_copy(&rsn_cap, local_ap_ie->RSN.RSN_Cap, sizeof(rsn_cap)); if (!ap_ie && local_ap_ie) /* locally allocated */ qdf_mem_free(local_ap_ie); @@ -2624,6 +2622,8 @@ uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId, } self_rsn_cap = (uint16_t)rsn_val; + /* get AP RSN cap */ + rsn_cap = pSirBssDesc->neg_rsn_caps; /* If AP is capable then use self capability else set PMF as 0 */ if (rsn_cap & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED && pProfile->MFPCapable) { From 7b381e0bec64c3c37bd4f6ad5735f77babc49b45 Mon Sep 17 00:00:00 2001 From: Surya Prakash Sivaraj Date: Wed, 18 Mar 2026 13:25:34 +0530 Subject: [PATCH 07/14] qcacld-3.0: Reset SPMK cache before every connection SPMK global cache in the vdev private is persistent across connections. Therefore, in cross-ssid roaming cases with different AKMs, SPMK in the global cache will always be sent to the firmware in RSO start, even for non-SAE connections. This causes roam failure. Reset the spmk global cache for every new connection. Change-Id: I03deefe16242ef79d0985a8c05881914e6f7af01 CRs-Fixed: 3310182 --- core/mac/src/pe/lim/lim_api.c | 4 ++++ core/mac/src/pe/lim/lim_process_sme_req_messages.c | 12 ++++++++++-- core/sme/src/csr/csr_api_roam.c | 5 ++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 80ee8867c140..2e0f0511dc89 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -2631,6 +2631,10 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, lim_fill_ft_session(mac_ctx, bss_desc, ft_session_ptr, session_ptr, roam_sync_ind_ptr->phy_mode); pe_update_crypto_params(mac_ctx, ft_session_ptr, roam_sync_ind_ptr); + + /* Reset the SPMK global cache */ + wlan_mlme_set_sae_single_pmk_bss_cap(mac_ctx->psoc, + ft_session_ptr->vdev_id, false); /* Next routine may update nss based on dot11Mode */ lim_ft_prepare_add_bss_req(mac_ctx, ft_session_ptr, bss_desc); if (session_ptr->is11Rconnection) diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 0f57abe3c224..f9eb195526dd 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -1604,6 +1604,14 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) session->connected_akm = sme_join_req->akm; session->is_adaptive_11r_connection = sme_join_req->is_adaptive_11r_connection; + /* Reset the SPMK global cache for non-SAE connection */ + if (session->connected_akm != ANI_AKM_TYPE_SAE) { + wlan_mlme_set_sae_single_pmk_bss_cap(mac_ctx->psoc, + session->vdev_id, + false); + wlan_mlme_clear_sae_single_pmk_info(session->vdev, + NULL); + } #ifdef FEATURE_WLAN_ESE session->isESEconnection = sme_join_req->isESEconnection; #endif @@ -1832,7 +1840,7 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) session->spectrumMgtEnabled = true; session->isOSENConnection = sme_join_req->isOSENConnection; - pe_debug("Freq %d width %d freq0 %d freq1 %d, Smps %d: mode %d action %d, nss 1x1 %d vdev_nss %d nss %d cbMode %d dot11mode %d subfer %d subfee %d csn %d is_cisco %d", + pe_debug("Freq %d width %d freq0 %d freq1 %d, Smps %d: mode %d action %d, nss 1x1 %d vdev_nss %d nss %d cbMode %d dot11mode %d subfer %d subfee %d csn %d is_cisco %d akm %d", session->curr_op_freq, session->ch_width, session->ch_center_freq_seg0, session->ch_center_freq_seg1, @@ -1843,7 +1851,7 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) session->vht_config.su_beam_former, session->vht_config.su_beam_formee, session->vht_config.csnof_beamformer_antSup, - session->isCiscoVendorAP); + session->isCiscoVendorAP, session->connected_akm); /* Issue LIM_MLM_JOIN_REQ to MLM */ status = lim_send_join_req(session, mlm_join_req); diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 4484ed3c5ce8..cf719e8501a6 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -21461,12 +21461,15 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx, mac_ctx->psoc); mac_ctx->sme.set_connection_info_cb(false); - if (roam_synch_data->pmk_len) + if (roam_synch_data->pmk_len) { + mlme_debug("Received pmk in roam sync. Length: %d", + roam_synch_data->pmk_len); csr_check_and_set_sae_single_pmk_cap( mac_ctx, session, session_id, roam_synch_data->pmk, roam_synch_data->pmk_len); + } if (ucfg_pkt_capture_get_pktcap_mode(mac_ctx->psoc)) ucfg_pkt_capture_record_channel(vdev); From 78e07c9a0196ccbf5d3dfbf008414455834e4d03 Mon Sep 17 00:00:00 2001 From: Abinandhu M Date: Tue, 10 Mar 2026 17:11:27 +0530 Subject: [PATCH 08/14] qcacld-3.0: Use orig_key_mgmt vdev param for AKM negotiation Currently, the driver overwrites the supplicant configured connect request AKMs with that of the candidate's AKM. Due to this, the STA attempts connection via an AKM which is not present in the original connect request. To fix this, use the intersection of original AKM list and the candidate supported AKMs to derive the connection AKM. Change-Id: I700630fda91b4b3ff73e50a38e3c0386ede85e42 CRs-Fixed: 4490428 --- core/sme/src/csr/csr_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index ecd857bcd604..a0ffa150b281 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -2454,7 +2454,7 @@ static void csr_update_key_mgmt_crypto_param(struct wlan_objmgr_vdev *vdev, int32_t ap_akm = 0; uint8_t i; - neg_akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); + neg_akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_ORIG_KEY_MGMT); if (neg_akm < 0) { sme_err("Invalid AKM suite"); return; @@ -2470,6 +2470,7 @@ static void csr_update_key_mgmt_crypto_param(struct wlan_objmgr_vdev *vdev, sme_err("Invalid AKM suite"); return; } + sme_debug("Intersected AKM with AP's AKM 0x%x", neg_akm); /* * As there can be multiple AKM present select the most secured AKM From e7116cb9e98bf2de8fa7d246d43dbb64cc0c1252 Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Tue, 7 Apr 2026 01:23:20 +0530 Subject: [PATCH 09/14] qcacld-3.0: Add A_INT64 typedef Add A_INT64 as a signed 64-bit integer type in uapi/linux/a_types.h. This complements the existing A_UINT64 definition and provides a consistent signed 64-bit typedef for consumers of this UAPI header. CRs-Fixed: 4492650 Change-Id: Ie7f5fb55ba291273ecf35920a217fc65dfa3f661 --- uapi/linux/a_types.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/uapi/linux/a_types.h b/uapi/linux/a_types.h index 190d40df6afd..5537fae67697 100644 --- a/uapi/linux/a_types.h +++ b/uapi/linux/a_types.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,15 +30,21 @@ #define _A_TYPES_H_ #include -typedef unsigned int A_UINT32; typedef unsigned long long A_UINT64; +typedef long long A_INT64; + +typedef unsigned int A_UINT32; +typedef int A_INT32; + typedef unsigned short A_UINT16; +typedef short A_INT16; + typedef unsigned char A_UINT8; -typedef int A_INT32; -typedef short A_INT16; -typedef char A_INT8; +typedef char A_INT8; + typedef unsigned char A_UCHAR; -typedef char A_CHAR; +typedef char A_CHAR; + typedef _Bool A_BOOL; #endif /* _ATHTYPES_H_ */ From 221de7eef147a76fc4764f863e2caddb79046de6 Mon Sep 17 00:00:00 2001 From: Deeksha Gupta Date: Thu, 25 Jan 2024 16:08:03 +0530 Subject: [PATCH 10/14] =?UTF-8?q?qcacld-3.0:=20Set=20=E2=80=9CWIPHY=5FFLAG?= =?UTF-8?q?=5FDFS=5FOFFLOAD=E2=80=9D=20always=20in=20wiphy=20flag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure the "WIPHY_FLAG_DFS_OFFLOAD" flag is always set in wiphy flag, regardless of DFS master capability ini. This changes eliminates the need for supplicant to check DFS flags for the SAP channel, as the DFS logic is consistently offloaded to the driver. CRs-Fixed: 3716167 Change-Id: I571f1cf15d268b85ad4de4d2f2a93d39f59b1231 --- core/hdd/src/wlan_hdd_cfg80211.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 9edadf77f669..3c0adf628743 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -1718,7 +1718,7 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = }; /** - * __is_driver_dfs_capable() - get driver DFS capability + * __is_driver_dfs_capable() - get driver DFS offload capability * @wiphy: pointer to wireless wiphy structure. * @wdev: pointer to wireless_dev structure. * @data: Pointer to the data to be passed via vendor interface @@ -17739,7 +17739,7 @@ void wlan_hdd_update_wiphy(struct hdd_context *hdd_ctx) { int value; bool fils_enabled, mac_spoofing_enabled; - bool dfs_master_capable = true, is_oce_sta_enabled = false; + bool is_oce_sta_enabled = false; QDF_STATUS status; struct wiphy *wiphy = hdd_ctx->wiphy; uint8_t allow_mcc_go_diff_bi = 0, enable_mcc = 0; @@ -17764,11 +17764,7 @@ void wlan_hdd_update_wiphy(struct hdd_context *hdd_ctx) if (fils_enabled) wlan_hdd_cfg80211_set_wiphy_fils_feature(wiphy); - status = ucfg_mlme_get_dfs_master_capability(hdd_ctx->psoc, - &dfs_master_capable); - if (QDF_IS_STATUS_SUCCESS(status) && dfs_master_capable) - wlan_hdd_cfg80211_set_dfs_offload_feature(wiphy); - + wlan_hdd_cfg80211_set_dfs_offload_feature(wiphy); status = ucfg_mlme_get_bigtk_support(hdd_ctx->psoc, &is_bigtk_supported); From 1b0f7e3489a3e79fee044d1795d1fdea2fc3f71b Mon Sep 17 00:00:00 2001 From: Abinandhu M Date: Sun, 10 May 2026 22:52:01 +0530 Subject: [PATCH 11/14] qcacld-3.0: Disable SAP bringup in DFS when DFSmastercap is disabled Issue Scenario: 1) INI gEnableDFSMasterCap is set to 0 2) User tries to force start SAP on 160 MHz. 3) SAP starts on 160 MHz which contains DFS channels. This is a violation since the DUT does not support DFS master capability. To fix this, stop the SAP bringup if atleast one of the bonded channels is DFS. CRs-Fixed: 4516874 Change-Id: Iaeb77d52059505bafb8a0d38386cb1790432b498 --- .../policy_mgr/inc/wlan_policy_mgr_api.h | 18 +++++++++ .../src/wlan_policy_mgr_get_set_utils.c | 39 +++++++++++++++++++ core/hdd/src/wlan_hdd_hostapd.c | 19 +++++++++ 3 files changed, 76 insertions(+) diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index d902f7ee4327..141ce08f47a2 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -210,6 +210,24 @@ QDF_STATUS policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc, uint8_t *sta_sap_scc_on_dfs_chnl); +/** + * policy_mgr_is_bonded_chan_dfs() - check whether the given bonded + * channel configuration falls under DFS + * @psoc: pointer to psoc + * @ch_width: channel width of the operating channel + * @mhz_freq_seg1: center frequency of segment 1; used for 80+80 MHz + * @chan_freq: primary/operating channel frequency in MHz + * + * This API checks whether the given channel or bonded channel span + * includes DFS, based on the channel width and frequency segments. + * + * Return: true if the given bonded channel is DFS, else false. + */ +bool +policy_mgr_is_bonded_chan_dfs(struct wlan_objmgr_psoc *psoc, + enum phy_ch_width ch_width, + qdf_freq_t mhz_freq_seg1, + uint32_t chan_freq); /** * policy_mgr_get_dfs_master_dynamic_enabled() - support dfs master or not * on AP interafce when STA+SAP(GO) concurrency diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 5661c5a03491..0bffbe5e612e 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -181,6 +181,45 @@ policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +bool +policy_mgr_is_bonded_chan_dfs(struct wlan_objmgr_psoc *psoc, + enum phy_ch_width ch_width, + qdf_freq_t mhz_freq_seg1, + uint32_t chan_freq) +{ + bool is_ch_dfs = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return false; + } + + if (ch_width == CH_WIDTH_160MHZ) { + if (wlan_reg_get_5g_bonded_channel_state_for_freq(pm_ctx->pdev, + chan_freq, + ch_width) + == CHANNEL_STATE_DFS) + is_ch_dfs = true; + } else if (ch_width == CH_WIDTH_80P80MHZ) { + if (wlan_reg_get_channel_state_for_freq( + pm_ctx->pdev, + chan_freq) == + CHANNEL_STATE_DFS || + wlan_reg_get_channel_state_for_freq( + pm_ctx->pdev, + mhz_freq_seg1) == + CHANNEL_STATE_DFS) + is_ch_dfs = true; + } else { + if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, chan_freq)) + is_ch_dfs = true; + } + + return is_ch_dfs; +} + static bool policy_mgr_update_dfs_master_dynamic_enabled( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 80659541d94a..76a1a5228125 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -5244,6 +5244,7 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, bool deliver_start_evt = true; struct s_ext_cap *p_ext_cap; enum reg_phymode reg_phy_mode, updated_phy_mode; + bool dfs_master_capable; hdd_enter(); @@ -5787,6 +5788,24 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, config->ch_width_orig = CH_WIDTH_20MHZ; } + status = ucfg_mlme_get_dfs_master_capability(hdd_ctx->psoc, + &dfs_master_capable); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to get dfs master capable"); + ret = -EINVAL; + goto error; + } + + if (!dfs_master_capable && + policy_mgr_is_bonded_chan_dfs(hdd_ctx->psoc, + config->ch_width_orig, + config->ch_params.mhz_freq_seg1, + config->chan_freq)) { + hdd_err("Failed to bringup SAP; Atleast one bonded channel is DFS"); + ret = -EINVAL; + goto error; + } + if (wlan_hdd_setup_driver_overrides(adapter)) { ret = -EINVAL; goto error; From 3759ce5221446164d7bef684402d16116215e927 Mon Sep 17 00:00:00 2001 From: Surya Prakash Sivaraj Date: Fri, 22 May 2026 11:01:54 +0530 Subject: [PATCH 12/14] qcacld-3.0: Add print log for new roam scan type Firmware sends the roam scan info tlv to driver during roaming. Currently, in this tlv, firmware fills scan type as (0-3) and driver log this as "PARTIAL", "FULL", "NO SCAN" and "Higher Band" But with new requirement, idle roaming shall only roam to higher band (2.4 GHz < 5 GHz < 6 GHz) than current band. 1. If current band is 2.4 GHz, it cannot roam to 2.4 GHz. It can roam to 5 GHz and 6 GHz. 2. If current band is 5 GHz, it cannot roam to 2.4 GHz and 5 GHz. It can roam to 6 GHz. So, to add this requirement, firmware introduces new scan type 4 for which driver need to log. Change-Id: I80d1c47a434da5009aed4cab08c6eae91bda5b0e CRs-Fixed: 3379468 --- .../mlme/dispatcher/inc/wlan_mlme_api.h | 23 +++++++++++++++++-- .../mlme/dispatcher/src/wlan_mlme_api.c | 12 ++++++---- core/hdd/src/wlan_hdd_stats.c | 6 +++-- core/wma/src/wma_scan_roam.c | 2 +- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 401bd9c549e5..3b757579f129 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -2444,11 +2444,30 @@ wlan_mlme_get_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc, char *mlme_get_roam_trigger_str(uint32_t roam_scan_trigger); /** - * mlme_get_roam_scan_type_str() - Get the string for roam sacn type + * enum roam_stats_scan_type - Roam scan type defines + * @ROAM_STATS_SCAN_TYPE_PARTIAL: Partial scan + * @ROAM_STATS_SCAN_TYPE_FULL: Full scan + * @ROAM_STATS_SCAN_TYPE_NO_SCAN: No roam scan was triggered. This is generally + * used in BTM events to indicate BTM frame exchange logs. + * @ROAM_STATS_SCAN_TYPE_HIGHER_BAND_5GHZ_6GHZ: Higher band roam scan from 2 GHz + * to 5 GHz or 6 GHz + * @ROAM_STATS_SCAN_TYPE_HIGHER_BAND_6GHZ: Higher band roam scan from 5 GHz to + * 6 GHz + */ +enum roam_stats_scan_type { + ROAM_STATS_SCAN_TYPE_PARTIAL = 0, + ROAM_STATS_SCAN_TYPE_FULL = 1, + ROAM_STATS_SCAN_TYPE_NO_SCAN = 2, + ROAM_STATS_SCAN_TYPE_HIGHER_BAND_5GHZ_6GHZ = 3, + ROAM_STATS_SCAN_TYPE_HIGHER_BAND_6GHZ = 4, +}; + +/** + * mlme_get_roam_scan_type_str() - Get the string for roam scan type * @roam_scan_type: roam scan type coming from fw via * wmi_roam_scan_info tlv * - * Return: Meaningful string for roam sacn type + * Return: Meaningful string for roam scan type */ char *mlme_get_roam_scan_type_str(uint32_t roam_scan_type); diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index dd930d969742..633b36067c91 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -3793,14 +3793,16 @@ char *mlme_get_roam_status_str(uint32_t roam_status) char *mlme_get_roam_scan_type_str(uint32_t roam_scan_type) { switch (roam_scan_type) { - case 0: + case ROAM_STATS_SCAN_TYPE_PARTIAL: return "PARTIAL"; - case 1: + case ROAM_STATS_SCAN_TYPE_FULL: return "FULL"; - case 2: + case ROAM_STATS_SCAN_TYPE_NO_SCAN: return "NO SCAN"; - case 3: - return "Higher Band"; + case ROAM_STATS_SCAN_TYPE_HIGHER_BAND_5GHZ_6GHZ: + return "Higher Band: 5 GHz + 6 GHz"; + case ROAM_STATS_SCAN_TYPE_HIGHER_BAND_6GHZ: + return "Higher Band : 6 GHz"; default: return "UNKNOWN"; } diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index 8f7deb17dcda..47c143862f89 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -3914,7 +3914,8 @@ hdd_get_roam_rt_stats_event_len(struct mlme_roam_debug_info *roam_stats) len += nla_total_size(sizeof(uint8_t)); if (roam_stats->scan.present) { - if (roam_stats->scan.num_chan && !roam_stats->scan.type) + if (roam_stats->scan.num_chan && + roam_stats->scan.type == ROAM_STATS_SCAN_TYPE_PARTIAL) for (i = 0; i < roam_stats->scan.num_chan;) i++; @@ -3987,7 +3988,8 @@ roam_rt_stats_fill_scan_freq(struct sk_buff *vendor_event, kfree_skb(vendor_event); return; } - if (roam_stats->scan.num_chan && !roam_stats->scan.type) { + if (roam_stats->scan.num_chan && + roam_stats->scan.type == ROAM_STATS_SCAN_TYPE_PARTIAL) { for (i = 0; i < roam_stats->scan.num_chan; i++) { if (nla_put_u32(vendor_event, i, roam_stats->scan.chan_freq[i])) { diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 276f64af9cf8..915e196f4d81 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -2070,7 +2070,7 @@ wma_rso_print_scan_info(struct wmi_roam_scan_data *scan, uint8_t vdev_id, tmp = buf; /* For partial scans, print the channel info */ - if (!scan->type) { + if (scan->type == ROAM_STATS_SCAN_TYPE_PARTIAL) { buf_cons = qdf_snprint(tmp, buf_left, "{"); buf_left -= buf_cons; tmp += buf_cons; From 9c3c5d8625f5ab259ebbdcea04745af610e1e59d Mon Sep 17 00:00:00 2001 From: Aasir Rasheed Date: Wed, 10 Jun 2026 12:27:59 +0530 Subject: [PATCH 13/14] qcacld-3.0: Update phymode along with ch_width update to FW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AP sends "Operating Mode Notification" IE contains max supported channel width indication (ap operating channel bandwidth) via beacon/probe response/association/re-association response frame. After sending OMN IE to DUT, AP expects DUT should do Tx/Rx of data packet on ap operating channel bandwidth. Due a recent change in FW (via CR/3701633), FW combined BW and PHYMODE update requests into single message to avoid race condition and assert in FW. It means whenever host updates ch_width to FW, should also update corresponding phymode immediately via same command WMI_PEER_SET_PARAM_CMDID with param id WMI_HOST_PEER_PHYMODE. Currently on detecting OMN IE in any of above frame, host sends WMI_PEER_SET_PARAM_CMDID command only once with param id WMI_HOST_PEER_CHWIDTH to update ch_width only with expectation “FW should use same ch_width for further Tx/Rx of data packet”. But FW ignoring only ch_width updates (without followed by phymode update), this results DUT fails to do Tx/Rx of data packet on ch_width present in OMN IE. Fix is to make sure on detection of OMN IE (contains valid ch_width) in above frame(s), host should send WMI_PEER_SET_PARAM_CMDID command two times to FW to update ch_width and corresponding phymode. Change-Id: Ic23205bb6c164b1bcb9c183d0f7818b082b84583 CRs-Fixed: 3734683 --- core/wma/src/wma_mgmt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index e6136508c682..44e28b904b3a 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022, 2026 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -2732,6 +2732,10 @@ void wma_process_update_opmode(tp_wma_handle wma_handle, wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac, WMI_PEER_CHWIDTH, update_vht_opmode->opMode, update_vht_opmode->smesessionId); + + wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac, + WMI_HOST_PEER_PHYMODE, + fw_phymode, update_vht_opmode->smesessionId); } /** From 2c47becdaf072266915bd9438620c060a6dc841d Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 11 Sep 2024 14:33:24 +0530 Subject: [PATCH 14/14] qcacld-3.0: Avoid phymode and puncture mismatch Host semd wmi as following order after CSA received/vdev restart and before vdev up, old puncture bitmap mismatched with new phy mode lead to F/W assert. 1. WMI PEER PHY MODE 2. WMI PEER BW To fix it, swap order as following 1. WMI PEER BW 2. WMI PEER PHY MODE Change-Id: I1ae3e5093cb45520be0f50ffb31fa7386201340b CRs-Fixed: 3650797 --- core/wma/src/wma_dev_if.c | 6 +++--- core/wma/src/wma_mgmt.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 15f3c657a065..4d045b27df28 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -943,14 +943,14 @@ static void wma_peer_send_phymode(struct wlan_objmgr_vdev *vdev, fw_phymode = wma_host_to_fw_phymode(new_phymode); vdev_id = wlan_vdev_get_id(vdev); - wma_set_peer_param(wma, peer_mac_addr, WMI_PEER_PHYMODE, - fw_phymode, vdev_id); - max_ch_width_supported = wmi_get_ch_width_from_phy_mode(wma->wmi_handle, fw_phymode); wma_set_peer_param(wma, peer_mac_addr, WMI_PEER_CHWIDTH, max_ch_width_supported, vdev_id); + wma_set_peer_param(wma, peer_mac_addr, WMI_PEER_PHYMODE, + fw_phymode, vdev_id); + wma_debug("FW phymode %d old phymode %d new phymode %d bw %d macaddr "QDF_MAC_ADDR_FMT, fw_phymode, old_peer_phymode, new_phymode, max_ch_width_supported, QDF_MAC_ADDR_REF(peer_mac_addr)); diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 44e28b904b3a..1eac8fcc7907 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -2734,7 +2734,7 @@ void wma_process_update_opmode(tp_wma_handle wma_handle, update_vht_opmode->smesessionId); wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac, - WMI_HOST_PEER_PHYMODE, + WMI_PEER_PHYMODE, fw_phymode, update_vht_opmode->smesessionId); }