From b444e5b8b541f7ac2859e848b615d5919c27ea10 Mon Sep 17 00:00:00 2001 From: Pindi Kiran Date: Tue, 20 May 2025 17:42:01 +0530 Subject: [PATCH 01/13] qcacmn: Fix for invalid dma unmap triggered by dma mapping failure When a DMA mapping failure occurs, the final else block after the last retry is missing the necessary steps to free the memory and set the pointer to NULL, which leads to a crash during the DMA unmap operation. This fix ensures the pointer is freed and set to NULL after a DMA map failure. CRs-Fixed: 4153939 Change-Id: I05348164aed4874a3799de4b03f3c51039dd5247 --- dp/wifi3.0/dp_rx_tid.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dp/wifi3.0/dp_rx_tid.c b/dp/wifi3.0/dp_rx_tid.c index ea19b2942b..4fd0ffbab2 100644 --- a/dp/wifi3.0/dp_rx_tid.c +++ b/dp/wifi3.0/dp_rx_tid.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2016-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 @@ -744,9 +744,10 @@ try_desc_alloc: if (dp_reo_desc_addr_chk(rx_tid->hw_qdesc_paddr) != QDF_STATUS_SUCCESS || ret) { + qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned); + rx_tid->hw_qdesc_vaddr_unaligned = NULL; + if (alloc_tries++ < 10) { - qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned); - rx_tid->hw_qdesc_vaddr_unaligned = NULL; goto try_desc_alloc; } else { dp_peer_err("%pK: Rx tid %d desc alloc fail (lowmem)", From 55192f742c800a740fb2b481d2d4ea91633779f6 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 30 May 2025 11:37:03 +0530 Subject: [PATCH 02/13] qcacmn: Increase timer threshold for RX exception ring interrupt Currently, timer threshold for RX exception ring interrupt is configured as 8 usecs. If the NAPI processing get delayed for some reason, then WLAN hardware will keep firing interrupts every 8usecs and in the worst-case scenario, this would result in an interrupt storm impacting other use cases in the system. Increase the timer threshold to 512 usecs to address this problem. Change-Id: I7343232da1628f0f7a26dff5c4f1304e5f103804 CRs-Fixed: 4167656 --- wlan_cfg/cfg_dp.h | 3 +++ wlan_cfg/wlan_cfg.c | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/wlan_cfg/cfg_dp.h b/wlan_cfg/cfg_dp.h index 61841c3ca1..5708d08236 100644 --- a/wlan_cfg/cfg_dp.h +++ b/wlan_cfg/cfg_dp.h @@ -149,6 +149,9 @@ #define WLAN_CFG_INT_TIMER_THRESHOLD_TX 8 #define WLAN_CFG_INT_TIMER_THRESHOLD_OTHER 8 +#define WLAN_CFG_INT_BATCH_THRESHOLD_RX_ERR 1 +#define WLAN_CFG_INT_TIMER_THRESHOLD_RX_ERR 512 + #ifdef WLAN_DP_PER_RING_TYPE_CONFIG #define WLAN_CFG_INT_BATCH_THRESHOLD_RX \ WLAN_CFG_INT_BATCH_THRESHOLD_REO_RING diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index 8a03fe8be2..c03edb8d8f 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/wlan_cfg/wlan_cfg.c @@ -3396,6 +3396,13 @@ struct wlan_srng_cfg wlan_srng_tx_monitor_buf_cfg = { .low_threshold = WLAN_CFG_TX_MONITOR_BUF_RING_SIZE_MAX >> 3, }; +/* RX Exception ring configuration */ +struct wlan_srng_cfg wlan_srng_rx_err_cfg = { + .timer_threshold = WLAN_CFG_INT_TIMER_THRESHOLD_RX_ERR, + .batch_count_threshold = WLAN_CFG_INT_BATCH_THRESHOLD_RX_ERR, + .low_threshold = 0, +}; + /* DEFAULT_CONFIG ring configuration */ struct wlan_srng_cfg wlan_srng_default_cfg = { .timer_threshold = WLAN_CFG_INT_TIMER_THRESHOLD_OTHER, @@ -3432,7 +3439,7 @@ void wlan_set_srng_cfg(struct wlan_srng_cfg **wlan_cfg) { g_wlan_srng_cfg[REO_DST] = wlan_srng_reo_cfg; g_wlan_srng_cfg[WBM2SW_RELEASE] = wlan_srng_wbm_release_cfg; - g_wlan_srng_cfg[REO_EXCEPTION] = wlan_srng_default_cfg; + g_wlan_srng_cfg[REO_EXCEPTION] = wlan_srng_rx_err_cfg; g_wlan_srng_cfg[REO_REINJECT] = wlan_src_srng_default_cfg; g_wlan_srng_cfg[REO_CMD] = wlan_src_srng_default_cfg; g_wlan_srng_cfg[REO_STATUS] = wlan_srng_default_cfg; From b76c74534f51af72d760167d4b43c5caff8bff88 Mon Sep 17 00:00:00 2001 From: Zhiwei Yang Date: Wed, 14 May 2025 18:50:21 +0800 Subject: [PATCH 03/13] qcacmn: Force disable runtime PM for single MSI mode Force disable runtime PM for single MSI mode. Change-Id: I71ea362e9abc02647efaf072450943b2d6cf2367 CRs-Fixed: 4148863 --- hif/src/hif_runtime_pm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hif/src/hif_runtime_pm.c b/hif/src/hif_runtime_pm.c index ae1ec83cd1..fd54a2b4cd 100644 --- a/hif/src/hif_runtime_pm.c +++ b/hif/src/hif_runtime_pm.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-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 above @@ -447,6 +447,11 @@ void hif_rtpm_start(struct hif_softc *scn) return; } + if (pld_is_one_msi(scn->qdf_dev->dev)) { + hif_info_high("RUNTIME PM is disabled for single MSI mode"); + return; + } + if (mode == QDF_GLOBAL_FTM_MODE || QDF_IS_EPPING_ENABLED(mode) || mode == QDF_GLOBAL_MONITOR_MODE) { hif_info("RUNTIME PM is disabled for FTM/EPPING/MONITOR mode"); From c942c509f2545c4b6d513abee675d37550b7ec73 Mon Sep 17 00:00:00 2001 From: Surya Prakash Sivaraj Date: Tue, 13 May 2025 11:06:13 +0530 Subject: [PATCH 04/13] qcacmn: Teardown TDLS upon STA-SAP MCC TDLS is not torn down when STA and SAP enters MCC. This leads to undefined behavior in firmware. To fix this, check and teardown the TDLS if the final channel for the SAP is in MCC with any of the STA interfaces. Change-Id: Ic4a7324b74c31cbdeb11658f046ea5b469cc2d5b CRs-Fixed: 4158170 --- .../interface_mgr/inc/wlan_if_mgr_ap.h | 12 +++++++++++- .../interface_mgr/inc/wlan_if_mgr_public_struct.h | 14 +++++++++++++- .../interface_mgr/src/wlan_if_mgr_core.c | 6 +++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/umac/cmn_services/interface_mgr/inc/wlan_if_mgr_ap.h b/umac/cmn_services/interface_mgr/inc/wlan_if_mgr_ap.h index f1b6da5e5a..6a5987b414 100644 --- a/umac/cmn_services/interface_mgr/inc/wlan_if_mgr_ap.h +++ b/umac/cmn_services/interface_mgr/inc/wlan_if_mgr_ap.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2021, 2023 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 above @@ -106,6 +106,16 @@ if_mgr_ap_csa_complete(struct wlan_objmgr_vdev *vdev, QDF_STATUS if_mgr_ap_csa_start(struct wlan_objmgr_vdev *vdev, struct if_mgr_event_data *event_data); +/** + * if_mgr_ap_channel_selected() - Handler to process channel selection + * completion of SAP/GO + * @vdev: Pointer to vdev object + * @event_data: Interface manager event data + * + * Return: QDF_STATUS + */ +QDF_STATUS if_mgr_ap_channel_selected(struct wlan_objmgr_vdev *vdev, + struct if_mgr_event_data *event_data); #if defined WLAN_MBSS /** * if_mgr_ap_start_acs() - ACS start event handler diff --git a/umac/cmn_services/interface_mgr/inc/wlan_if_mgr_public_struct.h b/umac/cmn_services/interface_mgr/inc/wlan_if_mgr_public_struct.h index 80634395de..984f230451 100644 --- a/umac/cmn_services/interface_mgr/inc/wlan_if_mgr_public_struct.h +++ b/umac/cmn_services/interface_mgr/inc/wlan_if_mgr_public_struct.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2020-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 above @@ -55,6 +55,7 @@ * @WLAN_IF_MGR_EV_NAN_PRE_ENABLE: nan pre enable * @WLAN_IF_MGR_EV_NAN_POST_ENABLE: nan post enable * @WLAN_IF_MGR_EV_NAN_POST_DISABLE: nan post disable + * @WLAN_IF_MGR_EV_AP_CHANNEL_SELECTED: AP channel has been selected * @WLAN_IF_MGR_EV_MAX: Max event */ enum wlan_if_mgr_evt { @@ -82,6 +83,7 @@ enum wlan_if_mgr_evt { WLAN_IF_MGR_EV_NAN_PRE_ENABLE = 21, WLAN_IF_MGR_EV_NAN_POST_ENABLE = 22, WLAN_IF_MGR_EV_NAN_POST_DISABLE = 23, + WLAN_IF_MGR_EV_AP_CHANNEL_SELECTED = 24, WLAN_IF_MGR_EV_MAX, }; @@ -103,16 +105,26 @@ struct validate_bss_data { #endif }; +/** + * struct if_mgr_ap_info- AP related interface manager data + * @ap_freq: SAP frequency + */ +struct if_mgr_ap_info { + qdf_freq_t ap_freq; +}; + /** * struct if_mgr_event_data - interface manager event data * @status: qdf status used to indicate if connect,disconnect, * start bss,stop bss event is success/failure. * @validate_bss_info: struct to hold the validate candidate information + * @ap_info: struct to hold AP related if_mgr information * @data: event data */ struct if_mgr_event_data { QDF_STATUS status; struct validate_bss_data validate_bss_info; + struct if_mgr_ap_info ap_info; void *data; }; diff --git a/umac/cmn_services/interface_mgr/src/wlan_if_mgr_core.c b/umac/cmn_services/interface_mgr/src/wlan_if_mgr_core.c index 40ada13ccc..5261af42b5 100644 --- a/umac/cmn_services/interface_mgr/src/wlan_if_mgr_core.c +++ b/umac/cmn_services/interface_mgr/src/wlan_if_mgr_core.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2021, 2023-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 above @@ -58,6 +58,7 @@ const char *if_mgr_get_event_str(enum wlan_if_mgr_evt event) CASE_RETURN_STRING(WLAN_IF_MGR_EV_NAN_PRE_ENABLE); CASE_RETURN_STRING(WLAN_IF_MGR_EV_NAN_POST_ENABLE); CASE_RETURN_STRING(WLAN_IF_MGR_EV_NAN_POST_DISABLE); + CASE_RETURN_STRING(WLAN_IF_MGR_EV_AP_CHANNEL_SELECTED); default: return "Unknown"; } @@ -183,6 +184,9 @@ QDF_STATUS if_mgr_deliver_event(struct wlan_objmgr_vdev *vdev, case WLAN_IF_MGR_EV_NAN_POST_DISABLE: status = if_mgr_nan_post_disable(vdev, event_data); break; + case WLAN_IF_MGR_EV_AP_CHANNEL_SELECTED: + status = if_mgr_ap_channel_selected(vdev, event_data); + break; default: status = if_mgr_deliver_mbss_event(vdev, event, event_data); } From c1df4ccdb48a239a9c69024a5ee0979862639b64 Mon Sep 17 00:00:00 2001 From: Amit Mehta Date: Fri, 30 May 2025 03:25:17 -0700 Subject: [PATCH 05/13] qcacmn: Fix DMA Sync IOVA Null pointer issue In current case Tx and Rx page pools are enabled and N/W stack forwards the Rx packet to Driver for Tx due to due IP forwarding. In case if Tx pagepool allocation fails. nbuf CB paddr value will not be updated. Which will result in Kernel Panic due to invalid address access. To fix the issue initialize nbuf CB paddr with 0 in Tx Page pool and check for nbuf CB PADDR in skip nbuf map API. Change-Id: Ide34302ddb1a7559d1f78a4c2635019dc739e065 CRs-Fixed: 4167428 --- dp/wifi3.0/dp_tx.c | 9 +++++++-- qdf/inc/qdf_nbuf.h | 2 +- qdf/linux/src/i_qdf_nbuf_m.h | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index a801fb179d..ec4a536975 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -192,8 +192,13 @@ dp_tx_page_pool_handle_nbuf_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, size_t size; if (!dp_tx_is_page_pool_enabled(soc) || !tx_pp || - !tx_pp->page_pool_init || - (tx_desc->flags & DP_TX_DESC_FLAG_TDLS_FRAME)) + !tx_pp->page_pool_init) + return nbuf; + + if (qdf_nbuf_get_dev_scratch(nbuf) != QDF_NBUF_SW_TSO_DEV_SCRATCH_VAL) + QDF_NBUF_CB_PADDR(nbuf) = 0; + + if (tx_desc->flags & DP_TX_DESC_FLAG_TDLS_FRAME) return nbuf; /* Non linear SKBs are not expected in this path */ diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 8a5c0c2067..b359c1f43f 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -1351,7 +1351,7 @@ qdf_skip_dma_map_unmap(qdf_device_t osdev, qdf_nbuf_t nbuf, qdf_dma_dir_t dir) { return ((dir == QDF_DMA_TO_DEVICE && osdev->no_dma_map) || dir == QDF_DMA_FROM_DEVICE || dir == QDF_DMA_BIDIRECTIONAL) && - __qdf_is_pp_nbuf(nbuf); + __qdf_is_pp_nbuf(nbuf) && QDF_NBUF_CB_PADDR(nbuf); } /** diff --git a/qdf/linux/src/i_qdf_nbuf_m.h b/qdf/linux/src/i_qdf_nbuf_m.h index 8e18c85ccf..95bdb58118 100644 --- a/qdf/linux/src/i_qdf_nbuf_m.h +++ b/qdf/linux/src/i_qdf_nbuf_m.h @@ -742,7 +742,7 @@ static inline QDF_STATUS __qdf_nbuf_map_nbytes_single( if (((dir == QDF_DMA_TO_DEVICE && osdev->no_dma_map) || dir == QDF_DMA_FROM_DEVICE || dir == QDF_DMA_BIDIRECTIONAL) && - __qdf_is_pp_nbuf(buf)) { + __qdf_is_pp_nbuf(buf) && QDF_NBUF_CB_PADDR(buf)) { dma_sync_single_for_device(osdev->dev, QDF_NBUF_CB_PADDR(buf), nbytes, __qdf_dma_dir_to_os(dir)); return QDF_STATUS_SUCCESS; @@ -788,7 +788,7 @@ __qdf_nbuf_unmap_nbytes_single(qdf_device_t osdev, struct sk_buff *buf, */ if (((dir == QDF_DMA_TO_DEVICE && osdev->no_dma_map) || dir == QDF_DMA_FROM_DEVICE || dir == QDF_DMA_BIDIRECTIONAL) && - __qdf_is_pp_nbuf(buf)) + __qdf_is_pp_nbuf(buf) && QDF_NBUF_CB_PADDR(buf)) return dma_sync_single_for_cpu(osdev->dev, paddr, nbytes, __qdf_dma_dir_to_os(dir)); From 95c10c60f951e688e64c209918a151c47d7e7bb3 Mon Sep 17 00:00:00 2001 From: "Signed-off-by: Chaoli Zhou" Date: Wed, 4 Jun 2025 21:30:01 -0700 Subject: [PATCH 06/13] qcacmn: Return invalid status if puncture bitmap and bandwidth same If puncture bitmap and bandwidth are same with connected external AP, then it was not necessary to update the wmi peer phy mode. So change the return value and based on that to decide if it need to update phy mode or not Change-Id: I34f03579d9603fca7ab648cce13a2093ba832ec9 CRs-Fixed: 4017978 --- umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c index 2ffa81b951..f670c95e99 100644 --- a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c +++ b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2015, 2020-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-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 above @@ -592,7 +592,7 @@ QDF_STATUS wlan_cm_sta_update_bw_puncture(struct wlan_objmgr_vdev *vdev, if (des_chan->puncture_bitmap == ch_param.reg_punc_bitmap && des_chan->ch_width == ch_param.ch_width) - return status; + return QDF_STATUS_E_INVAL; des_chan->ch_freq_seg1 = ch_param.center_freq_seg0; des_chan->ch_freq_seg2 = ch_param.center_freq_seg1; From eac6379a69d86d898670ff15a2977189edd9ca3c Mon Sep 17 00:00:00 2001 From: Pindi Kiran Date: Wed, 28 May 2025 15:30:48 +0530 Subject: [PATCH 07/13] qcacmn: Fix assertion failure due to incorrect LINK_DESC_ID_START Assertion in the code checking the magic number in the software cookie is failing.This is due to incorrect values of LINK_DESC_ID_START_21_BITS_COOKIE and LINK_DESC_ID_START_20_BITS_COOKIE being used for different PAGE_SIZE configurations (16K and 64K). Original values did not align with the actual bit positions of the link descriptor ID in the cookie, leading to false assertion failures. Fix introduces corrected values for LINK_DESC_ID_START_21_BITS_COOKIE and LINK_DESC_ID_START_20_BITS_COOKIE for each supported PAGE_SIZE (16K and 64K). These values now accurately reflect the expected bit positions of the link descriptor ID in the cookie. With this change, the assertion logic correctly validates the magic number. CRs-Fixed: 4138721 Change-Id: I8e6fda6244557cdbf79880b6ef10eaf1609be87c --- dp/wifi3.0/dp_types.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 29320bebb8..cb81f21e53 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -3813,14 +3813,17 @@ QDF_COMPILE_TIME_ASSERT(num_cpu_check, #define LINK_DESC_PAGE_ID_MASK 0x007FE0 #define LINK_DESC_ID_SHIFT 5 #define LINK_DESC_ID_START_21_BITS_COOKIE 0x8000 +#define LINK_DESC_ID_START_20_BITS_COOKIE 0x4000 #elif PAGE_SIZE == 16384 #define LINK_DESC_PAGE_ID_MASK 0x007F80 #define LINK_DESC_ID_SHIFT 7 -#define LINK_DESC_ID_START_21_BITS_COOKIE 0x8000 +#define LINK_DESC_ID_START_21_BITS_COOKIE 0x2000 +#define LINK_DESC_ID_START_20_BITS_COOKIE 0x1000 #elif PAGE_SIZE == 65536 #define LINK_DESC_PAGE_ID_MASK 0x007E00 #define LINK_DESC_ID_SHIFT 9 #define LINK_DESC_ID_START_21_BITS_COOKIE 0x800 +#define LINK_DESC_ID_START_20_BITS_COOKIE 0x400 #else #error "Unsupported kernel PAGE_SIZE" #endif @@ -3836,8 +3839,8 @@ QDF_COMPILE_TIME_ASSERT(num_cpu_check, #define LINK_DESC_COOKIE_PAGE_ID(_cookie) \ ((_cookie) & LINK_DESC_PAGE_ID_MASK) #define LINK_DESC_ID_START_21_BITS_COOKIE 0x8000 -#endif #define LINK_DESC_ID_START_20_BITS_COOKIE 0x4000 +#endif /* same as ieee80211_nac_param */ enum dp_nac_param_cmd { From 4001e6f6cc06a8492777b3f30fd8207c9b37608b Mon Sep 17 00:00:00 2001 From: Sheenam Monga Date: Thu, 5 Jun 2025 13:09:26 +0530 Subject: [PATCH 08/13] qcacmn: Add support to check FW cap Add support to check if FW is able to handle both PSD and EIRP powers together or not. Change-Id: I49884608e967aea5793862550bc2f72fe884602d CRs-Fixed: 3936590 --- wmi/inc/wmi_unified_api.h | 13 ++++++++++++- wmi/src/wmi_unified_tlv.c | 3 +-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index f0f9d1f294..4bde137b0f 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-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 @@ -5400,6 +5400,17 @@ QDF_STATUS wmi_unified_send_sta_vdev_report_ap_oper_bw_cmd( wmi_unified_t wmi_handle, struct wmi_sta_vdev_report_ap_oper_bw_params *param); +/** + * is_both_psd_eirp_support_present_for_sp() - FW can handle + * PSD and EIRP together or not + * + * @wmi_handle: wmi handle + * @param: reg tpc power + * + * Return: true if FW can handle PSD and EIRP together or not + */ +bool is_both_psd_eirp_support_present_for_sp(wmi_unified_t wmi_handle, + struct reg_tpc_power_info *param); #ifdef FEATURE_WLAN_ZERO_POWER_SCAN /** diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index d953ad7701..fbee03c866 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 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 @@ -21966,7 +21966,6 @@ send_both_eirp_psd_for_set_tpc_tlv(wmi_unified_t wmi_handle, return ret; } -static inline bool is_both_psd_eirp_support_present_for_sp(wmi_unified_t wmi_handle, struct reg_tpc_power_info *param) { From 664cd2052ef46965a841ec278648fd1792839296 Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Thu, 15 May 2025 14:13:10 +0800 Subject: [PATCH 09/13] qcacmn: Fix bss peer attach to sta vdev failure 16 RTT PASN peers are allowed for 1 vdev, but only 4 peers allowed for 1 sta vdev, if 4 RTT PASN peers exist for 1 sta vdev, can't attach any more bss peer to the vdev, roam or connect will fail. To fix it, increase max peer num for STA/P2P CLI vdev to consider PASN peer. Change-Id: I1513b9857602884028e5abc2fdf1cb0530fcce81 CRs-Fixed: 4150085 --- umac/wifi_pos/inc/wifi_pos_pasn_api.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/umac/wifi_pos/inc/wifi_pos_pasn_api.h b/umac/wifi_pos/inc/wifi_pos_pasn_api.h index fb1f632461..7e885e2ce7 100644 --- a/umac/wifi_pos/inc/wifi_pos_pasn_api.h +++ b/umac/wifi_pos/inc/wifi_pos_pasn_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2022-2023 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 above @@ -208,6 +209,13 @@ bool wifi_pos_is_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev); */ void wifi_pos_set_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev, bool flag); + +static inline uint8_t +wifi_pos_get_pasn_peer_max_num_per_vdev(void) +{ + return WLAN_MAX_11AZ_PEERS; +} + #else static inline QDF_STATUS wifi_pos_handle_ranging_peer_create(struct wlan_objmgr_psoc *psoc, @@ -288,5 +296,11 @@ static inline void wifi_pos_set_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev, bool flag) {} + +static inline uint8_t +wifi_pos_get_pasn_peer_max_num_per_vdev(void) +{ + return 0; +} #endif /* WIFI_POS_CONVERGED && WLAN_FEATURE_RTT_11AZ_SUPPORT */ #endif /* _WIFI_POS_PASN_API_H_ */ From 7097ab0926e35180267fc6f62cdce8353f732b31 Mon Sep 17 00:00:00 2001 From: Asutosh Mohapatra Date: Tue, 20 May 2025 23:51:36 -0700 Subject: [PATCH 10/13] qcacmn: Handling Dummy Netdev Allocation in Kernel 6.13+ With the introduction of kernel version 6.13, the init_dummy_netdev symbol has been made static and is no longer exported. Consequently, drivers must now utilize alloc_netdev_dummy() to allocate and initialize dummy network devices. The current implementation defines the net_device structure as a static instance within the driver. However, since alloc_netdev_dummy() dynamically allocates and initializes the dummy netdev, assigning its return value to a statically defined structure is incorrect and leads to undefined behavior. To address this, a pointer to a net_device structure should be added to the host context. The driver should store the pointer returned by alloc_netdev_dummy() in this new member. Additionally, appropriate cleanup logic must be implemented to free the allocated dummy netdev during driver teardown. Change-Id: I1d234d003e3ba99e0d91727a09c228ec1a3822c4 CRs-Fixed: 4158403 --- hif/inc/hif.h | 10 ++++- hif/src/hif_exec.c | 32 ++++++++++++++-- hif/src/hif_exec.h | 10 +++-- hif/src/hif_napi.c | 72 ++++++++++++++++++++++++++++++------ qdf/inc/qdf_net_if.h | 23 ++++++++++-- qdf/linux/src/i_qdf_net_if.h | 32 +++++++++++++--- qdf/linux/src/qdf_net_if.c | 35 ++++++++++++++++-- 7 files changed, 181 insertions(+), 33 deletions(-) diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 053c454157..0ced30637a 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-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 @@ -357,7 +357,11 @@ struct qca_napi_stat { * instances. */ struct qca_napi_info { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) + struct net_device *netdev; /* dummy net_dev ptr */ +#else struct net_device netdev; /* dummy net_dev */ +#endif void *hif_ctx; struct napi_struct napi; uint8_t scale; /* currently same on all instances */ @@ -370,7 +374,11 @@ struct qca_napi_info { /* will only be present for data rx CE's */ void (*offld_flush_cb)(void *); struct napi_struct rx_thread_napi; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) + struct net_device *rx_thread_netdev; +#else struct net_device rx_thread_netdev; +#endif #endif /* RECEIVE_OFFLOAD */ qdf_lro_ctx_t lro_ctx; #ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT diff --git a/hif/src/hif_exec.c b/hif/src/hif_exec.c index 662ee41db0..92f5d929b6 100644 --- a/hif/src/hif_exec.c +++ b/hif/src/hif_exec.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-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 @@ -902,6 +902,26 @@ static void hif_exec_napi_schedule(struct hif_exec_context *ctx) napi_schedule(&n_ctx->napi); } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +/** + * qdf_napi_get_dummy_nd_ptr() - Get dummy netdev pointer + * @ctx: hif_napi_exec_context pointer + * + * Return: dummy netdev pointer + */ +static inline struct net_device * +qdf_napi_get_dummy_nd_ptr(struct hif_napi_exec_context *ctx) +{ + return ctx->netdev; +} +#else +static inline struct net_device * +qdf_napi_get_dummy_nd_ptr(struct hif_napi_exec_context *ctx) +{ + return &ctx->netdev; +} +#endif + /** * hif_exec_napi_kill() - stop a napi exec context from being rescheduled * @ctx: a hif_exec_context known to be of napi type @@ -910,6 +930,7 @@ static void hif_exec_napi_kill(struct hif_exec_context *ctx) { struct hif_napi_exec_context *n_ctx = hif_exec_get_napi(ctx); int irq_ind; + struct net_device *dummy_nd = qdf_napi_get_dummy_nd_ptr(n_ctx); if (ctx->inited) { qdf_napi_disable(&n_ctx->napi); @@ -921,6 +942,7 @@ static void hif_exec_napi_kill(struct hif_exec_context *ctx) hif_core_ctl_set_boost(false); qdf_netif_napi_del(&(n_ctx->napi)); + qdf_net_if_destroy_dummy_if((struct qdf_net_if *)dummy_nd); } struct hif_execution_ops napi_sched_ops = { @@ -936,6 +958,7 @@ struct hif_execution_ops napi_sched_ops = { static struct hif_exec_context *hif_exec_napi_create(uint32_t scale) { struct hif_napi_exec_context *ctx; + struct net_device *dummy_nd; ctx = qdf_mem_malloc(sizeof(struct hif_napi_exec_context)); if (!ctx) @@ -944,9 +967,10 @@ static struct hif_exec_context *hif_exec_napi_create(uint32_t scale) ctx->exec_ctx.sched_ops = &napi_sched_ops; ctx->exec_ctx.inited = true; ctx->exec_ctx.scale_bin_shift = scale; - qdf_net_if_create_dummy_if((struct qdf_net_if *)&ctx->netdev); - qdf_netif_napi_add(&(ctx->netdev), &(ctx->napi), hif_exec_poll, - QCA_NAPI_BUDGET); + dummy_nd = qdf_napi_get_dummy_nd_ptr(ctx); + qdf_net_if_create_dummy_if((struct qdf_net_if **)&dummy_nd); + qdf_netif_napi_add(dummy_nd, &ctx->napi, + hif_exec_poll, QCA_NAPI_BUDGET); qdf_napi_enable(&ctx->napi); return &ctx->exec_ctx; diff --git a/hif/src/hif_exec.h b/hif/src/hif_exec.h index a89b2ca559..62d7fac95b 100644 --- a/hif/src/hif_exec.h +++ b/hif/src/hif_exec.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-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 @@ -156,8 +156,12 @@ struct hif_tasklet_exec_context { */ struct hif_napi_exec_context { struct hif_exec_context exec_ctx; - struct net_device netdev; /* dummy net_dev */ - struct napi_struct napi; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) + struct net_device *netdev; /* dummy net_dev ptr */ +#else + struct net_device netdev; /* dummy net_dev */ +#endif + struct napi_struct napi; }; static inline struct hif_napi_exec_context* diff --git a/hif/src/hif_napi.c b/hif/src/hif_napi.c index 82cbccbc9b..0b1c7d86c7 100644 --- a/hif/src/hif_napi.c +++ b/hif/src/hif_napi.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-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 @@ -72,6 +72,26 @@ static int hif_rxthread_napi_poll(struct napi_struct *napi, int budget) return 0; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +/** + * hif_rx_thread_napi_get_netdev_ptr() - Get dummy netdev pointer + * @napii: qca_napi_info pointer + * + * Return: dummy netdev pointer + */ +static inline struct net_device * +hif_rx_thread_napi_get_netdev_ptr(struct qca_napi_info *napii) +{ + return napii->rx_thread_netdev; +} +#else +static inline struct net_device * +hif_rx_thread_napi_get_netdev_ptr(struct qca_napi_info *napii) +{ + return &napii->rx_thread_netdev; +} +#endif + /** * hif_init_rx_thread_napi() - Initialize dummy Rx_thread NAPI * @napii: Handle to napi_info holding rx_thread napi @@ -80,10 +100,10 @@ static int hif_rxthread_napi_poll(struct napi_struct *napi, int budget) */ static void hif_init_rx_thread_napi(struct qca_napi_info *napii) { - struct qdf_net_if *nd = (struct qdf_net_if *)&napii->rx_thread_netdev; + struct net_device *nd = hif_rx_thread_napi_get_netdev_ptr(napii); - qdf_net_if_create_dummy_if(nd); - qdf_netif_napi_add(&napii->rx_thread_netdev, &napii->rx_thread_napi, + qdf_net_if_create_dummy_if((struct qdf_net_if **)&nd); + qdf_netif_napi_add(nd, &napii->rx_thread_napi, hif_rxthread_napi_poll, 64); qdf_napi_enable(&napii->rx_thread_napi); } @@ -96,6 +116,9 @@ static void hif_init_rx_thread_napi(struct qca_napi_info *napii) */ static void hif_deinit_rx_thread_napi(struct qca_napi_info *napii) { + struct net_device *nd = hif_rx_thread_napi_get_netdev_ptr(napii); + + qdf_net_if_destroy_dummy_if((struct qdf_net_if *)nd); qdf_netif_napi_del(&napii->rx_thread_napi); } #else /* RECEIVE_OFFLOAD */ @@ -108,6 +131,26 @@ static void hif_deinit_rx_thread_napi(struct qca_napi_info *napii) } #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +/** + * hif_napi_get_dummy_netdev_ptr() - Get dummy netdev pointer + * @napii: qca_napi_info pointer + * + * Return: dummy netdev pointer + */ +static inline struct net_device * +hif_napi_get_dummy_netdev_ptr(struct qca_napi_info *napii) +{ + return napii->netdev; +} +#else +static inline struct net_device * +hif_napi_get_dummy_netdev_ptr(struct qca_napi_info *napii) +{ + return &napii->netdev; +} +#endif + /** * hif_napi_create() - creates the NAPI structures for a given CE * @hif_ctx: pointer to hif context @@ -140,6 +183,7 @@ int hif_napi_create(struct hif_opaque_softc *hif_ctx, struct CE_state *ce_state; struct hif_softc *hif = HIF_GET_SOFTC(hif_ctx); int rc = 0; + struct net_device *dummy_netdev; NAPI_DEBUG("-->(budget=%d, scale=%d)", budget, scale); @@ -202,22 +246,23 @@ int hif_napi_create(struct hif_opaque_softc *hif_ctx, if (napii->irq < 0) hif_warn("bad IRQ value for CE %d: %d", i, napii->irq); - qdf_net_if_create_dummy_if((struct qdf_net_if *)&napii->netdev); + dummy_netdev = hif_napi_get_dummy_netdev_ptr(napii); + qdf_net_if_create_dummy_if((struct qdf_net_if **)&dummy_netdev); NAPI_DEBUG("adding napi=%pK to netdev=%pK (poll=%pK, bdgt=%d)", - &(napii->napi), &(napii->netdev), poll, budget); - qdf_netif_napi_add(&(napii->netdev), &(napii->napi), + &napii->napi, dummy_netdev, poll, budget); + qdf_netif_napi_add(dummy_netdev, &napii->napi, poll, budget); NAPI_DEBUG("after napi_add"); NAPI_DEBUG("napi=0x%pK, netdev=0x%pK", - &(napii->napi), &(napii->netdev)); + &napii->napi, dummy_netdev); NAPI_DEBUG("napi.dev_list.prev=0x%pK, next=0x%pK", napii->napi.dev_list.prev, napii->napi.dev_list.next); NAPI_DEBUG("dev.napi_list.prev=0x%pK, next=0x%pK", - napii->netdev.napi_list.prev, - napii->netdev.napi_list.next); + dummy_netdev->napi_list.prev, + dummy_netdev->napi_list.next); hif_init_rx_thread_napi(napii); napii->lro_ctx = qdf_lro_init(); @@ -337,6 +382,7 @@ int hif_napi_destroy(struct hif_opaque_softc *hif_ctx, uint8_t ce = NAPI_ID2PIPE(id); int rc = 0; struct hif_softc *hif = HIF_GET_SOFTC(hif_ctx); + struct net_device *dummy_nd; NAPI_DEBUG("-->(id=%d, force=%d)", id, force); @@ -373,17 +419,19 @@ int hif_napi_destroy(struct hif_opaque_softc *hif_ctx, } } if (0 == rc) { + dummy_nd = hif_napi_get_dummy_netdev_ptr(napii); NAPI_DEBUG("before napi_del"); NAPI_DEBUG("napi.dlist.prv=0x%pK, next=0x%pK", napii->napi.dev_list.prev, napii->napi.dev_list.next); NAPI_DEBUG("dev.napi_l.prv=0x%pK, next=0x%pK", - napii->netdev.napi_list.prev, - napii->netdev.napi_list.next); + dummy_nd->napi_list.prev, + dummy_nd->napi_list.next); qdf_lro_deinit(napii->lro_ctx); qdf_netif_napi_del(&(napii->napi)); hif_deinit_rx_thread_napi(napii); + qdf_net_if_destroy_dummy_if((struct qdf_net_if *)dummy_nd); napid->ce_map &= ~(0x01 << ce); napid->napis[ce] = NULL; diff --git a/qdf/inc/qdf_net_if.h b/qdf/inc/qdf_net_if.h index 40d8b786ee..0d0b9821ae 100644 --- a/qdf/inc/qdf_net_if.h +++ b/qdf/inc/qdf_net_if.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-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 @@ -41,7 +41,18 @@ struct qdf_net_if; * Return: QDF_STATUS_SUCCESS on success */ QDF_STATUS -qdf_net_if_create_dummy_if(struct qdf_net_if *nif); +qdf_net_if_create_dummy_if(struct qdf_net_if **nif); + +/** + * qdf_net_if_destroy_dummy_if() - destroy dummy interface + * @nif: interface handle + * + * This function will destroy a dummy network interface + * + * Return: None + */ +void +qdf_net_if_destroy_dummy_if(struct qdf_net_if *nif); /** * qdf_net_if_get_dev_by_name() - Find a network device by its name @@ -141,11 +152,17 @@ qdf_net_update_net_device_dev_addr(struct net_device *ndev, size_t len); #else /* ENHANCED_OS_ABSTRACTION */ static inline QDF_STATUS -qdf_net_if_create_dummy_if(struct qdf_net_if *nif) +qdf_net_if_create_dummy_if(struct qdf_net_if **nif) { return __qdf_net_if_create_dummy_if(nif); } +static inline void +qdf_net_if_destroy_dummy_if(struct qdf_net_if *nif) +{ + __qdf_net_if_destroy_dummy_if(nif); +} + static inline struct qdf_net_if * qdf_net_if_get_dev_by_name(char *nif_name) { diff --git a/qdf/linux/src/i_qdf_net_if.h b/qdf/linux/src/i_qdf_net_if.h index 4ea9decf50..f62b6d3c2a 100644 --- a/qdf/linux/src/i_qdf_net_if.h +++ b/qdf/linux/src/i_qdf_net_if.h @@ -33,6 +33,7 @@ struct qdf_net_if; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) /** * __qdf_net_if_create_dummy_if() - create dummy interface * @nif: interface handle @@ -41,24 +42,43 @@ struct qdf_net_if; * * Return: QDF_STATUS_SUCCESS on success */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) static inline QDF_STATUS -__qdf_net_if_create_dummy_if(struct qdf_net_if *nif) +__qdf_net_if_create_dummy_if(struct qdf_net_if **nif) { - nif = (struct qdf_net_if *)alloc_netdev_dummy(0); + *nif = (struct qdf_net_if *)alloc_netdev_dummy(0); - if (!nif) + if (!(*nif)) return QDF_STATUS_E_NOMEM; return QDF_STATUS_SUCCESS; } + +/** + * __qdf_net_if_destroy_dummy_if() - destroy dummy interface + * @nif: interface handle + * + * This function will destroy a dummy network interface + * + * Return: None + */ +static inline void +__qdf_net_if_destroy_dummy_if(struct qdf_net_if *nif) +{ + if (nif) + free_netdev((struct net_device *)nif); +} #else static inline QDF_STATUS -__qdf_net_if_create_dummy_if(struct qdf_net_if *nif) +__qdf_net_if_create_dummy_if(struct qdf_net_if **nif) { - init_dummy_netdev((struct net_device *)nif); + init_dummy_netdev((struct net_device *)*nif); return qdf_status_from_os_return(0); } + +static inline void +__qdf_net_if_destroy_dummy_if(struct qdf_net_if *nif) +{ +} #endif /** diff --git a/qdf/linux/src/qdf_net_if.c b/qdf/linux/src/qdf_net_if.c index 1f1a20a109..e3b735cd6b 100644 --- a/qdf/linux/src/qdf_net_if.c +++ b/qdf/linux/src/qdf_net_if.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018,2020 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 @@ -27,21 +27,48 @@ #include "qdf_util.h" #include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) QDF_STATUS -qdf_net_if_create_dummy_if(struct qdf_net_if *nif) +qdf_net_if_create_dummy_if(struct qdf_net_if **nif) +{ + *nif = (struct qdf_net_if *)alloc_netdev_dummy(0); + + if (!(*nif)) + return QDF_STATUS_E_NOMEM; + + return QDF_STATUS_SUCCESS; +} +#else +QDF_STATUS +qdf_net_if_create_dummy_if(struct qdf_net_if **nif) { int ret; - if (!nif) + if (!(*nif)) return QDF_STATUS_E_INVAL; - ret = init_dummy_netdev((struct net_device *)nif); + ret = init_dummy_netdev((struct net_device *)*nif); return qdf_status_from_os_return(ret); } +#endif qdf_export_symbol(qdf_net_if_create_dummy_if); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +void +qdf_net_if_destroy_dummy_if(struct qdf_net_if *nif) +{ + if (nif) + free_netdev((struct net_device *)nif); +} +#else +void +qdf_net_if_destroy_dummy_if(struct qdf_net_if *nif) +{ +} +#endif + /** * qdf_net_if_get_devname() - Retrieve netdevice name * @nif: Abstraction of netdevice From 0418d5fe255fa8d12b57f4b130c117825df3f6f0 Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Fri, 6 Jun 2025 07:59:10 -0700 Subject: [PATCH 11/13] qcacmn: Fix vdev_mgr_rsp_timer race condition issue During roaming, disconnect from os_if tries to stop RSO/start vdev_mgr_rsp_timer, Hand-off Failure from target_if received, stop vdev_mgr_rsp_timer, lead to psoc ref of WLAN_PSOC_TARGET_IF_ID released before held. To address it, add lock to protect vdev_mgr_rsp_timer start and stop. Change-Id: I0bdd5db88b1fa1eb1e5aaef8650d9dbda550f1fd CRs-Fixed: 4170826 --- .../vdev_mgr/src/target_if_vdev_mgr_tx_ops.c | 90 +++++++++++++++++-- umac/mlme/include/wlan_psoc_mlme.h | 4 +- .../dispatcher/src/wlan_psoc_mlme_api.c | 29 +++++- 3 files changed, 112 insertions(+), 11 deletions(-) diff --git a/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c b/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c index 51eb578183..c28f4abfe0 100644 --- a/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c +++ b/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 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 @@ -39,6 +39,7 @@ #include #include #include +#include static QDF_STATUS target_if_vdev_mgr_register_event_handler( struct wlan_objmgr_psoc *psoc) @@ -52,10 +53,19 @@ static QDF_STATUS target_if_vdev_mgr_unregister_event_handler( return target_if_vdev_mgr_wmi_event_unregister(psoc); } -QDF_STATUS -target_if_vdev_mgr_rsp_timer_stop(struct wlan_objmgr_psoc *psoc, - struct vdev_response_timer *vdev_rsp, - enum wlan_vdev_mgr_tgt_if_rsp_bit clear_bit) +/** + * _target_if_vdev_mgr_rsp_timer_stop() - API to stop response timer for + * vdev manager operations + * @psoc: pointer to psoc object + * @vdev_rsp: vdev response timer + * @clear_bit: enum of wlan_vdev_mgr_tgt_if_rsp_bit + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +static QDF_STATUS +_target_if_vdev_mgr_rsp_timer_stop(struct wlan_objmgr_psoc *psoc, + struct vdev_response_timer *vdev_rsp, + enum wlan_vdev_mgr_tgt_if_rsp_bit clear_bit) { struct wlan_lmac_if_mlme_tx_ops *txops; @@ -102,10 +112,19 @@ target_if_vdev_mgr_rsp_timer_stop(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } -QDF_STATUS -target_if_vdev_mgr_rsp_timer_start(struct wlan_objmgr_psoc *psoc, - struct vdev_response_timer *vdev_rsp, - enum wlan_vdev_mgr_tgt_if_rsp_bit set_bit) +/** + * _target_if_vdev_mgr_rsp_timer_start() - API to start response timer for + * vdev manager operations + * @psoc: pointer to psoc object + * @vdev_rsp: vdev response timer + * @set_bit: enum of wlan_vdev_mgr_tgt_if_rsp_bit + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +static QDF_STATUS +_target_if_vdev_mgr_rsp_timer_start(struct wlan_objmgr_psoc *psoc, + struct vdev_response_timer *vdev_rsp, + enum wlan_vdev_mgr_tgt_if_rsp_bit set_bit) { uint8_t rsp_pos; uint8_t vdev_id; @@ -149,6 +168,59 @@ target_if_vdev_mgr_rsp_timer_start(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +static QDF_STATUS +target_if_vdev_mgr_rsp_tmr_mutex_acquire(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mlme_obj *mlme_psoc_obj; + + mlme_psoc_obj = wlan_psoc_mlme_get_cmpt_obj(psoc); + + if (!mlme_psoc_obj) + return QDF_STATUS_E_INVAL; + + return qdf_mutex_acquire(&mlme_psoc_obj->vdev_rsp_timer_mutex); +} + +static QDF_STATUS +target_if_vdev_mgr_rsp_tmr_mutex_release(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mlme_obj *mlme_psoc_obj; + + mlme_psoc_obj = wlan_psoc_mlme_get_cmpt_obj(psoc); + + if (!mlme_psoc_obj) + return QDF_STATUS_E_INVAL; + + return qdf_mutex_release(&mlme_psoc_obj->vdev_rsp_timer_mutex); +} + +QDF_STATUS +target_if_vdev_mgr_rsp_timer_stop(struct wlan_objmgr_psoc *psoc, + struct vdev_response_timer *vdev_rsp, + enum wlan_vdev_mgr_tgt_if_rsp_bit clear_bit) +{ + QDF_STATUS status; + + target_if_vdev_mgr_rsp_tmr_mutex_acquire(psoc); + status = _target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, clear_bit); + target_if_vdev_mgr_rsp_tmr_mutex_release(psoc); + + return status; +} + +QDF_STATUS +target_if_vdev_mgr_rsp_timer_start(struct wlan_objmgr_psoc *psoc, + struct vdev_response_timer *vdev_rsp, + enum wlan_vdev_mgr_tgt_if_rsp_bit set_bit) +{ + QDF_STATUS status; + + target_if_vdev_mgr_rsp_tmr_mutex_acquire(psoc); + status = _target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp, set_bit); + target_if_vdev_mgr_rsp_tmr_mutex_release(psoc); + + return status; +} struct wmi_unified *target_if_vdev_mgr_wmi_handle_get(struct wlan_objmgr_vdev *vdev) diff --git a/umac/mlme/include/wlan_psoc_mlme.h b/umac/mlme/include/wlan_psoc_mlme.h index e7c7ab49b3..8bc922ba78 100644 --- a/umac/mlme/include/wlan_psoc_mlme.h +++ b/umac/mlme/include/wlan_psoc_mlme.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2019-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 above @@ -151,6 +151,7 @@ struct wlan_peer_tbl_trans_entry { * @psoc: PSoC object * @ext_psoc_ptr: PSoC legacy pointer * @psoc_vdev_rt: PSoC Vdev response timer + * @vdev_rsp_timer_mutex: vdev rsp timer mutex to avoid race condition issue * @psoc_mlme_wakelock: Wakelock to prevent system going to suspend * @rnr_6ghz_cache: Cache of 6Ghz vap in RNR ie format * @rnr_6ghz_cache_legacy: Legacy (13TBTT) cache of 6Ghz vap in RNR ie format @@ -161,6 +162,7 @@ struct psoc_mlme_obj { struct wlan_objmgr_psoc *psoc; mlme_psoc_ext_t *ext_psoc_ptr; struct vdev_response_timer psoc_vdev_rt[WLAN_UMAC_PSOC_MAX_VDEVS]; + qdf_mutex_t vdev_rsp_timer_mutex; #ifdef FEATURE_VDEV_OPS_WAKELOCK struct psoc_mlme_wakelock psoc_mlme_wakelock; #endif diff --git a/umac/mlme/psoc_mgr/dispatcher/src/wlan_psoc_mlme_api.c b/umac/mlme/psoc_mgr/dispatcher/src/wlan_psoc_mlme_api.c index 5d57457941..a5222ebdc7 100644 --- a/umac/mlme/psoc_mgr/dispatcher/src/wlan_psoc_mlme_api.c +++ b/umac/mlme/psoc_mgr/dispatcher/src/wlan_psoc_mlme_api.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2019-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 above @@ -196,17 +196,44 @@ static void mlme_init_cfg(struct wlan_objmgr_psoc *psoc) WLAN_MD_OBJMGR_PSOC_MLME, "psoc_mlme"); } +static void mlme_vdev_rsp_timer_mutex_create(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mlme_obj *mlme_psoc_obj; + + mlme_psoc_obj = wlan_psoc_mlme_get_cmpt_obj(psoc); + + if (!mlme_psoc_obj) + return; + + qdf_mutex_create(&mlme_psoc_obj->vdev_rsp_timer_mutex); +} + +static void mlme_vdev_rsp_timer_mutex_destroy(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mlme_obj *mlme_psoc_obj; + + mlme_psoc_obj = wlan_psoc_mlme_get_cmpt_obj(psoc); + + if (!mlme_psoc_obj) + return; + + qdf_mutex_destroy(&mlme_psoc_obj->vdev_rsp_timer_mutex); +} + QDF_STATUS mlme_psoc_open(struct wlan_objmgr_psoc *psoc) { mlme_init_cfg(psoc); + mlme_vdev_rsp_timer_mutex_create(psoc); return QDF_STATUS_SUCCESS; } QDF_STATUS mlme_psoc_close(struct wlan_objmgr_psoc *psoc) { + mlme_vdev_rsp_timer_mutex_destroy(psoc); if (qdf_is_recovering()) tgt_vdev_mgr_reset_response_timer_info(psoc); + return QDF_STATUS_SUCCESS; } From 070dd8602f68dde894aeb058cf27e5e1430dbf0e Mon Sep 17 00:00:00 2001 From: Vinod Kumar Pirla Date: Wed, 11 Jun 2025 03:11:50 -0700 Subject: [PATCH 12/13] qcacmn: Update policy mgr entry only if VDEV is connected On MLO link state switch event from FW, host tries to update the entries in policy manager table according to the new state of the link. Processing this event while any VDEV is not in connected state (disconnect sequence is on-going) can result in race condition and potentially corrupt the policy manager entries. Check the state of VDEV before updating the policy manager entry to prevent possibility of stale entries due to parallel access. Change-Id: I64abb5251e3a9a1b59a7b2315e9ed1e353f3a406 CRs-Fixed: 4179247 --- umac/mlo_mgr/src/wlan_mlo_mgr_link_switch.c | 22 +++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/umac/mlo_mgr/src/wlan_mlo_mgr_link_switch.c b/umac/mlo_mgr/src/wlan_mlo_mgr_link_switch.c index 8e09e4d926..2673bc249b 100644 --- a/umac/mlo_mgr/src/wlan_mlo_mgr_link_switch.c +++ b/umac/mlo_mgr/src/wlan_mlo_mgr_link_switch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2025 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 above @@ -1749,6 +1749,7 @@ static void mlo_mgr_update_link_state(struct wlan_objmgr_psoc *psoc, { uint8_t i, vdev_id, num_links = 0; struct mlo_link_info *link_info; + struct wlan_objmgr_vdev *vdev; struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx(); num_links = mlo_get_sta_num_links(mld_ctx); @@ -1779,9 +1780,22 @@ static void mlo_mgr_update_link_state(struct wlan_objmgr_psoc *psoc, mlo_ctx->mlme_ops->mlo_mlme_ext_teardown_tdls(psoc, vdev_id); - mlo_mgr_update_policy_mgr_disabled_links_info( - psoc, vdev_id, link_info->link_id, - link_info->is_link_active); + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLO_MGR_ID); + if (!vdev) + continue; + + /* + * If VDEV is not in connected state don't update the policy + * manager table, this can happen if disconnect is ongoing when + * host receives event from FW. + */ + if (wlan_cm_is_vdev_connected(vdev)) + mlo_mgr_update_policy_mgr_disabled_links_info(psoc, + vdev_id, + link_info->link_id, + link_info->is_link_active); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLO_MGR_ID); } } From 72a0d6f663e0e1d200f18e042e3808c2147556a6 Mon Sep 17 00:00:00 2001 From: Rahul Gusain Date: Mon, 19 May 2025 19:03:17 +0530 Subject: [PATCH 13/13] qcacmn: Process NAN disable response Currently, driver send NAN disable response event to userspace as generic event. With this change, it processes the NAN disable response event and clean up NAN in the driver. Change-Id: I955996c77c4e6c0dc0e5237e3f7ea39d08866d09 CRs-Fixed: 4153823 --- wmi/src/wmi_unified_nan_tlv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/wmi/src/wmi_unified_nan_tlv.c b/wmi/src/wmi_unified_nan_tlv.c index 6dfc0d8c37..33f0f54e0c 100644 --- a/wmi/src/wmi_unified_nan_tlv.c +++ b/wmi/src/wmi_unified_nan_tlv.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2025 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 @@ -131,6 +131,9 @@ extract_nan_event_rsp_tlv(wmi_unified_t wmi_handle, void *evt_buf, evt_params->is_nan_enable_success = (nan_evt_info->status == 0); evt_params->vdev_id = nan_evt_info->vdev_id; break; + case NAN_MSG_ID_DISABLE_RSP: + evt_params->evt_type = nan_event_id_disable_rsp; + break; case NAN_MSG_ID_DISABLE_IND: evt_params->evt_type = nan_event_id_disable_ind; break; @@ -188,6 +191,9 @@ extract_nan_event_rsp_tlv(wmi_unified_t wmi_handle, void *evt_buf, break; } + wmi_debug("msg_id %d, evt_type %d", nan_msg_hdr->msg_id, + evt_params->evt_type); + return QDF_STATUS_SUCCESS; }