2022-02-15 17:15:34

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH] mt76: improve signal strength reporting

Instead of just taking the maximum per-chain signal strength values,
add an approximation for the sum of the combined signal.
This should more accurately reflect the real signal strength, especially
if the per-chain signal strength values are close to each other

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mac80211.c | 32 +++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7603/mac.c | 5 ---
.../net/wireless/mediatek/mt76/mt7615/mac.c | 9 ------
.../net/wireless/mediatek/mt76/mt76x02_mac.c | 2 --
.../net/wireless/mediatek/mt76/mt7915/mac.c | 11 +------
.../net/wireless/mediatek/mt76/mt7921/mac.c | 3 --
6 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index a4bb281a74e6..9796419c99e1 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -932,6 +932,35 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
}
EXPORT_SYMBOL(mt76_wcid_key_setup);

+static int
+mt76_rx_signal(struct mt76_rx_status *status)
+{
+ s8 *chain_signal = status->chain_signal;
+ int signal = -128;
+ u8 chains;
+
+ for (chains = status->chains; chains; chains >>= 1, chain_signal++) {
+ int cur, diff;
+
+ if (!(chains & BIT(0)))
+ continue;
+
+ cur = *chain_signal;
+ if (cur > signal)
+ swap(cur, signal);
+
+ diff = signal - cur;
+ if (diff == 0)
+ signal += 3;
+ else if (diff <= 2)
+ signal += 2;
+ else if (diff <= 6)
+ signal += 1;
+ }
+
+ return signal;
+}
+
static void
mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
struct ieee80211_hw **hw,
@@ -960,6 +989,9 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
status->ampdu_reference = mstat.ampdu_ref;
status->device_timestamp = mstat.timestamp;
status->mactime = mstat.timestamp;
+ status->signal = mt76_rx_signal(&mstat);
+ if (status->signal <= -128)
+ status->flag |= RX_FLAG_NO_SIGNAL_VAL;

if (ieee80211_is_beacon(hdr->frame_control) ||
ieee80211_is_probe_resp(hdr->frame_control))
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index a272d64808c3..2e5d26616bc2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -643,11 +643,6 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
status->chain_signal[1] = FIELD_GET(MT_RXV4_IB_RSSI1, rxdg3) +
dev->rssi_offset[1];

- status->signal = status->chain_signal[0];
- if (status->chains & BIT(1))
- status->signal = max(status->signal,
- status->chain_signal[1]);
-
if (FIELD_GET(MT_RXV1_FRAME_MODE, rxdg0) == 1)
status->bw = RATE_INFO_BW_40;

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index 13109864b6d6..d1d87240f24f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -576,15 +576,6 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
status->chain_signal[1] = to_rssi(MT_RXV4_RCPI1, rxdg3);
status->chain_signal[2] = to_rssi(MT_RXV4_RCPI2, rxdg3);
status->chain_signal[3] = to_rssi(MT_RXV4_RCPI3, rxdg3);
- status->signal = status->chain_signal[0];
-
- for (i = 1; i < hweight8(mphy->antenna_mask); i++) {
- if (!(status->chains & BIT(i)))
- continue;
-
- status->signal = max(status->signal,
- status->chain_signal[i]);
- }

mt7615_mac_fill_tm_rx(mphy->priv, rxd);

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index dc2aeaab72ec..2afad8c76ca6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -860,9 +860,7 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
status->chain_signal[1] = mt76x02_mac_get_rssi(dev,
rxwi->rssi[1],
1);
- signal = max_t(s8, signal, status->chain_signal[1]);
}
- status->signal = signal;
status->freq = dev->mphy.chandef.chan->center_freq;
status->band = dev->mphy.chandef.chan->band;

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index e64afa2f181d..06186c034d93 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -593,7 +593,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
u16 seq_ctrl = 0;
u8 qos_ctl = 0;
__le16 fc = 0;
- int i, idx;
+ int idx;

memset(status, 0, sizeof(*status));

@@ -753,15 +753,6 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
status->chain_signal[1] = to_rssi(MT_PRXV_RCPI1, v1);
status->chain_signal[2] = to_rssi(MT_PRXV_RCPI2, v1);
status->chain_signal[3] = to_rssi(MT_PRXV_RCPI3, v1);
- status->signal = status->chain_signal[0];
-
- for (i = 1; i < hweight8(mphy->antenna_mask); i++) {
- if (!(status->chains & BIT(i)))
- continue;
-
- status->signal = max(status->signal,
- status->chain_signal[i]);
- }

/* RXD Group 5 - C-RXV */
if (rxd1 & MT_RXD1_NORMAL_GROUP_5) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 8e88445102ab..0a6c269a2fb6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -670,9 +670,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
status->chain_signal[i]);
}

- if (status->signal == -128)
- status->flag |= RX_FLAG_NO_SIGNAL_VAL;
-
stbc = FIELD_GET(MT_PRXV_STBC, v0);
gi = FIELD_GET(MT_PRXV_SGI, v0);
cck = false;
--
2.32.0 (Apple Git-132)


2022-02-16 07:15:17

by Ben Greear

[permalink] [raw]
Subject: Re: [PATCH] mt76: improve signal strength reporting

On 2/15/22 4:58 AM, Felix Fietkau wrote:
> Instead of just taking the maximum per-chain signal strength values,
> add an approximation for the sum of the combined signal.
> This should more accurately reflect the real signal strength, especially
> if the per-chain signal strength values are close to each other

My concern with this patch is that many of the mtk radios do not provide enough
info to know how many RX chains are used when receiving a frame. I think we should not
be summing more chains than the number of spatial streams received.

That said, this code may still be a closer estimate than existing code, and some
radios, like 7921 appear to report enough info by default to properly determine
the NSS count on a per frame basis.

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com