mt76: mt7921: properly configure rcpi adding a sta to the fw
authorLorenzo Bianconi <lorenzo@kernel.org>
Wed, 24 Mar 2021 08:37:37 +0000 (09:37 +0100)
committerFelix Fietkau <nbd@nbd.name>
Sun, 11 Apr 2021 22:03:04 +0000 (00:03 +0200)
Properly configure rcpi based on association process rssi. rcpi is used
by rate controller embedded into the fw to initialize amsdu size.

Tested-by: Jayden.Kuo <jayden.kuo@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7921/mac.c
drivers/net/wireless/mediatek/mt76/mt7921/main.c
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h

index 8faae260df79a34e51648873135e18ed0ce3f7bb..ee6482124c0a12f74130c64191a00603c4d5ca8a 100644 (file)
@@ -9,8 +9,6 @@
 #include "mac.h"
 #include "mcu.h"
 
-#define to_rssi(field, rxv)    ((FIELD_GET(field, rxv) - 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),\
                                                 IEEE80211_RADIOTAP_HE_##f)
@@ -277,6 +275,37 @@ mt7921_get_status_freq_info(struct mt7921_dev *dev, struct mt76_phy *mphy,
        status->freq = ieee80211_channel_to_frequency(chfreq, status->band);
 }
 
+static void
+mt7921_mac_rssi_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct sk_buff *skb = priv;
+       struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
+       struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
+       struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
+
+       if (status->signal > 0)
+               return;
+
+       if (!ether_addr_equal(vif->addr, hdr->addr1))
+               return;
+
+       ewma_rssi_add(&mvif->rssi, -status->signal);
+}
+
+static void
+mt7921_mac_assoc_rssi(struct mt7921_dev *dev, struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
+
+       if (!ieee80211_is_assoc_resp(hdr->frame_control) &&
+           !ieee80211_is_auth(hdr->frame_control))
+               return;
+
+       ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
+               IEEE80211_IFACE_ITER_RESUME_ALL,
+               mt7921_mac_rssi_iter, skb);
+}
+
 int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
 {
        struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
@@ -514,6 +543,8 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
                mt76_insert_ccmp_hdr(skb, key_id);
        }
 
+       mt7921_mac_assoc_rssi(dev, skb);
+
        if (rxv && status->flag & RX_FLAG_RADIOTAP_HE)
                mt7921_mac_decode_he_radiotap(skb, status, rxv, mode);
 
index 302d8d78d6f7e8762705b365705f867e3b3b1da2..7b4f6a70f87ad6d5c4eecd5437e3c1910e5488cf 100644 (file)
@@ -322,6 +322,8 @@ static int mt7921_add_interface(struct ieee80211_hw *hw,
        mt7921_mac_wtbl_update(dev, idx,
                               MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
 
+       ewma_rssi_init(&mvif->rssi);
+
        rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
        if (vif->txq) {
                mtxq = (struct mt76_txq *)vif->txq->drv_priv;
@@ -624,12 +626,14 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
        struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
        struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv;
        struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
+       int rssi = -ewma_rssi_read(&mvif->rssi);
        struct mt76_sta_cmd_info info = {
                .sta = sta,
                .vif = vif,
                .enable = true,
                .cmd = MCU_UNI_CMD_STA_REC_UPDATE,
                .wcid = &msta->wcid,
+               .rcpi = to_rcpi(rssi),
        };
        int ret, idx;
 
@@ -686,11 +690,13 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
        mt7921_mac_wtbl_update(dev, msta->wcid.idx,
                               MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
 
-       if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
+       if (vif->type == NL80211_IFTYPE_STATION) {
                struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
 
-               mt76_connac_mcu_uni_add_bss(&dev->mphy, vif, &mvif->sta.wcid,
-                                           false);
+               ewma_rssi_init(&mvif->rssi);
+               if (!sta->tdls)
+                       mt76_connac_mcu_uni_add_bss(&dev->mphy, vif,
+                                                   &mvif->sta.wcid, false);
        }
 
        spin_lock_bh(&dev->sta_poll_lock);
index df3c9730876c3f1410a01aeed9da335c195b7785..5cedefc4141694025430cb9068d656bc52dadb21 100644 (file)
@@ -46,6 +46,9 @@
 #define MT7921_SKU_MAX_DELTA_IDX       MT7921_SKU_RATE_NUM
 #define MT7921_SKU_TABLE_SIZE          (MT7921_SKU_RATE_NUM + 1)
 
+#define to_rssi(field, rxv)            ((FIELD_GET(field, rxv) - 220) / 2)
+#define to_rcpi(rssi)                  (2 * (rssi) + 220)
+
 struct mt7921_vif;
 struct mt7921_sta;
 
@@ -92,12 +95,16 @@ struct mt7921_sta {
        struct mt7921_sta_key_conf bip;
 };
 
+DECLARE_EWMA(rssi, 10, 8);
+
 struct mt7921_vif {
        struct mt76_vif mt76; /* must be first */
 
        struct mt7921_sta sta;
        struct mt7921_phy *phy;
 
+       struct ewma_rssi rssi;
+
        struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
 };