Commit 1953f134 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Jakub Kicinski

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: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarDaniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e05fd627
...@@ -876,6 +876,20 @@ void mtk_stats_update_mac(struct mtk_mac *mac) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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) ...@@ -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)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment