wifi: ath12k: add link support for multi-link in arsta

Currently, statistics in arsta are updated at deflink for both non-ML
and multi-link(ML) station. Link statistics are not updated for
multi-link operation(MLO).

Hence, add support to correctly obtain the link ID if the peer is ML,
fetch the arsta from the appropriate link ID, and update the
statistics in the corresponding arsta.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1

Signed-off-by: Sarika Sharma <quic_sarishar@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250701105927.803342-3-quic_sarishar@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
Sarika Sharma
2025-07-01 16:29:24 +05:30
committed by Jeff Johnson
parent ebebe66ec2
commit 3b8aa249d0
3 changed files with 48 additions and 11 deletions

View File

@@ -3615,7 +3615,6 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar,
struct hal_rx_mon_ppdu_info *ppdu_info,
u32 uid)
{
struct ath12k_sta *ahsta;
struct ath12k_link_sta *arsta;
struct ath12k_rx_peer_stats *rx_stats = NULL;
struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid];
@@ -3633,8 +3632,13 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar,
return;
}
ahsta = ath12k_sta_to_ahsta(peer->sta);
arsta = &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);
return;
}
arsta->rssi_comb = ppdu_info->rssi_comb;
ewma_avg_rssi_add(&arsta->avg_rssi, ppdu_info->rssi_comb);
rx_stats = arsta->rx_stats;
@@ -3747,7 +3751,6 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget,
struct dp_srng *mon_dst_ring;
struct hal_srng *srng;
struct dp_rxdma_mon_ring *buf_ring;
struct ath12k_sta *ahsta = NULL;
struct ath12k_link_sta *arsta;
struct ath12k_peer *peer;
struct sk_buff_head skb_list;
@@ -3873,8 +3876,15 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget,
}
if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) {
ahsta = ath12k_sta_to_ahsta(peer->sta);
arsta = &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);
spin_unlock_bh(&ab->base_lock);
rcu_read_unlock();
dev_kfree_skb_any(skb);
continue;
}
ath12k_dp_mon_rx_update_peer_su_stats(ar, arsta,
ppdu_info);
} else if ((ppdu_info->fc_valid) &&

View File

@@ -1417,8 +1417,6 @@ ath12k_update_per_peer_tx_stats(struct ath12k *ar,
{
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 ath12k_per_peer_tx_stats *peer_stats = &ar->peer_tx_stats;
@@ -1499,9 +1497,12 @@ ath12k_update_per_peer_tx_stats(struct ath12k *ar,
return;
}
sta = peer->sta;
ahsta = ath12k_sta_to_ahsta(sta);
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));

View File

@@ -91,5 +91,31 @@ struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, int ast_hash
int ath12k_peer_ml_create(struct ath12k_hw *ah, struct ieee80211_sta *sta);
int ath12k_peer_ml_delete(struct ath12k_hw *ah, struct ieee80211_sta *sta);
int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_sta *ahsta);
static inline
struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab,
struct ath12k_peer *peer)
{
struct ath12k_sta *ahsta;
struct ath12k_link_sta *arsta;
if (!peer->sta)
return NULL;
ahsta = ath12k_sta_to_ahsta(peer->sta);
if (peer->ml_id & ATH12K_PEER_ML_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;
}
arsta = rcu_dereference(ahsta->link[peer->link_id]);
if (!arsta)
return NULL;
} else {
arsta = &ahsta->deflink;
}
return arsta;
}
#endif /* _PEER_H_ */