Commit 35fcf4fa authored by Harsh Kumar Bijlani's avatar Harsh Kumar Bijlani Committed by Jeff Johnson
Browse files

wifi: ath12k: Move DP specific link stats to DP link peer



As part of peer modularization in the Driver Framework, the station view is as
follows:

            Common Path                      Data Path
    -------------------------------------------------------------------
    ath12k_sta                           ath12k_dp_peer
        |                                       |
        |-> ath12k_link_sta    <---->           |-> ath12k_dp_link_peer
        |                                       |
        |-> ath12k_link_sta    <---->           |-> ath12k_dp_link_peer
        |                                       |
        |-> ath12k_link_sta    <---->           |-> ath12k_dp_link_peer

Currently ath12k_link_sta has data path stats updated in tx_htt and rx monitor
path. Move those stats from ath12_link_sta to ath12k_dp_link_peer to align with
peer modularization model as shown above.

This allows datapath to use only ath12k_dp_link_peer without having to reach out
to other objects for updating stats, thereby improving the cache locality.

Add following API to fetch rate info from DP link peer:

	ath12k_dp_link_peer_get_sta_rate_info_stats()

This wrapper API populates link stats in 'struct ath12k_dp_link_peer_rate_info',
which can be extended to support out-of-band retrieval of various rate stats.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Signed-off-by: default avatarHarsh Kumar Bijlani <quic_hbijlani@quicinc.com>
Signed-off-by: default avatarRipan Deuri <quic_rdeuri@quicinc.com>
Reviewed-by: default avatarKarthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com>
Reviewed-by: default avatarBaochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20251103112111.2260639-4-quic_rdeuri@quicinc.com


Signed-off-by: default avatarJeff Johnson <jeff.johnson@oss.qualcomm.com>
parent 775fe5ac
Loading
Loading
Loading
Loading
+0 −59
Original line number Diff line number Diff line
@@ -395,51 +395,8 @@ struct ath12k_vif_iter {
	struct ath12k_link_vif *arvif;
};

#define HAL_AST_IDX_INVALID	0xFFFF
#define HAL_RX_MAX_MCS		12
#define HAL_RX_MAX_MCS_HT	31
#define HAL_RX_MAX_MCS_VHT	9
#define HAL_RX_MAX_MCS_HE	11
#define HAL_RX_MAX_MCS_BE	15
#define HAL_RX_MAX_NSS		8
#define HAL_RX_MAX_NUM_LEGACY_RATES 12

#define ATH12K_SCAN_TIMEOUT_HZ (20 * HZ)

struct ath12k_rx_peer_rate_stats {
	u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1];
	u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1];
	u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1];
	u64 be_mcs_count[HAL_RX_MAX_MCS_BE + 1];
	u64 nss_count[HAL_RX_MAX_NSS];
	u64 bw_count[HAL_RX_BW_MAX];
	u64 gi_count[HAL_RX_GI_MAX];
	u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES];
	u64 rx_rate[HAL_RX_BW_MAX][HAL_RX_GI_MAX][HAL_RX_MAX_NSS][HAL_RX_MAX_MCS_HT + 1];
};

struct ath12k_rx_peer_stats {
	u64 num_msdu;
	u64 num_mpdu_fcs_ok;
	u64 num_mpdu_fcs_err;
	u64 tcp_msdu_count;
	u64 udp_msdu_count;
	u64 other_msdu_count;
	u64 ampdu_msdu_count;
	u64 non_ampdu_msdu_count;
	u64 stbc_count;
	u64 beamformed_count;
	u64 coding_count[HAL_RX_SU_MU_CODING_MAX];
	u64 tid_count[IEEE80211_NUM_TIDS + 1];
	u64 pream_cnt[HAL_RX_PREAMBLE_MAX];
	u64 reception_type[HAL_RX_RECEPTION_TYPE_MAX];
	u64 rx_duration;
	u64 dcm_count;
	u64 ru_alloc_cnt[HAL_RX_RU_ALLOC_TYPE_MAX];
	struct ath12k_rx_peer_rate_stats pkt_stats;
	struct ath12k_rx_peer_rate_stats byte_stats;
};

#define ATH12K_HE_MCS_NUM       12
#define ATH12K_VHT_MCS_NUM      10
#define ATH12K_BW_NUM           5
@@ -521,12 +478,6 @@ struct ath12k_per_ppdu_tx_stats {
	u32 retry_bytes;
};

