From 31582373a4a8e888b29ed759d28330a1995f2162 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 11 Oct 2021 09:33:09 +0300 Subject: [PATCH] ath11k: Change number of TCL rings to one for QCA6390 Some targets, QCA6390 for example, use only one TCL ring, it is better to initialize only one ring and leave others untouched for such targets. This is a theoretical fix found during code review, no visible impact. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Baochen Qiang Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210914163726.38604-1-jouni@codeaurora.org --- drivers/net/wireless/ath/ath11k/core.c | 10 +++++----- drivers/net/wireless/ath/ath11k/debugfs.c | 2 +- drivers/net/wireless/ath/ath11k/dp.c | 10 +++++----- drivers/net/wireless/ath/ath11k/dp.h | 1 + drivers/net/wireless/ath/ath11k/dp_tx.c | 13 +++++-------- drivers/net/wireless/ath/ath11k/hw.h | 2 +- drivers/net/wireless/ath/ath11k/mac.c | 2 +- 7 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 2328e594a96af..b0d6922802edf 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -58,7 +58,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .rx_mac_buf_ring = false, .vdev_start_delay = false, .htt_peer_map_v2 = true, - .tcl_0_only = false, .spectral = { .fft_sz = 2, @@ -81,6 +80,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -109,7 +109,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .rx_mac_buf_ring = false, .vdev_start_delay = false, .htt_peer_map_v2 = true, - .tcl_0_only = false, .spectral = { .fft_sz = 4, @@ -129,6 +128,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX, }, { .name = "qca6390 hw2.0", @@ -157,7 +157,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .rx_mac_buf_ring = true, .vdev_start_delay = true, .htt_peer_map_v2 = false, - .tcl_0_only = true, .spectral = { .fft_sz = 0, @@ -176,6 +175,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = true, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, }, { .name = "qcn9074 hw1.0", @@ -203,7 +203,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .rx_mac_buf_ring = false, .vdev_start_delay = false, .htt_peer_map_v2 = true, - .tcl_0_only = false, .spectral = { .fft_sz = 2, @@ -223,6 +222,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), .fix_l1ss = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX, }, { .name = "wcn6855 hw2.0", @@ -251,7 +251,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .rx_mac_buf_ring = true, .vdev_start_delay = true, .htt_peer_map_v2 = false, - .tcl_0_only = true, .spectral = { .fft_sz = 0, @@ -270,6 +269,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = true, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), .fix_l1ss = false, + .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, }, }; diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c index 17f0bbbac7ae6..80afd35337a19 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -806,7 +806,7 @@ static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file, len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n"); len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n"); - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) + for (i = 0; i < ab->hw_params.max_tx_ring; i++) len += scnprintf(buf + len, size - len, "ring%d: %u\n", i, soc_stats->tx_err.desc_na[i]); diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index b0c8f62900997..c52d49cb8a048 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -311,7 +311,7 @@ void ath11k_dp_stop_shadow_timers(struct ath11k_base *ab) if (!ab->hw_params.supports_shadow_regs) return; - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) + for (i = 0; i < ab->hw_params.max_tx_ring; i++) ath11k_dp_shadow_stop_timer(ab, &ab->dp.tx_ring_timer[i]); ath11k_dp_shadow_stop_timer(ab, &ab->dp.reo_cmd_timer); @@ -326,7 +326,7 @@ static void ath11k_dp_srng_common_cleanup(struct ath11k_base *ab) ath11k_dp_srng_cleanup(ab, &dp->wbm_desc_rel_ring); ath11k_dp_srng_cleanup(ab, &dp->tcl_cmd_ring); ath11k_dp_srng_cleanup(ab, &dp->tcl_status_ring); - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_data_ring); ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_comp_ring); } @@ -366,7 +366,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab) goto err; } - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring, HAL_TCL_DATA, i, 0, DP_TCL_DATA_RING_SIZE); @@ -996,7 +996,7 @@ void ath11k_dp_free(struct ath11k_base *ab) ath11k_dp_reo_cmd_list_cleanup(ab); - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { spin_lock_bh(&dp->tx_ring[i].tx_idr_lock); idr_for_each(&dp->tx_ring[i].txbuf_idr, ath11k_dp_tx_pending_cleanup, ab); @@ -1046,7 +1046,7 @@ int ath11k_dp_alloc(struct ath11k_base *ab) size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE; - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { idr_init(&dp->tx_ring[i].txbuf_idr); spin_lock_init(&dp->tx_ring[i].tx_idr_lock); dp->tx_ring[i].tcl_data_ring_id = i; diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index d6267bfa02649..4794ca04f2136 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -170,6 +170,7 @@ struct ath11k_pdev_dp { #define DP_BA_WIN_SZ_MAX 256 #define DP_TCL_NUM_RING_MAX 3 +#define DP_TCL_NUM_RING_MAX_QCA6390 1 #define DP_IDLE_SCATTER_BUFS_MAX 16 diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c index 70d2cf010a686..879fb2a9dc0c6 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -115,11 +115,8 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, tcl_ring_sel: tcl_ring_retry = false; - /* For some chip, it can only use tcl0 to tx */ - if (ar->ab->hw_params.tcl_0_only) - ti.ring_id = 0; - else - ti.ring_id = ring_selector % DP_TCL_NUM_RING_MAX; + + ti.ring_id = ring_selector % ab->hw_params.max_tx_ring; ring_map |= BIT(ti.ring_id); @@ -131,7 +128,7 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, spin_unlock_bh(&tx_ring->tx_idr_lock); if (ret < 0) { - if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1)) { + if (ring_map == (BIT(ab->hw_params.max_tx_ring) - 1)) { atomic_inc(&ab->soc_stats.tx_err.misc_fail); return -ENOSPC; } @@ -248,8 +245,8 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, * checking this ring earlier for each pkt tx. * Restart ring selection if some rings are not checked yet. */ - if (ring_map != (BIT(DP_TCL_NUM_RING_MAX) - 1) && - !ar->ab->hw_params.tcl_0_only) { + if (ring_map != (BIT(ab->hw_params.max_tx_ring) - 1) && + ab->hw_params.max_tx_ring > 1) { tcl_ring_retry = true; ring_selector++; } diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 1535075eed038..8f92210edc8ff 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -152,7 +152,6 @@ struct ath11k_hw_params { bool rx_mac_buf_ring; bool vdev_start_delay; bool htt_peer_map_v2; - bool tcl_0_only; struct { u8 fft_sz; @@ -170,6 +169,7 @@ struct ath11k_hw_params { bool supports_suspend; u32 hal_desc_sz; bool fix_l1ss; + u8 max_tx_ring; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 89ab2fa7557ce..791c96b283e3b 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5797,7 +5797,7 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw, idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { spin_lock_bh(&ab->dp.tx_ring[i].tx_idr_lock); idr_for_each(&ab->dp.tx_ring[i].txbuf_idr, ath11k_mac_vif_unref, vif);