wifi: mt76: mt7996: enable PPDU-TxS to host
authorYi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
Thu, 21 Sep 2023 21:04:02 +0000 (14:04 -0700)
committerFelix Fietkau <nbd@nbd.name>
Sat, 30 Sep 2023 18:17:18 +0000 (20:17 +0200)
Enable PPDU TxS by default. This makes the driver able to get Tx rate
information from TxS. The driver will also refresh BA session timer
on receive of PPDU TxS when WED is on.

Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
Signed-off-by: Money Wang <Money.Wang@mediatek.com>
Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
Signed-off-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
drivers/net/wireless/mediatek/mt76/mt7996/init.c
drivers/net/wireless/mediatek/mt76/mt7996/mac.c
drivers/net/wireless/mediatek/mt76/mt7996/regs.h

index b614b92ebaa4610ae42c95e2d34272fac2941921..2250252b2047e72d87616e012ddc302e1df8e7b3 100644 (file)
@@ -317,6 +317,7 @@ enum tx_mgnt_type {
 
 #define MT_TXS4_TIMESTAMP              GENMASK(31, 0)
 
+/* MPDU based TXS */
 #define MT_TXS5_F0_FINAL_MPDU          BIT(31)
 #define MT_TXS5_F0_QOS                 BIT(30)
 #define MT_TXS5_F0_TX_COUNT            GENMASK(29, 25)
@@ -338,4 +339,17 @@ enum tx_mgnt_type {
 #define MT_TXS7_F1_MPDU_RETRY_COUNT    GENMASK(31, 24)
 #define MT_TXS7_F1_MPDU_RETRY_BYTES    GENMASK(23, 0)
 
+/* PPDU based TXS */
+#define MT_TXS5_MPDU_TX_CNT            GENMASK(30, 20)
+#define MT_TXS5_MPDU_TX_BYTE_SCALE     BIT(15)
+#define MT_TXS5_MPDU_TX_BYTE           GENMASK(14, 0)
+
+#define MT_TXS6_MPDU_FAIL_CNT          GENMASK(30, 20)
+#define MT_TXS6_MPDU_FAIL_BYTE_SCALE   BIT(15)
+#define MT_TXS6_MPDU_FAIL_BYTE         GENMASK(14, 0)
+
+#define MT_TXS7_MPDU_RETRY_CNT         GENMASK(30, 20)
+#define MT_TXS7_MPDU_RETRY_BYTE_SCALE  BIT(15)
+#define MT_TXS7_MPDU_RETRY_BYTE                GENMASK(14, 0)
+
 #endif /* __MT76_CONNAC3_MAC_H */
index e4bb22b84159b5483794eb95ec36e0a781965b0e..55cb1770fa34e1d781379669ec741d904915968e 100644 (file)
@@ -274,6 +274,11 @@ mt7996_mac_init_band(struct mt7996_dev *dev, u8 band)
        set = FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_MODE, 0) |
              FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_PARAM, 0x3);
        mt76_rmw(dev, MT_WTBLOFF_RSCR(band), mask, set);
+
+       /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
+        * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
+        */
+       mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H);
 }
 
 static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
index dc5e4739fd0796d9aefab9c880947114c8a7be5d..ffd15bfab48c2d3cff1b842b462c042bf184c8df 100644 (file)
@@ -1178,22 +1178,31 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
        bool cck = false;
        u32 txrate, txs, mode, stbc;
 
+       txs = le32_to_cpu(txs_data[0]);
+
        mt76_tx_status_lock(mdev, &list);
        skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list);
-       if (!skb)
-               goto out_no_skb;
 
-       txs = le32_to_cpu(txs_data[0]);
+       if (skb) {
+               info = IEEE80211_SKB_CB(skb);
+               if (!(txs & MT_TXS0_ACK_ERROR_MASK))
+                       info->flags |= IEEE80211_TX_STAT_ACK;
 
-       info = IEEE80211_SKB_CB(skb);
-       if (!(txs & MT_TXS0_ACK_ERROR_MASK))
-               info->flags |= IEEE80211_TX_STAT_ACK;
+               info->status.ampdu_len = 1;
+               info->status.ampdu_ack_len =
+                       !!(info->flags & IEEE80211_TX_STAT_ACK);
 
-       info->status.ampdu_len = 1;
-       info->status.ampdu_ack_len = !!(info->flags &
-                                       IEEE80211_TX_STAT_ACK);
+               info->status.rates[0].idx = -1;
+       }
 
-       info->status.rates[0].idx = -1;
+       if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wcid->sta) {
+               struct ieee80211_sta *sta;
+               u8 tid;
+
+               sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
+               tid = FIELD_GET(MT_TXS0_TID, txs);
+               ieee80211_refresh_tx_agg_session_timer(sta, tid);
+       }
 
        txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
 
@@ -1293,9 +1302,8 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
        wcid->rate = rate;
 
 out:
-       mt76_tx_status_skb_done(mdev, skb, &list);
-
-out_no_skb:
+       if (skb)
+               mt76_tx_status_skb_done(mdev, skb, &list);
        mt76_tx_status_unlock(mdev, &list);
 
        return !!skb;
@@ -1309,13 +1317,10 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)
        u16 wcidx;
        u8 pid;
 
-       if (le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT) > 1)
-               return;
-
        wcidx = le32_get_bits(txs_data[2], MT_TXS2_WCID);
        pid = le32_get_bits(txs_data[3], MT_TXS3_PID);
 
-       if (pid < MT_PACKET_ID_FIRST)
+       if (pid < MT_PACKET_ID_WED)
                return;
 
        if (wcidx >= mt7996_wtbl_size(dev))
index 57022906216c5c2a31be739b96666dc37ddab725..0086a78666579e23a0400f6ca0ac273d71b479b8 100644 (file)
@@ -243,6 +243,13 @@ enum base_rev {
                                                 FIELD_PREP(MT_WTBL_LMAC_ID, _id) | \
                                                 FIELD_PREP(MT_WTBL_LMAC_DW, _dw))
 
+/* AGG: band 0(0x820e2000), band 1(0x820f2000), band 2(0x830e2000) */
+#define MT_WF_AGG_BASE(_band)                  __BASE(WF_AGG_BASE, (_band))
+#define MT_WF_AGG(_band, ofs)                  (MT_WF_AGG_BASE(_band) + (ofs))
+
+#define MT_AGG_ACR4(_band)                     MT_WF_AGG(_band, 0x3c)
+#define MT_AGG_ACR_PPDU_TXS2H                  BIT(1)
+
 /* ARB: band 0(0x820e3000), band 1(0x820f3000), band 2(0x830e3000) */
 #define MT_WF_ARB_BASE(_band)                  __BASE(WF_ARB_BASE, (_band))
 #define MT_WF_ARB(_band, ofs)                  (MT_WF_ARB_BASE(_band) + (ofs))