]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
stmmac: s32: enable support for Multi-IRQ mode
authorJan Petrous (OSS) <jan.petrous@oss.nxp.com>
Fri, 13 Mar 2026 07:13:35 +0000 (08:13 +0100)
committerJakub Kicinski <kuba@kernel.org>
Tue, 17 Mar 2026 03:07:05 +0000 (20:07 -0700)
Based on previous changes in platform driver, the vendor
glue driver can enable Multi-IRQ mode, if needed.

To get enabled Multi-IRQ mode for dwmac-s32, the driver checks:

  1) property of 'snps,mtl-xx-config' subnode
     defines 'snps,xx-queues-to-use' bigger then one, ie:

     ethernet@4033c000 {
         compatible = "nxp,s32g2-dwmac";
         ...
         snps,mtl-rx-config = <&mtl_rx_setup>;
         ...

         mtl_rx_setup: rx-queues-config {
             snps,rx-queues-to-use = <2>;
         };

  2) queue based IRQs are set, ie:

     ethernet@4033c000 {
         compatible = "nxp,s32g2-dwmac";
         ...
         interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
                      /* CHN 0: tx, rx */
                      <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
                      <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
                      /* CHN 1: tx, rx */
                      <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
                      <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
         interrupt-names = "macirq",
                           "tx-queue-0", "rx-queue-0",
                           "tx-queue-1", "rx-queue-1";

If those prerequisites are met, the driver switches to Multi-IRQ mode,
using per-queue IRQs for rx/tx data pathr:

[    1.387045] s32-dwmac 4033c000.ethernet: Multi-IRQ mode (per queue IRQs) selected

Now the driver owns all queues IRQs:

root@s32g399aevb3:~# grep eth /proc/interrupts
 29:    0    0    0    0    0    0    0    0    GICv3  89 Level   eth0:mac
 30:    0    0    0    0    0    0    0    0    GICv3  91 Level   eth0:rx-0
 31:    0    0    0    0    0    0    0    0    GICv3  93 Level   eth0:rx-1
 32:    0    0    0    0    0    0    0    0    GICv3  95 Level   eth0:rx-2
 33:    0    0    0    0    0    0    0    0    GICv3  97 Level   eth0:rx-3
 34:    0    0    0    0    0    0    0    0    GICv3  99 Level   eth0:rx-4
 35:    0    0    0    0    0    0    0    0    GICv3  90 Level   eth0:tx-0
 36:    0    0    0    0    0    0    0    0    GICv3  92 Level   eth0:tx-1
 37:    0    0    0    0    0    0    0    0    GICv3  94 Level   eth0:tx-2
 38:    0    0    0    0    0    0    0    0    GICv3  96 Level   eth0:tx-3
 39:    0    0    0    0    0    0    0    0    GICv3  98 Level   eth0:tx-4

Otherwise, if one of the prerequisite don't met, the driver
continue with MAC IRQ mode:

[    1.387045] s32-dwmac 4033c000.ethernet: MAC IRQ mode selected

And only MAC IRQ will be attached:

root@s32g399aevb3:~# grep eth /proc/interrupts
 29:    0    0    0    0    0    0    0    0    GICv3  89 Level   eth0:mac

What represents the original MAC IRQ mode and is fully backward
compatible.

Reviewed-by: Matthias Brugger <mbrugger@suse.com>
Signed-off-by: Jan Petrous (OSS) <jan.petrous@oss.nxp.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://patch.msgid.link/20260313-dwmac_multi_irq-v12-4-b5c9d0aa13d6@oss.nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c

index 48fceadc55b12351a7021d7dfecb5af9ef7a8bf7..024d8e10e9188935a2abac3c14fdfea429d92665 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * NXP S32G/R GMAC glue layer
  *
- * Copyright 2019-2024 NXP
+ * Copyright 2019-2026 NXP
  *
  */
 
@@ -110,6 +110,37 @@ static void s32_gmac_exit(struct device *dev, void *priv)
        clk_disable_unprepare(gmac->rx_clk);
 }
 
+static void s32_gmac_setup_multi_irq(struct device *dev,
+                                    struct plat_stmmacenet_data *plat,
+                                    struct stmmac_resources *res)
+{
+       int i;
+
+       /* RX IRQs */
+       for (i = 0; i < plat->rx_queues_to_use; i++) {
+               if (res->rx_irq[i] <= 0) {
+                       dev_dbg(dev, "Missing RX queue %d interrupt\n", i);
+                       goto mac_irq_mode;
+               }
+       }
+
+       /* TX IRQs */
+       for (i = 0; i < plat->tx_queues_to_use; i++) {
+               if (res->tx_irq[i] <= 0) {
+                       dev_dbg(dev, "Missing TX queue %d interrupt\n", i);
+                       goto mac_irq_mode;
+               }
+       }
+
+       plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
+       dev_info(dev, "Multi-IRQ mode (per queue IRQs) selected\n");
+       return;
+
+mac_irq_mode:
+       plat->flags &= ~STMMAC_FLAG_MULTI_MSI_EN;
+       dev_info(dev, "MAC IRQ mode selected\n");
+}
+
 static int s32_dwmac_probe(struct platform_device *pdev)
 {
        struct plat_stmmacenet_data *plat;
@@ -165,6 +196,9 @@ static int s32_dwmac_probe(struct platform_device *pdev)
        plat->core_type = DWMAC_CORE_GMAC4;
        plat->pmt = true;
        plat->flags |= STMMAC_FLAG_SPH_DISABLE;
+
+       s32_gmac_setup_multi_irq(dev, plat, &res);
+
        plat->rx_fifo_size = 20480;
        plat->tx_fifo_size = 20480;