Netdev Archive mirror
 help / color / mirror / Atom feed
* [PATCH, net-next, 0/2] net: stmmac: support for BCM8958x SoC
@ 2024-05-10  0:03 Jitendra Vegiraju
  2024-05-10  0:03 ` [PATCH, net-next, 1/2] net: stmmac: Export dma_ops for reuse in glue drivers Jitendra Vegiraju
  2024-05-10  0:03 ` [PATCH, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC Jitendra Vegiraju
  0 siblings, 2 replies; 23+ messages in thread
From: Jitendra Vegiraju @ 2024-05-10  0:03 UTC (permalink / raw
  To: netdev
  Cc: jitendra.vegiraju, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list

This patchseries adds PCI driver support for Broadcom BCM8958x SoC devices.
BCM8958x core functionality is similar to existing dwxgmac2 implementation.
However, there are minor conflicting differences in dma operations.

This driver will utilize dwxgmac2 core functions as much possible and
implement alternative functions wherever functionality differs.

Jitendra Vegiraju (2):
  Export dma_ops for reuse in glue drivers.
  PCI driver for BCM8958X SoC

 MAINTAINERS                                   |   7 +
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 +
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../net/ethernet/stmicro/stmmac/dwmac-brcm.c  | 657 ++++++++++++++++++
 .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  62 ++
 .../ethernet/stmicro/stmmac/dwxgmac2_dma.c    | 149 ++--
 6 files changed, 826 insertions(+), 61 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c

-- 
2.25.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH, net-next, 1/2] net: stmmac: Export dma_ops for reuse in glue drivers.
  2024-05-10  0:03 [PATCH, net-next, 0/2] net: stmmac: support for BCM8958x SoC Jitendra Vegiraju
@ 2024-05-10  0:03 ` Jitendra Vegiraju
  2024-05-10  0:03 ` [PATCH, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC Jitendra Vegiraju
  1 sibling, 0 replies; 23+ messages in thread
From: Jitendra Vegiraju @ 2024-05-10  0:03 UTC (permalink / raw
  To: netdev
  Cc: jitendra.vegiraju, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list

In preparation for adding a new glue driver that relies on common
functionality provide by dwxgmac2 core functions.
The new device is mostly similar to dwxgmac2 implementation but,
with minor conflicting differences in certain operations.

By exporting the dwxgmac2 dma operations, new glue drivers
can reuse common functions.

Signed-off-by: Jitendra Vegiraju <jitendra.vegiraju@broadcom.com>
---
 .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  62 ++++++++
 .../ethernet/stmicro/stmmac/dwxgmac2_dma.c    | 149 +++++++++++-------
 2 files changed, 150 insertions(+), 61 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 6a2c7d22df1e..d4aa8e290ca1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -495,4 +495,66 @@
 #define XGMAC_RDES3_TSD			BIT(6)
 #define XGMAC_RDES3_TSA			BIT(4)
 
+int dwxgmac2_dma_reset(void __iomem *ioaddr);
+void dwxgmac2_dma_init(void __iomem *ioaddr,
+		       struct stmmac_dma_cfg *dma_cfg, int atds);
+void dwxgmac2_dma_init_chan(struct stmmac_priv *priv,
+			    void __iomem *ioaddr,
+			    struct stmmac_dma_cfg *dma_cfg, u32 chan);
+void dwxgmac2_dma_init_rx_chan(struct stmmac_priv *priv,
+			       void __iomem *ioaddr,
+			       struct stmmac_dma_cfg *dma_cfg,
+			       dma_addr_t phy, u32 chan);
+void dwxgmac2_dma_init_tx_chan(struct stmmac_priv *priv,
+			       void __iomem *ioaddr,
+			       struct stmmac_dma_cfg *dma_cfg,
+			       dma_addr_t phy, u32 chan);
+void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi);
+void dwxgmac2_dma_dump_regs(struct stmmac_priv *priv,
+			    void __iomem *ioaddr, u32 *reg_space);
+void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+			  int mode, u32 channel, int fifosz, u8 qmode);
+void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+			  int mode, u32 channel, int fifosz, u8 qmode);
+void dwxgmac2_enable_dma_irq(struct stmmac_priv *priv,
+			     void __iomem *ioaddr, u32 chan,
+			     bool rx, bool tx);
+void dwxgmac2_disable_dma_irq(struct stmmac_priv *priv,
+			      void __iomem *ioaddr, u32 chan,
+			      bool rx, bool tx);
+void dwxgmac2_dma_start_tx(struct stmmac_priv *priv,
+			   void __iomem *ioaddr, u32 chan);
+void dwxgmac2_dma_stop_tx(struct stmmac_priv *priv, void __iomem *ioaddr,
+			  u32 chan);
+void dwxgmac2_dma_start_rx(struct stmmac_priv *priv,
+			   void __iomem *ioaddr, u32 chan);
+void dwxgmac2_dma_stop_rx(struct stmmac_priv *priv, void __iomem *ioaddr,
+			  u32 chan);
+int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
+			   void __iomem *ioaddr,
+			   struct stmmac_extra_stats *x, u32 chan,
+			   u32 dir);
+int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+			    struct dma_features *dma_cap);
+void dwxgmac2_rx_watchdog(struct stmmac_priv *priv, void __iomem *ioaddr,
+			  u32 riwt, u32 queue);
+void dwxgmac2_set_rx_ring_len(struct stmmac_priv *priv,
+			      void __iomem *ioaddr, u32 len, u32 chan);
+void dwxgmac2_set_tx_ring_len(struct stmmac_priv *priv,
+			      void __iomem *ioaddr, u32 len, u32 chan);
+void dwxgmac2_set_rx_tail_ptr(struct stmmac_priv *priv,
+			      void __iomem *ioaddr, u32 ptr, u32 chan);
+void dwxgmac2_set_tx_tail_ptr(struct stmmac_priv *priv,
+			      void __iomem *ioaddr, u32 ptr, u32 chan);
+void dwxgmac2_enable_tso(struct stmmac_priv *priv, void __iomem *ioaddr,
+			 bool en, u32 chan);
+void dwxgmac2_qmode(struct stmmac_priv *priv, void __iomem *ioaddr,
+		    u32 channel, u8 qmode);
+void dwxgmac2_set_bfsize(struct stmmac_priv *priv, void __iomem *ioaddr,
+			 int bfsize, u32 chan);
+void dwxgmac2_enable_sph(struct stmmac_priv *priv, void __iomem *ioaddr,
+			 bool en, u32 chan);
+int dwxgmac2_enable_tbs(struct stmmac_priv *priv, void __iomem *ioaddr,
+			bool en, u32 chan);
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
index dd2ab6185c40..f437b63f57b9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -8,7 +8,7 @@
 #include "stmmac.h"
 #include "dwxgmac2.h"
 
-static int dwxgmac2_dma_reset(void __iomem *ioaddr)
+int dwxgmac2_dma_reset(void __iomem *ioaddr)
 {
 	u32 value = readl(ioaddr + XGMAC_DMA_MODE);
 
@@ -18,9 +18,10 @@ static int dwxgmac2_dma_reset(void __iomem *ioaddr)
 	return readl_poll_timeout(ioaddr + XGMAC_DMA_MODE, value,
 				  !(value & XGMAC_SWR), 0, 100000);
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_reset);
 
-static void dwxgmac2_dma_init(void __iomem *ioaddr,
-			      struct stmmac_dma_cfg *dma_cfg, int atds)
+void dwxgmac2_dma_init(void __iomem *ioaddr,
+		       struct stmmac_dma_cfg *dma_cfg, int atds)
 {
 	u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
 
@@ -32,10 +33,11 @@ static void dwxgmac2_dma_init(void __iomem *ioaddr,
 
 	writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_init);
 
-static void dwxgmac2_dma_init_chan(struct stmmac_priv *priv,
-				   void __iomem *ioaddr,
-				   struct stmmac_dma_cfg *dma_cfg, u32 chan)
+void dwxgmac2_dma_init_chan(struct stmmac_priv *priv,
+			    void __iomem *ioaddr,
+			    struct stmmac_dma_cfg *dma_cfg, u32 chan)
 {
 	u32 value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan));
 
@@ -45,11 +47,12 @@ static void dwxgmac2_dma_init_chan(struct stmmac_priv *priv,
 	writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
 	writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_init_chan);
 
-static void dwxgmac2_dma_init_rx_chan(struct stmmac_priv *priv,
-				      void __iomem *ioaddr,
-				      struct stmmac_dma_cfg *dma_cfg,
-				      dma_addr_t phy, u32 chan)
+void dwxgmac2_dma_init_rx_chan(struct stmmac_priv *priv,
+			       void __iomem *ioaddr,
+			       struct stmmac_dma_cfg *dma_cfg,
+			       dma_addr_t phy, u32 chan)
 {
 	u32 rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
 	u32 value;
@@ -62,11 +65,12 @@ static void dwxgmac2_dma_init_rx_chan(struct stmmac_priv *priv,
 	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chan));
 	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_init_rx_chan);
 
-static void dwxgmac2_dma_init_tx_chan(struct stmmac_priv *priv,
-				      void __iomem *ioaddr,
-				      struct stmmac_dma_cfg *dma_cfg,
-				      dma_addr_t phy, u32 chan)
+void dwxgmac2_dma_init_tx_chan(struct stmmac_priv *priv,
+			       void __iomem *ioaddr,
+			       struct stmmac_dma_cfg *dma_cfg,
+			       dma_addr_t phy, u32 chan)
 {
 	u32 txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
 	u32 value;
@@ -80,8 +84,9 @@ static void dwxgmac2_dma_init_tx_chan(struct stmmac_priv *priv,
 	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chan));
 	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_init_tx_chan);
 
-static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
+void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
 {
 	u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
 	int i;
@@ -133,18 +138,20 @@ static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
 	writel(XGMAC_TDPS, ioaddr + XGMAC_TX_EDMA_CTRL);
 	writel(XGMAC_RDPS, ioaddr + XGMAC_RX_EDMA_CTRL);
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_axi);
 
-static void dwxgmac2_dma_dump_regs(struct stmmac_priv *priv,
-				   void __iomem *ioaddr, u32 *reg_space)
+void dwxgmac2_dma_dump_regs(struct stmmac_priv *priv,
+			    void __iomem *ioaddr, u32 *reg_space)
 {
 	int i;
 
 	for (i = (XGMAC_DMA_MODE / 4); i < XGMAC_REGSIZE; i++)
 		reg_space[i] = readl(ioaddr + i * 4);
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_dump_regs);
 
-static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
-				 int mode, u32 channel, int fifosz, u8 qmode)
+void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+			  int mode, u32 channel, int fifosz, u8 qmode)
 {
 	u32 value = readl(ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
 	unsigned int rqs = fifosz / 256 - 1;
@@ -208,9 +215,10 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
 	value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
 	writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_rx_mode);
 
-static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
-				 int mode, u32 channel, int fifosz, u8 qmode)
+void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+			  int mode, u32 channel, int fifosz, u8 qmode)
 {
 	u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
 	unsigned int tqs = fifosz / 256 - 1;
@@ -251,10 +259,11 @@ static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
 
 	writel(value, ioaddr +  XGMAC_MTL_TXQ_OPMODE(channel));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_tx_mode);
 
