[net-next,5/8] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability bit

Message ID ZIUXf9APDFCNaUG1@makrotopia.org
State New
Headers
Series [net-next,1/8] dt-bindings: net: mediatek,net: add mt7988-eth binding |

Commit Message

Daniel Golle June 11, 2023, 12:38 a.m. UTC
  From: Lorenzo Bianconi <lorenzo@kernel.org>

Introduce MTK_NETSYS_V3 bit in the device capabilities.
This is a preliminary patch to introduce support for MT7988 SoC.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 115 ++++++++++++++++----
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  37 ++++++-
 2 files changed, 127 insertions(+), 25 deletions(-)
  

Comments

Russell King (Oracle) June 12, 2023, 11:19 a.m. UTC | #1
On Sun, Jun 11, 2023 at 01:38:23AM +0100, Daniel Golle wrote:
> @@ -1333,8 +1354,13 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
>  	mtk_tx_set_dma_desc(dev, itxd, &txd_info);
>  
>  	itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
> -	itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
> -			  MTK_TX_FLAGS_FPORT1;
> +	if (mac->id == MTK_GMAC1_ID)
> +		itx_buf->flags |= MTK_TX_FLAGS_FPORT0;
> +	else if (mac->id == MTK_GMAC2_ID)
> +		itx_buf->flags |= MTK_TX_FLAGS_FPORT1;
> +	else
> +		itx_buf->flags |= MTK_TX_FLAGS_FPORT2;

There appears to be two places that this code structure appears, and
this is in the path for packet transmission. I wonder if it would be
more efficient to instead do:

	itx_buf->flags |= MTK_TX_FLAGS_SINGLE0 | mac->tx_flags;

with mac->tx_flags appropriately initialised?

> @@ -2170,7 +2214,9 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget,
>  		tx_buf = mtk_desc_to_tx_buf(ring, desc,
>  					    eth->soc->txrx.txd_size);
>  		if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
> -			mac = 1;
> +			mac = MTK_GMAC2_ID;
> +		else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2)
> +			mac = MTK_GMAC3_ID;

This has me wondering whether the flags are used for hardware or just
for the driver's purposes. If it's the latter, can we instead store the
MAC index in tx_buf, rather than having to decode a bitfield?

I suspect these are just for the driver given that the addition of
MTK_TX_FLAGS_FPORT2 changes all subsequent bit numbers in this struct
member.

>  
>  		if (!tx_buf->data)
>  			break;
> @@ -3783,7 +3829,26 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
>  	mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
>  	mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
>  
> -	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
> +	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
> +		/* PSE should not drop port1, port8 and port9 packets */
> +		mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
> +
> +		/* GDM and CDM Threshold */
> +		mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
> +		mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
> +
> +		/* Disable GDM1 RX CRC stripping */
> +		val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0));
> +		val &= ~MTK_GDMA_STRP_CRC;
> +		mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0));

mtk_m32() ?

Thanks!
  
Lorenzo Bianconi June 12, 2023, 10:16 p.m. UTC | #2
> On Sun, Jun 11, 2023 at 01:38:23AM +0100, Daniel Golle wrote:
> > @@ -1333,8 +1354,13 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
> >  	mtk_tx_set_dma_desc(dev, itxd, &txd_info);
> >  
> >  	itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
> > -	itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
> > -			  MTK_TX_FLAGS_FPORT1;
> > +	if (mac->id == MTK_GMAC1_ID)
> > +		itx_buf->flags |= MTK_TX_FLAGS_FPORT0;
> > +	else if (mac->id == MTK_GMAC2_ID)
> > +		itx_buf->flags |= MTK_TX_FLAGS_FPORT1;
> > +	else
> > +		itx_buf->flags |= MTK_TX_FLAGS_FPORT2;
> 
> There appears to be two places that this code structure appears, and
> this is in the path for packet transmission. I wonder if it would be
> more efficient to instead do:
> 
> 	itx_buf->flags |= MTK_TX_FLAGS_SINGLE0 | mac->tx_flags;
> 
> with mac->tx_flags appropriately initialised?
> 
> > @@ -2170,7 +2214,9 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget,
> >  		tx_buf = mtk_desc_to_tx_buf(ring, desc,
> >  					    eth->soc->txrx.txd_size);
> >  		if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
> > -			mac = 1;
> > +			mac = MTK_GMAC2_ID;
> > +		else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2)
> > +			mac = MTK_GMAC3_ID;
> 
> This has me wondering whether the flags are used for hardware or just
> for the driver's purposes. If it's the latter, can we instead store the
> MAC index in tx_buf, rather than having to decode a bitfield?
> 
> I suspect these are just for the driver given that the addition of
> MTK_TX_FLAGS_FPORT2 changes all subsequent bit numbers in this struct
> member.

ack, I agree. I will rework it.

Regards,
Lorenzo

