wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/782-ath12k-add-MLO-group-descriptor-limit-check-in-dp-tx.patch
John Crispin 144c5d00f4 ipq95xx/mac80211: update to ATH12.3-CS
Signed-off-by: John Crispin <john@phrozen.org>
2024-02-28 18:56:21 +01:00

188 lines
6.5 KiB
Diff

From 1b566d8fccb4c4d499c4e4c597ebd4c5474daa7c Mon Sep 17 00:00:00 2001
From: P Praneesh <quic_ppranees@quicinc.com>
Date: Tue, 13 Jun 2023 16:17:20 +0530
Subject: [PATCH] ath12k: add MLO group descriptor limit check in dp tx
Limit the tx data packet for per MLO group with the threshold
limit of 0xC000. Without the Tx limit check Multicast frames
send lead to out of memory in the system where HW capable of processing
more than the system memory profile.
Remove ATH12K_NUM_EAPOL_RESERVE from the ATH12K_DP_PDEV_TX_LIMIT calculation
because driver tx limit check allows all the EAPOL frames irrespective of the
pdev/group limit threshold.
Rename Threshold limit as Pdev tx threshold limit to make it relevant to the
functionality. Add member in soc dp stats to capture the group threshold limit.
Signed-off-by: Balamurugan Mahalingam <quic_bmahalin@quicinc.com>
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
---
drivers/net/wireless/ath/ath12k/bondif.c | 14 ++------------
drivers/net/wireless/ath/ath12k/core.c | 1 +
drivers/net/wireless/ath/ath12k/core.h | 4 +++-
drivers/net/wireless/ath/ath12k/debugfs.c | 19 +++++++++++++++----
drivers/net/wireless/ath/ath12k/dp.h | 4 ++--
drivers/net/wireless/ath/ath12k/dp_tx.c | 4 ++++
drivers/net/wireless/ath/ath12k/mac.c | 20 ++++++++++++++------
7 files changed, 41 insertions(+), 25 deletions(-)
--- a/drivers/net/wireless/ath/ath12k/bondif.c
+++ b/drivers/net/wireless/ath/ath12k/bondif.c
@@ -505,6 +505,7 @@ int ath12k_mcast_dp_tx(struct ath12k *ar
ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ", skb->data, skb->len);
arvif->link_stats.tx_enqueued++;
atomic_inc(&ar->dp.num_tx_pending);
+ atomic_inc(&ab->ag->num_dp_tx_pending);
return 0;
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -156,6 +156,7 @@ ath12k_core_hw_group_alloc(u8 id, u8 max
ag->id = id;
ag->num_chip = max_chip;
ag->mlo_capable = !!ath12k_mlo_capable;
+ atomic_set(&ag->num_dp_tx_pending, 0);
list_add(&ag->list, &ath12k_hw_groups);
mutex_init(&ag->mutex_lock);
mutex_init(&ag->mlomem_arena.mutex_lock);
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -1118,7 +1118,8 @@ struct ath12k_soc_dp_tx_err_stats {
/* TCL Ring Buffers unavailable */
u32 txbuf_na[DP_TCL_NUM_RING_MAX];
- u32 threshold_limit;
+ u32 pdev_threshold_limit;
+ u32 group_threshold_limit;
/* Other failures during dp_tx due to mem allocation failure
* idr unavailable etc.
@@ -1251,6 +1252,7 @@ struct ath12k_hw_group {
struct mutex mutex_lock;
struct ath12k_mgmt_rx_reo_context rx_reo;
struct ath12k_host_mlo_mem_arena mlomem_arena;
+ atomic_t num_dp_tx_pending;
};
/* Master structure to hold the hw data which may be used in core module */
--- a/drivers/net/wireless/ath/ath12k/debugfs.c
+++ b/drivers/net/wireless/ath/ath12k/debugfs.c
@@ -1649,8 +1649,12 @@ static ssize_t ath12k_debugfs_dump_soc_d
i, soc_stats->tx_err.txbuf_na[i]);
len += scnprintf(buf + len, size - len,
- "\nThreshold limit: %d\n",
- soc_stats->tx_err.threshold_limit);
+ "\nTx Threshold limit: %d\n",
+ soc_stats->tx_err.pdev_threshold_limit);
+
+ len += scnprintf(buf + len, size - len,
+ "\nGroup Tx Threshold limit: %u\n",
+ soc_stats->tx_err.group_threshold_limit);
len += scnprintf(buf + len, size - len,
"\nMisc Transmit Failures: %d\n",
@@ -1726,14 +1730,17 @@ static ssize_t ath12k_debugfs_dump_soc_d
soc_stats->tx_completed[2],
soc_stats->tx_completed[3]);
- for (i = 0; i < 3; i++) {
+ len += scnprintf(buf + len, size - len,
+ "\nag tx_pending: %u\n",
+ atomic_read(&ab->ag->num_dp_tx_pending));
+
+ for (i = 1; i <= ab->num_radios; i++) {
ar = ath12k_mac_get_ar_by_pdev_id(ab, i);
if (ar) {
len += scnprintf(buf + len, size - len,
- "\ntx_pending [%d]: 0:%d\n",
- i,
- atomic_read(&ar->dp.num_tx_pending));
+ "\nar tx_pending [%d]: %u\n", i,
+ atomic_read(&ar->dp.num_tx_pending));
}
}
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -276,8 +276,8 @@ struct ath12k_pdev_dp {
#define DP_REO_QREF_NUM GENMASK(31, 16)
#define DP_MAX_PEER_ID 2047
-#define ATH12K_NUM_EAPOL_RESERVE 1024
-#define ATH12K_DP_PDEV_TX_LIMIT (ATH12K_NUM_POOL_TX_DESC - ATH12K_NUM_EAPOL_RESERVE)
+#define ATH12K_DP_PDEV_TX_LIMIT ATH12K_NUM_POOL_TX_DESC
+#define ATH12K_DP_GROUP_TX_LIMIT 49152
/* Total size of the LUT is based on 2K peers, each having reference
* for 17tids, note each entry is of type ath12k_reo_queue_ref
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -363,6 +363,7 @@ int ath12k_dp_tx_direct(struct ath12k_li
spin_unlock_bh(&tcl_ring->lock);
atomic_inc(&ar->dp.num_tx_pending);
+ atomic_inc(&ab->ag->num_dp_tx_pending);
return 0;
@@ -657,6 +658,7 @@ int ath12k_dp_tx(struct ath12k *ar, stru
arvif->link_stats.tx_enqueued++;
atomic_inc(&ar->dp.num_tx_pending);
+ atomic_inc(&ab->ag->num_dp_tx_pending);
return 0;
@@ -682,6 +684,8 @@ fail_remove_tx_buf:
static inline void ath12k_dp_tx_decrement(struct ath12k *ar)
{
+ atomic_dec(&ar->ab->ag->num_dp_tx_pending);
+
if (atomic_read(&ar->flush_request)) {
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
wake_up(&ar->tx_empty_waitq);
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -9062,14 +9062,22 @@ static u8 ath12k_mac_get_tx_link(struct
return link;
}
-static bool ath12k_mac_tx_check_max_limit(struct ath12k *ar, struct sk_buff *skb)
+bool ath12k_mac_tx_check_max_limit(struct ath12k *ar, struct sk_buff *skb)
{
+ struct ath12k_base *ab = ar->ab;
+
+ /* Allow EAPOL */
+ if (skb->protocol == cpu_to_be16(ETH_P_PAE))
+ return false;
+
+ if (atomic_read(&ab->ag->num_dp_tx_pending) > ATH12K_DP_GROUP_TX_LIMIT) {
+ ab->soc_stats.tx_err.group_threshold_limit++;
+ return true;
+ }
+
if (atomic_read(&ar->dp.num_tx_pending) > ATH12K_DP_PDEV_TX_LIMIT) {
- /* Allow EAPOL */
- if (!(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
- ar->ab->soc_stats.tx_err.threshold_limit++;
- return true;
- }
+ ar->ab->soc_stats.tx_err.pdev_threshold_limit++;
+ return true;
}
return false;
--- a/drivers/net/wireless/ath/ath12k/mac.h
+++ b/drivers/net/wireless/ath/ath12k/mac.h
@@ -241,4 +241,5 @@ bool ath12k_mac_is_ml_arvif(struct ath12
u16 ath12k_calculate_subchannel_count(enum nl80211_chan_width width);
void ath12k_mac_background_dfs_event(struct ath12k *ar,
enum ath12k_background_dfs_events ev);
+bool ath12k_mac_tx_check_max_limit(struct ath12k *ar, struct sk_buff *skb);
#endif