Commit ea5d99d0 authored by Ryder Lee's avatar Ryder Lee Committed by Felix Fietkau
Browse files

wifi: mt76: mt7996: enable ack signal support



This reports signal strength of ACK packets from the peer as measured
at each interface.

Signed-off-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent d75e739b
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -180,6 +180,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP);
	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY);
	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);

	if (!mdev->dev->of_node ||
	    !of_property_read_bool(mdev->dev->of_node,
@@ -240,6 +241,12 @@ mt7996_mac_init_band(struct mt7996_dev *dev, u8 band)
	set = FIELD_PREP(MT_WF_RMAC_MIB_OBSS_BACKOFF, 0) |
	      FIELD_PREP(MT_WF_RMAC_MIB_ED_OFFSET, 4);
	mt76_rmw(dev, MT_WF_RMAC_MIB_AIRTIME0(band), mask, set);

	/* filter out non-resp frames and get instanstaeous signal reporting */
	mask = MT_WTBLOFF_RSCR_RCPI_MODE | MT_WTBLOFF_RSCR_RCPI_PARAM;
	set = FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_MODE, 0) |
	      FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_PARAM, 0x3);
	mt76_rmw(dev, MT_WTBLOFF_RSCR(band), mask, set);
}

static void mt7996_mac_init(struct mt7996_dev *dev)
+18 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@
#include "mac.h"
#include "mcu.h"

#define to_rssi(field, rxv)	((FIELD_GET(field, rxv) - 220) / 2)
#define to_rssi(field, rcpi)	((FIELD_GET(field, rcpi) - 220) / 2)

#define HE_BITS(f)		cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
#define HE_PREP(f, m, v)	le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\
@@ -124,6 +124,7 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
		bool clear = false;
		u32 addr, val;
		u16 idx;
		s8 rssi[4];
		u8 bw;

		spin_lock_bh(&dev->sta_poll_lock);
@@ -137,6 +138,8 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
		spin_unlock_bh(&dev->sta_poll_lock);

		idx = msta->wcid.idx;

		/* refresh peer's airtime reporting */
		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 20);

		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
@@ -213,6 +216,20 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
			else
				rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
		}

		/* get signal strength of resp frames (CTS/BA/ACK) */
		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 34);
		val = mt76_rr(dev, addr);

		rssi[0] = to_rssi(GENMASK(7, 0), val);
		rssi[1] = to_rssi(GENMASK(15, 8), val);
		rssi[2] = to_rssi(GENMASK(23, 16), val);
		rssi[3] = to_rssi(GENMASK(31, 14), val);

		msta->ack_signal =
			mt76_rx_signal(msta->vif->phy->mt76->antenna_mask, rssi);

		ewma_avg_signal_add(&msta->avg_ack_signal, -msta->ack_signal);
	}

	rcu_read_unlock();
+8 −0
Original line number Diff line number Diff line
@@ -595,6 +595,8 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
	msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
	msta->jiffies = jiffies;

	ewma_avg_signal_init(&msta->avg_ack_signal);

	mt7996_mac_wtbl_update(dev, idx,
			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);

@@ -917,6 +919,12 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
	}
	sinfo->txrate.flags = txrate->flags;
	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);

	sinfo->ack_signal = (s8)msta->ack_signal;
	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);

	sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal);
	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);
}

static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta)
+9 −8
Original line number Diff line number Diff line
@@ -13,13 +13,14 @@

static const struct __base mt7996_reg_base[] = {
	[WF_AGG_BASE]		= { { 0x820e2000, 0x820f2000, 0x830e2000 } },
	[WF_MIB_BASE]	= { { 0x820ed000, 0x820fd000, 0x830ed000 } },
	[WF_ARB_BASE]		= { { 0x820e3000, 0x820f3000, 0x830e3000 } },
	[WF_TMAC_BASE]		= { { 0x820e4000, 0x820f4000, 0x830e4000 } },
	[WF_RMAC_BASE]		= { { 0x820e5000, 0x820f5000, 0x830e5000 } },
	[WF_ARB_BASE]	= { { 0x820e3000, 0x820f3000, 0x830e3000 } },
	[WF_LPON_BASE]	= { { 0x820eb000, 0x820fb000, 0x830eb000 } },
	[WF_ETBF_BASE]	= { { 0x820ea000, 0x820fa000, 0x830ea000 } },
	[WF_DMA_BASE]		= { { 0x820e7000, 0x820f7000, 0x830e7000 } },
	[WF_WTBLOFF_BASE]	= { { 0x820e9000, 0x820f9000, 0x830e9000 } },
	[WF_ETBF_BASE]		= { { 0x820ea000, 0x820fa000, 0x830ea000 } },
	[WF_LPON_BASE]		= { { 0x820eb000, 0x820fb000, 0x830eb000 } },
	[WF_MIB_BASE]		= { { 0x820ed000, 0x820fd000, 0x830ed000 } },
};

static const struct __map mt7996_reg_map[] = {
+5 −0
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ struct mt7996_twt_flow {
	u8 sched:1;
};

DECLARE_EWMA(avg_signal, 10, 8)

struct mt7996_sta {
	struct mt76_wcid wcid; /* must be first */

@@ -94,6 +96,9 @@ struct mt7996_sta {
	struct list_head rc_list;
	u32 airtime_ac[8];

	int ack_signal;
	struct ewma_avg_signal avg_ack_signal;

	unsigned long changed;
	unsigned long jiffies;
	unsigned long ampdu_state;
Loading