mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	net: ethernet: mtk_eth_soc: add NETSYS_V3 version support
Introduce NETSYS_V3 chipset version support. 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> Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									e05fd6274e
								
							
						
					
					
						commit
						1953f134a1
					
				| @ -876,6 +876,20 @@ void mtk_stats_update_mac(struct mtk_mac *mac) | |||||||
| 			mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs); | 			mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs); | ||||||
| 		hw_stats->rx_flow_control_packets += | 		hw_stats->rx_flow_control_packets += | ||||||
| 			mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs); | 			mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs); | ||||||
|  | 
 | ||||||
|  | 		if (mtk_is_netsys_v3_or_greater(eth)) { | ||||||
|  | 			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 += | 			hw_stats->tx_skip += | ||||||
| 				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs); | 				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs); | ||||||
| 			hw_stats->tx_collisions += | 			hw_stats->tx_collisions += | ||||||
| @ -888,6 +902,7 @@ void mtk_stats_update_mac(struct mtk_mac *mac) | |||||||
| 			hw_stats->tx_packets += | 			hw_stats->tx_packets += | ||||||
| 				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs); | 				mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs); | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	u64_stats_update_end(&hw_stats->syncp); | 	u64_stats_update_end(&hw_stats->syncp); | ||||||
| } | } | ||||||
| @ -1190,6 +1205,9 @@ static void mtk_tx_set_dma_desc_v2(struct net_device *dev, void *txd, | |||||||
| 		data |= TX_DMA_LS0; | 		data |= TX_DMA_LS0; | ||||||
| 	WRITE_ONCE(desc->txd3, data); | 	WRITE_ONCE(desc->txd3, data); | ||||||
| 
 | 
 | ||||||
|  | 	if (mac->id == MTK_GMAC3_ID) | ||||||
|  | 		data = PSE_GDM3_PORT; | ||||||
|  | 	else | ||||||
| 		data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ | 		data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ | ||||||
| 	data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); | 	data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); | ||||||
| 	WRITE_ONCE(desc->txd4, data); | 	WRITE_ONCE(desc->txd4, data); | ||||||
| @ -1201,6 +1219,8 @@ static void mtk_tx_set_dma_desc_v2(struct net_device *dev, void *txd, | |||||||
| 		/* tx checksum offload */ | 		/* tx checksum offload */ | ||||||
| 		if (info->csum) | 		if (info->csum) | ||||||
| 			data |= TX_DMA_CHKSUM_V2; | 			data |= TX_DMA_CHKSUM_V2; | ||||||
|  | 		if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev)) | ||||||
|  | 			data |= TX_DMA_SPTAG_V3; | ||||||
| 	} | 	} | ||||||
| 	WRITE_ONCE(desc->txd5, data); | 	WRITE_ONCE(desc->txd5, data); | ||||||
| 
 | 
 | ||||||
| @ -1266,8 +1286,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, | |||||||
| 	mtk_tx_set_dma_desc(dev, itxd, &txd_info); | 	mtk_tx_set_dma_desc(dev, itxd, &txd_info); | ||||||
| 
 | 
 | ||||||
| 	itx_buf->flags |= MTK_TX_FLAGS_SINGLE0; | 	itx_buf->flags |= MTK_TX_FLAGS_SINGLE0; | ||||||
| 	itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : | 	itx_buf->mac_id = mac->id; | ||||||
| 			  MTK_TX_FLAGS_FPORT1; |  | ||||||
| 	setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, | 	setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, | ||||||
| 		     k++); | 		     k++); | ||||||
| 
 | 
 | ||||||
| @ -1315,8 +1334,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, | |||||||
| 				memset(tx_buf, 0, sizeof(*tx_buf)); | 				memset(tx_buf, 0, sizeof(*tx_buf)); | ||||||
| 			tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; | 			tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; | ||||||
| 			tx_buf->flags |= MTK_TX_FLAGS_PAGE0; | 			tx_buf->flags |= MTK_TX_FLAGS_PAGE0; | ||||||
| 			tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : | 			tx_buf->mac_id = mac->id; | ||||||
| 					 MTK_TX_FLAGS_FPORT1; |  | ||||||
| 
 | 
 | ||||||
| 			setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, | 			setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, | ||||||
| 				     txd_info.size, k++); | 				     txd_info.size, k++); | ||||||
| @ -1618,7 +1636,7 @@ static int mtk_xdp_frame_map(struct mtk_eth *eth, struct net_device *dev, | |||||||
| 	} | 	} | ||||||
| 	mtk_tx_set_dma_desc(dev, txd, txd_info); | 	mtk_tx_set_dma_desc(dev, txd, txd_info); | ||||||
| 
 | 
 | ||||||
