Commit a71b648e authored by Ryder Lee's avatar Ryder Lee Committed by Felix Fietkau

wifi: mt76: mt7915: add ack signal support

This reports signal strength of ACK packets from the peer as measured
at each interface.
Tested-by: default avatarShurong Wen <shurong.wen@mediatek.com>
Signed-off-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent b0bfa005
...@@ -951,14 +951,12 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, ...@@ -951,14 +951,12 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
} }
EXPORT_SYMBOL(mt76_wcid_key_setup); EXPORT_SYMBOL(mt76_wcid_key_setup);
static int int mt76_rx_signal(u8 chain_mask, s8 *chain_signal)
mt76_rx_signal(struct mt76_rx_status *status)
{ {
s8 *chain_signal = status->chain_signal;
int signal = -128; int signal = -128;
u8 chains; u8 chains;
for (chains = status->chains; chains; chains >>= 1, chain_signal++) { for (chains = chain_mask; chains; chains >>= 1, chain_signal++) {
int cur, diff; int cur, diff;
cur = *chain_signal; cur = *chain_signal;
...@@ -980,6 +978,7 @@ mt76_rx_signal(struct mt76_rx_status *status) ...@@ -980,6 +978,7 @@ mt76_rx_signal(struct mt76_rx_status *status)
return signal; return signal;
} }
EXPORT_SYMBOL(mt76_rx_signal);
static void static void
mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
...@@ -1009,7 +1008,7 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, ...@@ -1009,7 +1008,7 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
status->ampdu_reference = mstat.ampdu_ref; status->ampdu_reference = mstat.ampdu_ref;
status->device_timestamp = mstat.timestamp; status->device_timestamp = mstat.timestamp;
status->mactime = mstat.timestamp; status->mactime = mstat.timestamp;
status->signal = mt76_rx_signal(&mstat); status->signal = mt76_rx_signal(mstat.chains, mstat.chain_signal);
if (status->signal <= -128) if (status->signal <= -128)
status->flag |= RX_FLAG_NO_SIGNAL_VAL; status->flag |= RX_FLAG_NO_SIGNAL_VAL;
......
...@@ -1149,6 +1149,7 @@ void mt76_update_survey(struct mt76_phy *phy); ...@@ -1149,6 +1149,7 @@ void mt76_update_survey(struct mt76_phy *phy);
void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time); void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time);
int mt76_get_survey(struct ieee80211_hw *hw, int idx, int mt76_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey); struct survey_info *survey);
int mt76_rx_signal(u8 chain_mask, s8 *chain_signal);
void mt76_set_stream_caps(struct mt76_phy *phy, bool vht); void mt76_set_stream_caps(struct mt76_phy *phy, bool vht);
int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid,
......
...@@ -353,6 +353,7 @@ mt7915_init_wiphy(struct ieee80211_hw *hw) ...@@ -353,6 +353,7 @@ mt7915_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_BEACON_RATE_HE);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP); 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_FILS_DISCOVERY);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
if (!mdev->dev->of_node || if (!mdev->dev->of_node ||
!of_property_read_bool(mdev->dev->of_node, !of_property_read_bool(mdev->dev->of_node,
...@@ -461,6 +462,12 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band) ...@@ -461,6 +462,12 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
set = FIELD_PREP(MT_WF_RMAC_MIB_OBSS_BACKOFF, 0) | set = FIELD_PREP(MT_WF_RMAC_MIB_OBSS_BACKOFF, 0) |
FIELD_PREP(MT_WF_RMAC_MIB_ED_OFFSET, 4); FIELD_PREP(MT_WF_RMAC_MIB_ED_OFFSET, 4);
mt76_rmw(dev, MT_WF_RMAC_MIB_AIRTIME0(band), mask, set); mt76_rmw(dev, MT_WF_RMAC_MIB_AIRTIME0(band), mask, set);
/* filter out non-resp frames and get instanstaeous signal reporting */
mask = MT_WTBLOFF_TOP_RSCR_RCPI_MODE | MT_WTBLOFF_TOP_RSCR_RCPI_PARAM;
set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) |
FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3);
mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set);
} }
static void mt7915_mac_init(struct mt7915_dev *dev) static void mt7915_mac_init(struct mt7915_dev *dev)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "mac.h" #include "mac.h"
#include "mcu.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)
static const struct mt7915_dfs_radar_spec etsi_radar_specs = { static const struct mt7915_dfs_radar_spec etsi_radar_specs = {
.pulse_th = { 110, -10, -80, 40, 5200, 128, 5200 }, .pulse_th = { 110, -10, -80, 40, 5200, 128, 5200 },
...@@ -118,6 +118,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev) ...@@ -118,6 +118,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
bool clear = false; bool clear = false;
u32 addr, val; u32 addr, val;
u16 idx; u16 idx;
s8 rssi[4];
u8 bw; u8 bw;
spin_lock_bh(&dev->sta_poll_lock); spin_lock_bh(&dev->sta_poll_lock);
...@@ -131,6 +132,8 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev) ...@@ -131,6 +132,8 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
spin_unlock_bh(&dev->sta_poll_lock); spin_unlock_bh(&dev->sta_poll_lock);
idx = msta->wcid.idx; idx = msta->wcid.idx;
/* refresh peer's airtime reporting */
addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 20); addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 20);
for (i = 0; i < IEEE80211_NUM_ACS; i++) { for (i = 0; i < IEEE80211_NUM_ACS; i++) {
...@@ -209,6 +212,20 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev) ...@@ -209,6 +212,20 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
else else
rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI; rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
} }
/* get signal strength of resp frames (CTS/BA/ACK) */
addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 30);
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(); rcu_read_unlock();
......
...@@ -665,6 +665,8 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, ...@@ -665,6 +665,8 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
msta->wcid.tx_info |= MT_WCID_TX_INFO_SET; msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
msta->jiffies = jiffies; msta->jiffies = jiffies;
ewma_avg_signal_init(&msta->avg_ack_signal);
mt7915_mac_wtbl_update(dev, idx, mt7915_mac_wtbl_update(dev, idx,
MT_WTBL_UPDATE_ADM_COUNT_CLEAR); MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
...@@ -1025,6 +1027,12 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, ...@@ -1025,6 +1027,12 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
sinfo->tx_retries = msta->wcid.stats.tx_retries; sinfo->tx_retries = msta->wcid.stats.tx_retries;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
} }
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 mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta) static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
......
...@@ -114,6 +114,8 @@ struct mt7915_twt_flow { ...@@ -114,6 +114,8 @@ struct mt7915_twt_flow {
u8 sched:1; u8 sched:1;
}; };
DECLARE_EWMA(avg_signal, 10, 8)
struct mt7915_sta { struct mt7915_sta {
struct mt76_wcid wcid; /* must be first */ struct mt76_wcid wcid; /* must be first */
...@@ -123,10 +125,12 @@ struct mt7915_sta { ...@@ -123,10 +125,12 @@ struct mt7915_sta {
struct list_head rc_list; struct list_head rc_list;
u32 airtime_ac[8]; u32 airtime_ac[8];
int ack_signal;
struct ewma_avg_signal avg_ack_signal;
unsigned long changed; unsigned long changed;
unsigned long jiffies; unsigned long jiffies;
unsigned long ampdu_state; unsigned long ampdu_state;
struct mt76_connac_sta_key_conf bip; struct mt76_connac_sta_key_conf bip;
struct { struct {
......
...@@ -226,6 +226,14 @@ enum offs_rev { ...@@ -226,6 +226,14 @@ enum offs_rev {
#define MT_DMA_DCR0_MAX_RX_LEN GENMASK(15, 3) #define MT_DMA_DCR0_MAX_RX_LEN GENMASK(15, 3)
#define MT_DMA_DCR0_RXD_G5_EN BIT(23) #define MT_DMA_DCR0_RXD_G5_EN BIT(23)
/* WTBLOFF TOP: band 0(0x820e9000),band 1(0x820f9000) */
#define MT_WTBLOFF_TOP_BASE(_band) ((_band) ? 0x820f9000 : 0x820e9000)
#define MT_WTBLOFF_TOP(_band, ofs) (MT_WTBLOFF_TOP_BASE(_band) + (ofs))
#define MT_WTBLOFF_TOP_RSCR(_band) MT_WTBLOFF_TOP(_band, 0x008)
#define MT_WTBLOFF_TOP_RSCR_RCPI_MODE GENMASK(31, 30)
#define MT_WTBLOFF_TOP_RSCR_RCPI_PARAM GENMASK(25, 24)
/* ETBF: band 0(0x820ea000), band 1(0x820fa000) */ /* ETBF: band 0(0x820ea000), band 1(0x820fa000) */
#define MT_WF_ETBF_BASE(_band) ((_band) ? 0x820fa000 : 0x820ea000) #define MT_WF_ETBF_BASE(_band) ((_band) ? 0x820fa000 : 0x820ea000)
#define MT_WF_ETBF(_band, ofs) (MT_WF_ETBF_BASE(_band) + (ofs)) #define MT_WF_ETBF(_band, ofs) (MT_WF_ETBF_BASE(_band) + (ofs))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment