generic: 6.18: fix mtk_eth_soc on MT7988 and MT7987

Our downstream patch for the new SerDes paths on MT7988 wasn't
correctly ported to Linux 6.18 which already got most of the XPCS
support upstream.

Fix (ie. reduce) the patch to make the built-in 2.5G PHY on MT7988 and
MT7987 work again.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
Daniel Golle 2026-04-10 23:08:28 +01:00
parent 8c434b8316
commit bdb8dea90d
4 changed files with 43 additions and 96 deletions

View File

@ -37,7 +37,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
.glo_cfg = 0x4604,
.rst_idx = 0x4608,
.delay_irq = 0x460c,
@@ -4160,6 +4163,56 @@ static void mtk_set_mcr_max_rx(struct mt
@@ -4178,6 +4181,56 @@ static void mtk_set_mcr_max_rx(struct mt
mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
}
@ -94,7 +94,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
static void mtk_hw_reset(struct mtk_eth *eth)
{
u32 val;
@@ -4639,6 +4692,8 @@ static void mtk_pending_work(struct work
@@ -4657,6 +4710,8 @@ static void mtk_pending_work(struct work
rtnl_lock();
set_bit(MTK_RESETTING, &eth->state);

View File

@ -212,32 +212,17 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
if (interface == PHY_INTERFACE_MODE_SGMII ||
phy_interface_mode_is_8023z(interface)) {
sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
@@ -543,21 +584,13 @@ static struct phylink_pcs *mtk_mac_selec
}
@@ -559,6 +600,9 @@ static int mtk_mac_prepare(struct phylin
MTK_XGMAC_FORCE_MODE(mac->id), MTK_XGMAC_STS(mac->id));
}
static int mtk_mac_prepare(struct phylink_config *config, unsigned int mode,
- phy_interface_t iface)
+ phy_interface_t interface)
{
struct mtk_mac *mac = container_of(config, struct mtk_mac,
phylink_config);
- struct mtk_eth *eth = mac->hw;
- if (mtk_interface_mode_is_xgmii(eth, iface) &&
- mac->id != MTK_GMAC1_ID) {
- mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE,
- XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id));
-
- mtk_m32(mac->hw, MTK_XGMAC_FORCE_MODE(mac->id) |
- MTK_XGMAC_FORCE_LINK(mac->id),
- MTK_XGMAC_FORCE_MODE(mac->id), MTK_XGMAC_STS(mac->id));
- }
+ if (mac->pextp && mac->interface != interface)
+ if (mac->pextp && mac->interface != iface)
+ phy_reset(mac->pextp);
+
return 0;
}
@@ -602,6 +635,15 @@ static void mtk_mac_config(struct phylin
@@ -602,6 +646,15 @@ static void mtk_mac_config(struct phylin
goto init_err;
}
break;
@ -253,7 +238,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
case PHY_INTERFACE_MODE_INTERNAL:
if (mac->id == MTK_GMAC2_ID &&
MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
@@ -655,8 +697,6 @@ static void mtk_mac_config(struct phylin
@@ -655,8 +708,6 @@ static void mtk_mac_config(struct phylin
val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
@ -262,7 +247,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
}
/* SGMII */
@@ -673,21 +713,40 @@ static void mtk_mac_config(struct phylin
@@ -673,21 +724,40 @@ static void mtk_mac_config(struct phylin
/* Save the syscfg0 value for mac_finish */
mac->syscfg0 = val;
@ -285,14 +270,14 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ if (mtk_interface_mode_is_xgmii(eth, state->interface)) {
+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
- if (mac->id == MTK_GMAC1_ID)
- mtk_setup_bridge_switch(eth);
+
+ if (mac->id == MTK_GMAC1_ID)
+ mtk_setup_bridge_switch(eth);
+ } else {
+ mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id));
+
- if (mac->id == MTK_GMAC1_ID)
- mtk_setup_bridge_switch(eth);
+ /* FIXME: In current hardware design, we have to reset FE
+ * when swtiching XGDM to GDM. Therefore, here trigger an SER
+ * to let GDM go back to the initial state.
@ -310,7 +295,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
return;
err_phy:
@@ -708,6 +767,10 @@ static int mtk_mac_finish(struct phylink
@@ -708,6 +778,10 @@ static int mtk_mac_finish(struct phylink
struct mtk_eth *eth = mac->hw;
u32 mcr_cur, mcr_new;
@ -321,48 +306,18 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/* Enable SGMII */
if (interface == PHY_INTERFACE_MODE_SGMII ||
phy_interface_mode_is_8023z(interface))
@@ -734,16 +797,11 @@ static void mtk_mac_link_down(struct phy
phylink_config);
if (!mtk_interface_mode_is_xgmii(mac->hw, interface)) {
- /* GMAC modes */
- mtk_m32(mac->hw,
- MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK, 0,
- MTK_MAC_MCR(mac->id));
- } else if (mac->id != MTK_GMAC1_ID) {
- /* XGMAC except for built-in switch */
- mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE,
- MTK_XMAC_MCR(mac->id));
- mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0,
- MTK_XGMAC_STS(mac->id));
+ mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK, 0, MTK_MAC_MCR(mac->id));
+ if (mtk_is_netsys_v3_or_greater(mac->hw))
+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id));
+ } else if (mtk_is_netsys_v3_or_greater(mac->hw) && mac->id != MTK_GMAC1_ID) {
+ mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id));
}
}
@@ -858,10 +916,9 @@ static void mtk_gdm_mac_link_up(struct m
static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
struct phy_device *phy,
unsigned int mode, phy_interface_t interface,
- int speed, int duplex, bool tx_pause,
- bool rx_pause)
+ int speed, int duplex, bool tx_pause, bool rx_pause)
@@ -861,7 +935,7 @@ static void mtk_xgdm_mac_link_up(struct
int speed, int duplex, bool tx_pause,
bool rx_pause)
{
- u32 mcr;
+ u32 mcr, force_link = 0;
if (mac->id == MTK_GMAC1_ID)
return;
@@ -869,15 +926,15 @@ static void mtk_xgdm_mac_link_up(struct
/* Eliminate the interference(before link-up) caused by PHY noise */
mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id));
mdelay(20);
- mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR,
- MTK_XMAC_CNT_CTRL(mac->id));
+ mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
@@ -872,8 +946,10 @@ static void mtk_xgdm_mac_link_up(struct
mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR,
MTK_XMAC_CNT_CTRL(mac->id));
- mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id),
- MTK_XGMAC_FORCE_LINK(mac->id), MTK_XGMAC_STS(mac->id));
@ -372,13 +327,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id));
mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
- mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC |
- XMAC_MCR_TRX_DISABLE);
+ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE);
/* Configure pause modes -
* phylink will avoid these for half duplex
*/
@@ -903,8 +960,13 @@ static void mtk_mac_link_up(struct phyli
mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC |
@@ -903,6 +979,10 @@ static void mtk_mac_link_up(struct phyli
else
mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
tx_pause, rx_pause);
@ -388,11 +338,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ phy_set_mode_ext(mac->pextp, PHY_MODE_ETHERNET, interface);
}
+
static void mtk_mac_disable_tx_lpi(struct phylink_config *config)
{
struct mtk_mac *mac = container_of(config, struct mtk_mac,
@@ -3765,6 +3827,9 @@ static int mtk_open(struct net_device *d
@@ -3765,6 +3845,9 @@ static int mtk_open(struct net_device *d
ppe_num = eth->soc->ppe_num;
@ -402,7 +349,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
if (err) {
netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
@@ -3912,6 +3977,9 @@ static int mtk_stop(struct net_device *d
@@ -3912,6 +3995,9 @@ static int mtk_stop(struct net_device *d
for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
mtk_ppe_stop(eth->ppe[i]);
@ -412,7 +359,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
return 0;
}
@@ -4968,6 +5036,7 @@ static const struct net_device_ops mtk_n
@@ -4968,6 +5054,7 @@ static const struct net_device_ops mtk_n
static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
{
const __be32 *_id = of_get_property(np, "reg", NULL);
@ -420,7 +367,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
phy_interface_t phy_mode;
struct phylink *phylink;
struct mtk_mac *mac;
@@ -5004,16 +5073,44 @@ static int mtk_add_mac(struct mtk_eth *e
@@ -5004,16 +5091,44 @@ static int mtk_add_mac(struct mtk_eth *e
mac->id = id;
mac->hw = eth;
mac->of_node = np;
@ -473,7 +420,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
}
memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip));
@@ -5099,8 +5196,21 @@ static int mtk_add_mac(struct mtk_eth *e
@@ -5099,8 +5214,21 @@ static int mtk_add_mac(struct mtk_eth *e
phy_interface_zero(mac->phylink_config.supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
mac->phylink_config.supported_interfaces);
@ -495,7 +442,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
phylink = phylink_create(&mac->phylink_config,
of_fwnode_handle(mac->of_node),
phy_mode, &mtk_phylink_ops);
@@ -5156,6 +5266,26 @@ free_netdev:
@@ -5156,6 +5284,26 @@ free_netdev:
return err;
}
@ -522,7 +469,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)
{
struct net_device *dev, *tmp;
@@ -5309,7 +5439,8 @@ static int mtk_probe(struct platform_dev
@@ -5309,7 +5457,8 @@ static int mtk_probe(struct platform_dev
regmap_write(cci, 0, 3);
}
@ -532,7 +479,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
err = mtk_sgmii_init(eth);
if (err)
@@ -5418,6 +5549,24 @@ static int mtk_probe(struct platform_dev
@@ -5418,6 +5567,24 @@ static int mtk_probe(struct platform_dev
}
}
@ -557,7 +504,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
err = devm_request_irq(eth->dev, eth->irq[MTK_FE_IRQ_SHARED],
mtk_handle_irq, 0,
@@ -5528,6 +5677,11 @@ static void mtk_remove(struct platform_d
@@ -5528,6 +5695,11 @@ static void mtk_remove(struct platform_d
mtk_stop(eth->netdev[i]);
mac = netdev_priv(eth->netdev[i]);
phylink_disconnect_phy(mac->phylink);

View File

@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -5715,7 +5715,7 @@ static const struct mtk_soc_data mt2701_
@@ -5733,7 +5733,7 @@ static const struct mtk_soc_data mt2701_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -39,7 +39,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5743,7 +5743,7 @@ static const struct mtk_soc_data mt7621_
@@ -5761,7 +5761,7 @@ static const struct mtk_soc_data mt7621_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -48,7 +48,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5773,7 +5773,7 @@ static const struct mtk_soc_data mt7622_
@@ -5791,7 +5791,7 @@ static const struct mtk_soc_data mt7622_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -57,7 +57,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5802,7 +5802,7 @@ static const struct mtk_soc_data mt7623_
@@ -5820,7 +5820,7 @@ static const struct mtk_soc_data mt7623_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5828,7 +5828,7 @@ static const struct mtk_soc_data mt7629_
@@ -5846,7 +5846,7 @@ static const struct mtk_soc_data mt7629_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5860,7 +5860,7 @@ static const struct mtk_soc_data mt7981_
@@ -5878,7 +5878,7 @@ static const struct mtk_soc_data mt7981_
.dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
},
};
@@ -5890,7 +5890,7 @@ static const struct mtk_soc_data mt7986_
@@ -5908,7 +5908,7 @@ static const struct mtk_soc_data mt7986_
.dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
@ -93,7 +93,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
},
};
@@ -5943,7 +5943,7 @@ static const struct mtk_soc_data rt5350_
@@ -5961,7 +5961,7 @@ static const struct mtk_soc_data rt5350_
.dma_l4_valid = RX_DMA_L4_VALID_PDMA,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,

View File

@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
help
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4845,6 +4845,7 @@ static int mtk_get_sset_count(struct net
@@ -4863,6 +4863,7 @@ static int mtk_get_sset_count(struct net
static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data)
{
@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct page_pool_stats stats = {};
int i;
@@ -4857,6 +4858,7 @@ static void mtk_ethtool_pp_stats(struct
@@ -4875,6 +4876,7 @@ static void mtk_ethtool_pp_stats(struct
page_pool_get_stats(ring->page_pool, &stats);
}
page_pool_ethtool_stats_get(data, &stats);