@@ -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
@@ -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);