[PATCH 04/16] net: stmmac: Introduce DMA core cleanup method

Serge Semin Sergey.Semin at baikalelectronics.ru
Mon Feb 8 09:08:08 EST 2021


Similarly to the MAC core cleanup method let's introduce the DMA core
cleanup method, since we need have a way to get the DMA registers back
to their initial state while the whole interface reset is unavailable for
the particular DW MAC IP-core setup, like in case of GPIs and GPOs
support.

For now we've created the DMA cleanup method for the DW GMAC IP only,
since the chip we've got has been equipped with that IP and we lack the
documents to add and test the rest of the IPs support.

Signed-off-by: Serge Semin <Sergey.Semin at baikalelectronics.ru>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c |  1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h     |  1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c     | 12 ++++++++++++
 drivers/net/ethernet/stmicro/stmmac/hwif.h          |  3 +++
 4 files changed, 17 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 2a04d9d45160..bae63e1420f2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -246,6 +246,7 @@ static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
 
 const struct stmmac_dma_ops dwmac1000_dma_ops = {
 	.reset = dwmac_dma_reset,
+	.clean = dwmac_dma_clean,
 	.init = dwmac1000_dma_init,
 	.init_rx_chan = dwmac_dma_init_rx,
 	.init_tx_chan = dwmac_dma_init_tx,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index fa919bf75e19..f6e759d039d7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -145,5 +145,6 @@ void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan);
 int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x,
 			u32 chan);
 int dwmac_dma_reset(void __iomem *ioaddr);
+void dwmac_dma_clean(void __iomem *ioaddr);
 
 #endif /* __DWMAC_DMA_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index 6ddfc689e77b..2186e95d5aa4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -26,6 +26,18 @@ int dwmac_dma_reset(void __iomem *ioaddr)
 				 10000, 200000);
 }
 
+void dwmac_dma_clean(void __iomem *ioaddr)
+{
+	/* Clean the basic DMA registers up */
+	writel(0, ioaddr + DMA_INTR_ENA);
+	writel(0x00020100, ioaddr + DMA_BUS_MODE);
+	writel(0, ioaddr + DMA_RCV_BASE_ADDR);
+	writel(0, ioaddr + DMA_TX_BASE_ADDR);
+	writel(0x00100000, ioaddr + DMA_CONTROL);
+	writel(0x00110001, ioaddr + DMA_AXI_BUS_MODE);
+	writel(0x0001FFFF, ioaddr + DMA_STATUS);
+}
+
 /* CSR1 enables the transmit DMA to check for new descriptor */
 void dwmac_enable_dma_transmission(void __iomem *ioaddr)
 {
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 3f5eed8333a5..dea5a4d17677 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -169,6 +169,7 @@ struct dma_features;
 struct stmmac_dma_ops {
 	/* DMA core initialization */
 	int (*reset)(void __iomem *ioaddr);
+	void (*clean)(void __iomem *ioaddr);
 	void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg,
 		     int atds);
 	void (*init_chan)(void __iomem *ioaddr,
@@ -219,6 +220,8 @@ struct stmmac_dma_ops {
 
 #define stmmac_reset(__priv, __args...) \
 	stmmac_do_callback(__priv, dma, reset, __args)
+#define stmmac_dma_clean(__priv, __args...) \
+	stmmac_do_void_callback(__priv, dma, clean, __args)
 #define stmmac_dma_init(__priv, __args...) \
 	stmmac_do_void_callback(__priv, dma, init, __args)
 #define stmmac_init_chan(__priv, __args...) \
-- 
2.29.2




More information about the linux-arm-kernel mailing list