Commit 6a0c3702 authored by John Crispin's avatar John Crispin Committed by Kalle Valo
Browse files

ath11k: add HE rate accounting to driver



Parse and store the out-of-band rates reported by the FW.

Signed-off-by: default avatarJohn Crispin <john@phrozen.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent be43ce64
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -243,6 +243,8 @@ struct ath11k_rx_peer_stats {
	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];
};

#define ATH11K_HE_MCS_NUM       12
+7 −0
Original line number Diff line number Diff line
@@ -379,6 +379,13 @@ static ssize_t ath11k_dbg_sta_dump_rx_stats(struct file *file,
		len += scnprintf(buf + len, size - len, "%llu ", rx_stats->nss_count[i]);
	len += scnprintf(buf + len, size - len, "\nRX Duration:%llu ",
			 rx_stats->rx_duration);
	len += scnprintf(buf + len, size - len,
			 "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n",
			 rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0],
			 rx_stats->ru_alloc_cnt[1], rx_stats->ru_alloc_cnt[2],
			 rx_stats->ru_alloc_cnt[3], rx_stats->ru_alloc_cnt[4],
			 rx_stats->ru_alloc_cnt[5]);

	len += scnprintf(buf + len, size - len, "\n");

	spin_unlock_bh(&ar->ab->base_lock);
+9 −0
Original line number Diff line number Diff line
@@ -1066,6 +1066,13 @@ struct htt_ppdu_stats_common {
	u16 bw_mhz;
} __packed;

enum htt_ppdu_stats_gi {
	HTT_PPDU_STATS_SGI_0_8_US,
	HTT_PPDU_STATS_SGI_0_4_US,
	HTT_PPDU_STATS_SGI_1_6_US,
	HTT_PPDU_STATS_SGI_3_2_US,
};

#define HTT_PPDU_STATS_USER_RATE_INFO0_USER_POS_M	GENMASK(3, 0)
#define HTT_PPDU_STATS_USER_RATE_INFO0_MU_GROUP_ID_M	GENMASK(11, 4)

@@ -1094,6 +1101,8 @@ struct htt_ppdu_stats_common {
		FIELD_GET(HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M, _val)
#define HTT_USR_RATE_GI(_val) \
		FIELD_GET(HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M, _val)
#define HTT_USR_RATE_DCM(_val) \
		FIELD_GET(HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M, _val)

#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LTF_SIZE_M		GENMASK(1, 0)
#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_STBC_M		BIT(2)
+45 −3
Original line number Diff line number Diff line
@@ -1028,6 +1028,25 @@ int ath11k_dp_htt_tlv_iter(struct ath11k_base *ab, const void *ptr, size_t len,
	return 0;
}

static inline u32 ath11k_he_gi_to_nl80211_he_gi(u8 sgi)
{
	u32 ret = 0;

	switch (sgi) {
	case RX_MSDU_START_SGI_0_8_US:
		ret = NL80211_RATE_INFO_HE_GI_0_8;
		break;
	case RX_MSDU_START_SGI_1_6_US:
		ret = NL80211_RATE_INFO_HE_GI_1_6;
		break;
	case RX_MSDU_START_SGI_3_2_US:
		ret = NL80211_RATE_INFO_HE_GI_3_2;
		break;
	}

	return ret;
}

static void
ath11k_update_per_peer_tx_stats(struct ath11k *ar,
				struct htt_ppdu_stats *ppdu_stats, u8 user)
@@ -1041,7 +1060,7 @@ ath11k_update_per_peer_tx_stats(struct ath11k *ar,
	struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user];
	struct htt_ppdu_stats_common *common = &ppdu_stats->common;
	int ret;
	u8 flags, mcs, nss, bw, sgi, rate_idx = 0;
	u8 flags, mcs, nss, bw, sgi, dcm, rate_idx = 0;
	u32 succ_bytes = 0;
	u16 rate = 0, succ_pkts = 0;
	u32 tx_duration = 0;
@@ -1076,18 +1095,29 @@ ath11k_update_per_peer_tx_stats(struct ath11k *ar,
	nss = HTT_USR_RATE_NSS(user_rate->rate_flags) + 1;
	mcs = HTT_USR_RATE_MCS(user_rate->rate_flags);
	sgi = HTT_USR_RATE_GI(user_rate->rate_flags);
	dcm = HTT_USR_RATE_DCM(user_rate->rate_flags);

	/* Note: If host configured fixed rates and in some other special
	 * cases, the broadcast/management frames are sent in different rates.
	 * Firmware rate's control to be skipped for this?
	 */

	if (flags == WMI_RATE_PREAMBLE_VHT && mcs > 9) {
	if (flags == WMI_RATE_PREAMBLE_HE && mcs > 11) {
		ath11k_warn(ab, "Invalid HE mcs %hhd peer stats",  mcs);
		return;
	}

	if (flags == WMI_RATE_PREAMBLE_HE && mcs > ATH11K_HE_MCS_MAX) {
		ath11k_warn(ab, "Invalid HE mcs %hhd peer stats",  mcs);
		return;
	}

	if (flags == WMI_RATE_PREAMBLE_VHT && mcs > ATH11K_VHT_MCS_MAX) {
		ath11k_warn(ab, "Invalid VHT mcs %hhd peer stats",  mcs);
		return;
	}

	if (flags == WMI_RATE_PREAMBLE_HT && (mcs > 7 || nss < 1)) {
	if (flags == WMI_RATE_PREAMBLE_HT && (mcs > ATH11K_HT_MCS_MAX || nss < 1)) {
		ath11k_warn(ab, "Invalid HT mcs %hhd nss %hhd peer stats",
			    mcs, nss);
		return;
@@ -1136,6 +1166,15 @@ ath11k_update_per_peer_tx_stats(struct ath11k *ar,
		if (sgi)
			arsta->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 = ath11k_he_gi_to_nl80211_he_gi(sgi);
		arsta->txrate.he_ru_alloc = ath11k_he_ru_tones_to_nl80211_he_ru_alloc(
						(user_rate->ru_end -
						 user_rate->ru_start) + 1);
		break;
	}

	arsta->txrate.nss = nss;
@@ -1941,6 +1980,7 @@ static void ath11k_dp_rx_h_rate(struct ath11k *ar, struct hal_rx_desc *rx_desc,
		}
		rx_status->encoding = RX_ENC_HE;
		rx_status->nss = nss;
		rx_status->he_gi = ath11k_he_gi_to_nl80211_he_gi(sgi);
		rx_status->bw = ath11k_mac_bw_to_mac80211_bw(bw);
		break;
	}
@@ -2364,6 +2404,8 @@ static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta,

	rx_stats->num_mpdu_fcs_ok += ppdu_info->num_mpdu_fcs_ok;
	rx_stats->num_mpdu_fcs_err += ppdu_info->num_mpdu_fcs_err;
	rx_stats->dcm_count += ppdu_info->dcm;
	rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu;

	arsta->rssi_comb = ppdu_info->rssi_comb;
	rx_stats->rx_duration += ppdu_info->rx_duration;
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include "dp_tx.h"
#include "debug.h"
#include "hw.h"
#include "peer.h"

/* NOTE: Any of the mapped ring id value must not exceed DP_TCL_NUM_RING_MAX */
static const u8
Loading