lkml.org 
[lkml]   [2023]   [Jul]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH net-next v5 6/9] net: ethernet: mtk_eth_soc: add NETSYS_V3 version support
    From: Lorenzo Bianconi <lorenzo@kernel.org>

    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>
    ---
    drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 ++++++++++++++------
    drivers/net/ethernet/mediatek/mtk_eth_soc.h | 48 +++++++--
    2 files changed, 116 insertions(+), 37 deletions(-)

    diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
    index 67109a38df31a..1344e2fc6d6f2 100644
    --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
    +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
    @@ -876,17 +876,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_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 +=
    + 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);
    @@ -1190,7 +1205,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);

    @@ -1201,6 +1219,8 @@ 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_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev))
    + data |= TX_DMA_SPTAG_V3;
    }
    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);

    itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
    - itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
    - MTK_TX_FLAGS_FPORT1;
    + itx_buf->mac_id = mac->id;
    setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
    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));
    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;
    + tx_buf->mac_id = mac->id;

    setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
    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);

    - 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->data = (void *)MTK_DMA_DUMMY_DESC;

    @@ -1868,11 +1886,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_is_netsys_v2_or_greater(eth))
    - 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_is_netsys_v2_or_greater(eth)) {
    + 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 >= MTK_MAX_DEVS ||
    !eth->netdev[mac]))
    @@ -2094,7 +2125,6 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget,

    while ((cpu != dma) && budget) {
    u32 next_cpu = desc->txd2;
    - int mac = 0;

    desc = mtk_qdma_phys_to_virt(ring, desc->txd2);
    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,
    eth->soc->txrx.txd_size);
    - if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
    - mac = 1;
    -
    if (!tx_buf->data)
    break;

    if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
    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--;
    }
    @@ -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, 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 */
    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);
    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 */
    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 4dc5611f859b0..3959bb39995fc 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
    @@ -634,12 +635,6 @@ enum mtk_tx_flags {
    */
    MTK_TX_FLAGS_SINGLE0 = 0x01,
    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
    @@ -725,6 +720,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,
    @@ -743,7 +767,8 @@ struct mtk_tx_buf {
    enum mtk_tx_buf_type type;
    void *data;

    - u32 flags;
    + u16 mac_id;
    + u16 flags;
    DEFINE_DMA_UNMAP_ADDR(dma_addr0);
    DEFINE_DMA_UNMAP_LEN(dma_len0);
    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;
    }

    +static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
    +{
    + return eth->soc->version > 2;
    +}
    +
    static inline struct mtk_foe_entry *
    mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
    {
    --
    2.41.0
    \
     
     \ /
      Last update: 2023-07-23 23:59    [W:2.577 / U:4.264 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site