[][kernel][mt7987][eth][Add XGMACv2 support for the NETSYS v3.1]
[Description]
Add XGMACv2 support for the NETSYS v3.1.
[Release-log]
N/A
Change-Id: I05a7f02f8626a05448497816f91af330778dcf77
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/9743740
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
index 045fc2b..0f95a0a 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
@@ -1157,12 +1157,20 @@
int xfi_cnt_read(struct seq_file *seq, void *v)
{
struct mtk_eth *eth = g_eth;
+ bool has_xgmac[MTK_MAX_DEVS] = {0,
+ MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_2P5GPHY) ||
+ MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_2P5GPHY_V2) ||
+ MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_USXGMII),
+ MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC3_USXGMII)};
int i;
seq_puts(seq, "+------------------------------------+\n");
seq_puts(seq, "| <<XFI MAC>> |\n");
for (i = MTK_GMAC2_ID; i < MTK_GMAC_ID_MAX; i++) {
+ if (!has_xgmac[i])
+ continue;
+
xfi_mib_dump(seq, i);
mtk_m32(eth, 0x1, 0x1, MTK_XFI_MIB_BASE(i) + MTK_XFI_CNT_CTRL);
seq_puts(seq, "| |\n");
@@ -1496,12 +1504,16 @@
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
seq_printf(seq, "| XMAC_P1_MCR : %08x |\n",
mtk_r32(eth, MTK_XMAC_MCR(1)));
- seq_printf(seq, "| XMAC_P2_MCR : %08x |\n",
- mtk_r32(eth, MTK_XMAC_MCR(2)));
seq_printf(seq, "| XMAC_P1_STS : %08x |\n",
- mtk_r32(eth, MTK_XGMAC_STS(1)));
- seq_printf(seq, "| XMAC_P2_STS : %08x |\n",
- mtk_r32(eth, MTK_XGMAC_STS(2)));
+ mtk_r32(eth, MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2) ?
+ MTK_XMAC_STS(1) : MTK_XGMAC_STS(1)));
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC3_USXGMII)) {
+ seq_printf(seq, "| XMAC_P2_MCR : %08x |\n",
+ mtk_r32(eth, MTK_XMAC_MCR(2)));
+ seq_printf(seq, "| XMAC_P2_STS : %08x |\n",
+ mtk_r32(eth, MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2) ?
+ MTK_XMAC_STS(2) : MTK_XGMAC_STS(2)));
+ }
}
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
index 5ebeb97..3cae2d1 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
@@ -272,11 +272,15 @@
"SGMII1", 0, 0x1a0);
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
mtk_dump_reg(eth, "XGMAC0", 0x12000, 0x300);
- mtk_dump_reg(eth, "XGMAC1", 0x13000, 0x300);
- mtk_dump_regmap(eth->usxgmii->pcs[0].regmap,
- "USXGMII0", 0x800, 0x500);
- mtk_dump_regmap(eth->usxgmii->pcs[1].regmap,
- "USXGMII1", 0x800, 0x500);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_USXGMII)) {
+ mtk_dump_regmap(eth->usxgmii->pcs[1].regmap,
+ "USXGMII1", 0x800, 0x500);
+ }
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC3_USXGMII)) {
+ mtk_dump_reg(eth, "XGMAC1", 0x13000, 0x300);
+ mtk_dump_regmap(eth->usxgmii->pcs[0].regmap,
+ "USXGMII0", 0x800, 0x500);
+ }
}
}
@@ -882,9 +886,15 @@
mcr |= XMAC_MCR_TRX_DISABLE;
mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
- sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
- sts &= ~MTK_XGMAC_FORCE_LINK(mac->id);
- mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2)) {
+ sts = mtk_r32(mac->hw, MTK_XMAC_STS_FRC(mac->id));
+ sts &= ~XMAC_FORCE_LINK;
+ mtk_w32(mac->hw, sts, MTK_XMAC_STS_FRC(mac->id));
+ } else {
+ sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
+ sts &= ~MTK_XGMAC_FORCE_LINK(mac->id);
+ mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
+ }
}
}
}
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index e7c7cd6..8196f2b 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -671,19 +671,32 @@
struct mtk_mac *mac = container_of(config, struct mtk_mac,
phylink_config);
struct mtk_eth *eth = mac->hw;
+ bool has_xgmac[MTK_MAX_DEVS] = {0,
+ MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_2P5GPHY) ||
+ MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_2P5GPHY_V2) ||
+ MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_USXGMII),
+ MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC3_USXGMII)};
u32 val;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
- mac->id != MTK_GMAC1_ID) {
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) && has_xgmac[mac->id]) {
val = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
val &= 0xfffffff0;
val |= XMAC_MCR_TRX_DISABLE;
mtk_w32(mac->hw, val, MTK_XMAC_MCR(mac->id));
- val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
- val |= MTK_XGMAC_FORCE_MODE(mac->id);
- val &= ~MTK_XGMAC_FORCE_LINK(mac->id);
- mtk_w32(mac->hw, val, MTK_XGMAC_STS(mac->id));
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2)) {
+ val = mtk_r32(mac->hw, MTK_XMAC_STS_FRC(mac->id));
+ val |= XMAC_FORCE_RX_FC_MODE;
+ val |= XMAC_FORCE_TX_FC_MODE;
+ val |= XMAC_FORCE_LINK_MODE;
+ val &= ~XMAC_FORCE_LINK;
+ mtk_w32(mac->hw, val, MTK_XMAC_STS_FRC(mac->id));
+ } else {
+ val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
+ val |= MTK_XGMAC_FORCE_MODE(mac->id);
+ val &= ~MTK_XGMAC_FORCE_LINK(mac->id);
+ mtk_w32(mac->hw, val, MTK_XGMAC_STS(mac->id));
+ }
}
return 0;
@@ -1029,7 +1042,8 @@
struct mtk_eth *eth = mac->hw;
u32 port = 0;
- if (!up && mac->id == MTK_GMAC2_ID &&
+ if (eth->soc->caps == MT7988_CAPS &&
+ !up && mac->id == MTK_GMAC2_ID &&
interface == PHY_INTERFACE_MODE_INTERNAL &&
MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
void __iomem *base;
@@ -1071,6 +1085,7 @@
{
struct mtk_mac *mac = container_of(config, struct mtk_mac,
phylink_config);
+ struct mtk_eth *eth = mac->hw;
u32 mcr, sts;
mtk_pse_set_mac_port_link(mac, false, interface);
@@ -1084,9 +1099,15 @@
mcr |= XMAC_MCR_TRX_DISABLE;
mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
- sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
- sts &= ~MTK_XGMAC_FORCE_LINK(mac->id);
- mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2)) {
+ sts = mtk_r32(mac->hw, MTK_XMAC_STS_FRC(mac->id));
+ sts &= ~XMAC_FORCE_LINK;
+ mtk_w32(mac->hw, sts, MTK_XMAC_STS_FRC(mac->id));
+ } else {
+ sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
+ sts &= ~MTK_XGMAC_FORCE_LINK(mac->id);
+ mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
+ }
}
}
@@ -1178,6 +1199,7 @@
{
struct mtk_mac *mac = container_of(config, struct mtk_mac,
phylink_config);
+ struct mtk_eth *eth = mac->hw;
u32 mcr, mcr_cur, sts;
mac->speed = speed;
@@ -1235,23 +1257,41 @@
mdelay(20);
mtk_m32(mac->hw, XMAC_GLB_CNTCLR, 0x1, MTK_XMAC_CNT_CTRL(mac->id));
- sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
- sts |= MTK_XGMAC_FORCE_LINK(mac->id);
- mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2)) {
+ sts = mtk_r32(mac->hw, MTK_XMAC_STS_FRC(mac->id));
+ sts &= ~(XMAC_FORCE_TX_FC | XMAC_FORCE_RX_FC);
+ /* Configure pause modes -
+ * phylink will avoid these for half duplex
+ */
+ if (tx_pause)
+ sts |= XMAC_FORCE_TX_FC;
+ if (rx_pause)
+ sts |= XMAC_FORCE_RX_FC;
+ sts |= XMAC_FORCE_LINK;
+ mtk_w32(mac->hw, sts, MTK_XMAC_STS_FRC(mac->id));
- mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
+ mcr &= ~(XMAC_MCR_TRX_DISABLE);
+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
+ } else {
+ sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
+ sts |= MTK_XGMAC_FORCE_LINK(mac->id);
+ mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
- mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC);
- /* Configure pause modes -
- * phylink will avoid these for half duplex
- */
- if (tx_pause)
- mcr |= XMAC_MCR_FORCE_TX_FC;
- if (rx_pause)
- mcr |= XMAC_MCR_FORCE_RX_FC;
+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
- mcr &= ~(XMAC_MCR_TRX_DISABLE);
- mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
+ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC);
+ /* Configure pause modes -
+ * phylink will avoid these for half duplex
+ */
+ if (tx_pause)
+ mcr |= XMAC_MCR_FORCE_TX_FC;
+ if (rx_pause)
+ mcr |= XMAC_MCR_FORCE_RX_FC;
+
+ mcr &= ~(XMAC_MCR_TRX_DISABLE);
+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
+ }
}
mtk_pse_set_mac_port_link(mac, true, interface);
}
@@ -5301,10 +5341,17 @@
pause->rx_pause = !!(val & MAC_MCR_FORCE_RX_FC);
pause->tx_pause = !!(val & MAC_MCR_FORCE_TX_FC);
} else if (mac->type == MTK_XGDM_TYPE) {
- val = mtk_r32(eth, MTK_XMAC_MCR(mac->id));
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2)) {
+ val = mtk_r32(mac->hw, MTK_XMAC_STS_FRC(mac->id));
- pause->rx_pause = !!(val & XMAC_MCR_FORCE_RX_FC);
- pause->tx_pause = !!(val & XMAC_MCR_FORCE_TX_FC);
+ pause->rx_pause = !!(val & XMAC_FORCE_RX_FC);
+ pause->tx_pause = !!(val & XMAC_FORCE_TX_FC);
+ } else {
+ val = mtk_r32(eth, MTK_XMAC_MCR(mac->id));
+
+ pause->rx_pause = !!(val & XMAC_MCR_FORCE_RX_FC);
+ pause->tx_pause = !!(val & XMAC_MCR_FORCE_TX_FC);
+ }
}
}
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index d9d6012..05c113d 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -793,12 +793,34 @@
#define XMAC_MCR_FORCE_TX_FC BIT(5)
#define XMAC_MCR_FORCE_RX_FC BIT(4)
+/* XFI Mac status force registers */
+#define MTK_XMAC_STS(x) (MTK_XMAC_MCR(x) + 0x14)
+
+/* XFI Mac status force registers */
+#define MTK_XMAC_STS_FRC(x) (MTK_XMAC_MCR(x) + 0x18)
+#define XMAC_FORCE_RX_FC_MODE BIT(13)
+#define XMAC_FORCE_TX_FC_MODE BIT(12)
+#define XMAC_FORCE_SPD_MODE BIT(10)
+#define XMAC_FORCE_LINK_MODE BIT(8)
+#define XMAC_FORCE_RX_FC BIT(5)
+#define XMAC_FORCE_TX_FC BIT(4)
+#define XMAC_FORCE_SPD_MASK GENMASK(3, 1)
+#define XMAC_FORCE_SPD_10 FIELD_PREP(XMAC_FORCE_SPD_MASK, 0)
+#define XMAC_FORCE_SPD_100 FIELD_PREP(XMAC_FORCE_SPD_MASK, 1)
+#define XMAC_FORCE_SPD_1000 FIELD_PREP(XMAC_FORCE_SPD_MASK, 2)
+#define XMAC_FORCE_SPD_10000 FIELD_PREP(XMAC_FORCE_SPD_MASK, 3)
+#define XMAC_FORCE_SPD_2500 FIELD_PREP(XMAC_FORCE_SPD_MASK, 4)
+#define XMAC_FORCE_SPD_5000 FIELD_PREP(XMAC_FORCE_SPD_MASK, 5)
+#define XMAC_FORCE_LINK BIT(0)
+
/* XFI Mac Rx configuration registers */
#define MTK_XMAC_RX_CFG2(x) (MTK_XMAC_MCR(x) + 0xd0)
#define MTK_XMAC_MAX_RX_MASK GENMASK(13, 0)
/* XFI Mac logic reset registers */
-#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10)
+#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + \
+ (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2) ? \
+ 0x820 : 0x10))
#define XMAC_LOGIC_RST BIT(0)
/* XFI Mac count global control */
@@ -1547,6 +1569,8 @@
MTK_SOC_MT7628_BIT,
MTK_RSTCTRL_PPE1_BIT,
MTK_RSTCTRL_PPE2_BIT,
+ MTK_XGMAC_BIT,
+ MTK_XGMAC_V2_BIT,
MTK_U3_COPHY_V2_BIT,
MTK_36BIT_DMA_BIT,
@@ -1599,6 +1623,8 @@
#define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT)
#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
#define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
+#define MTK_XGMAC BIT_ULL(MTK_XGMAC_BIT)
+#define MTK_XGMAC_V2 BIT_ULL(MTK_XGMAC_V2_BIT)
#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT)
@@ -1638,13 +1664,14 @@
#define MTK_GMAC1_SGMII (MTK_ETH_PATH_GMAC1_SGMII | MTK_SGMII)
#define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
#define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
-#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
+#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY | MTK_XGMAC)
+#define MTK_GMAC2_2P5GPHY_V2 (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY | MTK_XGMAC_V2)
#define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
#define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
-#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
-#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
-#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII | MTK_XGMAC)
+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII | MTK_XGMAC)
+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII | MTK_XGMAC)
/* MUXes present on SoCs */
/* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */