Commit 7e1c520c authored by Ong Boon Leong's avatar Ong Boon Leong Committed by David S. Miller
Browse files

net: stmmac: introduce DMA interrupt status masking per traffic direction



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: default avatarOng Boon Leong <boon.leong.ong@intel.com>
Signed-off-by: default avatarVoon Weifeng <weifeng.voon@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6c996e19
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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)
+23 −1
Original line number Diff line number Diff line
@@ -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++;
+20 −1
Original line number Diff line number Diff line
@@ -149,6 +149,25 @@
#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);
+6 −1
Original line number Diff line number Diff line
@@ -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))
+21 −1
Original line number Diff line number Diff line
@@ -128,6 +128,26 @@
#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__ */
Loading