From 3f111f2faea58b2aec2d116a2bdc98d8a473416f Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Mon, 12 May 2025 15:16:33 +0530 Subject: [PATCH] qcacmn: Fix null dma address mapping for page pool buffers Currently in a case where only RX page pool is enabled, when RX page pool buffers are forwarded by the network stack to the driver for TX due to IP forwarding, it is resulting in a NULL DMA address mapping. Since the RX page pool NBUFs have struct sk_buff::pp_recycle flag set, driver will end up calling dma_sync_single_for_device() for taking care of the cache ops in the transmit direction. When TX page pool feature is not enabled, NULL DMA address will be passed to the dma_sync_single_for_device() API resulting in assert. Check the status of TX page pool feature before invoking dma_sync_single_for_device() to fix this issue. CRs-Fixed: 4145181 Change-Id: I8ddb8f020d9a9d9fe6d8d969a58ecbcad7b52062 (cherry picked from commit cb44c3edd5d3c6ff1b20800e9ea9aa78bc583deb) --- dp/wifi3.0/dp_tx_flow_control.c | 1 + qdf/linux/src/i_qdf_nbuf_m.h | 2 +- qdf/linux/src/i_qdf_types.h | 4 +++- qdf/linux/src/qdf_nbuf.c | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dp/wifi3.0/dp_tx_flow_control.c b/dp/wifi3.0/dp_tx_flow_control.c index 78338b5188..288ebc24c1 100644 --- a/dp/wifi3.0/dp_tx_flow_control.c +++ b/dp/wifi3.0/dp_tx_flow_control.c @@ -550,6 +550,7 @@ static QDF_STATUS dp_tx_page_pool_init(struct dp_soc *soc, qdf_spinlock_create(&tx_pp->pp_lock); qdf_atomic_init(&tx_pp->ref_cnt); tx_pp->page_pool_init = true; + soc->osdev->no_dma_map = true; return QDF_STATUS_SUCCESS; } diff --git a/qdf/linux/src/i_qdf_nbuf_m.h b/qdf/linux/src/i_qdf_nbuf_m.h index 3b554e72b5..8cc1e10374 100644 --- a/qdf/linux/src/i_qdf_nbuf_m.h +++ b/qdf/linux/src/i_qdf_nbuf_m.h @@ -740,7 +740,7 @@ static inline QDF_STATUS __qdf_nbuf_map_nbytes_single( qdf_dma_addr_t paddr; QDF_STATUS ret; - if (__qdf_is_pp_nbuf(buf)) { + if (osdev->no_dma_map && __qdf_is_pp_nbuf(buf)) { dma_sync_single_for_device(osdev->dev, QDF_NBUF_CB_PADDR(buf), nbytes, __qdf_dma_dir_to_os(dir)); return QDF_STATUS_SUCCESS; diff --git a/qdf/linux/src/i_qdf_types.h b/qdf/linux/src/i_qdf_types.h index 59f20956a9..8c5d33d467 100644 --- a/qdf/linux/src/i_qdf_types.h +++ b/qdf/linux/src/i_qdf_types.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-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 @@ -286,6 +286,7 @@ enum qdf_bus_type { * @smmu_s1_enabled: SMMU S1 enabled or not * @domain: domain type * @iommu_mapping: DMA iommu mapping pointer + * @no_dma_map: Flag to check whether DMA mapping for TX buffers is needed */ struct __qdf_device { void *drv; @@ -307,6 +308,7 @@ struct __qdf_device { struct dma_iommu_mapping *iommu_mapping; #endif #endif + bool no_dma_map; }; typedef struct __qdf_device *__qdf_device_t; diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 5c36791a85..766eb386ac 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -1493,7 +1493,7 @@ __qdf_nbuf_map_single(qdf_device_t osdev, qdf_nbuf_t buf, qdf_dma_dir_t dir) qdf_dma_addr_t paddr; QDF_STATUS ret; - if (__qdf_is_pp_nbuf(buf)) { + if (osdev->no_dma_map && __qdf_is_pp_nbuf(buf)) { dma_sync_single_for_device(osdev->dev, QDF_NBUF_CB_PADDR(buf), skb_end_pointer(buf) - buf->data, __qdf_dma_dir_to_os(dir));