mt76: mt7915: significantly reduce interrupt load
authorFelix Fietkau <nbd@nbd.name>
Sat, 22 Aug 2020 12:41:42 +0000 (14:41 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 24 Sep 2020 16:10:16 +0000 (18:10 +0200)
On 7615 and newer, DMA completion only triggers unmap, but not free of queued
skbs, since pointers to packets are queued internally.
Because of that, there is no need to process the main data queue immediately
on DMA completion.
To improve performance, mask out the DMA data queue completion interrupt and
process the queue only when we receive a txfree event.
This brings the number of interrupts under load down to a small fraction.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7915/dma.c
drivers/net/wireless/mediatek/mt76/mt7915/mac.c
drivers/net/wireless/mediatek/mt76/mt7915/pci.c
drivers/net/wireless/mediatek/mt76/mt7915/regs.h

index 34e90bb..bdc6946 100644 (file)
@@ -84,8 +84,6 @@ mt7915_tx_cleanup(struct mt7915_dev *dev)
 {
        mt76_queue_tx_cleanup(dev, MT_TXQ_MCU, false);
        mt76_queue_tx_cleanup(dev, MT_TXQ_MCU_WA, false);
-       mt76_queue_tx_cleanup(dev, MT_TXQ_PSD, false);
-       mt76_queue_tx_cleanup(dev, MT_TXQ_BE, false);
 }
 
 static int mt7915_poll_tx(struct napi_struct *napi, int budget)
@@ -97,7 +95,7 @@ static int mt7915_poll_tx(struct napi_struct *napi, int budget)
        mt7915_tx_cleanup(dev);
 
        if (napi_complete_done(napi, 0))
-               mt7915_irq_enable(dev, MT_INT_TX_DONE_ALL);
+               mt7915_irq_enable(dev, MT_INT_TX_DONE_MCU);
 
        return 0;
 }
@@ -242,7 +240,7 @@ int mt7915_dma_init(struct mt7915_dev *dev)
                 MT_WFDMA1_GLO_CFG_TX_DMA_EN | MT_WFDMA1_GLO_CFG_RX_DMA_EN);
 
        /* enable interrupts for TX/RX rings */
-       mt7915_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
+       mt7915_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_MCU |
                          MT_INT_MCU_CMD);
 
        return 0;
index 9c920c9..22d12dd 100644 (file)
@@ -874,6 +874,10 @@ void mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
        struct ieee80211_sta *sta = NULL;
        u8 i, count;
 
+       /* clean DMA queues and unmap buffers first */
+       mt76_queue_tx_cleanup(dev, MT_TXQ_PSD, false);
+       mt76_queue_tx_cleanup(dev, MT_TXQ_BE, false);
+
        /*
         * TODO: MT_TX_FREE_LATENCY is msdu time from the TXD is queued into PLE,
         * to the time ack is received or dropped by hw (air + hw queue time).
index 91bff10..fe62b4d 100644 (file)
@@ -41,12 +41,12 @@ static irqreturn_t mt7915_irq_handler(int irq, void *dev_instance)
        trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
 
        mask = intr & MT_INT_RX_DONE_ALL;
-       if (intr & MT_INT_TX_DONE_ALL)
-               mask |= MT_INT_TX_DONE_ALL;
+       if (intr & MT_INT_TX_DONE_MCU)
+               mask |= MT_INT_TX_DONE_MCU;
 
        mt7915_irq_disable(dev, mask);
 
-       if (intr & MT_INT_TX_DONE_ALL)
+       if (intr & MT_INT_TX_DONE_MCU)
                napi_schedule(&dev->mt76.tx_napi);
 
        if (intr & MT_INT_RX_DONE_DATA)
index e098914..4b97b47 100644 (file)
 #define MT_INT_RX_DONE_WA              BIT(1)
 #define MT_INT_RX_DONE(_n)             ((_n) ? BIT((_n) - 1) : BIT(16))
 #define MT_INT_RX_DONE_ALL             (BIT(0) | BIT(1) | BIT(16))
-#define MT_INT_TX_DONE_ALL             (BIT(15) | GENMASK(27, 26) | BIT(30))
+#define MT_INT_TX_DONE_MCU_WA          BIT(15)
+#define MT_INT_TX_DONE_FWDL            BIT(26)
+#define MT_INT_TX_DONE_MCU_WM          BIT(27)
+#define MT_INT_TX_DONE_BAND0           BIT(30)
+#define MT_INT_TX_DONE_BAND1           BIT(31)
 #define MT_INT_MCU_CMD                 BIT(29)
 
+#define MT_INT_TX_DONE_MCU             (MT_INT_TX_DONE_MCU_WA |        \
+                                        MT_INT_TX_DONE_MCU_WM |        \
+                                        MT_INT_TX_DONE_FWDL)
+
 #define MT_WFDMA_EXT_CSR_HIF_MISC      MT_WFDMA_EXT_CSR(0x44)
 #define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY BIT(0)