]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: stmmac: introduce DMA interrupt status masking per traffic direction
authorOng Boon Leong <boon.leong.ong@intel.com>
Thu, 25 Mar 2021 17:39:12 +0000 (01:39 +0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 Mar 2021 00:37:30 +0000 (17:37 -0700)
In preparation to make stmmac support multi-vector MSI, we introduce the
interrupt status masking according to RX, TX or RXTX. Default to use RXTX
inside stmmac_dma_interrupt(), so there is no run-time logic difference
now.

Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com>
Signed-off-by: Voon Weifeng <weifeng.voon@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
drivers/net/ethernet/stmicro/stmmac/hwif.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index d065b11b7b1006f0ed50472a1c6dd2ccdeb3e2e8..5afb36a5c94ccfe5e32904e765559eb43e2568db 100644 (file)
@@ -309,6 +309,12 @@ enum dma_irq_status {
        handle_tx = 0x8,
 };
 
+enum dma_irq_dir {
+       DMA_DIR_RX = 0x1,
+       DMA_DIR_TX = 0x2,
+       DMA_DIR_RXTX = 0x3,
+};
+
 /* EEE and LPI defines */
 #define        CORE_IRQ_TX_PATH_IN_LPI_MODE    (1 << 0)
 #define        CORE_IRQ_TX_PATH_EXIT_LPI_MODE  (1 << 1)
index e62efd166ec8f3a13be5f23bbe80c5c6ac6abc10..19e7ec30af4ca3d1577dca09b826873f54aa9e4a 100644 (file)
@@ -239,6 +239,22 @@ static const struct emac_variant emac_variant_h6 = {
 #define EMAC_RX_EARLY_INT       BIT(13)
 #define EMAC_RGMII_STA_INT      BIT(16)
 
+#define EMAC_INT_MSK_COMMON    EMAC_RGMII_STA_INT
+#define EMAC_INT_MSK_TX                (EMAC_TX_INT | \
+                                EMAC_TX_DMA_STOP_INT | \
+                                EMAC_TX_BUF_UA_INT | \
+                                EMAC_TX_TIMEOUT_INT | \
+                                EMAC_TX_UNDERFLOW_INT | \
+                                EMAC_TX_EARLY_INT |\
+                                EMAC_INT_MSK_COMMON)
+#define EMAC_INT_MSK_RX                (EMAC_RX_INT | \
+                                EMAC_RX_BUF_UA_INT | \
+                                EMAC_RX_DMA_STOP_INT | \
+                                EMAC_RX_TIMEOUT_INT | \
+                                EMAC_RX_OVERFLOW_INT | \
+                                EMAC_RX_EARLY_INT | \
+                                EMAC_INT_MSK_COMMON)
+
 #define MAC_ADDR_TYPE_DST BIT(31)
 
 /* H3 specific bits for EPHY */
@@ -412,13 +428,19 @@ static void sun8i_dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan)
 }
 
 static int sun8i_dwmac_dma_interrupt(void __iomem *ioaddr,
-                                    struct stmmac_extra_stats *x, u32 chan)
+                                    struct stmmac_extra_stats *x, u32 chan,
+                                    u32 dir)
 {
        u32 v;
        int ret = 0;
 
        v = readl(ioaddr + EMAC_INT_STA);
 
+       if (dir == DMA_DIR_RX)
+               v &= EMAC_INT_MSK_RX;
+       else if (dir == DMA_DIR_TX)
+               v &= EMAC_INT_MSK_TX;
+
        if (v & EMAC_TX_INT) {
                ret |= handle_tx;
                x->tx_normal_irq_n++;
index 8391ca63d9437b4ea32f9ad03840e06bf5f972f1..5c0c53832adb1f33ed4233b2af445c6eb4f18772 100644 (file)
 #define DMA_CHAN_STATUS_TPS            BIT(1)
 #define DMA_CHAN_STATUS_TI             BIT(0)
 
+#define DMA_CHAN_STATUS_MSK_COMMON     (DMA_CHAN_STATUS_NIS | \
+                                        DMA_CHAN_STATUS_AIS | \
+                                        DMA_CHAN_STATUS_CDE | \
+                                        DMA_CHAN_STATUS_FBE)
+
+#define DMA_CHAN_STATUS_MSK_RX         (DMA_CHAN_STATUS_REB | \
+                                        DMA_CHAN_STATUS_ERI | \
+                                        DMA_CHAN_STATUS_RWT | \
+                                        DMA_CHAN_STATUS_RPS | \
+                                        DMA_CHAN_STATUS_RBU | \
+                                        DMA_CHAN_STATUS_RI | \
+                                        DMA_CHAN_STATUS_MSK_COMMON)
+
+#define DMA_CHAN_STATUS_MSK_TX         (DMA_CHAN_STATUS_ETI | \
+                                        DMA_CHAN_STATUS_TBU | \
+                                        DMA_CHAN_STATUS_TPS | \
+                                        DMA_CHAN_STATUS_TI | \
+                                        DMA_CHAN_STATUS_MSK_COMMON)
+
 /* Interrupt enable bits per channel */
 #define DMA_CHAN_INTR_ENA_NIE          BIT(16)
 #define DMA_CHAN_INTR_ENA_AIE          BIT(15)
