* [PATCH net-next 0/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY
@ 2026-08-25 19:34 Caleb James DeLisle
2026-08-25 19:34 ` [PATCH net-next 1/3] net: phy: mediatek: move mtk_cal_cycle_wait to mtk-phy-lib Caleb James DeLisle
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Caleb James DeLisle @ 2026-08-25 19:34 UTC (permalink / raw)
To: netdev, ansuelsmth
Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, daniel,
dqfext, SkyLake.Huang, matthias.bgg, angelogioacchino.delregno,
cjd, linux-kernel, linux-arm-kernel, linux-mediatek
NOTE: This patchset bases on https://lore.kernel.org/netdev/20260708102341.53919-1-ansuelsmth@gmail.com/
Add support for the EcoNet EN751221 SoC gigabit PHY, as identified by
product IDs 9451, and 9471.
Caleb James DeLisle (3):
net: phy: mediatek: move mtk_cal_cycle_wait to mtk-phy-lib
net: phy: mediatek: bug fixes to airoha-ge-soc.c
net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY
drivers/net/phy/mediatek/Kconfig | 9 +-
drivers/net/phy/mediatek/airoha-ge-soc.c | 215 ++++++++++++++++++++++-
drivers/net/phy/mediatek/mtk-ge-soc.c | 27 ---
drivers/net/phy/mediatek/mtk-ge-soc.h | 5 +-
drivers/net/phy/mediatek/mtk-phy-lib.c | 29 +++
drivers/net/phy/mediatek/mtk.h | 2 +
6 files changed, 250 insertions(+), 37 deletions(-)
--
2.39.5
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next 1/3] net: phy: mediatek: move mtk_cal_cycle_wait to mtk-phy-lib
2026-08-25 19:34 [PATCH net-next 0/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY Caleb James DeLisle
@ 2026-08-25 19:34 ` Caleb James DeLisle
2026-08-25 19:34 ` [PATCH net-next 2/3] net: phy: mediatek: bug fixes to airoha-ge-soc.c Caleb James DeLisle
2026-08-25 19:34 ` [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY Caleb James DeLisle
2 siblings, 0 replies; 10+ messages in thread
From: Caleb James DeLisle @ 2026-08-25 19:34 UTC (permalink / raw)
To: netdev, ansuelsmth
Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, daniel,
dqfext, SkyLake.Huang, matthias.bgg, angelogioacchino.delregno,
cjd, linux-kernel, linux-arm-kernel, linux-mediatek
mtk_cal_cycle_wait() is shared between mtk-ge-soc.c and airoha-ge-soc.c
making airoha-ge-soc fail to build unless mtk-ge-soc is built too.
Move it to mtk-phy-lib.c which is for this purpose.
Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
---
drivers/net/phy/mediatek/mtk-ge-soc.c | 27 ------------------------
drivers/net/phy/mediatek/mtk-ge-soc.h | 3 ---
drivers/net/phy/mediatek/mtk-phy-lib.c | 29 ++++++++++++++++++++++++++
drivers/net/phy/mediatek/mtk.h | 2 ++
4 files changed, 31 insertions(+), 30 deletions(-)
diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c
index 868ae089013d..614901a8b7f7 100644
--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
@@ -39,33 +39,6 @@ struct mtk_socphy_shared {
struct mtk_socphy_priv priv[4];
};
-int mtk_cal_cycle_wait(struct phy_device *phydev)
-{
- int reg_val;
- int ret;
-
- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
- MTK_PHY_DA_CALIN_FLAG);
-
- ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
- MTK_PHY_RG_AD_CAL_CLK, reg_val,
- reg_val & MTK_PHY_DA_CAL_CLK, 500,
- ANALOG_INTERNAL_OPERATION_MAX_US,
- false);
- if (ret) {
- phydev_err(phydev, "Calibration cycle timeout\n");
- return ret;
- }
-
- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
- MTK_PHY_DA_CALIN_FLAG);
- ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP);
- if (ret < 0)
- return ret;
-
- return FIELD_GET(MTK_PHY_AD_CAL_COMP_OUT_MASK, ret);
-}
-
/* One calibration cycle consists of:
* 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
* until AD_CAL_COMP is ready to output calibration result.
diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.h b/drivers/net/phy/mediatek/mtk-ge-soc.h
index 5e9d24a9833c..834b61dbc690 100644
--- a/drivers/net/phy/mediatek/mtk-ge-soc.h
+++ b/drivers/net/phy/mediatek/mtk-ge-soc.h
@@ -358,7 +358,4 @@ enum CAL_MODE {
SW_M
};
-/* MTK GE SoC common functions */
-int mtk_cal_cycle_wait(struct phy_device *phydev);
-
#endif /* _MTK_GE_SOC_H_ */
diff --git a/drivers/net/phy/mediatek/mtk-phy-lib.c b/drivers/net/phy/mediatek/mtk-phy-lib.c
index 8c2b26f9b840..e78dcc15f4e8 100644
--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
@@ -5,6 +5,7 @@
#include <linux/netdevice.h>
#include "mtk.h"
+#include "mtk-ge-soc.h"
/* Difference between functions with mtk_tr* and __mtk_tr* prefixes is
* mtk_tr* functions: wrapped by page switching operations
@@ -414,6 +415,34 @@ int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
};
EXPORT_SYMBOL_GPL(mt798x_phy_led_hw_control_set);
+int mtk_cal_cycle_wait(struct phy_device *phydev)
+{
+ int reg_val;
+ int ret;
+
+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
+ MTK_PHY_DA_CALIN_FLAG);
+
+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+ MTK_PHY_RG_AD_CAL_CLK, reg_val,
+ reg_val & MTK_PHY_DA_CAL_CLK, 500,
+ ANALOG_INTERNAL_OPERATION_MAX_US,
+ false);
+ if (ret) {
+ phydev_err(phydev, "Calibration cycle timeout\n");
+ return ret;
+ }
+
+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
+ MTK_PHY_DA_CALIN_FLAG);
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP);
+ if (ret < 0)
+ return ret;
+
+ return FIELD_GET(MTK_PHY_AD_CAL_COMP_OUT_MASK, ret);
+}
+EXPORT_SYMBOL_GPL(mtk_cal_cycle_wait);
+
MODULE_DESCRIPTION("MediaTek Ethernet PHY driver common");
MODULE_AUTHOR("Sky Huang <SkyLake.Huang@mediatek.com>");
MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
diff --git a/drivers/net/phy/mediatek/mtk.h b/drivers/net/phy/mediatek/mtk.h
index cd9d4c5550c3..950bc89d3c74 100644
--- a/drivers/net/phy/mediatek/mtk.h
+++ b/drivers/net/phy/mediatek/mtk.h
@@ -87,6 +87,8 @@ void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
int mtk_phy_read_page(struct phy_device *phydev);
int mtk_phy_write_page(struct phy_device *phydev, int page);
+int mtk_cal_cycle_wait(struct phy_device *phydev);
+
int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
unsigned long rules,
unsigned long supported_triggers);
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 2/3] net: phy: mediatek: bug fixes to airoha-ge-soc.c
2026-08-25 19:34 [PATCH net-next 0/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY Caleb James DeLisle
2026-08-25 19:34 ` [PATCH net-next 1/3] net: phy: mediatek: move mtk_cal_cycle_wait to mtk-phy-lib Caleb James DeLisle
@ 2026-08-25 19:34 ` Caleb James DeLisle
2026-08-25 19:34 ` [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY Caleb James DeLisle
2 siblings, 0 replies; 10+ messages in thread
From: Caleb James DeLisle @ 2026-08-25 19:34 UTC (permalink / raw)
To: netdev, ansuelsmth
Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, daniel,
dqfext, SkyLake.Huang, matthias.bgg, angelogioacchino.delregno,
cjd, linux-kernel, linux-arm-kernel, linux-mediatek
Fix crash bug from unconfigured shared, potential namespace collision
in devm_phy_package_join() and typo in Kconfig.
Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
---
drivers/net/phy/mediatek/Kconfig | 2 +-
drivers/net/phy/mediatek/airoha-ge-soc.c | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig
index fe51f4616c54..b8df1a8016c6 100644
--- a/drivers/net/phy/mediatek/Kconfig
+++ b/drivers/net/phy/mediatek/Kconfig
@@ -9,7 +9,7 @@ config AIROHA_GE_SOC_PHY
Supports Airoha SoC built-in Gigabit Ethernet PHYs.
Include support for built-in Ethernet PHYs which are present in
- the AN7581 and AN7583 SoCs. These PHYs d will dynamically
+ the AN7581 and AN7583 SoCs. These PHYs will dynamically
calibrate during startup.
config MEDIATEK_2P5GE_PHY
diff --git a/drivers/net/phy/mediatek/airoha-ge-soc.c b/drivers/net/phy/mediatek/airoha-ge-soc.c
index 601a64d83365..ab183779ee84 100644
--- a/drivers/net/phy/mediatek/airoha-ge-soc.c
+++ b/drivers/net/phy/mediatek/airoha-ge-soc.c
@@ -1596,11 +1596,14 @@ static int an7581_phy_probe(struct phy_device *phydev)
dev_err(&phydev->mdio.bus->dev,
"Failed to setup PHY LED pinctrl\n");
- ret = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
+ ret = devm_phy_package_join(&phydev->mdio.dev, phydev,
+ AIROHA_DEFAULT_PORT0_ADDR,
sizeof(struct airoha_socphy_shared));
if (ret)
return ret;
+ shared = phy_package_get_priv(phydev);
+
priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY
2026-08-25 19:34 [PATCH net-next 0/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY Caleb James DeLisle
2026-08-25 19:34 ` [PATCH net-next 1/3] net: phy: mediatek: move mtk_cal_cycle_wait to mtk-phy-lib Caleb James DeLisle
2026-08-25 19:34 ` [PATCH net-next 2/3] net: phy: mediatek: bug fixes to airoha-ge-soc.c Caleb James DeLisle
@ 2026-08-25 19:34 ` Caleb James DeLisle
2026-08-26 0:00 ` Andrew Lunn
2 siblings, 1 reply; 10+ messages in thread
From: Caleb James DeLisle @ 2026-08-25 19:34 UTC (permalink / raw)
To: netdev, ansuelsmth
Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, daniel,
dqfext, SkyLake.Huang, matthias.bgg, angelogioacchino.delregno,
cjd, linux-kernel, linux-arm-kernel, linux-mediatek
The EcoNet EN751221 gigabit SoC PHY is identified by product IDs 9451
and 9471. These devices have one such PHY which occupies MMIO index
12. This PHY is present in 3FE+1GE chips such as EN7526C, and also
the "G" chips which have an MCM gigabit switch. In the "G" chips,
this provides a 5th ethernet port.
Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
---
drivers/net/phy/mediatek/Kconfig | 9 +-
drivers/net/phy/mediatek/airoha-ge-soc.c | 214 ++++++++++++++++++++++-
drivers/net/phy/mediatek/mtk-ge-soc.h | 2 +
3 files changed, 217 insertions(+), 8 deletions(-)
diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig
index b8df1a8016c6..2d73ea6d8398 100644
--- a/drivers/net/phy/mediatek/Kconfig
+++ b/drivers/net/phy/mediatek/Kconfig
@@ -1,15 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-only
config AIROHA_GE_SOC_PHY
- tristate "Airoha SoC Ethernet PHYs"
- depends on ARM64 || COMPILE_TEST
- depends on ARCH_AIROHA || COMPILE_TEST
+ tristate "Airoha/EcoNet SoC Ethernet PHYs"
+ depends on ARCH_AIROHA || ECONET || COMPILE_TEST
select MTK_NET_PHYLIB
select PHY_PACKAGE
help
- Supports Airoha SoC built-in Gigabit Ethernet PHYs.
+ Supports Airoha and EcoNet SoC built-in Gigabit Ethernet PHYs.
Include support for built-in Ethernet PHYs which are present in
- the AN7581 and AN7583 SoCs. These PHYs will dynamically
+ the AN7581, AN7583, and EN751221 SoCs. These PHYs will dynamically
calibrate during startup.
config MEDIATEK_2P5GE_PHY
diff --git a/drivers/net/phy/mediatek/airoha-ge-soc.c b/drivers/net/phy/mediatek/airoha-ge-soc.c
index ab183779ee84..19c98d53a0fd 100644
--- a/drivers/net/phy/mediatek/airoha-ge-soc.c
+++ b/drivers/net/phy/mediatek/airoha-ge-soc.c
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0+
#include <linux/bitfield.h>
+#include <linux/mfd/syscon.h>
#include <linux/pinctrl/consumer.h>
#include <linux/phy.h>
+#include <linux/regmap.h>
#include "../phylib.h"
#include "mtk.h"
@@ -9,6 +11,8 @@
#define AIROHA_DEFAULT_PORT0_ADDR 0x9
#define AIROHA_PHY_MAX_LEDS 2
+#define ECONET_GPHY_CHIPSCU_RASEL_MASK GENMASK(15, 13)
+#define ECONET_GPHY_PORT0_ADDR 12
enum airoha_mdi_resister_type {
MDI_0R,
@@ -259,6 +263,69 @@ static u8 an7583_zcal_to_r50ohm_5R[64] = {
56, 54, 52, 50, 48, 46, 44, 42, 40, 39, 37, 36, 33, 32, 31, 29,
};
+/*
+ * 2 chip revisions
+ * TXMR (no evidence that these chips were ever discrete)
+ * MDI 0R (5R not known to exist)
+ * TX AMP test/TX AMP 1G/TX AMP 100M/TX AMP 10M/R50
+ * 1 PHY
+ */
+static int en751221_tx_amp_compensation_tbl[2][TRANSFORMER_TYPE_MAX][MDI_TYPE_MAX][CALIB_CONST_TYPE_MAX][4] = {
+ {
+ /* EN751221 */
+ [TXMR] = {
+ [MDI_0R] = {
+ [TX_AMP_TEST_A] = { 14 },
+ [TX_AMP_TEST_B] = { 14 },
+ [TX_AMP_TEST_C] = { 14 },
+ [TX_AMP_TEST_D] = { 14 },
+ [TX_AMP_1G_A] = { 2 },
+ [TX_AMP_1G_B] = { 2 },
+ [TX_AMP_1G_C] = { 2 },
+ [TX_AMP_1G_D] = { 2 },
+ [TX_AMP_100M_A] = { 4 },
+ [TX_AMP_100M_B] = { 4 },
+ [TX_AMP_10M_A] = { 0 },
+ [TX_AMP_10M_B] = { 0 },
+ [R50_A] = { 0 },
+ [R50_B] = { 0 },
+ [R50_C] = { 0 },
+ [R50_D] = { 0 },
+ },
+ },
+ },
+ {
+ /* EN7526C */
+ [TXMR] = {
+ [MDI_0R] = {
+ [TX_AMP_TEST_A] = { 14 },
+ [TX_AMP_TEST_B] = { 14 },
+ [TX_AMP_TEST_C] = { 14 },
+ [TX_AMP_TEST_D] = { 14 },
+ [TX_AMP_1G_A] = { 12 },
+ [TX_AMP_1G_B] = { 13 },
+ [TX_AMP_1G_C] = { 9 },
+ [TX_AMP_1G_D] = { 9 },
+ [TX_AMP_100M_A] = { 4 },
+ [TX_AMP_100M_B] = { 4 },
+ [TX_AMP_10M_A] = { 0 },
+ [TX_AMP_10M_B] = { 0 },
+ [R50_A] = { 0 },
+ [R50_B] = { 0 },
+ [R50_C] = { -4 },
+ [R50_D] = { -4 },
+ },
+ },
+ }
+};
+
+static u8 en751221_zcal_to_r50ohm[64] = {
+ 125, 125, 125, 125, 125, 125, 124, 121, 118, 115, 112, 110, 108, 105, 103, 101,
+ 99, 97, 95, 77, 75, 73, 72, 70, 68, 67, 65, 64, 63, 45, 44, 43,
+ 41, 40, 39, 38, 37, 36, 35, 34, 32, 32, 31, 30, 13, 12, 11, 10,
+ 9, 8, 8, 7, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0
+};
+
static int airoha_cal_cycle(struct phy_device *phydev, int devad,
u32 regnum, u16 mask, u16 cal_val)
{
@@ -276,6 +343,21 @@ static int airoha_cal_cycle(struct phy_device *phydev, int devad,
return ret;
}
+/* EN751221 also mirrors RG_BG_RASEL into CHIP SCU register 0x16c. */
+static void en751221_gphy_mirror_rext(struct phy_device *phydev, u8 zcal)
+{
+ struct regmap *chip_scu;
+
+ chip_scu = syscon_regmap_lookup_by_compatible("econet,en751221-chip-scu");
+ if (IS_ERR(chip_scu)) {
+ phydev_err(phydev, "CHIP SCU unavailable for REXT mirror: %ld\n",
+ PTR_ERR(chip_scu));
+ return;
+ }
+ regmap_update_bits(chip_scu, 0x16c, ECONET_GPHY_CHIPSCU_RASEL_MASK,
+ FIELD_PREP(ECONET_GPHY_CHIPSCU_RASEL_MASK, zcal >> 3));
+}
+
static int airoha_rext_cal_sw(struct phy_device *phydev)
{
int calibration_polarity;
@@ -349,6 +431,10 @@ static int airoha_rext_cal_sw(struct phy_device *phydev)
MTK_PHY_RG_BG_RASEL_MASK,
FIELD_PREP(MTK_PHY_RG_BG_RASEL_MASK, zcal_ctrl >> 3));
+ if (phydev->phy_id == ECONET_GPHY_ID_EN7526C ||
+ phydev->phy_id == ECONET_GPHY_ID_EN751221)
+ en751221_gphy_mirror_rext(phydev, zcal_ctrl);
+
phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0, 0);
return 0;
@@ -1369,6 +1455,106 @@ static int airoha_phy_tx_amp_compensation(struct phy_device *phydev)
return 0;
}
+static int en751221_gphy_config_init(struct phy_device *phydev)
+{
+ struct airoha_socphy_shared *shared = phy_package_get_priv(phydev);
+ int ret;
+
+ shared->mdi_resister_type = MDI_0R;
+
+ if (phydev->phy_id == ECONET_GPHY_ID_EN751221)
+ shared->tx_amp_compensation_tbl = &en751221_tx_amp_compensation_tbl[0];
+ else
+ shared->tx_amp_compensation_tbl = &en751221_tx_amp_compensation_tbl[1];
+
+ shared->r50_cal_tbl = en751221_zcal_to_r50ohm;
+
+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
+
+ /* Global MMD (devad 0x1f) settings. */
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x273, 0x1000);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x272, 0x3cff);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x269, 0x4344);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x044, 0x0030);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x27c, 0x0808);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x27b, 0x1177);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x268, 0x0728);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x269, 0x244f);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x271, 0x4e13);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x417, 0x7775);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x024, 0xc007);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x025, 0x003f);
+ phy_write_mmd(phydev, MDIO_MMD_VEND2, 0x021, 0x800a);
+
+ /* Local MMD (devad 0x1e) settings. */
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x000, 0x01b0);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x001, 0x01be);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x002, 0x01be);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x003, 0x0090);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x004, 0x0205);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x005, 0x0204);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x006, 0x039c);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x007, 0x03c0);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x008, 0x03bc);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x009, 0x0297);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x00a, 0x0005);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x00b, 0x0006);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x014, 0x0040);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x044, 0x0060);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x176, 0x5500);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x177, 0x0055);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x041, 0x3333);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x0a6, 0x0350);
+
+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+ __mtk_tr_write(phydev, 0x1, 0xf, 0x00, 0x00002b);
+ __mtk_tr_write(phydev, 0x1, 0xf, 0x03, 0x082422);
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+ ret = phy_write(phydev, MII_CTRL1000,
+ ADVERTISE_1000FULL | CTL1000_PREFER_MASTER |
+ CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER);
+ if (ret)
+ return ret;
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_1);
+ __phy_write(phydev, 0x14, 0x3a14);
+ phy_restore_page(phydev, ret, 0);
+
+ if (phydev->phy_id == ECONET_GPHY_ID_EN7526C) {
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x201, 0x4002);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x03d, 0x0c00);
+ } else {
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x012, 0x2c10);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x017, 0x0410);
+ }
+
+ phy_set_bits(phydev, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE);
+
+ ret = airoha_phy_calib(phydev);
+ if (ret)
+ return ret;
+
+ ret = airoha_phy_auto_select_transformer(phydev);
+ if (ret)
+ return ret;
+
+ ret = airoha_phy_tx_amp_compensation(phydev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int en751221_gphy_match(struct phy_device *phydev,
+ const struct phy_driver *phydrv)
+{
+ return phydev->phy_id == ECONET_GPHY_ID_EN751221 ||
+ phydev->phy_id == ECONET_GPHY_ID_EN7526C;
+}
+
static int an7581_phy_config_init(struct phy_device *phydev)
{
struct airoha_socphy_shared *shared = phy_package_get_priv(phydev);
@@ -1585,6 +1771,7 @@ static int an7581_phy_config_init(struct phy_device *phydev)
static int an7581_phy_probe(struct phy_device *phydev)
{
+ int port0 = AIROHA_DEFAULT_PORT0_ADDR;
struct airoha_socphy_shared *shared;
struct mtk_socphy_priv *priv;
struct pinctrl *pinctrl;
@@ -1596,8 +1783,11 @@ static int an7581_phy_probe(struct phy_device *phydev)
dev_err(&phydev->mdio.bus->dev,
"Failed to setup PHY LED pinctrl\n");
- ret = devm_phy_package_join(&phydev->mdio.dev, phydev,
- AIROHA_DEFAULT_PORT0_ADDR,
+ if (phydev->phy_id == ECONET_GPHY_ID_EN7526C ||
+ phydev->phy_id == ECONET_GPHY_ID_EN751221)
+ port0 = ECONET_GPHY_PORT0_ADDR;
+
+ ret = devm_phy_package_join(&phydev->mdio.dev, phydev, port0,
sizeof(struct airoha_socphy_shared));
if (ret)
return ret;
@@ -1608,7 +1798,7 @@ static int an7581_phy_probe(struct phy_device *phydev)
if (!priv)
return -ENOMEM;
- if (phydev->mdio.addr == AIROHA_DEFAULT_PORT0_ADDR)
+ if (phydev->mdio.addr == port0)
shared->phydev_p0 = phydev;
phydev->priv = priv;
@@ -1797,6 +1987,22 @@ static struct phy_driver mtk_socphy_driver[] = {
.read_page = mtk_phy_read_page,
.write_page = mtk_phy_write_page,
},
+ {
+ .name = "EcoNet EN751221 GPHY",
+ .config_init = en751221_gphy_config_init,
+ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+ .match_phy_device = en751221_gphy_match,
+ .probe = an7581_phy_probe,
+ .led_blink_set = mt798x_phy_led_blink_set,
+ .led_brightness_set = mt798x_phy_led_brightness_set,
+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+ .led_hw_control_set = mt798x_phy_led_hw_control_set,
+ .led_hw_control_get = mt798x_phy_led_hw_control_get,
+ .led_polarity_set = an7581_phy_led_polarity_set,
+ .read_page = mtk_phy_read_page,
+ .write_page = mtk_phy_write_page,
+ }
};
module_phy_driver(mtk_socphy_driver);
@@ -1804,6 +2010,8 @@ module_phy_driver(mtk_socphy_driver);
static const struct mdio_device_id __maybe_unused airoha_socphy_tbl[] = {
{ PHY_ID_MATCH_EXACT(AIROHA_GPHY_ID_AN7581) },
{ PHY_ID_MATCH_EXACT(AIROHA_GPHY_ID_AN7583) },
+ { PHY_ID_MATCH_EXACT(ECONET_GPHY_ID_EN751221) },
+ { PHY_ID_MATCH_EXACT(ECONET_GPHY_ID_EN7526C) },
{ }
};
diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.h b/drivers/net/phy/mediatek/mtk-ge-soc.h
index 834b61dbc690..1f38b4c81860 100644
--- a/drivers/net/phy/mediatek/mtk-ge-soc.h
+++ b/drivers/net/phy/mediatek/mtk-ge-soc.h
@@ -9,6 +9,8 @@
#define MTK_GPHY_ID_MT7988 0x03a29481
#define AIROHA_GPHY_ID_AN7581 0x03a294c1
#define AIROHA_GPHY_ID_AN7583 0xc0ff0420
+#define ECONET_GPHY_ID_EN751221 0x03a29451
+#define ECONET_GPHY_ID_EN7526C 0x03a29471
#define MTK_EXT_PAGE_ACCESS 0x1f
#define MTK_PHY_PAGE_STANDARD 0x0000
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY
2026-08-25 19:34 ` [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY Caleb James DeLisle
@ 2026-08-26 0:00 ` Andrew Lunn
2026-08-26 0:59 ` Caleb James DeLisle
0 siblings, 1 reply; 10+ messages in thread
From: Andrew Lunn @ 2026-08-26 0:00 UTC (permalink / raw)
To: Caleb James DeLisle
Cc: netdev, ansuelsmth, hkallweit1, linux, davem, edumazet, kuba,
pabeni, daniel, dqfext, SkyLake.Huang, matthias.bgg,
angelogioacchino.delregno, linux-kernel, linux-arm-kernel,
linux-mediatek
> +static int en751221_tx_amp_compensation_tbl[2][TRANSFORMER_TYPE_MAX][MDI_TYPE_MAX][CALIB_CONST_TYPE_MAX][4] = {
const?
> +static u8 en751221_zcal_to_r50ohm[64] = {
const?
> + 125, 125, 125, 125, 125, 125, 124, 121, 118, 115, 112, 110, 108, 105, 103, 101,
> + 99, 97, 95, 77, 75, 73, 72, 70, 68, 67, 65, 64, 63, 45, 44, 43,
> + 41, 40, 39, 38, 37, 36, 35, 34, 32, 32, 31, 30, 13, 12, 11, 10,
> + 9, 8, 8, 7, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0
> +};
> +/* EN751221 also mirrors RG_BG_RASEL into CHIP SCU register 0x16c. */
> +static void en751221_gphy_mirror_rext(struct phy_device *phydev, u8 zcal)
> +{
> + struct regmap *chip_scu;
> +
> + chip_scu = syscon_regmap_lookup_by_compatible("econet,en751221-chip-scu");
Does this need a change to the binding document?
> +static int en751221_gphy_config_init(struct phy_device *phydev)
> +{
> + phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
Why is the EEE register being cleared?
> +
> + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
> + __mtk_tr_write(phydev, 0x1, 0xf, 0x00, 0x00002b);
> + __mtk_tr_write(phydev, 0x1, 0xf, 0x03, 0x082422);
> + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
> +
> + ret = phy_write(phydev, MII_CTRL1000,
> + ADVERTISE_1000FULL | CTL1000_PREFER_MASTER |
> + CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER);
What does this default to?
> +
> + phy_set_bits(phydev, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE);
Why? config_aneg() will do this, if needed.
Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY
2026-08-26 0:00 ` Andrew Lunn
@ 2026-08-26 0:59 ` Caleb James DeLisle
2026-08-26 2:21 ` Andrew Lunn
0 siblings, 1 reply; 10+ messages in thread
From: Caleb James DeLisle @ 2026-08-26 0:59 UTC (permalink / raw)
To: Andrew Lunn, ansuelsmth
Cc: netdev, hkallweit1, linux, davem, edumazet, kuba, pabeni, daniel,
dqfext, SkyLake.Huang, matthias.bgg, angelogioacchino.delregno,
linux-kernel, linux-arm-kernel, linux-mediatek
On 26/08/2026 02:00, Andrew Lunn wrote:
>> +static int en751221_tx_amp_compensation_tbl[2][TRANSFORMER_TYPE_MAX][MDI_TYPE_MAX][CALIB_CONST_TYPE_MAX][4] = {
> const?
Ahh yes, indeed all of them should be. Note to Ansuel: This is relevant
to your Airoha code as well.
>
>> +static u8 en751221_zcal_to_r50ohm[64] = {
> const?
>
>> + 125, 125, 125, 125, 125, 125, 124, 121, 118, 115, 112, 110, 108, 105, 103, 101,
>> + 99, 97, 95, 77, 75, 73, 72, 70, 68, 67, 65, 64, 63, 45, 44, 43,
>> + 41, 40, 39, 38, 37, 36, 35, 34, 32, 32, 31, 30, 13, 12, 11, 10,
>> + 9, 8, 8, 7, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0
>> +};
>> +/* EN751221 also mirrors RG_BG_RASEL into CHIP SCU register 0x16c. */
>> +static void en751221_gphy_mirror_rext(struct phy_device *phydev, u8 zcal)
>> +{
>> + struct regmap *chip_scu;
>> +
>> + chip_scu = syscon_regmap_lookup_by_compatible("econet,en751221-chip-scu");
> Does this need a change to the binding document?
Not as far as I know. econet,en751221-chip-scu is defined in
mfd/syscon.yaml because it's a catch-all for configuration that the
engineers didn't know what to do with.
>
>> +static int en751221_gphy_config_init(struct phy_device *phydev)
>> +{
>> + phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
> Why is the EEE register being cleared?
From reading the reference implementation, I get the impression that
this hardware is something of a basket case. There was a certain amount
of "write three times and then read back" type magic that I just omitted
because it really looks like they were actively debugging and as soon as
it started working they shipped the code exactly as it was.
In the case of disabling EEE, I thought it more prudent to follow them
because I don't have every SoC that this PHY ever appeared on and I
would rather not diverge too greatly and risk it being unreliable on
some devices.
>
>> +
>> + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
>> + __mtk_tr_write(phydev, 0x1, 0xf, 0x00, 0x00002b);
>> + __mtk_tr_write(phydev, 0x1, 0xf, 0x03, 0x082422);
>> + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
>> +
>> + ret = phy_write(phydev, MII_CTRL1000,
>> + ADVERTISE_1000FULL | CTL1000_PREFER_MASTER |
>> + CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER);
> What does this default to?
It starts with only ADVERTISE_1000FULL. I don't know why the engineers
wanted to set it to master, but its definitely intentional.
>
>> +
>> + phy_set_bits(phydev, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE);
> Why? config_aneg() will do this, if needed.
Okay this is probably just because the code I was working from is very
old. I will review this and see if it's truly needed.
Also you're certainly more knowledgeable than me about what to expect
from PHY hardware, so if it is your opinion that setting master and
disabling EEE are probably not a real workaround for stability problems,
then I'll be happy to give it a try with these omitted.
Thanks,
Caleb
>
> Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY
2026-08-26 0:59 ` Caleb James DeLisle
@ 2026-08-26 2:21 ` Andrew Lunn
2026-08-26 16:37 ` Caleb James DeLisle
0 siblings, 1 reply; 10+ messages in thread
From: Andrew Lunn @ 2026-08-26 2:21 UTC (permalink / raw)
To: Caleb James DeLisle
Cc: ansuelsmth, netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, daniel, dqfext, SkyLake.Huang, matthias.bgg,
angelogioacchino.delregno, linux-kernel, linux-arm-kernel,
linux-mediatek
> > Does this need a change to the binding document?
>
>
> Not as far as I know. econet,en751221-chip-scu is defined in mfd/syscon.yaml
> because it's a catch-all for configuration that the engineers didn't know
> what to do with.
Do you need a property in the PHY node to make this work?
> > > +static int en751221_gphy_config_init(struct phy_device *phydev)
> > > +{
> > > + phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
> > Why is the EEE register being cleared?
>
>
> From reading the reference implementation, I get the impression that this
> hardware is something of a basket case. There was a certain amount of "write
> three times and then read back" type magic that I just omitted because it
> really looks like they were actively debugging and as soon as it started
> working they shipped the code exactly as it was.
>
>
> In the case of disabling EEE, I thought it more prudent to follow them
> because I don't have every SoC that this PHY ever appeared on and I would
> rather not diverge too greatly and risk it being unreliable on some devices.
Is EEE broken? If it is, this is not the correct way to disable
it. You should call phy_disable_eee(phydev); This will also prevent
user space enabling it again.
> > > + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
> > > + __mtk_tr_write(phydev, 0x1, 0xf, 0x00, 0x00002b);
> > > + __mtk_tr_write(phydev, 0x1, 0xf, 0x03, 0x082422);
> > > + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
> > > +
> > > + ret = phy_write(phydev, MII_CTRL1000,
> > > + ADVERTISE_1000FULL | CTL1000_PREFER_MASTER |
> > > + CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER);
> > What does this default to?
> It starts with only ADVERTISE_1000FULL. I don't know why the engineers
> wanted to set it to master, but its definitely intentional.
Generally, switches take the master role, and client take the slave
role. So this does make sense for a PHY used in a switch.
Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY
2026-08-26 2:21 ` Andrew Lunn
@ 2026-08-26 16:37 ` Caleb James DeLisle
2026-08-26 16:50 ` Andrew Lunn
0 siblings, 1 reply; 10+ messages in thread
From: Caleb James DeLisle @ 2026-08-26 16:37 UTC (permalink / raw)
To: Andrew Lunn
Cc: ansuelsmth, netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, daniel, dqfext, SkyLake.Huang, matthias.bgg,
angelogioacchino.delregno, linux-kernel, linux-arm-kernel,
linux-mediatek
On 26/08/2026 04:21, Andrew Lunn wrote:
>>> Does this need a change to the binding document?
>>
>> Not as far as I know. econet,en751221-chip-scu is defined in mfd/syscon.yaml
>> because it's a catch-all for configuration that the engineers didn't know
>> what to do with.
> Do you need a property in the PHY node to make this work?
No it's not requiring anything in the PHY node, instead it fishes for
econet,en751221-chip-scu in the DT. I'm not much a fan of this pattern
because of the magic, but this way of accessing is fairly common and in
this case it is how Airoha likes to access the chip-scu thingy when they
need it.
https://lore.kernel.org/all/20241112-clk-en7581-syscon-v2-4-8ada5e394ae4@kernel.org/
>
>>>> +static int en751221_gphy_config_init(struct phy_device *phydev)
>>>> +{
>>>> + phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
>>> Why is the EEE register being cleared?
>>
>> From reading the reference implementation, I get the impression that this
>> hardware is something of a basket case. There was a certain amount of "write
>> three times and then read back" type magic that I just omitted because it
>> really looks like they were actively debugging and as soon as it started
>> working they shipped the code exactly as it was.
>>
>>
>> In the case of disabling EEE, I thought it more prudent to follow them
>> because I don't have every SoC that this PHY ever appeared on and I would
>> rather not diverge too greatly and risk it being unreliable on some devices.
> Is EEE broken? If it is, this is not the correct way to disable
> it. You should call phy_disable_eee(phydev); This will also prevent
> user space enabling it again.
I tested my board removing the EEE disable and the MASTER line, and it
seems to work. I can't get any CRC errors flooding the link, and
MII_STAT1000 reads LPA_1000LOCALRXOK | LPA_1000REMRXOK | LPA_1000FULL
which suggests to me that it's able to operate happily in slave mode.
So unless you or someone else thinks it's inadvisable, I'm inclined to
just enable these things and then wait to see if anybody finds a board
that has problems.
Thanks,
Caleb
>
>>>> + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
>>>> + __mtk_tr_write(phydev, 0x1, 0xf, 0x00, 0x00002b);
>>>> + __mtk_tr_write(phydev, 0x1, 0xf, 0x03, 0x082422);
>>>> + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
>>>> +
>>>> + ret = phy_write(phydev, MII_CTRL1000,
>>>> + ADVERTISE_1000FULL | CTL1000_PREFER_MASTER |
>>>> + CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER);
>>> What does this default to?
>> It starts with only ADVERTISE_1000FULL. I don't know why the engineers
>> wanted to set it to master, but its definitely intentional.
> Generally, switches take the master role, and client take the slave
> role. So this does make sense for a PHY used in a switch.
>
> Andrew
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY
2026-08-26 16:37 ` Caleb James DeLisle
@ 2026-08-26 16:50 ` Andrew Lunn
2026-08-26 20:27 ` Caleb James DeLisle
0 siblings, 1 reply; 10+ messages in thread
From: Andrew Lunn @ 2026-08-26 16:50 UTC (permalink / raw)
To: Caleb James DeLisle
Cc: ansuelsmth, netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, daniel, dqfext, SkyLake.Huang, matthias.bgg,
angelogioacchino.delregno, linux-kernel, linux-arm-kernel,
linux-mediatek
> I tested my board removing the EEE disable and the MASTER line, and it seems
> to work. I can't get any CRC errors flooding the link, and MII_STAT1000
> reads LPA_1000LOCALRXOK | LPA_1000REMRXOK | LPA_1000FULL which suggests to
> me that it's able to operate happily in slave mode.
>
>
> So unless you or someone else thinks it's inadvisable, I'm inclined to just
> enable these things and then wait to see if anybody finds a board that has
> problems.
Master/slave should sort itself out, maybe taking a little longer if
there is an initial conflict. Where it can go wrong is when the random
number generator in the PHY always returns 42. Put the same PHY on the
other end and the election always fails.
EEE issues can be more subtle, it depends on what the link partner is.
But yes, we can start without these. But please mention this in the
commit message, just to give a hint to anybody who ends up trying to
debug in these areas.
Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY
2026-08-26 16:50 ` Andrew Lunn
@ 2026-08-26 20:27 ` Caleb James DeLisle
0 siblings, 0 replies; 10+ messages in thread
From: Caleb James DeLisle @ 2026-08-26 20:27 UTC (permalink / raw)
To: Andrew Lunn
Cc: ansuelsmth, netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, daniel, dqfext, SkyLake.Huang, matthias.bgg,
angelogioacchino.delregno, linux-kernel, linux-arm-kernel,
linux-mediatek
On 26/08/2026 18:50, Andrew Lunn wrote:
>> I tested my board removing the EEE disable and the MASTER line, and it seems
>> to work. I can't get any CRC errors flooding the link, and MII_STAT1000
>> reads LPA_1000LOCALRXOK | LPA_1000REMRXOK | LPA_1000FULL which suggests to
>> me that it's able to operate happily in slave mode.
>>
>>
>> So unless you or someone else thinks it's inadvisable, I'm inclined to just
>> enable these things and then wait to see if anybody finds a board that has
>> problems.
> Master/slave should sort itself out, maybe taking a little longer if
> there is an initial conflict. Where it can go wrong is when the random
> number generator in the PHY always returns 42. Put the same PHY on the
> other end and the election always fails.
>
> EEE issues can be more subtle, it depends on what the link partner is.
>
> But yes, we can start without these. But please mention this in the
> commit message, just to give a hint to anybody who ends up trying to
> debug in these areas.
Just re-sent v2, in fact after this conversation I did more testing and
caught it sporadically failing to negotiate, so I put back the force
master, confirmed it is fixed, and added a comment.
Thanks again for your kind review and advice.
Caleb
>
> Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-08-26 20:27 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-25 19:34 [PATCH net-next 0/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY Caleb James DeLisle
2026-08-25 19:34 ` [PATCH net-next 1/3] net: phy: mediatek: move mtk_cal_cycle_wait to mtk-phy-lib Caleb James DeLisle
2026-08-25 19:34 ` [PATCH net-next 2/3] net: phy: mediatek: bug fixes to airoha-ge-soc.c Caleb James DeLisle
2026-08-25 19:34 ` [PATCH net-next 3/3] net: phy: mediatek: support EcoNet EN751221 gbit SoC PHY Caleb James DeLisle
2026-08-26 0:00 ` Andrew Lunn
2026-08-26 0:59 ` Caleb James DeLisle
2026-08-26 2:21 ` Andrew Lunn
2026-08-26 16:37 ` Caleb James DeLisle
2026-08-26 16:50 ` Andrew Lunn
2026-08-26 20:27 ` Caleb James DeLisle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).