From: Ben Greear <greearb@xxxxxxxxxxxxxxx> Sum up individual chains to provide more accurate total power reporting. Use reported NSS to determine chains. Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx> --- drivers/net/wireless/mediatek/mt76/mt76.h | 32 +++++++++++++++++ .../net/wireless/mediatek/mt76/mt7921/mac.c | 36 ++++++++++++------- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 3c0e2cda36acf..96587680b6fa4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -1425,4 +1425,36 @@ mt76_packet_id_flush(struct mt76_dev *dev, struct mt76_wcid *wcid) idr_destroy(&wcid->pktid); } +/* Estimated summing of dbm without resorting to log(10) business */ +static inline int mt76_sum_sigs_2(int a, int b) +{ + int diff; + + /* 0x80 means value-is-not-set */ + if (b == 0x80) + return a; + + if (a >= b) { + /* a is largest value, add to it. */ + diff = a - b; + if (diff == 0) + return a + 3; + else if (diff == 1) + return a + 2; + else if (diff == 2) + return a + 1; + return a; + } else { + /* b is largest value, add to it. */ + diff = b - a; + if (diff == 0) + return b + 3; + else if (diff == 1) + return b + 2; + else if (diff == 2) + return b + 1; + return b; + } +} + #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 609497a85942f..b8ce9d1e10cc9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -648,23 +648,10 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) if (v0 & MT_PRXV_HT_AD_CODE) status->enc_flags |= RX_ENC_FLAG_LDPC; - status->chains = mphy->antenna_mask; status->chain_signal[0] = to_rssi(MT_PRXV_RCPI0, v1); 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 = -128; - for (i = 0; i < hweight8(mphy->antenna_mask); i++) { - if (!(status->chains & BIT(i)) || - status->chain_signal[i] >= 0) - continue; - - status->signal = max(status->signal, - 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); @@ -679,10 +666,15 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) fallthrough; case MT_PHY_TYPE_OFDM: i = mt76_get_rate(&dev->mt76, sband, i, cck); + if (stbc) + status->nss = 2; + else + status->nss = 1; break; case MT_PHY_TYPE_HT_GF: case MT_PHY_TYPE_HT: status->encoding = RX_ENC_HT; + status->nss = i / 8 + 1; if (i > 31) return -EINVAL; break; @@ -745,6 +737,24 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) if ((u8 *)rxd - skb->data >= skb->len) return -EINVAL; } + + for (i = 0; i < status->nss; i++) { + if (status->chain_signal[i] < 0) + status->chains |= BIT(i); + } + + if (status->nss == 1) { + status->signal = status->chain_signal[0]; + } else if (status->nss == 2) { + status->signal = mt76_sum_sigs_2(status->chain_signal[0], + status->chain_signal[1]); + } else { + WARN_ON_ONCE(1); /* this driver is for only 2x2 AFAIK */ + status->signal = status->chain_signal[0]; + } + + if (!status->chains) + status->flag |= RX_FLAG_NO_SIGNAL_VAL; } amsdu_info = FIELD_GET(MT_RXD4_NORMAL_PAYLOAD_FORMAT, rxd4); -- 2.26.3