@@ -206,7 +225,7 @@ void dwmac4_dma_stop_tx(void __iomem *ioaddr, u32 chan);
 void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan);
 void dwmac4_dma_stop_rx(void __iomem *ioaddr, u32 chan);
 int dwmac4_dma_interrupt(void __iomem *ioaddr,
-                        struct stmmac_extra_stats *x, u32 chan);
+                        struct stmmac_extra_stats *x, u32 chan, u32 dir);
 void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan);
 void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len, u32 chan);
 void dwmac4_set_rx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
index 71e50751ef2dc2c6ba3d1a133edb3663dc5a6968..3fa602dabf49ac9f11fc7cfdbcfe3b0fc0038a2f 100644 (file)
@@ -135,12 +135,17 @@ void dwmac410_disable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
 }
 
 int dwmac4_dma_interrupt(void __iomem *ioaddr,
-                        struct stmmac_extra_stats *x, u32 chan)
+                        struct stmmac_extra_stats *x, u32 chan, u32 dir)
 {
        u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(chan));
        u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(chan));
        int ret = 0;
 
+       if (dir == DMA_DIR_RX)
+               intr_status &= DMA_CHAN_STATUS_MSK_RX;
+       else if (dir == DMA_DIR_TX)
+               intr_status &= DMA_CHAN_STATUS_MSK_TX;
+
        /* ABNORMAL interrupts */
        if (unlikely(intr_status & DMA_CHAN_STATUS_AIS)) {
                if (unlikely(intr_status & DMA_CHAN_STATUS_RBU))
index e5dbd0bc257e7a1d8136bca183f972be4f75740b..1914ad698cab24e4df398cbafd3e40d677a50d02 100644 (file)
 #define DMA_STATUS_TI  0x00000001      /* Transmit Interrupt */
 #define DMA_CONTROL_FTF                0x00100000      /* Flush transmit FIFO */
 
+#define DMA_STATUS_MSK_COMMON          (DMA_STATUS_NIS | \
+                                        DMA_STATUS_AIS | \
+                                        DMA_STATUS_FBI)
+
+#define DMA_STATUS_MSK_RX              (DMA_STATUS_ERI | \
+                                        DMA_STATUS_RWT | \
+                                        DMA_STATUS_RPS | \
+                                        DMA_STATUS_RU | \
+                                        DMA_STATUS_RI | \
+                                        DMA_STATUS_OVF | \
+                                        DMA_STATUS_MSK_COMMON)
+
+#define DMA_STATUS_MSK_TX              (DMA_STATUS_ETI | \
+                                        DMA_STATUS_UNF | \
+                                        DMA_STATUS_TJT | \
+                                        DMA_STATUS_TU | \
+                                        DMA_STATUS_TPS | \
+                                        DMA_STATUS_TI | \
+                                        DMA_STATUS_MSK_COMMON)
+
 #define NUM_DWMAC100_DMA_REGS  9
 #define NUM_DWMAC1000_DMA_REGS 23
 
@@ -139,7 +159,7 @@ void dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan);
 void dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan);
 void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan);
 int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x,
-                       u32 chan);
+                       u32 chan, u32 dir);
 int dwmac_dma_reset(void __iomem *ioaddr);
 
 #endif /* __DWMAC_DMA_H__ */
