diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath12k/dp.c')
-rw-r--r-- | drivers/net/wireless/ath/ath12k/dp.c | 89 |
1 files changed, 67 insertions, 22 deletions
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index c99e9ceb1a6e..b1f27c3ac723 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <crypto/hash.h> @@ -41,6 +41,11 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) return; } + if (!peer->primary_link) { + spin_unlock_bh(&ab->base_lock); + return; + } + ath12k_dp_rx_peer_tid_cleanup(ar, peer); crypto_free_shash(peer->tfm_mmic); peer->dp_setup_done = false; @@ -977,27 +982,23 @@ void ath12k_dp_pdev_free(struct ath12k_base *ab) { int i; + if (!ab->mon_reap_timer.function) + return; + del_timer_sync(&ab->mon_reap_timer); for (i = 0; i < ab->num_radios; i++) ath12k_dp_rx_pdev_free(ab, i); } -void ath12k_dp_pdev_pre_alloc(struct ath12k_base *ab) +void ath12k_dp_pdev_pre_alloc(struct ath12k *ar) { - struct ath12k *ar; - struct ath12k_pdev_dp *dp; - int i; + struct ath12k_pdev_dp *dp = &ar->dp; - for (i = 0; i < ab->num_radios; i++) { - ar = ab->pdevs[i].ar; - dp = &ar->dp; - dp->mac_id = i; - atomic_set(&dp->num_tx_pending, 0); - init_waitqueue_head(&dp->tx_empty_waitq); - - /* TODO: Add any RXDMA setup required per pdev */ - } + dp->mac_id = ar->pdev_idx; + atomic_set(&dp->num_tx_pending, 0); + init_waitqueue_head(&dp->tx_empty_waitq); + /* TODO: Add any RXDMA setup required per pdev */ } bool ath12k_dp_wmask_compaction_rx_tlv_supported(struct ath12k_base *ab) @@ -1260,15 +1261,23 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) if (!ab->hw_params->reoq_lut_support) return; - if (!dp->reoq_lut.vaddr) - return; - - dma_free_coherent(ab->dev, DP_REOQ_LUT_SIZE, - dp->reoq_lut.vaddr, dp->reoq_lut.paddr); - dp->reoq_lut.vaddr = NULL; + if (dp->reoq_lut.vaddr) { + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_REO_REG + + HAL_REO1_QDESC_LUT_BASE0(ab), 0); + dma_free_coherent(ab->dev, DP_REOQ_LUT_SIZE, + dp->reoq_lut.vaddr, dp->reoq_lut.paddr); + dp->reoq_lut.vaddr = NULL; + } - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE0(ab), 0); + if (dp->ml_reoq_lut.vaddr) { + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_REO_REG + + HAL_REO1_QDESC_LUT_BASE1(ab), 0); + dma_free_coherent(ab->dev, DP_REOQ_LUT_SIZE, + dp->ml_reoq_lut.vaddr, dp->ml_reoq_lut.paddr); + dp->ml_reoq_lut.vaddr = NULL; + } } void ath12k_dp_free(struct ath12k_base *ab) @@ -1276,6 +1285,9 @@ void ath12k_dp_free(struct ath12k_base *ab) struct ath12k_dp *dp = &ab->dp; int i; + if (!dp->ab) + return; + ath12k_dp_link_desc_cleanup(ab, dp->link_desc_banks, HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring); @@ -1293,6 +1305,7 @@ void ath12k_dp_free(struct ath12k_base *ab) ath12k_dp_rx_free(ab); /* Deinit any SOC level resource */ + dp->ab = NULL; } void ath12k_dp_cc_config(struct ath12k_base *ab) @@ -1302,6 +1315,9 @@ void ath12k_dp_cc_config(struct ath12k_base *ab) u32 wbm_base = HAL_SEQ_WCSS_UMAC_WBM_REG; u32 val = 0; + if (ath12k_ftm_mode) + return; + ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(ab), cmem_base); val |= u32_encode_bits(ATH12K_CMEM_ADDR_MSB, @@ -1432,6 +1448,7 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) for (j = 0; j < ATH12K_MAX_SPT_ENTRIES; j++) { rx_descs[j].cookie = ath12k_dp_cc_cookie_gen(cookie_ppt_idx, j); rx_descs[j].magic = ATH12K_DP_RX_DESC_MAGIC; + rx_descs[j].device_id = ab->device_id; list_add_tail(&rx_descs[j].list, &dp->rx_desc_free_list); /* Update descriptor VA in SPT */ @@ -1508,6 +1525,19 @@ static int ath12k_dp_cmem_init(struct ath12k_base *ab, return 0; } +void ath12k_dp_partner_cc_init(struct ath12k_base *ab) +{ + struct ath12k_hw_group *ag = ab->ag; + int i; + + for (i = 0; i < ag->num_devices; i++) { + if (ag->ab[i] == ab) + continue; + + ath12k_dp_cmem_init(ab, &ag->ab[i]->dp, ATH12K_DP_RX_DESC); + } +} + static int ath12k_dp_cc_init(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; @@ -1594,8 +1624,23 @@ static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) return -ENOMEM; } + dp->ml_reoq_lut.vaddr = dma_alloc_coherent(ab->dev, + DP_REOQ_LUT_SIZE, + &dp->ml_reoq_lut.paddr, + GFP_KERNEL | __GFP_ZERO); + if (!dp->ml_reoq_lut.vaddr) { + ath12k_warn(ab, "failed to allocate memory for ML reoq table"); + dma_free_coherent(ab->dev, DP_REOQ_LUT_SIZE, + dp->reoq_lut.vaddr, dp->reoq_lut.paddr); + dp->reoq_lut.vaddr = NULL; + return -ENOMEM; + } + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE0(ab), dp->reoq_lut.paddr); + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(ab), + dp->ml_reoq_lut.paddr >> 8); + return 0; } |