--- /dev/null
+From 9d844da693d6d0813714d9b5b7a58ac05c4cf7f0 Mon Sep 17 00:00:00 2001
+From: Chad Monroe <chad@monroe.io>
+Date: Sat, 22 Nov 2025 13:32:15 +0000
+Subject: [PATCH] net: phy: mxl-gpy: add support for MxL86211C
+
+MxL86211C is a smaller and more efficient version of the GPY211C.
+Add the PHY ID and phy_driver instance to the mxl-gpy driver.
+
+Signed-off-by: Chad Monroe <chad@monroe.io>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/cabf3559d6511bed6b8a925f540e3162efc20f6b.1763818120.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/mxl-gpy.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/drivers/net/phy/mxl-gpy.c
++++ b/drivers/net/phy/mxl-gpy.c
+@@ -30,6 +30,7 @@
+ #define PHY_ID_GPY241B 0x67C9DE40
+ #define PHY_ID_GPY241BM 0x67C9DE80
+ #define PHY_ID_GPY245B 0x67C9DEC0
++#define PHY_ID_MXL86211C 0xC1335400
+
+ #define PHY_CTL1 0x13
+ #define PHY_CTL1_MDICD BIT(3)
+@@ -1275,6 +1276,28 @@ static struct phy_driver gpy_drivers[] =
+ .get_wol = gpy_get_wol,
+ .set_loopback = gpy_loopback,
+ },
++ {
++ PHY_ID_MATCH_MODEL(PHY_ID_MXL86211C),
++ .name = "Maxlinear Ethernet MxL86211C",
++ .get_features = genphy_c45_pma_read_abilities,
++ .config_init = gpy_config_init,
++ .probe = gpy_probe,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .config_aneg = gpy_config_aneg,
++ .aneg_done = genphy_c45_aneg_done,
++ .read_status = gpy_read_status,
++ .config_intr = gpy_config_intr,
++ .handle_interrupt = gpy_handle_interrupt,
++ .set_wol = gpy_set_wol,
++ .get_wol = gpy_get_wol,
++ .set_loopback = gpy_loopback,
++ .led_brightness_set = gpy_led_brightness_set,
++ .led_hw_is_supported = gpy_led_hw_is_supported,
++ .led_hw_control_get = gpy_led_hw_control_get,
++ .led_hw_control_set = gpy_led_hw_control_set,
++ .led_polarity_set = gpy_led_polarity_set,
++ },
+ };
+ module_phy_driver(gpy_drivers);
+
+@@ -1291,6 +1314,7 @@ static const struct mdio_device_id __may
+ {PHY_ID_MATCH_MODEL(PHY_ID_GPY241B)},
+ {PHY_ID_MATCH_MODEL(PHY_ID_GPY241BM)},
+ {PHY_ID_MATCH_MODEL(PHY_ID_GPY245B)},
++ {PHY_ID_MATCH_MODEL(PHY_ID_MXL86211C)},
+ { }
+ };
+ MODULE_DEVICE_TABLE(mdio, gpy_tbl);
--- /dev/null
+From aaf0094daf0d7a0e4599280341710c98ba1e9d35 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 7 Jan 2026 13:48:16 +0000
+Subject: [PATCH] net: phy: mxl-gpy: implement SGMII in-band configuration
+
+SGMII in-band autonegotiation was previously kept untouched (and restored
+after switching back from 2500Base-X to SGMII). Now that the kernel offers
+a way to announce in-band capabilities and enable/disable in-band AN,
+implement the .inband_caps and .config_inband driver ops.
+This moves the responsibility to configure SGMII in-band AN from the PHY
+driver to phylink.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/mxl-gpy.c | 61 ++++++++++++++++++++++++++++++---------
+ 1 file changed, 47 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/phy/mxl-gpy.c
++++ b/drivers/net/phy/mxl-gpy.c
+@@ -568,20 +568,6 @@ static int gpy_update_interface(struct p
+ case SPEED_100:
+ case SPEED_10:
+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
+- if (gpy_sgmii_aneg_en(phydev))
+- break;
+- /* Enable and restart SGMII ANEG for 10/100/1000Mbps link speed
+- * if ANEG is disabled (in 2500-BaseX mode).
+- */
+- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
+- VSPEC1_SGMII_ANEN_ANRS,
+- VSPEC1_SGMII_ANEN_ANRS);
+- if (ret < 0) {
+- phydev_err(phydev,
+- "Error: Enable of SGMII ANEG failed: %d\n",
+- ret);
+- return ret;
+- }
+ break;
+ }
+
+@@ -1022,6 +1008,27 @@ static int gpy_led_polarity_set(struct p
+ return -EINVAL;
+ }
+
++static unsigned int gpy_inband_caps(struct phy_device *phydev,
++ phy_interface_t interface)
++{
++ switch (interface) {
++ case PHY_INTERFACE_MODE_SGMII:
++ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
++ case PHY_INTERFACE_MODE_2500BASEX:
++ return LINK_INBAND_DISABLE;
++ default:
++ return 0;
++ }
++}
++
++static int gpy_config_inband(struct phy_device *phydev, unsigned int modes)
++{
++ return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
++ VSPEC1_SGMII_ANEN_ANRS,
++ (modes == LINK_INBAND_DISABLE) ? 0 :
++ VSPEC1_SGMII_ANEN_ANRS);
++}
++
+ static struct phy_driver gpy_drivers[] = {
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_GPY2xx),
+@@ -1029,6 +1036,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1052,6 +1061,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1074,6 +1085,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1097,6 +1110,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy21x_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1119,6 +1134,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy21x_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1141,6 +1158,8 @@ static struct phy_driver gpy_drivers[] =
+ .name = "Maxlinear Ethernet GPY212B",
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy21x_config_init,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .probe = gpy_probe,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+@@ -1164,6 +1183,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy21x_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1187,6 +1208,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy21x_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1209,6 +1232,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy21x_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1231,6 +1256,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1248,6 +1275,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1265,6 +1294,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+@@ -1282,6 +1313,8 @@ static struct phy_driver gpy_drivers[] =
+ .get_features = genphy_c45_pma_read_abilities,
+ .config_init = gpy_config_init,
+ .probe = gpy_probe,
++ .inband_caps = gpy_inband_caps,
++ .config_inband = gpy_config_inband,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .config_aneg = gpy_config_aneg,
+++ /dev/null
-From a969b663c866129ed9eb217785a6574fbe826f1d Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 6 Apr 2023 23:36:50 +0100
-Subject: [PATCH] net: phy: mxl-gpy: don't use SGMII AN if using phylink
-
-MAC drivers using phylink expect SGMII in-band-status to be switched off
-when attached to a PHY. Make sure this is the case also for mxl-gpy which
-keeps SGMII in-band-status in case of SGMII interface mode is used.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/mxl-gpy.c | 19 ++++++++++++++++---
- 1 file changed, 16 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/mxl-gpy.c
-+++ b/drivers/net/phy/mxl-gpy.c
-@@ -380,8 +380,11 @@ static bool gpy_2500basex_chk(struct phy
-
- phydev->speed = SPEED_2500;
- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-- phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
-- VSPEC1_SGMII_CTRL_ANEN, 0);
-+
-+ if (!phydev->phylink)
-+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
-+ VSPEC1_SGMII_CTRL_ANEN, 0);
-+
- return true;
- }
-
-@@ -432,6 +435,14 @@ static int gpy_config_aneg(struct phy_de
- u32 adv;
- int ret;
-
-+ /* Disable SGMII auto-negotiation if using phylink */
-+ if (phydev->phylink) {
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
-+ VSPEC1_SGMII_CTRL_ANEN, 0);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
- if (phydev->autoneg == AUTONEG_DISABLE) {
- /* Configure half duplex with genphy_setup_forced,
- * because genphy_c45_pma_setup_forced does not support.
-@@ -554,6 +565,8 @@ static int gpy_update_interface(struct p
- switch (phydev->speed) {
- case SPEED_2500:
- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ if (phydev->phylink)
-+ break;
- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
- VSPEC1_SGMII_CTRL_ANEN, 0);
- if (ret < 0) {
-@@ -567,7 +580,7 @@ static int gpy_update_interface(struct p
- case SPEED_100:
- case SPEED_10:
- phydev->interface = PHY_INTERFACE_MODE_SGMII;
-- if (gpy_sgmii_aneg_en(phydev))
-+ if (phydev->phylink || gpy_sgmii_aneg_en(phydev))
- break;
- /* Enable and restart SGMII ANEG for 10/100/1000Mbps link speed
- * if ANEG is disabled (in 2500-BaseX mode).