struct ath12k_wbm_tx_stats {
	u64 wbm_tx_comp_stats[HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX];
};

DECLARE_EWMA(avg_rssi, 10, 8)

struct ath12k_link_sta {
	struct ath12k_link_vif *arvif;
	struct ath12k_sta *ahsta;
@@ -541,15 +492,7 @@ struct ath12k_link_sta {
	u32 smps;

	struct wiphy_work update_wk;
	struct rate_info txrate;
	struct rate_info last_txrate;
	u64 rx_duration;
	u64 tx_duration;
	u8 rssi_comb;
	struct ewma_avg_rssi avg_rssi;
	u8 link_id;
	struct ath12k_rx_peer_stats *rx_stats;
	struct ath12k_wbm_tx_stats *wbm_tx_stats;
	u32 bw_prev;
	u32 peer_nss;
	s8 rssi_beacon;
@@ -559,8 +502,6 @@ struct ath12k_link_sta {

	 /* for firmware use only */
	u8 link_idx;
	u32 tx_retry_failed;
	u32 tx_retry_count;

	/* peer addr based rhashtable list pointer */
	struct rhash_head rhash_addr;
+17 −18
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include "debug.h"
#include "debugfs_htt_stats.h"
#include "debugfs.h"
#include "dp_cmn.h"

static
u32 ath12k_dbg_sta_dump_rate_stats(u8 *buf, u32 offset, const int size,
@@ -144,9 +145,11 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file,
	const int size = ATH12K_STA_RX_STATS_BUF_SIZE;
	struct ath12k_hw *ah = ahsta->ahvif->ah;
	struct ath12k_rx_peer_stats *rx_stats;
	struct ath12k_dp_link_peer *link_peer;
	struct ath12k_link_sta *arsta;
	u8 link_id = link_sta->link_id;
	int len = 0, i, ret = 0;
	struct ath12k_dp *dp;
	bool he_rates_avail;
	struct ath12k *ar;

@@ -171,9 +174,16 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file,
		goto out;
	}

	spin_lock_bh(&ar->ab->base_lock);
	dp = ath12k_ab_to_dp(ar->ab);
	spin_lock_bh(&dp->dp_lock);

	rx_stats = arsta->rx_stats;
	link_peer = ath12k_dp_link_peer_find_by_addr(dp, arsta->addr);
	if (!link_peer) {
		ret = -ENOENT;
		goto unlock;
	}

	rx_stats = link_peer->peer_stats.rx_stats;
	if (!rx_stats) {
		ret = -ENOENT;
		goto unlock;
@@ -238,7 +248,7 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file,
					      &rx_stats->byte_stats);

unlock:
	spin_unlock_bh(&ar->ab->base_lock);
	spin_unlock_bh(&dp->dp_lock);

	if (len)
		ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
@@ -261,10 +271,9 @@ static ssize_t ath12k_dbg_sta_reset_rx_stats(struct file *file,
	struct ieee80211_link_sta *link_sta = file->private_data;
	struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(link_sta->sta);
	struct ath12k_hw *ah = ahsta->ahvif->ah;
	struct ath12k_rx_peer_stats *rx_stats;
	struct ath12k_link_sta *arsta;
	u8 link_id = link_sta->link_id;
	struct ath12k *ar;
	struct ath12k_link_sta *arsta;
	struct ath12k_dp *dp;
	bool reset;
	int ret;

@@ -288,19 +297,9 @@ static ssize_t ath12k_dbg_sta_reset_rx_stats(struct file *file,
		goto out;
	}

	ar = arsta->arvif->ar;

	spin_lock_bh(&ar->ab->base_lock);

	rx_stats = arsta->rx_stats;
	if (!rx_stats) {
		spin_unlock_bh(&ar->ab->base_lock);
		ret = -ENOENT;
		goto out;
	}
	dp = ath12k_ab_to_dp(arsta->arvif->ar->ab);

	memset(rx_stats, 0, sizeof(*rx_stats));
	spin_unlock_bh(&ar->ab->base_lock);
	ath12k_dp_link_peer_reset_rx_stats(dp, arsta->addr);

	ret = count;
out:
+12 −0
Original line number Diff line number Diff line
@@ -74,6 +74,14 @@ struct ath12k_dp_peer_create_params {
	bool ucast_ra_only;
};

struct ath12k_dp_link_peer_rate_info {
	struct rate_info txrate;
	u64 rx_duration;
	u64 tx_duration;
	u8 rssi_comb;
	s8 signal_avg;
};

static inline struct ath12k_dp_link_vif *
ath12k_dp_vif_to_dp_link_vif(struct ath12k_dp_vif *dp_vif, u8 link_id)
{
@@ -91,4 +99,8 @@ int ath12k_dp_link_peer_assign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw,
			       u8 link_id, u32 hw_link_id);
void ath12k_dp_link_peer_unassign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw,
				  u8 vdev_id, u8 *addr, u32 hw_link_id);
void
ath12k_dp_link_peer_get_sta_rate_info_stats(struct ath12k_dp *dp, const u8 *addr,
					    struct ath12k_dp_link_peer_rate_info *info);
void ath12k_dp_link_peer_reset_rx_stats(struct ath12k_dp *dp, const u8 *addr);
#endif
+30 −33
Original line number Diff line number Diff line
@@ -189,7 +189,6 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev,
	struct ath12k_dp *dp = dp_pdev->dp;
	struct ath12k_base *ab = dp->ab;
	struct ath12k_dp_link_peer *peer;
	struct ath12k_link_sta *arsta;
	struct htt_ppdu_stats_user_rate *user_rate;
	struct ath12k_per_peer_tx_stats *peer_stats = &dp_pdev->peer_tx_stats;
	struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user];
@@ -279,66 +278,64 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev,
		return;
	}