| 	tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; | 	tx_buf->mac_id = mac->id; | ||||||
| 	tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; | 	tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; | ||||||
| 	tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; | 	tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; | ||||||
| 
 | 
 | ||||||
| @ -1868,11 +1886,24 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, | |||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		/* find out which mac the packet come from. values start at 1 */ | 		/* find out which mac the packet come from. values start at 1 */ | ||||||
| 		if (mtk_is_netsys_v2_or_greater(eth)) | 		if (mtk_is_netsys_v2_or_greater(eth)) { | ||||||
| 			mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; | 			u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5); | ||||||
| 		else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && | 
 | ||||||
| 			 !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) | 			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; | 			mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS || | 		if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS || | ||||||
| 			     !eth->netdev[mac])) | 			     !eth->netdev[mac])) | ||||||
| @ -2094,7 +2125,6 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, | |||||||
| 
 | 
 | ||||||
| 	while ((cpu != dma) && budget) { | 	while ((cpu != dma) && budget) { | ||||||
| 		u32 next_cpu = desc->txd2; | 		u32 next_cpu = desc->txd2; | ||||||
| 		int mac = 0; |  | ||||||
| 
 | 
 | ||||||
| 		desc = mtk_qdma_phys_to_virt(ring, desc->txd2); | 		desc = mtk_qdma_phys_to_virt(ring, desc->txd2); | ||||||
| 		if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0) | 		if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0) | ||||||
| @ -2102,15 +2132,13 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, | |||||||
| 
 | 
 | ||||||
| 		tx_buf = mtk_desc_to_tx_buf(ring, desc, | 		tx_buf = mtk_desc_to_tx_buf(ring, desc, | ||||||
| 					    eth->soc->txrx.txd_size); | 					    eth->soc->txrx.txd_size); | ||||||
| 		if (tx_buf->flags & MTK_TX_FLAGS_FPORT1) |  | ||||||
| 			mac = 1; |  | ||||||
| 
 |  | ||||||
| 		if (!tx_buf->data) | 		if (!tx_buf->data) | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { | 		if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { | ||||||
| 			if (tx_buf->type == MTK_TYPE_SKB) | 			if (tx_buf->type == MTK_TYPE_SKB) | ||||||
| 				mtk_poll_tx_done(eth, state, mac, tx_buf->data); | 				mtk_poll_tx_done(eth, state, tx_buf->mac_id, | ||||||
|  | 						 tx_buf->data); | ||||||
| 
 | 
 | ||||||
| 			budget--; | 			budget--; | ||||||
| 		} | 		} | ||||||
| @ -3721,7 +3749,24 @@ 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, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); | ||||||
| 	mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); | 	mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); | ||||||
| 
 | 
 | ||||||
| 	if (mtk_is_netsys_v2_or_greater(eth)) { | 	if (mtk_is_netsys_v3_or_greater(eth)) { | ||||||
|  | 		/* 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 */ | ||||||
|  | 		mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, 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_is_netsys_v1(eth)) { | ||||||
| 		/* PSE should not drop port8 and port9 packets from WDMA Tx */ | 		/* PSE should not drop port8 and port9 packets from WDMA Tx */ | ||||||
| 		mtk_w32(eth, 0x00000300, PSE_DROP_CFG); | 		mtk_w32(eth, 0x00000300, PSE_DROP_CFG); | ||||||
| 
 | 
 | ||||||
| @ -4284,7 +4329,11 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) | |||||||
| 	} | 	} | ||||||
| 	spin_lock_init(&mac->hw_stats->stats_lock); | 	spin_lock_init(&mac->hw_stats->stats_lock); | ||||||
| 	u64_stats_init(&mac->hw_stats->syncp); | 	u64_stats_init(&mac->hw_stats->syncp); | ||||||
| 	mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET; | 
 | ||||||
|  | 	if (mtk_is_netsys_v3_or_greater(eth)) | ||||||
|  | 		mac->hw_stats->reg_offset = id * 0x80; | ||||||
|  | 	else | ||||||
|  | 		mac->hw_stats->reg_offset = id * 0x40; | ||||||
| 
 | 
 | ||||||
| 	/* phylink create */ | 	/* phylink create */ | ||||||
| 	err = of_get_phy_mode(np, &phy_mode); | 	err = of_get_phy_mode(np, &phy_mode); | ||||||
|  | |||||||
| @ -122,6 +122,7 @@ | |||||||
| #define MTK_GDMA_ICS_EN		BIT(22) | #define MTK_GDMA_ICS_EN		BIT(22) | ||||||
| #define MTK_GDMA_TCS_EN		BIT(21) | #define MTK_GDMA_TCS_EN		BIT(21) | ||||||
| #define MTK_GDMA_UCS_EN		BIT(20) | #define MTK_GDMA_UCS_EN		BIT(20) | ||||||
|  | #define MTK_GDMA_STRP_CRC	BIT(16) | ||||||
| #define MTK_GDMA_TO_PDMA	0x0 | #define MTK_GDMA_TO_PDMA	0x0 | ||||||
| #define MTK_GDMA_DROP_ALL       0x7777 | #define MTK_GDMA_DROP_ALL       0x7777 | ||||||
| 
 | 
 | ||||||