> 
> >  
> >  		if (!tx_buf->data)
> >  			break;
> > @@ -3783,7 +3829,26 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
> >  	mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
> >  	mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
> >  
> > -	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
> > +	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
> > +		/* PSE should not drop port1, port8 and port9 packets */
> > +		mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
> > +
> > +		/* GDM and CDM Threshold */
> > +		mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
> > +		mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
> > +
> > +		/* Disable GDM1 RX CRC stripping */
> > +		val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0));
> > +		val &= ~MTK_GDMA_STRP_CRC;
> > +		mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0));
> 
> mtk_m32() ?
> 
> Thanks!
> 
> -- 
> RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
> FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
>
  

Patch

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 45b6f85f0822c..d516917effca6 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -943,17 +943,32 @@  void mtk_stats_update_mac(struct mtk_mac *mac)
 			mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
 		hw_stats->rx_flow_control_packets +=
 			mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
-		hw_stats->tx_skip +=
-			mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
-		hw_stats->tx_collisions +=
-			mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
-		hw_stats->tx_bytes +=
-			mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
-		stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
-		if (stats)
-			hw_stats->tx_bytes += (stats << 32);
-		hw_stats->tx_packets +=
-			mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
+
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+			hw_stats->tx_skip +=
+				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
+			hw_stats->tx_collisions +=
+				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
+			hw_stats->tx_bytes +=
+				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
+			stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
+			if (stats)
+				hw_stats->tx_bytes += (stats << 32);
+			hw_stats->tx_packets +=
+				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
+		} else {
+			hw_stats->tx_skip +=
+				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
+			hw_stats->tx_collisions +=
+				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
+			hw_stats->tx_bytes +=
+				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
+			stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
+			if (stats)
+				hw_stats->tx_bytes += (stats << 32);
+			hw_stats->tx_packets +=
+				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
+		}
 	}
 
 	u64_stats_update_end(&hw_stats->syncp);
@@ -1257,7 +1272,10 @@  static void mtk_tx_set_dma_desc_v2(struct net_device *dev, void *txd,
 		data |= TX_DMA_LS0;
 	WRITE_ONCE(desc->txd3, data);
 
-	data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
+	if (mac->id == MTK_GMAC3_ID)
+		data = PSE_GDM3_PORT;
+	else
+		data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
 	data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
 	WRITE_ONCE(desc->txd4, data);
 
@@ -1268,6 +1286,9 @@  static void mtk_tx_set_dma_desc_v2(struct net_device *dev, void *txd,
 		/* tx checksum offload */
 		if (info->csum)
 			data |= TX_DMA_CHKSUM_V2;
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
+		    netdev_uses_dsa(dev))
+			data |= TX_DMA_SPTAG_V3;
 	}
 	WRITE_ONCE(desc->txd5, data);
 
@@ -1333,8 +1354,13 @@  static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
 	mtk_tx_set_dma_desc(dev, itxd, &txd_info);
 
 	itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
-	itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
-			  MTK_TX_FLAGS_FPORT1;
+	if (mac->id == MTK_GMAC1_ID)
+		itx_buf->flags |= MTK_TX_FLAGS_FPORT0;
+	else if (mac->id == MTK_GMAC2_ID)
+		itx_buf->flags |= MTK_TX_FLAGS_FPORT1;
+	else
+		itx_buf->flags |= MTK_TX_FLAGS_FPORT2;
+
 	setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
 		     k++);
 
@@ -1382,8 +1408,13 @@  static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
 				memset(tx_buf, 0, sizeof(*tx_buf));
 			tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
 			tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
-			tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
-					 MTK_TX_FLAGS_FPORT1;
+
+			if (mac->id == MTK_GMAC1_ID)
+				tx_buf->flags |= MTK_TX_FLAGS_FPORT0;
+			else if (mac->id == MTK_GMAC2_ID)
+				tx_buf->flags |= MTK_TX_FLAGS_FPORT1;
+			else
+				tx_buf->flags |= MTK_TX_FLAGS_FPORT2;
 
 			setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
 				     txd_info.size, k++);
@@ -1935,11 +1966,24 @@  static int mtk_poll_rx(struct napi_struct *napi, int budget,
 			break;
 
 		/* find out which mac the packet come from. values start at 1 */
-		if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-			mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
-		else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-			 !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
+		if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
+			u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
+
+			switch (val) {
+			case PSE_GDM1_PORT:
+			case PSE_GDM2_PORT:
+				mac = val - 1;
+				break;
+			case PSE_GDM3_PORT:
+				mac = MTK_GMAC3_ID;
+				break;
+			default:
+				break;
+			}
+		} else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
+			 !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
 			mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
+		}
 
 		if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
 			     !eth->netdev[mac]))
@@ -2170,7 +2214,9 @@  static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget,
 		tx_buf = mtk_desc_to_tx_buf(ring, desc,
 					    eth->soc->txrx.txd_size);
 		if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
-			mac = 1;
+			mac = MTK_GMAC2_ID;
+		else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2)
+			mac = MTK_GMAC3_ID;
 
 		if (!tx_buf->data)
 			break;
@@ -3783,7 +3829,26 @@  static int mtk_hw_init(struct mtk_eth *eth, bool reset)
 	mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
 	mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+		/* PSE should not drop port1, port8 and port9 packets */