	arsta = ath12k_dp_link_peer_to_link_sta(ab, peer);
	if (!arsta) {
		rcu_read_unlock();
		return;
	}
	spin_lock_bh(&dp->dp_lock);

	memset(&arsta->txrate, 0, sizeof(arsta->txrate));
	memset(&peer->txrate, 0, sizeof(peer->txrate));

	arsta->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw);
	peer->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw);

	switch (flags) {
	case WMI_RATE_PREAMBLE_OFDM:
		arsta->txrate.legacy = rate;
		peer->txrate.legacy = rate;
		break;
	case WMI_RATE_PREAMBLE_CCK:
		arsta->txrate.legacy = rate;
		peer->txrate.legacy = rate;
		break;
	case WMI_RATE_PREAMBLE_HT:
		arsta->txrate.mcs = mcs + 8 * (nss - 1);
		arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
		peer->txrate.mcs = mcs + 8 * (nss - 1);
		peer->txrate.flags = RATE_INFO_FLAGS_MCS;
		if (sgi)
			arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
			peer->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
		break;
	case WMI_RATE_PREAMBLE_VHT:
		arsta->txrate.mcs = mcs;
		arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
		peer->txrate.mcs = mcs;
		peer->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
		if (sgi)
			arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
			peer->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
		break;
	case WMI_RATE_PREAMBLE_HE:
		arsta->txrate.mcs = mcs;
		arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS;
		arsta->txrate.he_dcm = dcm;
		arsta->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
		peer->txrate.mcs = mcs;
		peer->txrate.flags = RATE_INFO_FLAGS_HE_MCS;
		peer->txrate.he_dcm = dcm;
		peer->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
		tones = le16_to_cpu(user_rate->ru_end) -
			le16_to_cpu(user_rate->ru_start) + 1;
		v = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(tones);
		arsta->txrate.he_ru_alloc = v;
		peer->txrate.he_ru_alloc = v;
		if (is_ofdma)
			arsta->txrate.bw = RATE_INFO_BW_HE_RU;
			peer->txrate.bw = RATE_INFO_BW_HE_RU;
		break;
	case WMI_RATE_PREAMBLE_EHT:
		arsta->txrate.mcs = mcs;
		arsta->txrate.flags = RATE_INFO_FLAGS_EHT_MCS;
		arsta->txrate.he_dcm = dcm;
		arsta->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi);
		peer->txrate.mcs = mcs;
		peer->txrate.flags = RATE_INFO_FLAGS_EHT_MCS;
		peer->txrate.he_dcm = dcm;
		peer->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi);
		tones = le16_to_cpu(user_rate->ru_end) -
			le16_to_cpu(user_rate->ru_start) + 1;
		v = ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(tones);
		arsta->txrate.eht_ru_alloc = v;
		peer->txrate.eht_ru_alloc = v;
		if (is_ofdma)
			arsta->txrate.bw = RATE_INFO_BW_EHT_RU;
			peer->txrate.bw = RATE_INFO_BW_EHT_RU;
		break;
	}

	arsta->tx_retry_failed += tx_retry_failed;
	arsta->tx_retry_count += tx_retry_count;
	arsta->txrate.nss = nss;
	arsta->tx_duration += tx_duration;
	memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info));
	peer->tx_retry_failed += tx_retry_failed;
	peer->tx_retry_count += tx_retry_count;
	peer->txrate.nss = nss;
	peer->tx_duration += tx_duration;
	memcpy(&peer->last_txrate, &peer->txrate, sizeof(struct rate_info));

	spin_unlock_bh(&dp->dp_lock);

	/* PPDU stats reported for mgmt packet doesn't have valid tx bytes.
	 * So skip peer stats update for mgmt packets.
+13 −28
Original line number Diff line number Diff line
@@ -3456,6 +3456,9 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st
	u32 gi_idx = ppdu_info->gi;
	u32 len;

	if (!rx_stats)
		return;

	if (mcs_idx > HAL_RX_MAX_MCS_HT || nss_idx >= HAL_RX_MAX_NSS ||
	    bw_idx >= HAL_RX_BW_MAX || gi_idx >= HAL_RX_GI_MAX) {
		return;
@@ -3476,14 +3479,14 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st
	stats->rx_rate[bw_idx][gi_idx][nss_idx][mcs_idx] += len;
}

static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_link_sta *arsta,
static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer,
						  struct hal_rx_mon_ppdu_info *ppdu_info)
{
	struct ath12k_rx_peer_stats *rx_stats = arsta->rx_stats;
	struct ath12k_rx_peer_stats *rx_stats = peer->peer_stats.rx_stats;
	u32 num_msdu;

	arsta->rssi_comb = ppdu_info->rssi_comb;
	ewma_avg_rssi_add(&arsta->avg_rssi, ppdu_info->rssi_comb);
	peer->rssi_comb = ppdu_info->rssi_comb;
	ewma_avg_rssi_add(&peer->avg_rssi, ppdu_info->rssi_comb);
	if (!rx_stats)
		return;

@@ -3531,7 +3534,7 @@ static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_link_sta *arsta,
	rx_stats->dcm_count += ppdu_info->dcm;

	rx_stats->rx_duration += ppdu_info->rx_duration;
	arsta->rx_duration = rx_stats->rx_duration;
	peer->rx_duration = rx_stats->rx_duration;

	if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) {
		rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu;
@@ -3638,7 +3641,6 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab,
				   struct hal_rx_mon_ppdu_info *ppdu_info,
				   u32 uid)
{
	struct ath12k_link_sta *arsta;
	struct ath12k_rx_peer_stats *rx_stats = NULL;
	struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid];
	struct ath12k_dp_link_peer *peer;
@@ -3656,16 +3658,9 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab,
		return;
	}

	arsta = ath12k_dp_link_peer_to_link_sta(ab, peer);
	if (!arsta) {
		ath12k_warn(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;
	peer->rssi_comb = ppdu_info->rssi_comb;
	ewma_avg_rssi_add(&peer->avg_rssi, ppdu_info->rssi_comb);
	rx_stats = peer->peer_stats.rx_stats;
	if (!rx_stats)
		return;

@@ -3709,7 +3704,7 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab,
		rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu;

	rx_stats->rx_duration += ppdu_info->rx_duration;
	arsta->rx_duration = rx_stats->rx_duration;
	peer->rx_duration = rx_stats->rx_duration;

	if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) {
		rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu;
@@ -3774,7 +3769,6 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget,
	struct dp_srng *mon_dst_ring;
	struct hal_srng *srng;
	struct dp_rxdma_mon_ring *buf_ring;
	struct ath12k_link_sta *arsta;
	struct ath12k_dp_link_peer *peer;
	struct sk_buff_head skb_list;
	u64 cookie;
@@ -3898,16 +3892,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget,
		}

		if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) {
			arsta = ath12k_dp_link_peer_to_link_sta(ab, peer);
			if (!arsta) {
				ath12k_warn(ab, "link sta not found on peer %pM id %d\n",
					    peer->addr, peer->peer_id);
				rcu_read_unlock();
				dev_kfree_skb_any(skb);
				continue;
			}
			ath12k_dp_mon_rx_update_peer_su_stats(arsta,
							      ppdu_info);
			ath12k_dp_mon_rx_update_peer_su_stats(peer, ppdu_info);
		} else if ((ppdu_info->fc_valid) &&
			   (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) {
			ath12k_dp_mon_rx_process_ulofdma(ppdu_info);
Loading