-static void dwxgmac2_enable_dma_irq(struct stmmac_priv *priv,
-				    void __iomem *ioaddr, u32 chan,
-				    bool rx, bool tx)
+void dwxgmac2_enable_dma_irq(struct stmmac_priv *priv,
+			     void __iomem *ioaddr, u32 chan,
+			     bool rx, bool tx)
 {
 	u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
 
@@ -265,10 +274,11 @@ static void dwxgmac2_enable_dma_irq(struct stmmac_priv *priv,
 
 	writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_enable_dma_irq);
 
-static void dwxgmac2_disable_dma_irq(struct stmmac_priv *priv,
-				     void __iomem *ioaddr, u32 chan,
-				     bool rx, bool tx)
+void dwxgmac2_disable_dma_irq(struct stmmac_priv *priv,
+			      void __iomem *ioaddr, u32 chan,
+			      bool rx, bool tx)
 {
 	u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
 
@@ -279,9 +289,10 @@ static void dwxgmac2_disable_dma_irq(struct stmmac_priv *priv,
 
 	writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_disable_dma_irq);
 
-static void dwxgmac2_dma_start_tx(struct stmmac_priv *priv,
-				  void __iomem *ioaddr, u32 chan)
+void dwxgmac2_dma_start_tx(struct stmmac_priv *priv,
+			   void __iomem *ioaddr, u32 chan)
 {
 	u32 value;
 
@@ -293,9 +304,10 @@ static void dwxgmac2_dma_start_tx(struct stmmac_priv *priv,
 	value |= XGMAC_CONFIG_TE;
 	writel(value, ioaddr + XGMAC_TX_CONFIG);
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_start_tx);
 
-static void dwxgmac2_dma_stop_tx(struct stmmac_priv *priv, void __iomem *ioaddr,
-				 u32 chan)
+void dwxgmac2_dma_stop_tx(struct stmmac_priv *priv, void __iomem *ioaddr,
+			  u32 chan)
 {
 	u32 value;
 
@@ -307,9 +319,10 @@ static void dwxgmac2_dma_stop_tx(struct stmmac_priv *priv, void __iomem *ioaddr,
 	value &= ~XGMAC_CONFIG_TE;
 	writel(value, ioaddr + XGMAC_TX_CONFIG);
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_stop_tx);
 
-static void dwxgmac2_dma_start_rx(struct stmmac_priv *priv,
-				  void __iomem *ioaddr, u32 chan)
+void dwxgmac2_dma_start_rx(struct stmmac_priv *priv,
+			   void __iomem *ioaddr, u32 chan)
 {
 	u32 value;
 
@@ -321,9 +334,10 @@ static void dwxgmac2_dma_start_rx(struct stmmac_priv *priv,
 	value |= XGMAC_CONFIG_RE;
 	writel(value, ioaddr + XGMAC_RX_CONFIG);
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_start_rx);
 
-static void dwxgmac2_dma_stop_rx(struct stmmac_priv *priv, void __iomem *ioaddr,
-				 u32 chan)
+void dwxgmac2_dma_stop_rx(struct stmmac_priv *priv, void __iomem *ioaddr,
+			  u32 chan)
 {
 	u32 value;
 
@@ -331,11 +345,12 @@ static void dwxgmac2_dma_stop_rx(struct stmmac_priv *priv, void __iomem *ioaddr,
 	value &= ~XGMAC_RXST;
 	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_stop_rx);
 
-static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
-				  void __iomem *ioaddr,
-				  struct stmmac_extra_stats *x, u32 chan,
-				  u32 dir)
+int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
+			   void __iomem *ioaddr,
+			   struct stmmac_extra_stats *x, u32 chan,
+			   u32 dir)
 {
 	struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
 	u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
@@ -384,9 +399,10 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_dma_interrupt);
 
-static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
-				   struct dma_features *dma_cap)
+int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+			    struct dma_features *dma_cap)
 {
 	u32 hw_cap;
 
@@ -499,39 +515,45 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_get_hw_feature);
 
-static void dwxgmac2_rx_watchdog(struct stmmac_priv *priv, void __iomem *ioaddr,
-				 u32 riwt, u32 queue)
+void dwxgmac2_rx_watchdog(struct stmmac_priv *priv, void __iomem *ioaddr,
+			  u32 riwt, u32 queue)
 {
 	writel(riwt & XGMAC_RWT, ioaddr + XGMAC_DMA_CH_Rx_WATCHDOG(queue));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_rx_watchdog);
 
-static void dwxgmac2_set_rx_ring_len(struct stmmac_priv *priv,
-				     void __iomem *ioaddr, u32 len, u32 chan)
+void dwxgmac2_set_rx_ring_len(struct stmmac_priv *priv,
+			      void __iomem *ioaddr, u32 len, u32 chan)
 {
 	writel(len, ioaddr + XGMAC_DMA_CH_RxDESC_RING_LEN(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_set_rx_ring_len);
 
-static void dwxgmac2_set_tx_ring_len(struct stmmac_priv *priv,
-				     void __iomem *ioaddr, u32 len, u32 chan)
+void dwxgmac2_set_tx_ring_len(struct stmmac_priv *priv,
+			      void __iomem *ioaddr, u32 len, u32 chan)
 {
 	writel(len, ioaddr + XGMAC_DMA_CH_TxDESC_RING_LEN(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_set_tx_ring_len);
 
-static void dwxgmac2_set_rx_tail_ptr(struct stmmac_priv *priv,
-				     void __iomem *ioaddr, u32 ptr, u32 chan)
+void dwxgmac2_set_rx_tail_ptr(struct stmmac_priv *priv,
+			      void __iomem *ioaddr, u32 ptr, u32 chan)
 {
 	writel(ptr, ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_set_rx_tail_ptr);
 
-static void dwxgmac2_set_tx_tail_ptr(struct stmmac_priv *priv,
-				     void __iomem *ioaddr, u32 ptr, u32 chan)
+void dwxgmac2_set_tx_tail_ptr(struct stmmac_priv *priv,
+			      void __iomem *ioaddr, u32 ptr, u32 chan)
 {
 	writel(ptr, ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_set_tx_tail_ptr);
 
-static void dwxgmac2_enable_tso(struct stmmac_priv *priv, void __iomem *ioaddr,
-				bool en, u32 chan)
+void dwxgmac2_enable_tso(struct stmmac_priv *priv, void __iomem *ioaddr,
+			 bool en, u32 chan)
 {
 	u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
 
@@ -542,9 +564,10 @@ static void dwxgmac2_enable_tso(struct stmmac_priv *priv, void __iomem *ioaddr,
 
 	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_enable_tso);
 
-static void dwxgmac2_qmode(struct stmmac_priv *priv, void __iomem *ioaddr,
-			   u32 channel, u8 qmode)
+void dwxgmac2_qmode(struct stmmac_priv *priv, void __iomem *ioaddr,
+		    u32 channel, u8 qmode)
 {
 	u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
 	u32 flow = readl(ioaddr + XGMAC_RX_FLOW_CTRL);
@@ -560,9 +583,10 @@ static void dwxgmac2_qmode(struct stmmac_priv *priv, void __iomem *ioaddr,
 
 	writel(value, ioaddr +  XGMAC_MTL_TXQ_OPMODE(channel));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_qmode);
 
-static void dwxgmac2_set_bfsize(struct stmmac_priv *priv, void __iomem *ioaddr,
-				int bfsize, u32 chan)
+void dwxgmac2_set_bfsize(struct stmmac_priv *priv, void __iomem *ioaddr,
+			 int bfsize, u32 chan)
 {
 	u32 value;
 
@@ -571,9 +595,10 @@ static void dwxgmac2_set_bfsize(struct stmmac_priv *priv, void __iomem *ioaddr,
 	value |= bfsize << XGMAC_RBSZ_SHIFT;
 	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_set_bfsize);
 
-static void dwxgmac2_enable_sph(struct stmmac_priv *priv, void __iomem *ioaddr,
-				bool en, u32 chan)
+void dwxgmac2_enable_sph(struct stmmac_priv *priv, void __iomem *ioaddr,
+			 bool en, u32 chan)
 {
 	u32 value = readl(ioaddr + XGMAC_RX_CONFIG);
 
@@ -588,9 +613,10 @@ static void dwxgmac2_enable_sph(struct stmmac_priv *priv, void __iomem *ioaddr,
 		value &= ~XGMAC_SPH;
 	writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_enable_sph);
 
-static int dwxgmac2_enable_tbs(struct stmmac_priv *priv, void __iomem *ioaddr,
-			       bool en, u32 chan)
+int dwxgmac2_enable_tbs(struct stmmac_priv *priv, void __iomem *ioaddr,
+			bool en, u32 chan)
 {
 	u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
 
@@ -611,6 +637,7 @@ static int dwxgmac2_enable_tbs(struct stmmac_priv *priv, void __iomem *ioaddr,
 	writel(XGMAC_DEF_FTOS, ioaddr + XGMAC_DMA_TBS_CTRL3);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dwxgmac2_enable_tbs);
 
 const struct stmmac_dma_ops dwxgmac210_dma_ops = {
 	.reset = dwxgmac2_dma_reset,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-10  0:03 [PATCH, net-next, 0/2] net: stmmac: support for BCM8958x SoC Jitendra Vegiraju
  2024-05-10  0:03 ` [PATCH, net-next, 1/2] net: stmmac: Export dma_ops for reuse in glue drivers Jitendra Vegiraju
@ 2024-05-10  0:03 ` Jitendra Vegiraju
  2024-05-11  1:35   ` Jakub Kicinski
                     ` (2 more replies)
  1 sibling, 3 replies; 23+ messages in thread
From: Jitendra Vegiraju @ 2024-05-10  0:03 UTC (permalink / raw
  To: netdev
  Cc: jitendra.vegiraju, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list

Broadcom BCM8958X SoCs use Synopsys XGMAC design, which is similar to
dwxgmac2 core implementation in stmmac driver. The existing dwxgmac2 dma
operation functions have some conflicting differences with BCM8958X.
This glue driver attempts to reuse dwxgmac2 implementation wherever
possible, adding alternative implementations where necessary.

Signed-off-by: Jitendra Vegiraju <jitendra.vegiraju@broadcom.com>
---
 MAINTAINERS                                   |   7 +
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 +
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../net/ethernet/stmicro/stmmac/dwmac-brcm.c  | 657 ++++++++++++++++++
 4 files changed, 676 insertions(+)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 294e472d7de8..8bf9df7028d6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4115,6 +4115,13 @@ N:	brcmstb
 N:	bcm7038
 N:	bcm7120
 
+BROADCOM BCM8958X ETHERNET DRIVER
+M:	Jitendra Vegiraju <jitendra.vegiraju@broadcom.com>
+R:	Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
+L:	netdev@vger.kernel.org
+S:	Maintained
+F:	drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c
+
 BROADCOM BCMBCA ARM ARCHITECTURE
 M:	William Zhang <william.zhang@broadcom.com>
 M:	Anand Gore <anand.gore@broadcom.com>
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 4ec61f1ee71a..6c06149712c8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -286,6 +286,17 @@ config DWMAC_LOONGSON
 	  This selects the LOONGSON PCI bus support for the stmmac driver,
 	  Support for ethernet controller on Loongson-2K1000 SoC and LS7A1000 bridge.
 
+config DWMAC_BRCM
+	tristate "Broadcom XGMAC support"
+	depends on STMMAC_ETH && PCI
+	depends on COMMON_CLK
+	help
+	  Support for ethernet controllers on Broadcom BCM8958x SoCs
+
+	  This selects Broadcom XGMAC specific PCI bus support for the
+	  stmmac driver. This driver provides the glue layer on top of the
+	  stmmac driver required for the Broadcom BCM8958x SoC devices.
+
 config STMMAC_PCI
 	tristate "STMMAC PCI bus support"
 	depends on STMMAC_ETH && PCI
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 26cad4344701..1cd0f508bafb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -40,4 +40,5 @@ dwmac-altr-socfpga-objs := dwmac-socfpga.o
 obj-$(CONFIG_STMMAC_PCI)	+= stmmac-pci.o
 obj-$(CONFIG_DWMAC_INTEL)	+= dwmac-intel.o
 obj-$(CONFIG_DWMAC_LOONGSON)	+= dwmac-loongson.o
+obj-$(CONFIG_DWMAC_BRCM)	+= dwmac-brcm.o
 stmmac-pci-objs:= stmmac_pci.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c
new file mode 100644
index 000000000000..86125f59a8ff
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c
@@ -0,0 +1,657 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Broadcom Corporation
+ * This file contains the functions to handle the Broadcom XGMAC PCI driver.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/dmi.h>
+#include <linux/pci.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
+
+#include "stmmac.h"
+#include "dwxgmac2.h"
+
+#define PCI_DEVICE_ID_BROADCOM_BCM8958X		0xa00d
+#define BRCM_MAX_MTU				1500
+#define READ_POLL_DELAY_US			100
+#define READ_POLL_TIMEOUT_US			10000
+#define DWMAC_125MHZ				125000000
+#define DWMAC_250MHZ				250000000
+
+/* TX and RX Queue couts */
+#define BRCM_TX_Q_COUNT				4
+#define BRCM_RX_Q_COUNT				1
+
+/* PDMA Channel counts */
+#define PDMA_TX_CH_COUNT			8
+#define PDMA_RX_CH_COUNT			10
+
+/* PDMA register type */
+#define PDMA_CH_TX_EXT_CFGR			0
+#define PDMA_CH_RX_EXT_CFGR			1
+#define PDMA_CH_TX_DBG_STSR			2
+#define PDMA_CH_RX_DBG_STSR			3
+
+/* VDMA register type */
+#define VDMA_CH_TX_DESC_CTRLR			4
+#define VDMA_CH_RX_DESC_CTRLR			5
+
+/* VDMA channel count */
+#define VDMA_TOTAL_CH_COUNT			32
+
+#define DMA_CH_IND_CTRLR			0x3080
+#define DMA_CH_IND_DATAR			0x3084
+
+#define BRCM_XGMAC_RX_CFG			0x2000
+#define BRCM_XGMAC_RXQ_CTRL1_CFG		0x8000
+
+#define BRCM_XGMAC_DMA_TX_SIZE			4096
+#define BRCM_XGMAC_DMA_RX_SIZE			4096
+#define BRCM_XGMAC_BAR0_MASK			BIT(0)
+
+#define BRCM_XGMAC_IOMEM_MISC_REG_OFFSET	0x0
+#define BRCM_XGMAC_IOMEM_MBOX_REG_OFFSET	0x1000
+#define BRCM_XGMAC_IOMEM_CFG_REG_OFFSET		0x3000
+
+#define XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_LOW	0x940
+#define XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_LO_VALUE	0x00000001
+#define XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_HIGH	0x944
+#define XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_HI_VALUE	0x88000000
+
+#define XGMAC_PCIE_MISC_MII_CTRL			0x4
+#define XGMAC_PCIE_MISC_MII_CTRL_VALUE			0x7
+#define XGMAC_PCIE_MISC_PCIESS_CTRL			0x8
+#define XGMAC_PCIE_MISC_PCIESS_CTRL_VALUE		0x200
+#define XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_LO		0x90
+#define XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_LO_VALUE	0x00000001
+#define XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_HI		0x94
+#define XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_HI_VALUE	0x88000000
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST0	0x700
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST0_VALUE	1
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST1	0x704
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST1_VALUE	1
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST_DBELL	0x728
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST_DBELL_VALUE	1
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_SBD_ALL		0x740
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_SBD_ALL_VALUE	0
+
+#define DMA_CH_IND_CTRLR_MSEL_OFF		24
+#define DMA_CH_IND_CTRLR_MSEL_MASK		GENMASK(27, 24)
+#define DMA_CH_IND_CTRLR_AOFF_OFF		8
+#define DMA_CH_IND_CTRLR_AOFF_MASK		GENMASK(14, 8)
+#define DMA_CH_IND_CTRLR_AUTO_OFF		4
+#define DMA_CH_IND_CTRLR_AUTO_MASK		GENMASK(5, 4)
+#define DMA_CH_IND_CTRLR_CT_OFF			1
+#define DMA_CH_IND_CTRLR_CT_MASK		BIT(1)
+#define DMA_CH_IND_CTRLR_OB_OFF			0
+#define DMA_CH_IND_CTRLR_OB_MASK		BIT(0)
+
+/* DMA Descriptor configuration */
+#define BRCM_PDMA_DESC_CTRL_CFG_VALUE		0x1B
+
+#define XGMAC_PCIE_MISC_FUNC_RESOURCES_PF0	0x804
+
+/* MSIX Vector map register starting offsets */
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_RX0_PF0	0x840
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_TX0_PF0	0x890
+#define BRCM_MAX_DMA_CHANNEL_PAIRS		4
+
+#define BRCM_XGMAC_MSI_MAC_VECTOR		0
+#define BRCM_XGMAC_MSI_RX_VECTOR_START		9
+#define BRCM_XGMAC_MSI_TX_VECTOR_START		10
+
+static int num_instances;
+
+struct brcm_priv_data {
+	struct phy_device *phy_dev;
+	void __iomem *mbox_regs;    /* MBOX */
+	void __iomem *misc_regs;    /* MISC_cfg */
+	u16	dev_id;
+	u16	phy_addr;
+};
+
+static struct fixed_phy_status dwxgmac_brcm_fixed_phy_status = {
+	.link	= 1,
+	.speed	= SPEED_1000,
+	.duplex	= DUPLEX_FULL,
+};
+
+struct dwxgmac_brcm_pci_info {
+	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);
+};
+
+static inline void misc_iowrite(struct brcm_priv_data *brcm_priv,
+				u32 reg, u32 val)
+{
+	iowrite32(val, brcm_priv->misc_regs + reg);
+}
+
+static void dwxgmac_brcm_pdma_set(void __iomem *ioaddr, u32 type, u32 chan,
+				  u32 val)
+{
+	u32 var = 0;
+
+	var |= FIELD_PREP(DMA_CH_IND_CTRLR_MSEL_MASK, type);
+	var |= FIELD_PREP(DMA_CH_IND_CTRLR_AOFF_MASK, chan);
+	var |= FIELD_PREP(DMA_CH_IND_CTRLR_CT_MASK, 0);
+	var |= FIELD_PREP(DMA_CH_IND_CTRLR_OB_MASK, 1);
+
+	if (!FIELD_GET(DMA_CH_IND_CTRLR_OB_MASK,
+		       readl(ioaddr + DMA_CH_IND_CTRLR))) {
+		writel(0x0, (ioaddr + DMA_CH_IND_CTRLR));
+		writel(val, (ioaddr + DMA_CH_IND_DATAR));
+	}
+
+	writel(var, (ioaddr + DMA_CH_IND_CTRLR));
+	readl_poll_timeout(ioaddr + DMA_CH_IND_CTRLR, var,
+			   !(var & XGMAC_OB), READ_POLL_TIMEOUT_US,
+			   READ_POLL_TIMEOUT_US);
+}
+
+static void dwxgmac_brcm_dma_init(void __iomem *ioaddr,
+				  struct stmmac_dma_cfg *dma_cfg, int atds)
+{
+	u32 val = dma_cfg->pbl << 24;
+	u32 i;
+
+	if (dma_cfg->pblx8)
+		val |= (1 << 19);
+
+	dwxgmac2_dma_init(ioaddr, dma_cfg, atds);
+
+	for (i = 0; i < PDMA_TX_CH_COUNT; i++)
+		dwxgmac_brcm_pdma_set(ioaddr, PDMA_CH_TX_EXT_CFGR, i, val);
+
+	for (i = 0; i < PDMA_RX_CH_COUNT; i++)
+		dwxgmac_brcm_pdma_set(ioaddr, PDMA_CH_RX_EXT_CFGR, i, val);
+
+	for (i = 0; i < VDMA_TOTAL_CH_COUNT; i++) {
+		dwxgmac_brcm_pdma_set(ioaddr, VDMA_CH_TX_DESC_CTRLR, i,
+				      BRCM_PDMA_DESC_CTRL_CFG_VALUE);
+		dwxgmac_brcm_pdma_set(ioaddr, VDMA_CH_RX_DESC_CTRLR, i,
+				      BRCM_PDMA_DESC_CTRL_CFG_VALUE);
+	}
+}
+
+static void dwxgmac_brcm_dma_init_tx_chan(struct stmmac_priv *priv,
+					  void __iomem *ioaddr,
+					  struct stmmac_dma_cfg *dma_cfg,
+					  dma_addr_t phy, u32 chan)
+{
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	value &= ~XGMAC_TxPBL;
+	value &= ~GENMASK(6, 4);
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+
+	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chan));
+	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));
+}
+
+static void dwxgmac_brcm_dma_init_rx_chan(struct stmmac_priv *priv,
+					  void __iomem *ioaddr,
+					  struct stmmac_dma_cfg *dma_cfg,
+					  dma_addr_t phy, u32 chan)
+{
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	value &= ~XGMAC_RxPBL;
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+
+	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chan));
+	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));
+}
+
+const struct stmmac_dma_ops dwxgmac_brcm_dma_ops = {
+	.reset = dwxgmac2_dma_reset,
+	.init = dwxgmac_brcm_dma_init,
+	.init_chan = dwxgmac2_dma_init_chan,
+	.init_rx_chan = dwxgmac_brcm_dma_init_rx_chan,
+	.init_tx_chan = dwxgmac_brcm_dma_init_tx_chan,
+	.axi = dwxgmac2_dma_axi,
+	.dump_regs = dwxgmac2_dma_dump_regs,
+	.dma_rx_mode = dwxgmac2_dma_rx_mode,
+	.dma_tx_mode = dwxgmac2_dma_tx_mode,
+	.enable_dma_irq = dwxgmac2_enable_dma_irq,
+	.disable_dma_irq = dwxgmac2_disable_dma_irq,
+	.start_tx = dwxgmac2_dma_start_tx,
+	.stop_tx = dwxgmac2_dma_stop_tx,
+	.start_rx = dwxgmac2_dma_start_rx,
+	.stop_rx = dwxgmac2_dma_stop_rx,
+	.dma_interrupt = dwxgmac2_dma_interrupt,
+	.get_hw_feature = dwxgmac2_get_hw_feature,
+	.rx_watchdog = dwxgmac2_rx_watchdog,
+	.set_rx_ring_len = dwxgmac2_set_rx_ring_len,
+	.set_tx_ring_len = dwxgmac2_set_tx_ring_len,
+	.set_rx_tail_ptr = dwxgmac2_set_rx_tail_ptr,
+	.set_tx_tail_ptr = dwxgmac2_set_tx_tail_ptr,
+	.enable_tso = dwxgmac2_enable_tso,
+	.qmode = dwxgmac2_qmode,
+	.set_bfsize = dwxgmac2_set_bfsize,
+	.enable_sph = dwxgmac2_enable_sph,
+	.enable_tbs = dwxgmac2_enable_tbs,
+};
+
+static void dwxgmac_brcm_fix_speed(void *priv, unsigned int speed,
+				   unsigned int mode)
+{
+}
+
+static struct mac_device_info *dwxgmac_brcm_setup(void *ppriv)
+{
+	struct mac_device_info *mac;
+	struct stmmac_priv *priv = ppriv;
+
+	mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
+	if (!mac)
+		return NULL;
+
+	mac->dma = &dwxgmac_brcm_dma_ops;
+
+	priv->dma_conf.dma_tx_size = BRCM_XGMAC_DMA_TX_SIZE;
+	priv->dma_conf.dma_rx_size = BRCM_XGMAC_DMA_RX_SIZE;
+	priv->plat->rss_en = 1;
+	mac->pcsr = priv->ioaddr;
+	priv->dev->priv_flags |= IFF_UNICAST_FLT;
+	mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
+	mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
+	mac->mcast_bits_log2 = 0;
+
+	if (mac->multicast_filter_bins)
+		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+
+	mac->link.duplex = 0;
+	mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000;
+	mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
+	return mac;
+}
+
+static void dwxgmac_brcm_common_default_data(struct plat_stmmacenet_data *plat)
+{
+	int i;
+
+	plat->has_xgmac = 1;
+	plat->force_sf_dma_mode = 1;
+	plat->mac_port_sel_speed = SPEED_10000;
+	plat->clk_ptp_rate = DWMAC_125MHZ;
+	plat->clk_ref_rate = DWMAC_250MHZ;
+	plat->setup = dwxgmac_brcm_setup;
+	plat->tx_coe = 1;
+	plat->rx_coe = 1;
+	plat->max_speed = SPEED_10000;
+	plat->fix_mac_speed = dwxgmac_brcm_fix_speed;
+
+	/* Set default value for multicast hash bins */
+	plat->multicast_filter_bins = HASH_TABLE_SIZE;
+
+	/* Set default value for unicast filter entries */
+	plat->unicast_filter_entries = 1;
+
+	/* Set the maxmtu to device's default */
+	plat->maxmtu = BRCM_MAX_MTU;
+
+	/* Set default number of RX and TX queues to use */
+	plat->tx_queues_to_use = BRCM_TX_Q_COUNT;
+	plat->rx_queues_to_use = BRCM_RX_Q_COUNT;
+
+	plat->tx_sched_algorithm = MTL_TX_ALGORITHM_SP;
+	for (i = 0; i < plat->tx_queues_to_use; i++) {
+		plat->tx_queues_cfg[i].use_prio = false;
+		plat->tx_queues_cfg[i].prio = 0;
+		plat->tx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;
+	}
+
+	plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
+	for (i = 0; i < plat->rx_queues_to_use; i++) {
+		plat->rx_queues_cfg[i].use_prio = false;
+		plat->rx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;
+		plat->rx_queues_cfg[i].pkt_route = 0x0;
+		plat->rx_queues_cfg[i].chan = i;
+	}
+}
+
+static int dwxgmac_brcm_default_data(struct pci_dev *pdev,
+				     struct plat_stmmacenet_data *plat)
+{
+	struct brcm_priv_data *brcm_priv = plat->bsp_priv;
+
+	/* Set common default data first */
+	dwxgmac_brcm_common_default_data(plat);
+
+	plat->bus_id = 0;
+	plat->phy_addr = num_instances++;
+	brcm_priv->phy_addr = num_instances;
+	plat->phy_interface = PHY_INTERFACE_MODE_USXGMII;
+
+	plat->dma_cfg->pbl = 32;
+	plat->dma_cfg->pblx8 = 0;
+	plat->dma_cfg->aal = 0;
+	plat->dma_cfg->eame = 1;
+
+	plat->axi->axi_wr_osr_lmt = 31;
+	plat->axi->axi_rd_osr_lmt = 31;
+	plat->axi->axi_fb = 0;
+	plat->axi->axi_blen[0] = 4;
+	plat->axi->axi_blen[1] = 8;
+	plat->axi->axi_blen[2] = 16;
+	plat->axi->axi_blen[3] = 32;
+	plat->axi->axi_blen[4] = 64;
+	plat->axi->axi_blen[5] = 128;
+	plat->axi->axi_blen[6] = 256;
+
+	plat->msi_mac_vec = BRCM_XGMAC_MSI_MAC_VECTOR;
+	plat->msi_rx_base_vec = BRCM_XGMAC_MSI_RX_VECTOR_START;
+	plat->msi_tx_base_vec = BRCM_XGMAC_MSI_TX_VECTOR_START;
+
+	return 0;
+}
+
+static struct dwxgmac_brcm_pci_info dwxgmac_brcm_pci_info = {
+	.setup = dwxgmac_brcm_default_data,
+};
+
+static int brcm_config_multi_msi(struct pci_dev *pdev,
+				 struct plat_stmmacenet_data *plat,
+				 struct stmmac_resources *res)
+{
+	int ret;
+	int i;
+
+	if (plat->msi_rx_base_vec >= STMMAC_MSI_VEC_MAX ||
+	    plat->msi_tx_base_vec >= STMMAC_MSI_VEC_MAX) {
+		dev_err(&pdev->dev, "%s: Invalid RX & TX vector defined\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	ret = pci_alloc_irq_vectors(pdev, 2, STMMAC_MSI_VEC_MAX,
+				    PCI_IRQ_MSI | PCI_IRQ_MSIX);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "%s: multi MSI enablement failed\n",
+			__func__);
+		return ret;
+	}
+
+	/* For RX MSI */
+	for (i = 0; i < plat->rx_queues_to_use; i++)
+		res->rx_irq[i] = pci_irq_vector(pdev,
+						plat->msi_rx_base_vec + i * 2);
+
+	/* For TX MSI */
+	for (i = 0; i < plat->tx_queues_to_use; i++)
+		res->tx_irq[i] = pci_irq_vector(pdev,
+						plat->msi_tx_base_vec + i * 2);
+
+	if (plat->msi_mac_vec < STMMAC_MSI_VEC_MAX)
+		res->irq = pci_irq_vector(pdev, plat->msi_mac_vec);
+
+	plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
+	plat->flags |= STMMAC_FLAG_TSO_EN;
+
+	return 0;
+}
+
+/**
+ * dwxgmac_brcm_pci_probe
+ *
+ * @pdev: pci device pointer
+ * @id: pointer to table of device id/id's.
+ *
+ * Description: This probing function gets called for all PCI devices which
+ * match the ID table and are not "owned" by other driver yet. This function
+ * gets passed a "struct pci_dev *" for each device whose entry in the ID table
+ * matches the device. The probe functions returns zero when the driver choose
+ * to take "ownership" of the device or an error code(-ve no) otherwise.
+ */
+static int dwxgmac_brcm_pci_probe(struct pci_dev *pdev,
+				  const struct pci_device_id *id)
+{
+	struct dwxgmac_brcm_pci_info *info =
+		(struct dwxgmac_brcm_pci_info *)id->driver_data;
+	struct plat_stmmacenet_data *plat;
+	struct brcm_priv_data *brcm_priv;
+	struct stmmac_resources res;
+	struct net_device *ndev;
+	struct stmmac_priv *priv;
+	int rx_offset;
+	int tx_offset;
+	int vector;
+	int ret;
+
+	brcm_priv = devm_kzalloc(&pdev->dev, sizeof(*brcm_priv), GFP_KERNEL);
+	if (!brcm_priv)
+		return -ENOMEM;
+
+	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
+	if (!plat)
+		return -ENOMEM;
+
+	plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg),
+				     GFP_KERNEL);
+	if (!plat->dma_cfg)
+		return -ENOMEM;
+
+	plat->axi = devm_kzalloc(&pdev->dev, sizeof(*plat->axi), GFP_KERNEL);
+	if (!plat->axi)
+		return -ENOMEM;
+
+	pci_read_config_word(pdev, 2, &brcm_priv->dev_id);
+
+	/* This device interface is directly attached to the switch chip on
+	 *  the SoC. Since no MDIO is present, register fixed_phy.
+	 */
+	brcm_priv->phy_dev =
+		 fixed_phy_register(PHY_POLL,
+				    &dwxgmac_brcm_fixed_phy_status, NULL);
+	if (IS_ERR(brcm_priv->phy_dev)) {
+		dev_err(&pdev->dev, "%s\tNo PHY/fixed_PHY found\n", __func__);
+		return -ENODEV;
+	}
+	phy_attached_info(brcm_priv->phy_dev);
+
+	/* Disable D3COLD as our device does not support it */
+	pci_d3cold_disable(pdev);
+
+	/* Enable PCI device */
+	ret = pcim_enable_device(pdev);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n",
+			__func__);
+		return ret;
+	}
+
+	/* Get the base address of device */
+	ret = pcim_iomap_regions(pdev, BRCM_XGMAC_BAR0_MASK, pci_name(pdev));
+	if (ret)
+		goto err_disable_device;
+	pci_set_master(pdev);
+
+	memset(&res, 0, sizeof(res));
+	res.addr = pcim_iomap_table(pdev)[0];
+	/* MISC Regs */
+	brcm_priv->misc_regs = res.addr + BRCM_XGMAC_IOMEM_MISC_REG_OFFSET;
+	/* MBOX Regs */
+	brcm_priv->mbox_regs = res.addr + BRCM_XGMAC_IOMEM_MBOX_REG_OFFSET;
+	/* XGMAC config Regs */
+	res.addr += BRCM_XGMAC_IOMEM_CFG_REG_OFFSET;
+
+	plat->bsp_priv = brcm_priv;
+
+	/* Initialize all MSI vectors to invalid so that it can be set
+	 * according to platform data settings below.
+	 * Note: MSI vector takes value from 0 up to 31 (STMMAC_MSI_VEC_MAX)
+	 */
+	plat->msi_mac_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_wol_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_lpi_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_sfty_ce_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_sfty_ue_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_rx_base_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_tx_base_vec = STMMAC_MSI_VEC_MAX;
+
+	ret = info->setup(pdev, plat);
+	if (ret)
+		goto err_disable_device;
+
+	pci_write_config_dword(pdev, XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_LOW,
+			       XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_LO_VALUE);
+	pci_write_config_dword(pdev, XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_HIGH,
+			       XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_HI_VALUE);
+
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_LO,
+		     XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_LO_VALUE);
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_HI,
+		     XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_HI_VALUE);
+
+	/* SBD Interrupt */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_SBD_ALL,
+		     XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_SBD_ALL_VALUE);
+	/* EP_DOORBELL Interrupt */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST_DBELL,
+		     XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST_DBELL_VALUE);
+	/* EP_H0 Interrupt */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST0,
+		     XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST0_VALUE);
+	/* EP_H1 Interrupt */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST1,
+		     XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST1_VALUE);
+
+	rx_offset = XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_RX0_PF0;
+	tx_offset = XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_TX0_PF0;
+	vector = BRCM_XGMAC_MSI_RX_VECTOR_START;
+	for (int i = 0; i < BRCM_MAX_DMA_CHANNEL_PAIRS; i++) {
+		/* RX Interrupt */
+		misc_iowrite(brcm_priv, rx_offset, vector++);
+		/* TX Interrupt */
+		misc_iowrite(brcm_priv, tx_offset, vector++);
+		rx_offset += 4;
+		tx_offset += 4;
+	}
+
+	/* Enable Switch Link */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MII_CTRL,
+		     XGMAC_PCIE_MISC_MII_CTRL_VALUE);
+	/* Enable MSI-X */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_PCIESS_CTRL,
+		     XGMAC_PCIE_MISC_PCIESS_CTRL_VALUE);
+
+	ret = brcm_config_multi_msi(pdev, plat, &res);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s: ERROR: failed to enable IRQ\n", __func__);
+		return ret;
+	}
+
+	ret = stmmac_dvr_probe(&pdev->dev, plat, &res);
+	if (ret)
+		goto err_disable_msi;
+
+	/* The stmmac core driver doesn't have the infrastructure to
+	 * support fixed-phy mdio bus for non-platform bus drivers.
+	 * Until a better solution is implemented, initialize the
+	 * following entries after priv structure is populated.
+	 */
+	ndev = dev_get_drvdata(&pdev->dev);
+	priv = netdev_priv(ndev);
+	priv->mii = mdio_find_bus("fixed-0");
+
+	ndev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX;
+	priv->hw->hw_vlan_en = false;
+
+	dev_info(&pdev->dev, "%s\tComplete\n", __func__);
+
+	return ret;
+
+err_disable_msi:
+	pci_disable_msi(pdev);
+err_disable_device:
+	pci_disable_device(pdev);
+	return ret;
+}
+
+/**
+ * dwxgmac_brcm_pci_remove
+ *
+ * @pdev: platform device pointer
+ * Description: this function calls the main to free the net resources
+ * and releases the PCI resources.
+ */
+static void dwxgmac_brcm_pci_remove(struct pci_dev *pdev)
+{
+	struct net_device *ndev = dev_get_drvdata(&pdev->dev);
+	struct stmmac_priv *priv = netdev_priv(ndev);
+	struct brcm_priv_data *brcm_priv = priv->plat->bsp_priv;
+	struct phy_device *phydev = brcm_priv->phy_dev;
+
+	priv->mii = NULL;
+	stmmac_dvr_remove(&pdev->dev);
+	pcim_iounmap_regions(pdev, BRCM_XGMAC_BAR0_MASK);
+	pci_clear_master(pdev);
+	fixed_phy_unregister(phydev);
+}
+
+static int __maybe_unused dwxgmac_brcm_pci_suspend(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	int ret;
+
+	ret = stmmac_suspend(dev);
+	if (ret)
+		return ret;
+
+	ret = pci_save_state(pdev);
+	if (ret)
+		return ret;
+
+	pci_disable_device(pdev);
+	pci_wake_from_d3(pdev, true);
+	return 0;
+}
+
+static int __maybe_unused dwxgmac_brcm_pci_resume(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	int ret;
+
+	pci_restore_state(pdev);
+	pci_set_power_state(pdev, PCI_D0);
+
+	ret = pci_enable_device(pdev);
+	if (ret)
+		return ret;
+
+	pci_set_master(pdev);
+
+	return stmmac_resume(dev);
+}
+
+static SIMPLE_DEV_PM_OPS(dwxgmac_brcm_pm_ops,
+			 dwxgmac_brcm_pci_suspend,
+			 dwxgmac_brcm_pci_resume);
+
+static const struct pci_device_id dwxgmac_brcm_id_table[] = {
+	{ PCI_DEVICE_DATA(BROADCOM, BCM8958X, &dwxgmac_brcm_pci_info) },
+	{}
+};
+
+MODULE_DEVICE_TABLE(pci, dwxgmac_brcm_id_table);
+
+static struct pci_driver dwxgmac_brcm_pci_driver = {
+	.name = "brcm-bcm8958x",
+	.id_table = dwxgmac_brcm_id_table,
+	.probe	= dwxgmac_brcm_pci_probe,
+	.remove = dwxgmac_brcm_pci_remove,
+	.driver = {
+		.pm = &dwxgmac_brcm_pm_ops,
+	},
+};
+
+module_pci_driver(dwxgmac_brcm_pci_driver);
+
+MODULE_DESCRIPTION("Broadcom 10G Automotive Ethernet PCIe driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-10  0:03 ` [PATCH, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC Jitendra Vegiraju
@ 2024-05-11  1:35   ` Jakub Kicinski
  2024-05-11  1:59   ` [PATCH v2, " Jitendra Vegiraju
  2024-05-17 23:50   ` [PATCH, " kernel test robot
  2 siblings, 0 replies; 23+ messages in thread
From: Jakub Kicinski @ 2024-05-11  1:35 UTC (permalink / raw
  To: Jitendra Vegiraju
  Cc: netdev, davem, edumazet, pabeni, bcm-kernel-feedback-list

On Thu,  9 May 2024 17:03:31 -0700 Jitendra Vegiraju wrote:
> + * dwxgmac_brcm_pci_probe
> + *
> + * @pdev: pci device pointer
> + * @id: pointer to table of device id/id's.

the kdoc format for probe and remove is not completely correct 
(try ./scripts/kernel-doc -Wall -none $filename)
I'd just remove it, it doesn't explain anything of importance.
-- 
pw-bot: cr

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-10  0:03 ` [PATCH, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC Jitendra Vegiraju
  2024-05-11  1:35   ` Jakub Kicinski
@ 2024-05-11  1:59   ` Jitendra Vegiraju
  2024-05-11  2:08     ` Jakub Kicinski
                       ` (3 more replies)
  2024-05-17 23:50   ` [PATCH, " kernel test robot
  2 siblings, 4 replies; 23+ messages in thread
From: Jitendra Vegiraju @ 2024-05-11  1:59 UTC (permalink / raw
  To: netdev
  Cc: jitendra.vegiraju, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel

Broadcom BCM8958X SoCs use Synopsys XGMAC design, which is similar to
dwxgmac2 core implementation in stmmac driver. The existing dwxgmac2 dma
operation functions have some conflicting differences with BCM8958X.
This glue driver attempts to reuse dwxgmac2 implementation wherever
possible, adding alternative implementations where necessary.

v2: code cleanup to address patchwork reports.

Signed-off-by: Jitendra Vegiraju <jitendra.vegiraju@broadcom.com>
---
 MAINTAINERS                                   |   7 +
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 +
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../net/ethernet/stmicro/stmmac/dwmac-brcm.c  | 638 ++++++++++++++++++
 4 files changed, 657 insertions(+)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c

diff --git a/MAINTAINERS b/MAINTAINERS
index b81b2be60b77..1eaf52047810 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4115,6 +4115,13 @@ N:	brcmstb
 N:	bcm7038
 N:	bcm7120
 
+BROADCOM BCM8958X ETHERNET DRIVER
+M:	Jitendra Vegiraju <jitendra.vegiraju@broadcom.com>
+R:	Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
+L:	netdev@vger.kernel.org
+S:	Maintained
+F:	drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c
+
 BROADCOM BCMBCA ARM ARCHITECTURE
 M:	William Zhang <william.zhang@broadcom.com>
 M:	Anand Gore <anand.gore@broadcom.com>
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 4ec61f1ee71a..6c06149712c8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -286,6 +286,17 @@ config DWMAC_LOONGSON
 	  This selects the LOONGSON PCI bus support for the stmmac driver,
 	  Support for ethernet controller on Loongson-2K1000 SoC and LS7A1000 bridge.
 
+config DWMAC_BRCM
+	tristate "Broadcom XGMAC support"
+	depends on STMMAC_ETH && PCI
+	depends on COMMON_CLK
+	help
+	  Support for ethernet controllers on Broadcom BCM8958x SoCs
+
+	  This selects Broadcom XGMAC specific PCI bus support for the
+	  stmmac driver. This driver provides the glue layer on top of the
+	  stmmac driver required for the Broadcom BCM8958x SoC devices.
+
 config STMMAC_PCI
 	tristate "STMMAC PCI bus support"
 	depends on STMMAC_ETH && PCI
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 26cad4344701..1cd0f508bafb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -40,4 +40,5 @@ dwmac-altr-socfpga-objs := dwmac-socfpga.o
 obj-$(CONFIG_STMMAC_PCI)	+= stmmac-pci.o
 obj-$(CONFIG_DWMAC_INTEL)	+= dwmac-intel.o
 obj-$(CONFIG_DWMAC_LOONGSON)	+= dwmac-loongson.o
+obj-$(CONFIG_DWMAC_BRCM)	+= dwmac-brcm.o
 stmmac-pci-objs:= stmmac_pci.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c
new file mode 100644
index 000000000000..74f8e137d823
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c
@@ -0,0 +1,638 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Broadcom Corporation
+ * This file contains the functions to handle the Broadcom XGMAC PCI driver.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/dmi.h>
+#include <linux/pci.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
+
+#include "stmmac.h"
+#include "dwxgmac2.h"
+
+#define PCI_DEVICE_ID_BROADCOM_BCM8958X		0xa00d
+#define BRCM_MAX_MTU				1500
+#define READ_POLL_DELAY_US			100
+#define READ_POLL_TIMEOUT_US			10000
+#define DWMAC_125MHZ				125000000
+#define DWMAC_250MHZ				250000000
+
+/* TX and RX Queue couts */
+#define BRCM_TX_Q_COUNT				4
+#define BRCM_RX_Q_COUNT				1
+
+/* PDMA Channel counts */
+#define PDMA_TX_CH_COUNT			8
+#define PDMA_RX_CH_COUNT			10
+
+/* PDMA register type */
+#define PDMA_CH_TX_EXT_CFGR			0
+#define PDMA_CH_RX_EXT_CFGR			1
+#define PDMA_CH_TX_DBG_STSR			2
+#define PDMA_CH_RX_DBG_STSR			3
+
+/* VDMA register type */
+#define VDMA_CH_TX_DESC_CTRLR			4
+#define VDMA_CH_RX_DESC_CTRLR			5
+
+/* VDMA channel count */
+#define VDMA_TOTAL_CH_COUNT			32
+
+#define DMA_CH_IND_CTRLR			0x3080
+#define DMA_CH_IND_DATAR			0x3084
+
+#define BRCM_XGMAC_RX_CFG			0x2000
+#define BRCM_XGMAC_RXQ_CTRL1_CFG		0x8000
+
+#define BRCM_XGMAC_DMA_TX_SIZE			4096
+#define BRCM_XGMAC_DMA_RX_SIZE			4096
+#define BRCM_XGMAC_BAR0_MASK			BIT(0)
+
+#define BRCM_XGMAC_IOMEM_MISC_REG_OFFSET	0x0
+#define BRCM_XGMAC_IOMEM_MBOX_REG_OFFSET	0x1000
+#define BRCM_XGMAC_IOMEM_CFG_REG_OFFSET		0x3000
+
+#define XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_LOW	0x940
+#define XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_LO_VALUE	0x00000001
+#define XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_HIGH	0x944
+#define XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_HI_VALUE	0x88000000
+
+#define XGMAC_PCIE_MISC_MII_CTRL			0x4
+#define XGMAC_PCIE_MISC_MII_CTRL_VALUE			0x7
+#define XGMAC_PCIE_MISC_PCIESS_CTRL			0x8
+#define XGMAC_PCIE_MISC_PCIESS_CTRL_VALUE		0x200
+#define XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_LO		0x90
+#define XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_LO_VALUE	0x00000001
+#define XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_HI		0x94
+#define XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_HI_VALUE	0x88000000
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST0	0x700
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST0_VALUE	1
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST1	0x704
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST1_VALUE	1
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST_DBELL	0x728
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST_DBELL_VALUE	1
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_SBD_ALL		0x740
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_SBD_ALL_VALUE	0
+
+#define DMA_CH_IND_CTRLR_MSEL_OFF		24
+#define DMA_CH_IND_CTRLR_MSEL_MASK		GENMASK(27, 24)
+#define DMA_CH_IND_CTRLR_AOFF_OFF		8
+#define DMA_CH_IND_CTRLR_AOFF_MASK		GENMASK(14, 8)
+#define DMA_CH_IND_CTRLR_AUTO_OFF		4
+#define DMA_CH_IND_CTRLR_AUTO_MASK		GENMASK(5, 4)
+#define DMA_CH_IND_CTRLR_CT_OFF			1
+#define DMA_CH_IND_CTRLR_CT_MASK		BIT(1)
+#define DMA_CH_IND_CTRLR_OB_OFF			0
+#define DMA_CH_IND_CTRLR_OB_MASK		BIT(0)
+
+/* DMA Descriptor configuration */
+#define BRCM_PDMA_DESC_CTRL_CFG_VALUE		0x1B
+
+#define XGMAC_PCIE_MISC_FUNC_RESOURCES_PF0	0x804
+
+/* MSIX Vector map register starting offsets */
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_RX0_PF0	0x840
+#define XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_TX0_PF0	0x890
+#define BRCM_MAX_DMA_CHANNEL_PAIRS		4
+
+#define BRCM_XGMAC_MSI_MAC_VECTOR		0
+#define BRCM_XGMAC_MSI_RX_VECTOR_START		9
+#define BRCM_XGMAC_MSI_TX_VECTOR_START		10
+
+static int num_instances;
+
+struct brcm_priv_data {
+	struct phy_device *phy_dev;
+	void __iomem *mbox_regs;    /* MBOX */
+	void __iomem *misc_regs;    /* MISC_cfg */
+	u16	dev_id;
+	u16	phy_addr;
+};
+
+static struct fixed_phy_status dwxgmac_brcm_fixed_phy_status = {
+	.link	= 1,
+	.speed	= SPEED_1000,
+	.duplex	= DUPLEX_FULL,
+};
+
+struct dwxgmac_brcm_pci_info {
+	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);
+};
+
+static void misc_iowrite(struct brcm_priv_data *brcm_priv,
+			 u32 reg, u32 val)
+{
+	iowrite32(val, brcm_priv->misc_regs + reg);
+}
+
+static void dwxgmac_brcm_pdma_set(void __iomem *ioaddr, u32 type, u32 chan,
+				  u32 val)
+{
+	u32 var = 0;
+
+	var |= FIELD_PREP(DMA_CH_IND_CTRLR_MSEL_MASK, type);
+	var |= FIELD_PREP(DMA_CH_IND_CTRLR_AOFF_MASK, chan);
+	var |= FIELD_PREP(DMA_CH_IND_CTRLR_CT_MASK, 0);
+	var |= FIELD_PREP(DMA_CH_IND_CTRLR_OB_MASK, 1);
+
+	if (!FIELD_GET(DMA_CH_IND_CTRLR_OB_MASK,
+		       readl(ioaddr + DMA_CH_IND_CTRLR))) {
+		writel(0x0, (ioaddr + DMA_CH_IND_CTRLR));
+		writel(val, (ioaddr + DMA_CH_IND_DATAR));
+	}
+
+	writel(var, (ioaddr + DMA_CH_IND_CTRLR));
+	readl_poll_timeout(ioaddr + DMA_CH_IND_CTRLR, var,
+			   !(var & XGMAC_OB), READ_POLL_TIMEOUT_US,
+			   READ_POLL_TIMEOUT_US);
+}
+
+static void dwxgmac_brcm_dma_init(void __iomem *ioaddr,
+				  struct stmmac_dma_cfg *dma_cfg, int atds)
+{
+	u32 val = dma_cfg->pbl << 24;
+	u32 i;
+
+	if (dma_cfg->pblx8)
+		val |= (1 << 19);
+
+	dwxgmac2_dma_init(ioaddr, dma_cfg, atds);
+
+	for (i = 0; i < PDMA_TX_CH_COUNT; i++)
+		dwxgmac_brcm_pdma_set(ioaddr, PDMA_CH_TX_EXT_CFGR, i, val);
+
+	for (i = 0; i < PDMA_RX_CH_COUNT; i++)
+		dwxgmac_brcm_pdma_set(ioaddr, PDMA_CH_RX_EXT_CFGR, i, val);
+
+	for (i = 0; i < VDMA_TOTAL_CH_COUNT; i++) {
+		dwxgmac_brcm_pdma_set(ioaddr, VDMA_CH_TX_DESC_CTRLR, i,
+				      BRCM_PDMA_DESC_CTRL_CFG_VALUE);
+		dwxgmac_brcm_pdma_set(ioaddr, VDMA_CH_RX_DESC_CTRLR, i,
+				      BRCM_PDMA_DESC_CTRL_CFG_VALUE);
+	}
+}
+
+static void dwxgmac_brcm_dma_init_tx_chan(struct stmmac_priv *priv,
+					  void __iomem *ioaddr,
+					  struct stmmac_dma_cfg *dma_cfg,
+					  dma_addr_t phy, u32 chan)
+{
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	value &= ~XGMAC_TxPBL;
+	value &= ~GENMASK(6, 4);
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+
+	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chan));
+	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));
+}
+
+static void dwxgmac_brcm_dma_init_rx_chan(struct stmmac_priv *priv,
+					  void __iomem *ioaddr,
+					  struct stmmac_dma_cfg *dma_cfg,
+					  dma_addr_t phy, u32 chan)
+{
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	value &= ~XGMAC_RxPBL;
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+
+	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chan));
+	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));
+}
+
+static const struct stmmac_dma_ops dwxgmac_brcm_dma_ops = {
+	.reset = dwxgmac2_dma_reset,
+	.init = dwxgmac_brcm_dma_init,
+	.init_chan = dwxgmac2_dma_init_chan,
+	.init_rx_chan = dwxgmac_brcm_dma_init_rx_chan,
+	.init_tx_chan = dwxgmac_brcm_dma_init_tx_chan,
+	.axi = dwxgmac2_dma_axi,
+	.dump_regs = dwxgmac2_dma_dump_regs,
+	.dma_rx_mode = dwxgmac2_dma_rx_mode,
+	.dma_tx_mode = dwxgmac2_dma_tx_mode,
+	.enable_dma_irq = dwxgmac2_enable_dma_irq,
+	.disable_dma_irq = dwxgmac2_disable_dma_irq,
+	.start_tx = dwxgmac2_dma_start_tx,
+	.stop_tx = dwxgmac2_dma_stop_tx,
+	.start_rx = dwxgmac2_dma_start_rx,
+	.stop_rx = dwxgmac2_dma_stop_rx,
+	.dma_interrupt = dwxgmac2_dma_interrupt,
+	.get_hw_feature = dwxgmac2_get_hw_feature,
+	.rx_watchdog = dwxgmac2_rx_watchdog,
+	.set_rx_ring_len = dwxgmac2_set_rx_ring_len,
+	.set_tx_ring_len = dwxgmac2_set_tx_ring_len,
+	.set_rx_tail_ptr = dwxgmac2_set_rx_tail_ptr,
+	.set_tx_tail_ptr = dwxgmac2_set_tx_tail_ptr,
+	.enable_tso = dwxgmac2_enable_tso,
+	.qmode = dwxgmac2_qmode,
+	.set_bfsize = dwxgmac2_set_bfsize,
+	.enable_sph = dwxgmac2_enable_sph,
+	.enable_tbs = dwxgmac2_enable_tbs,
+};
+
+static void dwxgmac_brcm_fix_speed(void *priv, unsigned int speed,
+				   unsigned int mode)
+{
+}
+
+static struct mac_device_info *dwxgmac_brcm_setup(void *ppriv)
+{
+	struct mac_device_info *mac;
+	struct stmmac_priv *priv = ppriv;
+
+	mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
+	if (!mac)
+		return NULL;
+
+	mac->dma = &dwxgmac_brcm_dma_ops;
+
+	priv->dma_conf.dma_tx_size = BRCM_XGMAC_DMA_TX_SIZE;
+	priv->dma_conf.dma_rx_size = BRCM_XGMAC_DMA_RX_SIZE;
+	priv->plat->rss_en = 1;
+	mac->pcsr = priv->ioaddr;
+	priv->dev->priv_flags |= IFF_UNICAST_FLT;
+	mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
+	mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
+	mac->mcast_bits_log2 = 0;
+
+	if (mac->multicast_filter_bins)
+		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+
+	mac->link.duplex = 0;
+	mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000;
+	mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
+	return mac;
+}
+
+static void dwxgmac_brcm_common_default_data(struct plat_stmmacenet_data *plat)
+{
+	int i;
+
+	plat->has_xgmac = 1;
+	plat->force_sf_dma_mode = 1;
+	plat->mac_port_sel_speed = SPEED_10000;
+	plat->clk_ptp_rate = DWMAC_125MHZ;
+	plat->clk_ref_rate = DWMAC_250MHZ;
+	plat->setup = dwxgmac_brcm_setup;
+	plat->tx_coe = 1;
+	plat->rx_coe = 1;
+	plat->max_speed = SPEED_10000;
+	plat->fix_mac_speed = dwxgmac_brcm_fix_speed;
+
+	/* Set default value for multicast hash bins */
+	plat->multicast_filter_bins = HASH_TABLE_SIZE;
+
+	/* Set default value for unicast filter entries */
+	plat->unicast_filter_entries = 1;
+
+	/* Set the maxmtu to device's default */
+	plat->maxmtu = BRCM_MAX_MTU;
+
+	/* Set default number of RX and TX queues to use */
+	plat->tx_queues_to_use = BRCM_TX_Q_COUNT;
+	plat->rx_queues_to_use = BRCM_RX_Q_COUNT;
+
+	plat->tx_sched_algorithm = MTL_TX_ALGORITHM_SP;
+	for (i = 0; i < plat->tx_queues_to_use; i++) {
+		plat->tx_queues_cfg[i].use_prio = false;
+		plat->tx_queues_cfg[i].prio = 0;
+		plat->tx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;
+	}
+
+	plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
+	for (i = 0; i < plat->rx_queues_to_use; i++) {
+		plat->rx_queues_cfg[i].use_prio = false;
+		plat->rx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;
+		plat->rx_queues_cfg[i].pkt_route = 0x0;
+		plat->rx_queues_cfg[i].chan = i;
+	}
+}
+
+static int dwxgmac_brcm_default_data(struct pci_dev *pdev,
+				     struct plat_stmmacenet_data *plat)
+{
+	struct brcm_priv_data *brcm_priv = plat->bsp_priv;
+
+	/* Set common default data first */
+	dwxgmac_brcm_common_default_data(plat);
+
+	plat->bus_id = 0;
+	plat->phy_addr = num_instances++;
+	brcm_priv->phy_addr = num_instances;
+	plat->phy_interface = PHY_INTERFACE_MODE_USXGMII;
+
+	plat->dma_cfg->pbl = 32;
+	plat->dma_cfg->pblx8 = 0;
+	plat->dma_cfg->aal = 0;
+	plat->dma_cfg->eame = 1;
+
+	plat->axi->axi_wr_osr_lmt = 31;
+	plat->axi->axi_rd_osr_lmt = 31;
+	plat->axi->axi_fb = 0;
+	plat->axi->axi_blen[0] = 4;
+	plat->axi->axi_blen[1] = 8;
+	plat->axi->axi_blen[2] = 16;
+	plat->axi->axi_blen[3] = 32;
+	plat->axi->axi_blen[4] = 64;
+	plat->axi->axi_blen[5] = 128;
+	plat->axi->axi_blen[6] = 256;
+
+	plat->msi_mac_vec = BRCM_XGMAC_MSI_MAC_VECTOR;
+	plat->msi_rx_base_vec = BRCM_XGMAC_MSI_RX_VECTOR_START;
+	plat->msi_tx_base_vec = BRCM_XGMAC_MSI_TX_VECTOR_START;
+
+	return 0;
+}
+
+static struct dwxgmac_brcm_pci_info dwxgmac_brcm_pci_info = {
+	.setup = dwxgmac_brcm_default_data,
+};
+
+static int brcm_config_multi_msi(struct pci_dev *pdev,
+				 struct plat_stmmacenet_data *plat,
+				 struct stmmac_resources *res)
+{
+	int ret;
+	int i;
+
+	if (plat->msi_rx_base_vec >= STMMAC_MSI_VEC_MAX ||
+	    plat->msi_tx_base_vec >= STMMAC_MSI_VEC_MAX) {
+		dev_err(&pdev->dev, "%s: Invalid RX & TX vector defined\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	ret = pci_alloc_irq_vectors(pdev, 2, STMMAC_MSI_VEC_MAX,
+				    PCI_IRQ_MSI | PCI_IRQ_MSIX);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "%s: multi MSI enablement failed\n",
+			__func__);
+		return ret;
+	}
+
+	/* For RX MSI */
+	for (i = 0; i < plat->rx_queues_to_use; i++)
+		res->rx_irq[i] = pci_irq_vector(pdev,
+						plat->msi_rx_base_vec + i * 2);
+
+	/* For TX MSI */
+	for (i = 0; i < plat->tx_queues_to_use; i++)
+		res->tx_irq[i] = pci_irq_vector(pdev,
+						plat->msi_tx_base_vec + i * 2);
+
+	if (plat->msi_mac_vec < STMMAC_MSI_VEC_MAX)
+		res->irq = pci_irq_vector(pdev, plat->msi_mac_vec);
+
+	plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
+	plat->flags |= STMMAC_FLAG_TSO_EN;
+
+	return 0;
+}
+
+static int dwxgmac_brcm_pci_probe(struct pci_dev *pdev,
+				  const struct pci_device_id *id)
+{
+	struct dwxgmac_brcm_pci_info *info =
+		(struct dwxgmac_brcm_pci_info *)id->driver_data;
+	struct plat_stmmacenet_data *plat;
+	struct brcm_priv_data *brcm_priv;
+	struct stmmac_resources res;
+	struct net_device *ndev;
+	struct stmmac_priv *priv;
+	int rx_offset;
+	int tx_offset;
+	int vector;
+	int ret;
+
+	brcm_priv = devm_kzalloc(&pdev->dev, sizeof(*brcm_priv), GFP_KERNEL);
+	if (!brcm_priv)
+		return -ENOMEM;
+
+	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
+	if (!plat)
+		return -ENOMEM;
+
+	plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg),
+				     GFP_KERNEL);
+	if (!plat->dma_cfg)
+		return -ENOMEM;
+
+	plat->axi = devm_kzalloc(&pdev->dev, sizeof(*plat->axi), GFP_KERNEL);
+	if (!plat->axi)
+		return -ENOMEM;
+
+	pci_read_config_word(pdev, 2, &brcm_priv->dev_id);
+
+	/* This device interface is directly attached to the switch chip on
+	 *  the SoC. Since no MDIO is present, register fixed_phy.
+	 */
+	brcm_priv->phy_dev =
+		 fixed_phy_register(PHY_POLL,
+				    &dwxgmac_brcm_fixed_phy_status, NULL);
+	if (IS_ERR(brcm_priv->phy_dev)) {
+		dev_err(&pdev->dev, "%s\tNo PHY/fixed_PHY found\n", __func__);
+		return -ENODEV;
+	}
+	phy_attached_info(brcm_priv->phy_dev);
+
+	/* Disable D3COLD as our device does not support it */
+	pci_d3cold_disable(pdev);
+
+	/* Enable PCI device */
+	ret = pcim_enable_device(pdev);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n",
+			__func__);
+		return ret;
+	}
+
+	/* Get the base address of device */
+	ret = pcim_iomap_regions(pdev, BRCM_XGMAC_BAR0_MASK, pci_name(pdev));
+	if (ret)
+		goto err_disable_device;
+	pci_set_master(pdev);
+
+	memset(&res, 0, sizeof(res));
+	res.addr = pcim_iomap_table(pdev)[0];
+	/* MISC Regs */
+	brcm_priv->misc_regs = res.addr + BRCM_XGMAC_IOMEM_MISC_REG_OFFSET;
+	/* MBOX Regs */
+	brcm_priv->mbox_regs = res.addr + BRCM_XGMAC_IOMEM_MBOX_REG_OFFSET;
+	/* XGMAC config Regs */
+	res.addr += BRCM_XGMAC_IOMEM_CFG_REG_OFFSET;
+
+	plat->bsp_priv = brcm_priv;
+
+	/* Initialize all MSI vectors to invalid so that it can be set
+	 * according to platform data settings below.
+	 * Note: MSI vector takes value from 0 up to 31 (STMMAC_MSI_VEC_MAX)
+	 */
+	plat->msi_mac_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_wol_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_lpi_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_sfty_ce_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_sfty_ue_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_rx_base_vec = STMMAC_MSI_VEC_MAX;
+	plat->msi_tx_base_vec = STMMAC_MSI_VEC_MAX;
+
+	ret = info->setup(pdev, plat);
+	if (ret)
+		goto err_disable_device;
+
+	pci_write_config_dword(pdev, XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_LOW,
+			       XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_LO_VALUE);
+	pci_write_config_dword(pdev, XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_HIGH,
+			       XGMAC_PCIE_CFG_MSIX_ADDR_MATCH_HI_VALUE);
+
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_LO,
+		     XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_LO_VALUE);
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_HI,
+		     XGMAC_PCIE_MISC_MSIX_ADDR_MATCH_HI_VALUE);
+
+	/* SBD Interrupt */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_SBD_ALL,
+		     XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_SBD_ALL_VALUE);
+	/* EP_DOORBELL Interrupt */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST_DBELL,
+		     XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST_DBELL_VALUE);
+	/* EP_H0 Interrupt */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST0,
+		     XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST0_VALUE);
+	/* EP_H1 Interrupt */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST1,
+		     XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_EP2HOST1_VALUE);
+
+	rx_offset = XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_RX0_PF0;
+	tx_offset = XGMAC_PCIE_MISC_MSIX_VECTOR_MAP_TX0_PF0;
+	vector = BRCM_XGMAC_MSI_RX_VECTOR_START;
+	for (int i = 0; i < BRCM_MAX_DMA_CHANNEL_PAIRS; i++) {
+		/* RX Interrupt */
+		misc_iowrite(brcm_priv, rx_offset, vector++);
+		/* TX Interrupt */
+		misc_iowrite(brcm_priv, tx_offset, vector++);
+		rx_offset += 4;
+		tx_offset += 4;
+	}
+
+	/* Enable Switch Link */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_MII_CTRL,
+		     XGMAC_PCIE_MISC_MII_CTRL_VALUE);
+	/* Enable MSI-X */
+	misc_iowrite(brcm_priv, XGMAC_PCIE_MISC_PCIESS_CTRL,
+		     XGMAC_PCIE_MISC_PCIESS_CTRL_VALUE);
+
+	ret = brcm_config_multi_msi(pdev, plat, &res);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s: ERROR: failed to enable IRQ\n", __func__);
+		return ret;
+	}
+
+	ret = stmmac_dvr_probe(&pdev->dev, plat, &res);
+	if (ret)
+		goto err_disable_msi;
+
+	/* The stmmac core driver doesn't have the infrastructure to
+	 * support fixed-phy mdio bus for non-platform bus drivers.
+	 * Until a better solution is implemented, initialize the
+	 * following entries after priv structure is populated.
+	 */
+	ndev = dev_get_drvdata(&pdev->dev);
+	priv = netdev_priv(ndev);
+	priv->mii = mdio_find_bus("fixed-0");
+
+	ndev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX;
+	priv->hw->hw_vlan_en = false;
+
+	dev_info(&pdev->dev, "%s\tComplete\n", __func__);
+
+	return ret;
+
+err_disable_msi:
+	pci_disable_msi(pdev);
+err_disable_device:
+	pci_disable_device(pdev);
+	return ret;
+}
+
+static void dwxgmac_brcm_pci_remove(struct pci_dev *pdev)
+{
+	struct net_device *ndev = dev_get_drvdata(&pdev->dev);
+	struct stmmac_priv *priv = netdev_priv(ndev);
+	struct brcm_priv_data *brcm_priv = priv->plat->bsp_priv;
+	struct phy_device *phydev = brcm_priv->phy_dev;
+
+	priv->mii = NULL;
+	stmmac_dvr_remove(&pdev->dev);
+	pcim_iounmap_regions(pdev, BRCM_XGMAC_BAR0_MASK);
+	pci_clear_master(pdev);
+	fixed_phy_unregister(phydev);
+}
+
+static int __maybe_unused dwxgmac_brcm_pci_suspend(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	int ret;
+
+	ret = stmmac_suspend(dev);
+	if (ret)
+		return ret;
+
+	ret = pci_save_state(pdev);
+	if (ret)
+		return ret;
+
+	pci_disable_device(pdev);
+	pci_wake_from_d3(pdev, true);
+	return 0;
+}
+
+static int __maybe_unused dwxgmac_brcm_pci_resume(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	int ret;
+
+	pci_restore_state(pdev);
+	pci_set_power_state(pdev, PCI_D0);
+
+	ret = pci_enable_device(pdev);
+	if (ret)
+		return ret;
+
+	pci_set_master(pdev);
+
+	return stmmac_resume(dev);
+}
+
+static SIMPLE_DEV_PM_OPS(dwxgmac_brcm_pm_ops,
+			 dwxgmac_brcm_pci_suspend,
+			 dwxgmac_brcm_pci_resume);
+
+static const struct pci_device_id dwxgmac_brcm_id_table[] = {
+	{ PCI_DEVICE_DATA(BROADCOM, BCM8958X, &dwxgmac_brcm_pci_info) },
+	{}
+};
+
+MODULE_DEVICE_TABLE(pci, dwxgmac_brcm_id_table);
+
+static struct pci_driver dwxgmac_brcm_pci_driver = {
+	.name = "brcm-bcm8958x",
+	.id_table = dwxgmac_brcm_id_table,
+	.probe	= dwxgmac_brcm_pci_probe,
+	.remove = dwxgmac_brcm_pci_remove,
+	.driver = {
+		.pm = &dwxgmac_brcm_pm_ops,
+	},
+};
+
+module_pci_driver(dwxgmac_brcm_pci_driver);
+
+MODULE_DESCRIPTION("Broadcom 10G Automotive Ethernet PCIe driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11  1:59   ` [PATCH v2, " Jitendra Vegiraju
@ 2024-05-11  2:08     ` Jakub Kicinski
  2024-05-13 16:47       ` Jitendra Vegiraju
  2024-05-11 16:16     ` Andrew Lunn
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 23+ messages in thread
From: Jakub Kicinski @ 2024-05-11  2:08 UTC (permalink / raw
  To: Jitendra Vegiraju
  Cc: netdev, davem, edumazet, pabeni, bcm-kernel-feedback-list,
	alexandre.torgue, joabreu, mcoquelin.stm32, richardcochran,
	linux-kernel, linux-stm32, linux-arm-kernel

On Fri, 10 May 2024 18:59:24 -0700 Jitendra Vegiraju wrote:
> v2: code cleanup to address patchwork reports.

Please read:

https://www.kernel.org/doc/html/next/process/maintainer-netdev.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11  1:59   ` [PATCH v2, " Jitendra Vegiraju
  2024-05-11  2:08     ` Jakub Kicinski
@ 2024-05-11 16:16     ` Andrew Lunn
  2024-05-11 17:12       ` Russell King (Oracle)
  2024-05-11 19:34     ` Russell King (Oracle)
  2024-05-12  8:35     ` Simon Horman
  3 siblings, 1 reply; 23+ messages in thread
From: Andrew Lunn @ 2024-05-11 16:16 UTC (permalink / raw
  To: Jitendra Vegiraju
  Cc: netdev, davem, edumazet, kuba, pabeni, bcm-kernel-feedback-list,
	alexandre.torgue, joabreu, mcoquelin.stm32, richardcochran,
	linux-kernel, linux-stm32, linux-arm-kernel

> +	/* This device interface is directly attached to the switch chip on
> +	 *  the SoC. Since no MDIO is present, register fixed_phy.
> +	 */
> +	brcm_priv->phy_dev =
> +		 fixed_phy_register(PHY_POLL,
> +				    &dwxgmac_brcm_fixed_phy_status, NULL);
> +	if (IS_ERR(brcm_priv->phy_dev)) {
> +		dev_err(&pdev->dev, "%s\tNo PHY/fixed_PHY found\n", __func__);
> +		return -ENODEV;
> +	}
> +	phy_attached_info(brcm_priv->phy_dev);

What switch is it? Will there be patches to extend SF2?

	Andrew


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11 16:16     ` Andrew Lunn
@ 2024-05-11 17:12       ` Russell King (Oracle)
  2024-05-11 17:19         ` Andrew Lunn
  2024-05-11 17:50         ` Andrew Lunn
  0 siblings, 2 replies; 23+ messages in thread
From: Russell King (Oracle) @ 2024-05-11 17:12 UTC (permalink / raw
  To: Andrew Lunn
  Cc: Jitendra Vegiraju, netdev, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel

On Sat, May 11, 2024 at 06:16:52PM +0200, Andrew Lunn wrote:
> > +	/* This device interface is directly attached to the switch chip on
> > +	 *  the SoC. Since no MDIO is present, register fixed_phy.
> > +	 */
> > +	brcm_priv->phy_dev =
> > +		 fixed_phy_register(PHY_POLL,
> > +				    &dwxgmac_brcm_fixed_phy_status, NULL);
> > +	if (IS_ERR(brcm_priv->phy_dev)) {
> > +		dev_err(&pdev->dev, "%s\tNo PHY/fixed_PHY found\n", __func__);
> > +		return -ENODEV;
> > +	}
> > +	phy_attached_info(brcm_priv->phy_dev);
> 
> What switch is it? Will there be patches to extend SF2?

... and why is this legacy fixed_phy even necessary when stmmac uses
phylink which supports fixed links, including with custom fixed status?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11 17:12       ` Russell King (Oracle)
@ 2024-05-11 17:19         ` Andrew Lunn
  2024-05-11 19:35           ` Russell King (Oracle)
  2024-05-11 17:50         ` Andrew Lunn
  1 sibling, 1 reply; 23+ messages in thread
From: Andrew Lunn @ 2024-05-11 17:19 UTC (permalink / raw
  To: Russell King (Oracle)
  Cc: Jitendra Vegiraju, netdev, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel

On Sat, May 11, 2024 at 06:12:38PM +0100, Russell King (Oracle) wrote:
> On Sat, May 11, 2024 at 06:16:52PM +0200, Andrew Lunn wrote:
> > > +	/* This device interface is directly attached to the switch chip on
> > > +	 *  the SoC. Since no MDIO is present, register fixed_phy.
> > > +	 */
> > > +	brcm_priv->phy_dev =
> > > +		 fixed_phy_register(PHY_POLL,
> > > +				    &dwxgmac_brcm_fixed_phy_status, NULL);
> > > +	if (IS_ERR(brcm_priv->phy_dev)) {
> > > +		dev_err(&pdev->dev, "%s\tNo PHY/fixed_PHY found\n", __func__);
> > > +		return -ENODEV;
> > > +	}
> > > +	phy_attached_info(brcm_priv->phy_dev);
> > 
> > What switch is it? Will there be patches to extend SF2?
> 
> ... and why is this legacy fixed_phy even necessary when stmmac uses
> phylink which supports fixed links, including with custom fixed status?

It might be because it is a PCI device, and they are trying to avoid
DT? Maybe because they have not figured out how to add DT properties
to a PCI device. It is possible.

	Andrew

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11 17:12       ` Russell King (Oracle)
  2024-05-11 17:19         ` Andrew Lunn
@ 2024-05-11 17:50         ` Andrew Lunn
  2024-05-11 19:36           ` Russell King (Oracle)
  2024-05-13 17:32           ` Jitendra Vegiraju
  1 sibling, 2 replies; 23+ messages in thread
From: Andrew Lunn @ 2024-05-11 17:50 UTC (permalink / raw
  To: Russell King (Oracle)
  Cc: Jitendra Vegiraju, netdev, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel

On Sat, May 11, 2024 at 06:12:38PM +0100, Russell King (Oracle) wrote:
> On Sat, May 11, 2024 at 06:16:52PM +0200, Andrew Lunn wrote:
> > > +	/* This device interface is directly attached to the switch chip on
> > > +	 *  the SoC. Since no MDIO is present, register fixed_phy.
> > > +	 */
> > > +	brcm_priv->phy_dev =
> > > +		 fixed_phy_register(PHY_POLL,
> > > +				    &dwxgmac_brcm_fixed_phy_status, NULL);
> > > +	if (IS_ERR(brcm_priv->phy_dev)) {
> > > +		dev_err(&pdev->dev, "%s\tNo PHY/fixed_PHY found\n", __func__);
> > > +		return -ENODEV;
> > > +	}
> > > +	phy_attached_info(brcm_priv->phy_dev);
> > 
> > What switch is it? Will there be patches to extend SF2?
> 
> ... and why is this legacy fixed_phy even necessary when stmmac uses
> phylink which supports fixed links, including with custom fixed status?

And now you mentions legacy Fixed link:

+MODULE_DESCRIPTION("Broadcom 10G Automotive Ethernet PCIe driver");

This claims it is a 10G device. You cannot represent 10G using legacy
fixed link.

Does this MAC directly connect to the switch within the SoC? There is
no external MII interface? Realtek have been posting a MAC driver for
something similar were the MAC is directly connected to the switch
within the SoC. The MAC is fixed at 5G, there is no phylink/phylib
support, set_link_ksetting return -EOPNOTSUPP and get_link_ksettings
returns hard coded 5G.

We need a better understanding of the architecture here, before we can
advise the correct way to do this.

      Andrew

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11  1:59   ` [PATCH v2, " Jitendra Vegiraju
  2024-05-11  2:08     ` Jakub Kicinski
  2024-05-11 16:16     ` Andrew Lunn
@ 2024-05-11 19:34     ` Russell King (Oracle)
  2024-05-13 17:38       ` Jitendra Vegiraju
  2024-05-12  8:35     ` Simon Horman
  3 siblings, 1 reply; 23+ messages in thread
From: Russell King (Oracle) @ 2024-05-11 19:34 UTC (permalink / raw
  To: Jitendra Vegiraju
  Cc: netdev, davem, edumazet, kuba, pabeni, bcm-kernel-feedback-list,
	alexandre.torgue, joabreu, mcoquelin.stm32, richardcochran,
	linux-kernel, linux-stm32, linux-arm-kernel

Hi,

Thanks for the patch,. but there are things that need some improvement.

On Fri, May 10, 2024 at 06:59:24PM -0700, Jitendra Vegiraju wrote:
> +static void dwxgmac_brcm_dma_init_tx_chan(struct stmmac_priv *priv,
> +					  void __iomem *ioaddr,
> +					  struct stmmac_dma_cfg *dma_cfg,
> +					  dma_addr_t phy, u32 chan)
> +{
> +	u32 value;
> +
> +	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
> +	value &= ~XGMAC_TxPBL;
> +	value &= ~GENMASK(6, 4);
> +	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
> +
> +	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chan));
> +	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));

Please use "dma_addr" not "phy" here. "phy" could mean ethernet phy.
I personally dislike "physical address" for DMA stuff because if
there's an IOMMU or other translation layer present, what you have
here is *not* a physical address.

> +static void dwxgmac_brcm_dma_init_rx_chan(struct stmmac_priv *priv,
> +					  void __iomem *ioaddr,
> +					  struct stmmac_dma_cfg *dma_cfg,
> +					  dma_addr_t phy, u32 chan)
> +{
> +	u32 value;
> +
> +	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
> +	value &= ~XGMAC_RxPBL;
> +	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
> +
> +	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chan));
> +	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));

Ditto.

...

> +static void dwxgmac_brcm_fix_speed(void *priv, unsigned int speed,
> +				   unsigned int mode)
> +{
> +}

If this is empty, do you really need it? The method is optional.

...

> +static int dwxgmac_brcm_pci_probe(struct pci_dev *pdev,
> +				  const struct pci_device_id *id)
> +{
...
> +	/* This device interface is directly attached to the switch chip on
> +	 *  the SoC. Since no MDIO is present, register fixed_phy.
> +	 */
> +	brcm_priv->phy_dev =
> +		 fixed_phy_register(PHY_POLL,
> +				    &dwxgmac_brcm_fixed_phy_status, NULL);
> +	if (IS_ERR(brcm_priv->phy_dev)) {
> +		dev_err(&pdev->dev, "%s\tNo PHY/fixed_PHY found\n", __func__);
> +		return -ENODEV;
> +	}
> +	phy_attached_info(brcm_priv->phy_dev);

As pointed out in the other sub-thread, you don't need this. If you need
a fixed-link and you don't have a firmware description of it, you can
provide a swnode based description through plat->port_node that will be
passed to phylink. Through that, you can tell phylink to create a
fixed link.

> +	ret = stmmac_dvr_probe(&pdev->dev, plat, &res);
> +	if (ret)
> +		goto err_disable_msi;
> +
> +	/* The stmmac core driver doesn't have the infrastructure to
> +	 * support fixed-phy mdio bus for non-platform bus drivers.
> +	 * Until a better solution is implemented, initialize the
> +	 * following entries after priv structure is populated.
> +	 */
> +	ndev = dev_get_drvdata(&pdev->dev);
> +	priv = netdev_priv(ndev);
> +	priv->mii = mdio_find_bus("fixed-0");
> +
> +	ndev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX;
> +	priv->hw->hw_vlan_en = false;

Basically... no. Do not do any setup after stmmac_dvr_probe(), because
the network device has already been registered and published to
userspace, and userspace may have already opened the network device.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11 17:19         ` Andrew Lunn
@ 2024-05-11 19:35           ` Russell King (Oracle)
  0 siblings, 0 replies; 23+ messages in thread
From: Russell King (Oracle) @ 2024-05-11 19:35 UTC (permalink / raw
  To: Andrew Lunn
  Cc: Jitendra Vegiraju, netdev, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel

On Sat, May 11, 2024 at 07:19:07PM +0200, Andrew Lunn wrote:
> It might be because it is a PCI device, and they are trying to avoid
> DT? Maybe because they have not figured out how to add DT properties
> to a PCI device. It is possible.

swnodes.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11 17:50         ` Andrew Lunn
@ 2024-05-11 19:36           ` Russell King (Oracle)
  2024-05-13 17:32           ` Jitendra Vegiraju
  1 sibling, 0 replies; 23+ messages in thread
From: Russell King (Oracle) @ 2024-05-11 19:36 UTC (permalink / raw
  To: Andrew Lunn
  Cc: Jitendra Vegiraju, netdev, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel

On Sat, May 11, 2024 at 07:50:03PM +0200, Andrew Lunn wrote:
> And now you mentions legacy Fixed link:
> 
> +MODULE_DESCRIPTION("Broadcom 10G Automotive Ethernet PCIe driver");
> 
> This claims it is a 10G device. You cannot represent 10G using legacy
> fixed link.

While it may be a 10G device, it seems the fixed-link specification
in the driver is set to 1G !

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11  1:59   ` [PATCH v2, " Jitendra Vegiraju
                       ` (2 preceding siblings ...)
  2024-05-11 19:34     ` Russell King (Oracle)
@ 2024-05-12  8:35     ` Simon Horman
  3 siblings, 0 replies; 23+ messages in thread
From: Simon Horman @ 2024-05-12  8:35 UTC (permalink / raw
  To: Jitendra Vegiraju
  Cc: netdev, davem, edumazet, kuba, pabeni, bcm-kernel-feedback-list,
	alexandre.torgue, joabreu, mcoquelin.stm32, richardcochran,
	linux-kernel, linux-stm32, linux-arm-kernel

On Fri, May 10, 2024 at 06:59:24PM -0700, Jitendra Vegiraju wrote:
> Broadcom BCM8958X SoCs use Synopsys XGMAC design, which is similar to
> dwxgmac2 core implementation in stmmac driver. The existing dwxgmac2 dma
> operation functions have some conflicting differences with BCM8958X.
> This glue driver attempts to reuse dwxgmac2 implementation wherever
> possible, adding alternative implementations where necessary.
> 
> v2: code cleanup to address patchwork reports.
> 
> Signed-off-by: Jitendra Vegiraju <jitendra.vegiraju@broadcom.com>

...

> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c

...

> +static struct mac_device_info *dwxgmac_brcm_setup(void *ppriv)
> +{
> +	struct mac_device_info *mac;
> +	struct stmmac_priv *priv = ppriv;

Hi, Jitendra,

A minor nit from my side.

Please consider using reverse xmas tree order - longest line to shortest -
for new Networking code.

This tool can be of assistance: https://github.com/ecree-solarflare/xmastree

...

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11  2:08     ` Jakub Kicinski
@ 2024-05-13 16:47       ` Jitendra Vegiraju
  0 siblings, 0 replies; 23+ messages in thread
From: Jitendra Vegiraju @ 2024-05-13 16:47 UTC (permalink / raw
  To: Jakub Kicinski
  Cc: netdev, davem, edumazet, pabeni, bcm-kernel-feedback-list,
	alexandre.torgue, joabreu, mcoquelin.stm32, richardcochran,
	linux-kernel, linux-stm32, linux-arm-kernel

Sorry, I will review the process before sending next patch update.
Thank you for the link.

On Fri, May 10, 2024 at 7:08 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Fri, 10 May 2024 18:59:24 -0700 Jitendra Vegiraju wrote:
> > v2: code cleanup to address patchwork reports.
>
> Please read:
>
> https://www.kernel.org/doc/html/next/process/maintainer-netdev.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11 17:50         ` Andrew Lunn
  2024-05-11 19:36           ` Russell King (Oracle)
@ 2024-05-13 17:32           ` Jitendra Vegiraju
  2024-05-13 18:07             ` Andrew Lunn
  2024-05-14  8:19             ` Russell King (Oracle)
  1 sibling, 2 replies; 23+ messages in thread
From: Jitendra Vegiraju @ 2024-05-13 17:32 UTC (permalink / raw
  To: Andrew Lunn
  Cc: Russell King (Oracle), netdev, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel

On Sat, May 11, 2024 at 10:50 AM Andrew Lunn <andrew@lunn.ch> wrote:
>
> On Sat, May 11, 2024 at 06:12:38PM +0100, Russell King (Oracle) wrote:
> > On Sat, May 11, 2024 at 06:16:52PM +0200, Andrew Lunn wrote:
> > > > + /* This device interface is directly attached to the switch chip on
> > > > +  *  the SoC. Since no MDIO is present, register fixed_phy.
> > > > +  */
> > > > + brcm_priv->phy_dev =
> > > > +          fixed_phy_register(PHY_POLL,
> > > > +                             &dwxgmac_brcm_fixed_phy_status, NULL);
> > > > + if (IS_ERR(brcm_priv->phy_dev)) {
> > > > +         dev_err(&pdev->dev, "%s\tNo PHY/fixed_PHY found\n", __func__);
> > > > +         return -ENODEV;
> > > > + }
> > > > + phy_attached_info(brcm_priv->phy_dev);
> > >
> > > What switch is it? Will there be patches to extend SF2?
> >
> > ... and why is this legacy fixed_phy even necessary when stmmac uses
> > phylink which supports fixed links, including with custom fixed status?
>
> And now you mentions legacy Fixed link:
>
> +MODULE_DESCRIPTION("Broadcom 10G Automotive Ethernet PCIe driver");
>
> This claims it is a 10G device. You cannot represent 10G using legacy
> fixed link.
>
> Does this MAC directly connect to the switch within the SoC? There is
> no external MII interface? Realtek have been posting a MAC driver for
> something similar were the MAC is directly connected to the switch
> within the SoC. The MAC is fixed at 5G, there is no phylink/phylib
> support, set_link_ksetting return -EOPNOTSUPP and get_link_ksettings
> returns hard coded 5G.
>
> We need a better understanding of the architecture here, before we can
> advise the correct way to do this.
>
Yes, the MAC directly connects to switch within the SoC with no external MII.
The SoC is BCM89586M/BCM89587 automotive ethernet switch.
The SOC presents PCIE interfaces on BCM89586M/BCM89587 automotive
ethernet switch.
The switch supports many ethernet interfaces out of which one or two
interfaces are presented as PCIE endpoints to the host connected on
the PCIE bus.
The MAC connects to switch using XGMII interface internal to the SOC.
The high level diagram is shown below:

+==================================================+
   +--------+                     |                     BCM8958X
switch SoC               +----------------+         |
   | Host   |                      |  +----------------+
    +-------+                 |                     |         | ===
more ethernet IFs
   | CPU   | ===PCIE===| PCIE endpoint |==DMA==| MAC |==XGMII==|
switch fabric |         | === more ethernet IFs
   |Linux   |                      | +----------------+
   +-------+                 |                      |         |
   +-------+                       |
                                      +-----------------+        |

+==================================================+
Since the legacy fixed link cannot support 10G, we are initializing to
fixed speed 1G.
>       Andrew

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-11 19:34     ` Russell King (Oracle)
@ 2024-05-13 17:38       ` Jitendra Vegiraju
  2024-05-13 17:41         ` Russell King (Oracle)
  0 siblings, 1 reply; 23+ messages in thread
From: Jitendra Vegiraju @ 2024-05-13 17:38 UTC (permalink / raw
  To: Russell King (Oracle)
  Cc: netdev, davem, edumazet, kuba, pabeni, bcm-kernel-feedback-list,
	alexandre.torgue, joabreu, mcoquelin.stm32, richardcochran,
	linux-kernel, linux-stm32, linux-arm-kernel

Thanks for reviewing the patch.
On Sat, May 11, 2024 at 12:34 PM Russell King (Oracle)
<linux@armlinux.org.uk> wrote:
>
> Hi,
>
> Thanks for the patch,. but there are things that need some improvement.
>
> On Fri, May 10, 2024 at 06:59:24PM -0700, Jitendra Vegiraju wrote:
> > +static void dwxgmac_brcm_dma_init_tx_chan(struct stmmac_priv *priv,
> > +                                       void __iomem *ioaddr,
> > +                                       struct stmmac_dma_cfg *dma_cfg,
> > +                                       dma_addr_t phy, u32 chan)
> > +{
> > +     u32 value;
> > +
> > +     value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
> > +     value &= ~XGMAC_TxPBL;
> > +     value &= ~GENMASK(6, 4);
> > +     writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
> > +
> > +     writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chan));
> > +     writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));
>
> Please use "dma_addr" not "phy" here. "phy" could mean ethernet phy.
> I personally dislike "physical address" for DMA stuff because if
> there's an IOMMU or other translation layer present, what you have
> here is *not* a physical address.
>
Yes, we will address it.
> > +static void dwxgmac_brcm_dma_init_rx_chan(struct stmmac_priv *priv,
> > +                                       void __iomem *ioaddr,
> > +                                       struct stmmac_dma_cfg *dma_cfg,
> > +                                       dma_addr_t phy, u32 chan)
> > +{
> > +     u32 value;
> > +
> > +     value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
> > +     value &= ~XGMAC_RxPBL;
> > +     writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
> > +
> > +     writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chan));
> > +     writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));
>
> Ditto.
>
Noted.
> ...
>
> > +static void dwxgmac_brcm_fix_speed(void *priv, unsigned int speed,
> > +                                unsigned int mode)
> > +{
> > +}
>
> If this is empty, do you really need it? The method is optional.
>
> ...
>
> > +static int dwxgmac_brcm_pci_probe(struct pci_dev *pdev,
> > +                               const struct pci_device_id *id)
> > +{
> ...
> > +     /* This device interface is directly attached to the switch chip on
> > +      *  the SoC. Since no MDIO is present, register fixed_phy.
> > +      */
> > +     brcm_priv->phy_dev =
> > +              fixed_phy_register(PHY_POLL,
> > +                                 &dwxgmac_brcm_fixed_phy_status, NULL);
> > +     if (IS_ERR(brcm_priv->phy_dev)) {
> > +             dev_err(&pdev->dev, "%s\tNo PHY/fixed_PHY found\n", __func__);
> > +             return -ENODEV;
> > +     }
> > +     phy_attached_info(brcm_priv->phy_dev);
>
> As pointed out in the other sub-thread, you don't need this. If you need
> a fixed-link and you don't have a firmware description of it, you can
> provide a swnode based description through plat->port_node that will be
> passed to phylink. Through that, you can tell phylink to create a
> fixed link.
>
Thank you for the pointers or software node support.
Since the driver is initially targetted for X86/_64, we were not sure
how to deal with lack of OF support.
We will try out the software node facility.
> > +     ret = stmmac_dvr_probe(&pdev->dev, plat, &res);
> > +     if (ret)
> > +             goto err_disable_msi;
> > +
> > +     /* The stmmac core driver doesn't have the infrastructure to
> > +      * support fixed-phy mdio bus for non-platform bus drivers.
> > +      * Until a better solution is implemented, initialize the
> > +      * following entries after priv structure is populated.
> > +      */
> > +     ndev = dev_get_drvdata(&pdev->dev);
> > +     priv = netdev_priv(ndev);
> > +     priv->mii = mdio_find_bus("fixed-0");
> > +
> > +     ndev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX;
> > +     priv->hw->hw_vlan_en = false;
>
> Basically... no. Do not do any setup after stmmac_dvr_probe(), because
> the network device has already been registered and published to
> userspace, and userspace may have already opened the network device.
>
This will be tied to the above topic.
> --
> RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
> FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-13 17:38       ` Jitendra Vegiraju
@ 2024-05-13 17:41         ` Russell King (Oracle)
  2024-05-13 19:52           ` Andrew Lunn
  0 siblings, 1 reply; 23+ messages in thread
From: Russell King (Oracle) @ 2024-05-13 17:41 UTC (permalink / raw
  To: Jitendra Vegiraju
  Cc: netdev, davem, edumazet, kuba, pabeni, bcm-kernel-feedback-list,
	alexandre.torgue, joabreu, mcoquelin.stm32, richardcochran,
	linux-kernel, linux-stm32, linux-arm-kernel

On Mon, May 13, 2024 at 10:38:46AM -0700, Jitendra Vegiraju wrote:
> Thanks for reviewing the patch.
> On Sat, May 11, 2024 at 12:34 PM Russell King (Oracle)
> <linux@armlinux.org.uk> wrote:
> > As pointed out in the other sub-thread, you don't need this. If you need
> > a fixed-link and you don't have a firmware description of it, you can
> > provide a swnode based description through plat->port_node that will be
> > passed to phylink. Through that, you can tell phylink to create a
> > fixed link.
> >
> Thank you for the pointers or software node support.
> Since the driver is initially targetted for X86/_64, we were not sure
> how to deal with lack of OF support.
> We will try out the software node facility.

You may wish to have a look at drivers/net/ethernet/wangxun/ which
also creates software nodes for phylink.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-13 17:32           ` Jitendra Vegiraju
@ 2024-05-13 18:07             ` Andrew Lunn
  2024-05-14  8:19             ` Russell King (Oracle)
  1 sibling, 0 replies; 23+ messages in thread
From: Andrew Lunn @ 2024-05-13 18:07 UTC (permalink / raw
  To: Jitendra Vegiraju
  Cc: Russell King (Oracle), netdev, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel

> Yes, the MAC directly connects to switch within the SoC with no external MII.
> The SoC is BCM89586M/BCM89587 automotive ethernet switch.
> The SOC presents PCIE interfaces on BCM89586M/BCM89587 automotive
> ethernet switch.
> The switch supports many ethernet interfaces out of which one or two
> interfaces are presented as PCIE endpoints to the host connected on
> the PCIE bus.
> The MAC connects to switch using XGMII interface internal to the SOC.
> The high level diagram is shown below:
> 
> +==================================================+
>    +--------+                     |                     BCM8958X
> switch SoC               +----------------+         |
>    | Host   |                      |  +----------------+
>     +-------+                 |                     |         | ===
> more ethernet IFs
>    | CPU   | ===PCIE===| PCIE endpoint |==DMA==| MAC |==XGMII==|
> switch fabric |         | === more ethernet IFs
>    |Linux   |                      | +----------------+
>    +-------+                 |                      |         |
>    +-------+                       |
>                                       +-----------------+        |
> 
> +==================================================+
> Since the legacy fixed link cannot support 10G, we are initializing to
> fixed speed 1G.

You ASCII art is broken, probably because you are not using a fixed
width font.

So the interface between the MAC and the switch is fixed at XGMII. Is
the MAC actually capable of anything other than XGMII? If XGMII is all
it can do, then there is no need for a fixed link. You use a
fixed-link when you have a conventional off the shelf MAC which can do
10BaseT_Half through to 10GBaseT. Normally there would be a PHY
connected to the MAC and phylib/phylink will determine the line rate
and tell the MAC what speed to operate at. However, if this device
only supports XGMII, it is impossible to connect to a PHY because
there is no external MII interface, then skip all the phylib/phylink
support and hard code it. Look at the patches on the netdev list for
the RealTek automotive driver which seems to be pretty similar.

	   Andrew

	       

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-13 17:41         ` Russell King (Oracle)
@ 2024-05-13 19:52           ` Andrew Lunn
  0 siblings, 0 replies; 23+ messages in thread
From: Andrew Lunn @ 2024-05-13 19:52 UTC (permalink / raw
  To: Russell King (Oracle)
  Cc: Jitendra Vegiraju, netdev, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel, Herve Codina

On Mon, May 13, 2024 at 06:41:35PM +0100, Russell King (Oracle) wrote:
> On Mon, May 13, 2024 at 10:38:46AM -0700, Jitendra Vegiraju wrote:
> > Thanks for reviewing the patch.
> > On Sat, May 11, 2024 at 12:34 PM Russell King (Oracle)
> > <linux@armlinux.org.uk> wrote:
> > > As pointed out in the other sub-thread, you don't need this. If you need
> > > a fixed-link and you don't have a firmware description of it, you can
> > > provide a swnode based description through plat->port_node that will be
> > > passed to phylink. Through that, you can tell phylink to create a
> > > fixed link.
> > >
> > Thank you for the pointers or software node support.
> > Since the driver is initially targetted for X86/_64, we were not sure
> > how to deal with lack of OF support.
> > We will try out the software node facility.
> 
> You may wish to have a look at drivers/net/ethernet/wangxun/ which
> also creates software nodes for phylink.

How complex is the switch configuration? So far, you have not said
anything about it. Is it derived from b53/SF2?

There is an alternative route you can take. Work with bootlin and use
DT overlays.

https://lore.kernel.org/linux-pci/20240430083730.134918-1-herve.codina@bootlin.com/

Looking at the product brief, the BCM89586M has MDIO busses, SPI
busses, GPIO, etc. It is unclear if these are available on the PCIe
interface, or are only connected to the Cortex-M7? I would guess the
QSPI, DEBUG/JTAG and the UART go to the M7, for its boot media and
console. But the other interfaces could be for Linux to control over
the PCIe. Additionally, the PHY-less ports doing XFI, 5G, 2.5G SGMII
etc, would have either an SFP or multi-gigi PHY connected, hanging of
one of the MDIO busses, GPIOs used for SFP LOS, TX-enable etc. Oddly
there is no I2C for the SPF, but i suppose you could do SPI->I2C.
Anyway, all that is going to need a complex configuration, so maybe DT
overlays make sense, because once the initial work getting Bootlins
patches merged is complete, you get the rest pretty much for free.

	Andrew

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-13 17:32           ` Jitendra Vegiraju
  2024-05-13 18:07             ` Andrew Lunn
@ 2024-05-14  8:19             ` Russell King (Oracle)
  2024-05-14 16:18               ` Florian Fainelli
  1 sibling, 1 reply; 23+ messages in thread
From: Russell King (Oracle) @ 2024-05-14  8:19 UTC (permalink / raw
  To: Jitendra Vegiraju
  Cc: Andrew Lunn, netdev, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel

On Mon, May 13, 2024 at 10:32:19AM -0700, Jitendra Vegiraju wrote:
> +==================================================+
> Since the legacy fixed link cannot support 10G, we are initializing to
> fixed speed 1G.

Or to put it a different way... "I can't represent my hardware so I'm
going to hack around with the kernel in a way that lies to the kernel
about what the hardware is doing but it'll work for me!"

Sorry, but no, this isn't some hacky github project, this is the kernel
where we engineer proper solutions.

I think I've just lost all interest in this... 

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-14  8:19             ` Russell King (Oracle)
@ 2024-05-14 16:18               ` Florian Fainelli
  0 siblings, 0 replies; 23+ messages in thread
From: Florian Fainelli @ 2024-05-14 16:18 UTC (permalink / raw
  To: Russell King (Oracle), Jitendra Vegiraju
  Cc: Andrew Lunn, netdev, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list, alexandre.torgue, joabreu,
	mcoquelin.stm32, richardcochran, linux-kernel, linux-stm32,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 1416 bytes --]

On 5/14/24 01:19, Russell King (Oracle) wrote:
> On Mon, May 13, 2024 at 10:32:19AM -0700, Jitendra Vegiraju wrote:
>> +==================================================+
>> Since the legacy fixed link cannot support 10G, we are initializing to
>> fixed speed 1G.
> 
> Or to put it a different way... "I can't represent my hardware so I'm
> going to hack around with the kernel in a way that lies to the kernel
> about what the hardware is doing but it'll work for me!"
> 
> Sorry, but no, this isn't some hacky github project, this is the kernel
> where we engineer proper solutions.

You are painting a picture of someone who is a first time contributor to 
Linux, there should not be any ill intentions at that point, just a 
knowledge gap that needs to be filled.

When I reviewed the patches internally the topic of fixed-link versus 
using PHYLINK did come up, and I should have dug a lot more and asked 
more questions to understand the full picture. Since the bulk of the 
changes had to do with hooking up a different DMA engine and 
configuration, I focused on that part and let the PHY connectivity 
aspect slip.

I will work with Jitendra to bring him up to speed with the software 
nodes, the work that Herve is doing on supporting OF overlays with PCIe 
root complexes and when net-next re-opens, we should have a different 
submission for you to look at then.

Thanks for your patience.
-- 
Florian


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4221 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
  2024-05-10  0:03 ` [PATCH, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC Jitendra Vegiraju
  2024-05-11  1:35   ` Jakub Kicinski
  2024-05-11  1:59   ` [PATCH v2, " Jitendra Vegiraju
@ 2024-05-17 23:50   ` kernel test robot
  2 siblings, 0 replies; 23+ messages in thread
From: kernel test robot @ 2024-05-17 23:50 UTC (permalink / raw
  To: Jitendra Vegiraju, netdev
  Cc: oe-kbuild-all, jitendra.vegiraju, davem, edumazet, kuba, pabeni,
	bcm-kernel-feedback-list

Hi Jitendra,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.9 next-20240517]
[cannot apply to horms-ipvs/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Jitendra-Vegiraju/net-stmmac-Export-dma_ops-for-reuse-in-glue-drivers/20240511-141147
base:   linus/master
patch link:    https://lore.kernel.org/r/20240510000331.154486-3-jitendra.vegiraju%40broadcom.com
patch subject: [PATCH, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC
config: parisc-randconfig-r111-20240518 (https://download.01.org/0day-ci/archive/20240518/202405180744.BCWHYhmN-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20240518/202405180744.BCWHYhmN-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405180744.BCWHYhmN-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c:210:29: sparse: sparse: symbol 'dwxgmac_brcm_dma_ops' was not declared. Should it be static?

vim +/dwxgmac_brcm_dma_ops +210 drivers/net/ethernet/stmicro/stmmac/dwmac-brcm.c

   209	
 > 210	const struct stmmac_dma_ops dwxgmac_brcm_dma_ops = {
   211		.reset = dwxgmac2_dma_reset,
   212		.init = dwxgmac_brcm_dma_init,
   213		.init_chan = dwxgmac2_dma_init_chan,
   214		.init_rx_chan = dwxgmac_brcm_dma_init_rx_chan,
   215		.init_tx_chan = dwxgmac_brcm_dma_init_tx_chan,
   216		.axi = dwxgmac2_dma_axi,
   217		.dump_regs = dwxgmac2_dma_dump_regs,
   218		.dma_rx_mode = dwxgmac2_dma_rx_mode,
   219		.dma_tx_mode = dwxgmac2_dma_tx_mode,
   220		.enable_dma_irq = dwxgmac2_enable_dma_irq,
   221		.disable_dma_irq = dwxgmac2_disable_dma_irq,
   222		.start_tx = dwxgmac2_dma_start_tx,
   223		.stop_tx = dwxgmac2_dma_stop_tx,
   224		.start_rx = dwxgmac2_dma_start_rx,
   225		.stop_rx = dwxgmac2_dma_stop_rx,
   226		.dma_interrupt = dwxgmac2_dma_interrupt,
   227		.get_hw_feature = dwxgmac2_get_hw_feature,
   228		.rx_watchdog = dwxgmac2_rx_watchdog,
   229		.set_rx_ring_len = dwxgmac2_set_rx_ring_len,
   230		.set_tx_ring_len = dwxgmac2_set_tx_ring_len,
   231		.set_rx_tail_ptr = dwxgmac2_set_rx_tail_ptr,
   232		.set_tx_tail_ptr = dwxgmac2_set_tx_tail_ptr,
   233		.enable_tso = dwxgmac2_enable_tso,
   234		.qmode = dwxgmac2_qmode,
   235		.set_bfsize = dwxgmac2_set_bfsize,
   236		.enable_sph = dwxgmac2_enable_sph,
   237		.enable_tbs = dwxgmac2_enable_tbs,
   238	};
   239	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2024-05-17 23:55 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-10  0:03 [PATCH, net-next, 0/2] net: stmmac: support for BCM8958x SoC Jitendra Vegiraju
2024-05-10  0:03 ` [PATCH, net-next, 1/2] net: stmmac: Export dma_ops for reuse in glue drivers Jitendra Vegiraju
2024-05-10  0:03 ` [PATCH, net-next, 2/2] net: stmmac: PCI driver for BCM8958X SoC Jitendra Vegiraju
2024-05-11  1:35   ` Jakub Kicinski
2024-05-11  1:59   ` [PATCH v2, " Jitendra Vegiraju
2024-05-11  2:08     ` Jakub Kicinski
2024-05-13 16:47       ` Jitendra Vegiraju
2024-05-11 16:16     ` Andrew Lunn
2024-05-11 17:12       ` Russell King (Oracle)
2024-05-11 17:19         ` Andrew Lunn
2024-05-11 19:35           ` Russell King (Oracle)
2024-05-11 17:50         ` Andrew Lunn
2024-05-11 19:36           ` Russell King (Oracle)
2024-05-13 17:32           ` Jitendra Vegiraju
2024-05-13 18:07             ` Andrew Lunn
2024-05-14  8:19             ` Russell King (Oracle)
2024-05-14 16:18               ` Florian Fainelli
2024-05-11 19:34     ` Russell King (Oracle)
2024-05-13 17:38       ` Jitendra Vegiraju
2024-05-13 17:41         ` Russell King (Oracle)
2024-05-13 19:52           ` Andrew Lunn
2024-05-12  8:35     ` Simon Horman
2024-05-17 23:50   ` [PATCH, " kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).