| @ -287,8 +288,6 @@ | |||||||
| /* QDMA Interrupt grouping registers */ | /* QDMA Interrupt grouping registers */ | ||||||
| #define MTK_RLS_DONE_INT	BIT(0) | #define MTK_RLS_DONE_INT	BIT(0) | ||||||
| 
 | 
 | ||||||
| #define MTK_STAT_OFFSET		0x40 |  | ||||||
| 
 |  | ||||||
| /* QDMA TX NUM */ | /* QDMA TX NUM */ | ||||||
| #define QID_BITS_V2(x)		(((x) & 0x3f) << 16) | #define QID_BITS_V2(x)		(((x) & 0x3f) << 16) | ||||||
| #define MTK_QDMA_GMAC2_QID	8 | #define MTK_QDMA_GMAC2_QID	8 | ||||||
| @ -301,6 +300,8 @@ | |||||||
| #define TX_DMA_CHKSUM_V2	(0x7 << 28) | #define TX_DMA_CHKSUM_V2	(0x7 << 28) | ||||||
| #define TX_DMA_TSO_V2		BIT(31) | #define TX_DMA_TSO_V2		BIT(31) | ||||||
| 
 | 
 | ||||||
|  | #define TX_DMA_SPTAG_V3         BIT(27) | ||||||
|  | 
 | ||||||
| /* QDMA V2 descriptor txd4 */ | /* QDMA V2 descriptor txd4 */ | ||||||
| #define TX_DMA_FPORT_SHIFT_V2	8 | #define TX_DMA_FPORT_SHIFT_V2	8 | ||||||
| #define TX_DMA_FPORT_MASK_V2	0xf | #define TX_DMA_FPORT_MASK_V2	0xf | ||||||
| @ -634,12 +635,6 @@ enum mtk_tx_flags { | |||||||
| 	 */ | 	 */ | ||||||
| 	MTK_TX_FLAGS_SINGLE0	= 0x01, | 	MTK_TX_FLAGS_SINGLE0	= 0x01, | ||||||
| 	MTK_TX_FLAGS_PAGE0	= 0x02, | 	MTK_TX_FLAGS_PAGE0	= 0x02, | ||||||
| 
 |  | ||||||
| 	/* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted
 |  | ||||||
| 	 * SKB out instead of looking up through hardware TX descriptor. |  | ||||||
| 	 */ |  | ||||||
| 	MTK_TX_FLAGS_FPORT0	= 0x04, |  | ||||||
| 	MTK_TX_FLAGS_FPORT1	= 0x08, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* This enum allows us to identify how the clock is defined on the array of the
 | /* This enum allows us to identify how the clock is defined on the array of the
 | ||||||
| @ -725,6 +720,35 @@ enum mtk_dev_state { | |||||||
| 	MTK_RESETTING | 	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 { | enum mtk_tx_buf_type { | ||||||
| 	MTK_TYPE_SKB, | 	MTK_TYPE_SKB, | ||||||
| 	MTK_TYPE_XDP_TX, | 	MTK_TYPE_XDP_TX, | ||||||
| @ -743,7 +767,8 @@ struct mtk_tx_buf { | |||||||
| 	enum mtk_tx_buf_type type; | 	enum mtk_tx_buf_type type; | ||||||
| 	void *data; | 	void *data; | ||||||
| 
 | 
 | ||||||
| 	u32 flags; | 	u16 mac_id; | ||||||
|  | 	u16 flags; | ||||||
| 	DEFINE_DMA_UNMAP_ADDR(dma_addr0); | 	DEFINE_DMA_UNMAP_ADDR(dma_addr0); | ||||||
| 	DEFINE_DMA_UNMAP_LEN(dma_len0); | 	DEFINE_DMA_UNMAP_LEN(dma_len0); | ||||||
| 	DEFINE_DMA_UNMAP_ADDR(dma_addr1); | 	DEFINE_DMA_UNMAP_ADDR(dma_addr1); | ||||||
| @ -1192,6 +1217,11 @@ static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) | |||||||
| 	return eth->soc->version > 1; | 	return eth->soc->version > 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) | ||||||
|  | { | ||||||
|  | 	return eth->soc->version > 2; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static inline struct mtk_foe_entry * | static inline struct mtk_foe_entry * | ||||||
| mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) | mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) | ||||||
| { | { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Lorenzo Bianconi
						Lorenzo Bianconi