+		mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
+
+		/* GDM and CDM Threshold */
+		mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
+		mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
+
+		/* Disable GDM1 RX CRC stripping */
+		val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0));
+		val &= ~MTK_GDMA_STRP_CRC;
+		mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0));
+
+		/* PSE GDM3 MIB counter has incorrect hw default values,
+		 * so the driver ought to read clear the values beforehand
+		 * in case ethtool retrieve wrong mib values.
+		 */
+		for (i = 0; i < 0x80; i += 0x4)
+			mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
+	} else if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
 		/* PSE should not drop port8 and port9 packets from WDMA Tx */
 		mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
 
@@ -4356,7 +4421,11 @@  static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	}
 	spin_lock_init(&mac->hw_stats->stats_lock);
 	u64_stats_init(&mac->hw_stats->syncp);
-	mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
+
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+		mac->hw_stats->reg_offset = id * 0x80;
+	else
+		mac->hw_stats->reg_offset = id * 0x40;
 
 	/* phylink create */
 	err = of_get_phy_mode(np, &phy_mode);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 2af7e46cadcbb..08d1e73985f08 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -122,6 +122,7 @@ 
 #define MTK_GDMA_ICS_EN		BIT(22)
 #define MTK_GDMA_TCS_EN		BIT(21)
 #define MTK_GDMA_UCS_EN		BIT(20)
+#define MTK_GDMA_STRP_CRC	BIT(16)
 #define MTK_GDMA_TO_PDMA	0x0
 #define MTK_GDMA_DROP_ALL       0x7777
 
@@ -287,8 +288,6 @@ 
 /* QDMA Interrupt grouping registers */
 #define MTK_RLS_DONE_INT	BIT(0)
 
-#define MTK_STAT_OFFSET		0x40
-
 /* QDMA TX NUM */
 #define QID_BITS_V2(x)		(((x) & 0x3f) << 16)
 #define MTK_QDMA_GMAC2_QID	8
@@ -301,6 +300,8 @@ 
 #define TX_DMA_CHKSUM_V2	(0x7 << 28)
 #define TX_DMA_TSO_V2		BIT(31)
 
+#define TX_DMA_SPTAG_V3         BIT(27)
+
 /* QDMA V2 descriptor txd4 */
 #define TX_DMA_FPORT_SHIFT_V2	8
 #define TX_DMA_FPORT_MASK_V2	0xf
@@ -640,6 +641,7 @@  enum mtk_tx_flags {
 	 */
 	MTK_TX_FLAGS_FPORT0	= 0x04,
 	MTK_TX_FLAGS_FPORT1	= 0x08,
+	MTK_TX_FLAGS_FPORT2	= 0x10,
 };
 
 /* This enum allows us to identify how the clock is defined on the array of the
@@ -725,6 +727,35 @@  enum mtk_dev_state {
 	MTK_RESETTING
 };
 
+/* PSE Port Definition */
+enum mtk_pse_port {
+	PSE_ADMA_PORT = 0,
+	PSE_GDM1_PORT,
+	PSE_GDM2_PORT,
+	PSE_PPE0_PORT,
+	PSE_PPE1_PORT,
+	PSE_QDMA_TX_PORT,
+	PSE_QDMA_RX_PORT,
+	PSE_DROP_PORT,
+	PSE_WDMA0_PORT,
+	PSE_WDMA1_PORT,
+	PSE_TDMA_PORT,
+	PSE_NONE_PORT,
+	PSE_PPE2_PORT,
+	PSE_WDMA2_PORT,
+	PSE_EIP197_PORT,
+	PSE_GDM3_PORT,
+	PSE_PORT_MAX
+};
+
+/* GMAC Identifier */
+enum mtk_gmac_id {
+	MTK_GMAC1_ID = 0,
+	MTK_GMAC2_ID,
+	MTK_GMAC3_ID,
+	MTK_GMAC_ID_MAX
+};
+
 enum mtk_tx_buf_type {
 	MTK_TYPE_SKB,
 	MTK_TYPE_XDP_TX,
@@ -821,6 +852,7 @@  enum mkt_eth_capabilities {
 	MTK_QDMA_BIT,
 	MTK_NETSYS_V1_BIT,
 	MTK_NETSYS_V2_BIT,
+	MTK_NETSYS_V3_BIT,
 	MTK_SOC_MT7628_BIT,
 	MTK_RSTCTRL_PPE1_BIT,
 	MTK_U3_COPHY_V2_BIT,
@@ -857,6 +889,7 @@  enum mkt_eth_capabilities {
 #define MTK_QDMA		BIT(MTK_QDMA_BIT)
 #define MTK_NETSYS_V1		BIT(MTK_NETSYS_V1_BIT)
 #define MTK_NETSYS_V2		BIT(MTK_NETSYS_V2_BIT)
+#define MTK_NETSYS_V3		BIT(MTK_NETSYS_V3_BIT)
 #define MTK_SOC_MT7628		BIT(MTK_SOC_MT7628_BIT)
 #define MTK_RSTCTRL_PPE1	BIT(MTK_RSTCTRL_PPE1_BIT)
 #define MTK_U3_COPHY_V2		BIT(MTK_U3_COPHY_V2_BIT)