generic: 6.18: add and fix support for Aquantia PHYs

Add support for Aquantia CUX3410 and fix/sync support for the AQR112
variants.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
Daniel Golle
2026-04-27 01:52:38 +01:00
parent be0a49cfe8
commit 10ca4886c4
4 changed files with 161 additions and 31 deletions
@@ -15,7 +15,7 @@ Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -116,6 +116,29 @@
@@ -120,6 +120,29 @@
#define AQR107_OP_IN_PROG_SLEEP 1000
#define AQR107_OP_IN_PROG_TIMEOUT 100000
@@ -45,7 +45,7 @@ Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
static int aqr107_get_sset_count(struct phy_device *phydev)
{
return AQR107_SGMII_STAT_SZ;
@@ -250,6 +273,51 @@ static int aqr_config_aneg(struct phy_de
@@ -264,6 +287,51 @@ static int aqr_config_aneg(struct phy_de
return genphy_c45_check_and_restart_aneg(phydev, changed);
}
@@ -97,7 +97,7 @@ Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
static int aqr_config_intr(struct phy_device *phydev)
{
bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
@@ -1338,7 +1406,7 @@ static struct phy_driver aqr_driver[] =
@@ -1356,7 +1424,7 @@ static struct phy_driver aqr_driver[] =
.name = "Aquantia AQR112",
.probe = aqr107_probe,
.config_init = aqr_gen3_config_init,
@@ -106,7 +106,7 @@ Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
.get_tunable = aqr107_get_tunable,
@@ -1364,7 +1432,7 @@ static struct phy_driver aqr_driver[] =
@@ -1382,7 +1450,7 @@ static struct phy_driver aqr_driver[] =
.name = "Aquantia AQR412",
.probe = aqr107_probe,
.config_init = aqr_gen3_config_init,
@@ -14,7 +14,7 @@ Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -306,10 +306,16 @@ static int aqr_config_aneg_set_prot(stru
@@ -320,10 +320,16 @@ static int aqr_config_aneg_set_prot(stru
phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE,
aquantia_syscfg[if_type].start_rate);
@@ -12,52 +12,80 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -34,6 +34,8 @@
#define PHY_ID_AQR115 0x31c31c63
#define PHY_ID_AQR115C 0x31c31c33
#define PHY_ID_AQR813 0x31c31cb2
@@ -26,6 +26,8 @@
#define PHY_ID_AQR111 0x03a1b610
#define PHY_ID_AQR111B0 0x03a1b612
#define PHY_ID_AQR112 0x03a1b662
+#define PHY_ID_AQR112C 0x03a1b790
+#define PHY_ID_AQR112R 0x31c31d12
#define MDIO_PHYXS_VEND_PROV2 0xc441
#define MDIO_PHYXS_VEND_PROV2_USX_AN BIT(3)
@@ -1634,6 +1636,30 @@ static struct phy_driver aqr_driver[] =
.inband_caps = aqr_gen2_inband_caps,
#define PHY_ID_AQR412 0x03a1b6f2
#define PHY_ID_AQR412C 0x03a1b712
#define PHY_ID_AQR113 0x31c31c40
@@ -1452,6 +1454,58 @@ static struct phy_driver aqr_driver[] =
.config_inband = aqr_gen2_config_inband,
},
+{
{
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112C),
+ .name = "Aquantia AQR112C",
+ .probe = aqr107_probe,
+ .config_aneg = aqr_config_aneg,
+ .config_init = aqr_gen3_config_init,
+ .config_aneg = aqr_config_aneg_set_prot,
+ .config_intr = aqr_config_intr,
+ .handle_interrupt = aqr_handle_interrupt,
+ .read_status = aqr_read_status,
+ .get_tunable = aqr107_get_tunable,
+ .set_tunable = aqr107_set_tunable,
+ .suspend = aqr_gen1_suspend,
+ .resume = aqr_gen1_resume,
+ .read_status = aqr_gen2_read_status,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
+ .get_sset_count = aqr107_get_sset_count,
+ .get_strings = aqr107_get_strings,
+ .get_stats = aqr107_get_stats,
+ .link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
+ .inband_caps = aqr_gen2_inband_caps,
+ .config_inband = aqr_gen2_config_inband,
+},
+{
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112R),
+ .name = "Aquantia AQR112R",
+ .probe = aqr107_probe,
+ .config_init = aqr_gen3_config_init,
+ .config_aneg = aqr_config_aneg_set_prot,
+ .config_intr = aqr_config_intr,
+ .handle_interrupt = aqr_handle_interrupt,
+ .read_status = aqr_read_status,
+ .get_tunable = aqr107_get_tunable,
+ .set_tunable = aqr107_set_tunable,
+ .suspend = aqr_gen1_suspend,
+ .resume = aqr_gen1_resume,
+ .read_status = aqr_gen2_read_status,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
+ .get_sset_count = aqr107_get_sset_count,
+ .get_strings = aqr107_get_strings,
+ .get_stats = aqr107_get_stats,
+ .link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
+ .inband_caps = aqr_gen2_inband_caps,
+ .config_inband = aqr_gen2_config_inband,
+},
};
module_phy_driver(aqr_driver);
@@ -1657,6 +1683,8 @@ static const struct mdio_device_id __may
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR115) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR115C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
+{
PHY_ID_MATCH_MODEL(PHY_ID_AQR412),
.name = "Aquantia AQR412",
.probe = aqr107_probe,
@@ -1693,6 +1747,8 @@ static const struct mdio_device_id __may
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR111) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112C) },
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112R) },
{ }
};
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR412C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
@@ -0,0 +1,102 @@
From c52f17573b48bdb09be946ba5d70c206ef9b2ab0 Mon Sep 17 00:00:00 2001
From: Chad Monroe <chad@monroe.io>
Date: Fri, 11 Oct 2024 16:41:37 -0700
Subject: [PATCH] net: phy: aquantia: add support for CUX3410
Add support for Marvell CUX3410. This PHY is nearly identical to
the AQR113C but without MACsec, SyncE and PTP support.
Signed-off-by: Chad Monroe <chad@monroe.io>
---
drivers/net/phy/aquantia/aquantia_main.c | 45 ++++++++++++++++++++++++
1 file changed, 45 insertions(+)
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -34,6 +34,7 @@
#define PHY_ID_AQR115 0x31c31c63
#define PHY_ID_AQR115C 0x31c31c33
#define PHY_ID_AQR813 0x31c31cb2
+#define PHY_ID_CUX3410 0x31c31dd3
#define MDIO_PHYXS_VEND_PROV2 0xc441
#define MDIO_PHYXS_VEND_PROV2_USX_AN BIT(3)
@@ -50,6 +51,9 @@
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF 9
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10
+#define MDIO_PHYXS_TX_RSVD_VEND_PROV2 0xc441
+#define MDIO_PHYXS_TX_RSVD_VEND_PROV2_ANEG BIT(3)
+
#define MDIO_AN_VEND_PROV 0xc400
#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15)
#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14)
@@ -195,6 +199,16 @@ static int aqr_set_mdix(struct phy_devic
MDIO_AN_RESVD_VEND_PROV_MDIX_MASK, val);
}
+static int aqr107_config_usx_aneg_en(struct phy_device *phydev)
+{
+ u16 val;
+
+ val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_TX_RSVD_VEND_PROV2);
+ val |= MDIO_PHYXS_TX_RSVD_VEND_PROV2_ANEG;
+
+ return phy_write_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_TX_RSVD_VEND_PROV2, val);
+}
+
static int aqr_config_aneg(struct phy_device *phydev)
{
bool changed = false;
@@ -806,6 +820,10 @@ static int aqr_gen1_config_init(struct p
if (ret)
return ret;
+ ret = aqr107_config_usx_aneg_en(phydev);
+ if (ret)
+ phydev_err(phydev, "USX autonegotiation disabled, ret: %d\n", ret);
+
ret = aqr107_config_mdi(phydev);
if (ret)
return ret;
@@ -1560,6 +1578,32 @@ static struct phy_driver aqr_driver[] =
.inband_caps = aqr_gen2_inband_caps,
.config_inband = aqr_gen2_config_inband,
},
+{
+ PHY_ID_MATCH_MODEL(PHY_ID_CUX3410),
+ .name = "Aquantia CUX3410",
+ .probe = aqr107_probe,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
+ .config_init = aqr_gen4_config_init,
+ .config_aneg = aqr_config_aneg,
+ .config_intr = aqr_config_intr,
+ .handle_interrupt = aqr_handle_interrupt,
+ .read_status = aqr_gen2_read_status,
+ .get_tunable = aqr107_get_tunable,
+ .set_tunable = aqr107_set_tunable,
+ .suspend = aqr_gen1_suspend,
+ .resume = aqr_gen1_resume,
+ .get_sset_count = aqr107_get_sset_count,
+ .get_strings = aqr107_get_strings,
+ .get_stats = aqr107_get_stats,
+ .link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
+ .inband_caps = aqr_gen2_inband_caps,
+ .config_inband = aqr_gen2_config_inband,
+},
};
module_phy_driver(aqr_driver);
@@ -1583,6 +1627,7 @@ static const struct mdio_device_id __may
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR115) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR115C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
+ { PHY_ID_MATCH_MODEL(PHY_ID_CUX3410) },
{ }
};