From: Lorenzo Bianconi <[email protected]>
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 <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
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(-)
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)
--
2.41.0
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!
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
> 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!
>