wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/708-wifi-ath12k-add-proper-link-stats-support.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

287 lines
9.3 KiB
Diff

From 5fb36a3a19a56956c397b2123c4f5747f20c48c1 Mon Sep 17 00:00:00 2001
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Date: Mon, 16 Jan 2023 04:13:41 +0530
Subject: [PATCH] wifi: ath12k: add proper link stats support
Get proper link id if the peer is ML. Fetch the arsta from the proper link
id and update the statistics in the corresponding arsta instead of always
default link.
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
---
drivers/net/wireless/ath/ath12k/core.h | 2 ++
drivers/net/wireless/ath/ath12k/debugfs.c | 3 +++
drivers/net/wireless/ath/ath12k/dp_mon.c | 17 ++++++++++++++---
drivers/net/wireless/ath/ath12k/dp_rx.c | 12 ++++++++++--
drivers/net/wireless/ath/ath12k/dp_tx.c | 11 +++++++++--
drivers/net/wireless/ath/ath12k/peer.c | 2 --
6 files changed, 38 insertions(+), 9 deletions(-)
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -3484,7 +3484,6 @@ ath12k_dp_mon_rx_update_user_stats(struc
struct hal_rx_mon_ppdu_info *ppdu_info,
u32 uid)
{
- struct ath12k_sta *ahsta = NULL;
struct ath12k_link_sta *arsta;
struct ath12k_rx_peer_stats *rx_stats = NULL;
struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid];
@@ -3502,10 +3501,14 @@ ath12k_dp_mon_rx_update_user_stats(struc
return;
}
- ahsta = (struct ath12k_sta *)peer->sta->drv_priv;
- arsta = &ahsta->deflink;
- rx_stats = arsta->rx_stats;
+ arsta = ath12k_peer_get_link_sta(ar->ab, peer);
+ if (!arsta) {
+ ath12k_warn(ar->ab, "link sta not found on peer %pM id %d\n",
+ peer->addr, peer->peer_id);
+ return;
+ }
+ rx_stats = arsta->rx_stats;
if (!rx_stats)
return;
@@ -3632,7 +3635,7 @@ int ath12k_dp_mon_srng_process(struct at
struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
struct sk_buff_head skb_list;
struct ath12k_peer *peer = NULL;
- struct ath12k_sta *ahsta = NULL;
+ struct ath12k_link_sta *arsta;
u64 cookie;
u32 hal_status, end_reason, ppdu_id, end_offset;
int num_buffs_reaped = 0, srng_id, buf_id;
@@ -3754,8 +3757,14 @@ move_next:
}
if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) {
- ahsta = (struct ath12k_sta *)peer->sta->drv_priv;
- ath12k_dp_mon_rx_update_peer_su_stats(ar, &ahsta->deflink,
+ arsta = ath12k_peer_get_link_sta(ar->ab, peer);
+ if (!arsta) {
+ ath12k_warn(ar->ab, "link sta not found on peer %pM id %d\n",
+ peer->addr, peer->peer_id);
+ goto next_skb;
+ }
+
+ ath12k_dp_mon_rx_update_peer_su_stats(ar, arsta,
ppdu_info);
} else if ((ppdu_info->fc_valid) &&
(ppdu_info->ast_index != HAL_AST_IDX_INVALID)) {
@@ -3789,7 +3798,7 @@ int ath12k_dp_mon_rx_process_stats(struc
struct dp_srng *mon_dst_ring;
struct hal_srng *srng;
struct dp_rxdma_ring *buf_ring;
- struct ath12k_sta *ahsta = NULL;
+ struct ath12k_link_sta *arsta = NULL;
struct ath12k_peer *peer;
struct sk_buff_head skb_list;
u64 cookie;
@@ -3911,9 +3920,14 @@ move_next:
}
if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) {
- ahsta = (struct ath12k_sta *)peer->sta->drv_priv;
- /* TODO Extend for Link STA */
- ath12k_dp_mon_rx_update_peer_su_stats(ar, &ahsta->deflink,
+ arsta = ath12k_peer_get_link_sta(ar->ab, peer);
+ if (!arsta) {
+ ath12k_warn(ab, "link sta not found on peer %pM id %d\n",
+ peer->addr, peer->peer_id);
+ goto next_skb;
+ }
+
+ ath12k_dp_mon_rx_update_peer_su_stats(ar, arsta,
ppdu_info);
} else if ((ppdu_info->fc_valid) &&
(ppdu_info->ast_index != HAL_AST_IDX_INVALID)) {
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -1480,7 +1480,6 @@ ath12k_update_per_peer_tx_stats(struct a
struct ath12k_base *ab = ar->ab;
struct ath12k_peer *peer;
struct ieee80211_sta *sta;
- struct ath12k_sta *ahsta;
struct ath12k_link_sta *arsta;
struct htt_ppdu_stats_user_rate *user_rate;
struct htt_ppdu_stats *ppdu_stats = &ppdu_info->ppdu_stats;
@@ -1608,8 +1607,12 @@ ath12k_update_per_peer_tx_stats(struct a
}
sta = peer->sta;
- ahsta = (struct ath12k_sta *)sta->drv_priv;
- arsta = &ahsta->deflink;
+ arsta = ath12k_peer_get_link_sta(ab, peer);
+ if (!arsta) {
+ spin_unlock_bh(&ab->base_lock);
+ rcu_read_unlock();
+ return;
+ }
memset(&arsta->txrate, 0, sizeof(arsta->txrate));
@@ -2925,7 +2928,6 @@ static void ath12k_dp_rx_deliver_msdu(st
bool is_mcbc = rxcb->is_mcbc;
bool is_eapol = rxcb->is_eapol;
struct ath12k_link_sta *arsta = NULL;
- struct ath12k_sta *ahsta = NULL;
if (status->encoding == RX_ENC_HE && !(status->flag & RX_FLAG_RADIOTAP_HE) &&
!(status->flag & RX_FLAG_SKIP_MONITOR)) {
@@ -3002,10 +3004,8 @@ exit:
if (ath12k_debugfs_is_extd_rx_stats_enabled(ar)) {
if (!(status->flag & RX_FLAG_ONLY_MONITOR)) {
spin_lock_bh(&ar->ab->base_lock);
- if (peer && peer->sta) {
- ahsta = (struct ath12k_sta *)peer->sta->drv_priv;
- arsta = &ahsta->deflink;
- }
+ if (peer && peer->sta)
+ arsta = ath12k_peer_get_link_sta(ar->ab, peer);
spin_unlock_bh(&ar->ab->base_lock);
if (arsta)
atomic_inc(&arsta->drv_rx_pkts.pkts_out);
@@ -3208,7 +3208,6 @@ int ath12k_dp_rx_process(struct ath12k_b
bool done = false;
u32 *rx_desc;
u64 desc_va;
- struct ath12k_sta *ahsta = NULL;
struct ath12k_link_sta *arsta = NULL;
struct ath12k_peer *peer = NULL;
struct ath12k *ar;
@@ -3311,10 +3310,8 @@ try_again:
rcu_read_lock();
spin_lock_bh(&src_ab->base_lock);
peer = ath12k_peer_find_by_id(src_ab, rxcb->peer_id);
- if (peer && peer->sta) {
- ahsta = (struct ath12k_sta *)peer->sta->drv_priv;
- arsta = &ahsta->deflink;
- }
+ if (peer && peer->sta)
+ arsta = ath12k_peer_get_link_sta(src_ab, peer);
spin_unlock_bh(&src_ab->base_lock);
if (arsta)
atomic_inc(&arsta->drv_rx_pkts.pkts_frm_hw);
@@ -4186,7 +4183,6 @@ static int ath12k_dp_rx_h_null_q_desc(st
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
u32 hal_rx_desc_sz = ar->ab->hw_params->hal_desc_sz;
bool fast_rx;
- struct ath12k_sta *ahsta = NULL;
struct ath12k_link_sta *arsta = NULL;
struct ath12k_peer *peer = NULL;
@@ -4252,10 +4248,8 @@ static int ath12k_dp_rx_h_null_q_desc(st
spin_lock_bh(&ar->ab->base_lock);
if (peer_id)
peer = ath12k_peer_find_by_id(ar->ab, rxcb->peer_id);
- if (peer && peer->sta) {
- ahsta = (struct ath12k_sta *)peer->sta->drv_priv;
- arsta = &ahsta->deflink;
- }
+ if (peer && peer->sta)
+ arsta = ath12k_peer_get_link_sta(ar->ab, peer);
spin_unlock_bh(&ar->ab->base_lock);
if (arsta)
atomic_inc(&arsta->drv_rx_pkts.pkts_frm_hw);
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -526,9 +526,7 @@ void ath12k_dp_tx_update_txcompl(struct
enum hal_tx_rate_stats_sgi sgi;
enum hal_tx_rate_stats_bw bw;
struct ath12k_peer *peer;
- struct ath12k_sta *ahsta;
struct ath12k_link_sta *arsta;
- struct ieee80211_sta *sta;
u16 rate, ru_tones;
u8 mcs, rate_idx, ofdma;
int ret;
@@ -541,10 +539,12 @@ void ath12k_dp_tx_update_txcompl(struct
goto err_out;
}
- /* TODO move to per link stats */
- sta = peer->sta;
- ahsta = (struct ath12k_sta *)sta->drv_priv;
- arsta = &ahsta->deflink;
+ arsta = ath12k_peer_get_link_sta(ab, peer);
+ if (!arsta) {
+ ath12k_warn(ab, "link sta not found on peer %pM id %d\n",
+ peer->addr, peer->peer_id);
+ goto err_out;
+ }
memset(&arsta->txrate, 0, sizeof(arsta->txrate));
pkt_type = FIELD_GET(HAL_TX_RATE_STATS_INFO0_PKT_TYPE,
@@ -670,7 +670,6 @@ static void ath12k_dp_tx_complete_msdu(s
struct ieee80211_tx_info *info;
struct ath12k_skb_cb *skb_cb;
struct ath12k_peer *peer;
- struct ath12k_sta *ahsta;
struct ath12k_link_sta *arsta;
struct rate_info rate;
struct hal_tx_status ts = { 0 };
@@ -786,8 +785,16 @@ static void ath12k_dp_tx_complete_msdu(s
return;
}
- ahsta = (struct ath12k_sta *)peer->sta->drv_priv;
- arsta = &ahsta->deflink;
+ arsta = ath12k_peer_get_link_sta(ab, peer);
+ if (!arsta) {
+ ath12k_warn(ab, "link sta not found on peer %pM id %d\n",
+ peer->addr, peer->peer_id);
+
+ spin_unlock_bh(&ab->base_lock);
+ dev_kfree_skb_any(msdu);
+ return;
+ }
+
status.sta = peer->sta;
status.skb = msdu;
status.info = info;
--- a/drivers/net/wireless/ath/ath12k/peer.c
+++ b/drivers/net/wireless/ath/ath12k/peer.c
@@ -511,10 +511,8 @@ int ath12k_peer_create(struct ath12k *ar
peer->primary_link = true;
peer->mlo = false;
}
-
}
-
ar->num_peers++;
spin_unlock_bh(&ar->ab->base_lock);
--- a/drivers/net/wireless/ath/ath12k/peer.h
+++ b/drivers/net/wireless/ath/ath12k/peer.h
@@ -100,4 +100,26 @@ struct ath12k_peer *ath12k_peer_find_by_
void ath12k_peer_mlo_map_event(struct ath12k_base *ab, struct sk_buff *skb);
void ath12k_peer_mlo_unmap_event(struct ath12k_base *ab, struct sk_buff *skb);
+static inline
+struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab,
+ struct ath12k_peer *peer)
+{
+ struct ath12k_sta *ahsta;
+
+ if (!peer->sta)
+ return NULL;
+
+ ahsta = (struct ath12k_sta *)peer->sta->drv_priv;
+ if (peer->ml_peer_id & ATH12K_ML_PEER_ID_VALID) {
+ if (!(ahsta->links_map & BIT(peer->link_id))) {
+ ath12k_warn(ab, "peer %pM id %d link_id %d can't found in STA link_map 0x%x\n",
+ peer->addr, peer->peer_id, peer->link_id, ahsta->links_map);
+ return NULL;
+ }
+
+ return ahsta->link[peer->link_id];
+ } else {
+ return &ahsta->deflink;
+ }
+}
#endif /* _PEER_H_ */