index 57a53a600aa556672c82b12d40f4a35bc572187d..d1c31200bb9111d66613bd86f85bbc09afe22cc9 100644 (file)
@@ -155,7 +155,7 @@ static void show_rx_process_state(unsigned int status)
 #endif
 
 int dwmac_dma_interrupt(void __iomem *ioaddr,
-                       struct stmmac_extra_stats *x, u32 chan)
+                       struct stmmac_extra_stats *x, u32 chan, u32 dir)
 {
        int ret = 0;
        /* read the status register (CSR5) */
@@ -167,6 +167,12 @@ int dwmac_dma_interrupt(void __iomem *ioaddr,
        show_tx_process_state(intr_status);
        show_rx_process_state(intr_status);
 #endif
+
+       if (dir == DMA_DIR_RX)
+               intr_status &= DMA_STATUS_MSK_RX;
+       else if (dir == DMA_DIR_TX)
+               intr_status &= DMA_STATUS_MSK_TX;
+
        /* ABNORMAL interrupts */
        if (unlikely(intr_status & DMA_STATUS_AIS)) {
                if (unlikely(intr_status & DMA_STATUS_UNF)) {
index 6c3b8a950f58d4dcb4857b6d9a307d604e7024a6..1913385df6856a26ad6915471bd7943de19aba44 100644 (file)
 #define XGMAC_TI                       BIT(0)
 #define XGMAC_REGSIZE                  ((0x0000317c + (0x80 * 15)) / 4)
 
+#define XGMAC_DMA_STATUS_MSK_COMMON    (XGMAC_NIS | XGMAC_AIS | XGMAC_FBE)
+#define XGMAC_DMA_STATUS_MSK_RX                (XGMAC_RBU | XGMAC_RI | \
+                                        XGMAC_DMA_STATUS_MSK_COMMON)
+#define XGMAC_DMA_STATUS_MSK_TX                (XGMAC_TBU | XGMAC_TPS | XGMAC_TI | \
+                                        XGMAC_DMA_STATUS_MSK_COMMON)
+
 /* Descriptors */
 #define XGMAC_TDES0_LTV                        BIT(31)
 #define XGMAC_TDES0_LT                 GENMASK(7, 0)
index f2cab5b767320a1959a0d12fad3b3da4b8dd6718..906e985441a93b17c11bb89bd8554ad4961fa917 100644 (file)
@@ -323,12 +323,18 @@ static void dwxgmac2_dma_stop_rx(void __iomem *ioaddr, u32 chan)
 }
 
 static int dwxgmac2_dma_interrupt(void __iomem *ioaddr,
-                                 struct stmmac_extra_stats *x, u32 chan)
+                                 struct stmmac_extra_stats *x, u32 chan,
+                                 u32 dir)
 {
        u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
        u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
        int ret = 0;
 
+       if (dir == DMA_DIR_RX)
+               intr_status &= XGMAC_DMA_STATUS_MSK_RX;
+       else if (dir == DMA_DIR_TX)
+               intr_status &= XGMAC_DMA_STATUS_MSK_TX;
+
        /* ABNORMAL interrupts */
        if (unlikely(intr_status & XGMAC_AIS)) {
                if (unlikely(intr_status & XGMAC_RBU)) {
index 45edac5f60db6fac4bf26640bd337e398d0f6888..c9cf89e21a411019908ac30d862f8f8f2789fe55 100644 (file)
@@ -201,7 +201,7 @@ struct stmmac_dma_ops {
        void (*start_rx)(void __iomem *ioaddr, u32 chan);
        void (*stop_rx)(void __iomem *ioaddr, u32 chan);
        int (*dma_interrupt) (void __iomem *ioaddr,
-                             struct stmmac_extra_stats *x, u32 chan);
+                             struct stmmac_extra_stats *x, u32 chan, u32 dir);
        /* If supported then get the optional core features */
        void (*get_hw_feature)(void __iomem *ioaddr,
                               struct dma_features *dma_cap);
index 170296820af019ff2c342ef4932a3c8fb68c382b..7c352d017eb2ae75611467934baaea3adf108830 100644 (file)
@@ -2337,10 +2337,10 @@ static bool stmmac_safety_feat_interrupt(struct stmmac_priv *priv)
        return false;
 }
 
-static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan)
+static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan, u32 dir)
 {
        int status = stmmac_dma_interrupt_status(priv, priv->ioaddr,
-                                                &priv->xstats, chan);
+                                                &priv->xstats, chan, dir);
        struct stmmac_channel *ch = &priv->channel[chan];
        unsigned long flags;
 
@@ -2386,7 +2386,8 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
                channels_to_check = ARRAY_SIZE(status);
 
        for (chan = 0; chan < channels_to_check; chan++)
-               status[chan] = stmmac_napi_check(priv, chan);
+               status[chan] = stmmac_napi_check(priv, chan,
+                                                DMA_DIR_RXTX);
 
        for (chan = 0; chan < tx_channel_count; chan++) {
                if (unlikely(status[chan] & tx_hard_error_bump_tc)) {