From bc3d60bd4c91c338d44ad7d8a7389e3663e3ecb5 Mon Sep 17 00:00:00 2001 From: Paul Davey Date: Thu, 7 Nov 2024 11:20:57 +1300 Subject: net: phy: aquantia: Add mdix config and reporting Add support for configuring MDI-X state of PHY. Add reporting of resolved MDI-X state in status information. Tested on AQR113C. Signed-off-by: Paul Davey Link: https://patch.msgid.link/20241106222057.3965379-1-paul.davey@alliedtelesis.co.nz Signed-off-by: Jakub Kicinski --- drivers/net/phy/aquantia/aquantia_main.c | 52 ++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c index 38d0dd5c80a4..bb56a66d2a48 100644 --- a/drivers/net/phy/aquantia/aquantia_main.c +++ b/drivers/net/phy/aquantia/aquantia_main.c @@ -54,6 +54,12 @@ #define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0) #define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4 +#define MDIO_AN_RESVD_VEND_PROV 0xc410 +#define MDIO_AN_RESVD_VEND_PROV_MDIX_AUTO 0 +#define MDIO_AN_RESVD_VEND_PROV_MDIX_MDI 1 +#define MDIO_AN_RESVD_VEND_PROV_MDIX_MDIX 2 +#define MDIO_AN_RESVD_VEND_PROV_MDIX_MASK GENMASK(1, 0) + #define MDIO_AN_TX_VEND_STATUS1 0xc800 #define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1) #define MDIO_AN_TX_VEND_STATUS1_10BASET 0 @@ -64,6 +70,9 @@ #define MDIO_AN_TX_VEND_STATUS1_5000BASET 5 #define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX BIT(0) +#define MDIO_AN_RESVD_VEND_STATUS1 0xc810 +#define MDIO_AN_RESVD_VEND_STATUS1_MDIX BIT(8) + #define MDIO_AN_TX_VEND_INT_STATUS1 0xcc00 #define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT BIT(1) @@ -155,12 +164,40 @@ static void aqr107_get_stats(struct phy_device *phydev, } } +static int aqr_set_mdix(struct phy_device *phydev, int mdix) +{ + u16 val = 0; + + switch (mdix) { + case ETH_TP_MDI: + val = MDIO_AN_RESVD_VEND_PROV_MDIX_MDI; + break; + case ETH_TP_MDI_X: + val = MDIO_AN_RESVD_VEND_PROV_MDIX_MDIX; + break; + case ETH_TP_MDI_AUTO: + case ETH_TP_MDI_INVALID: + default: + val = MDIO_AN_RESVD_VEND_PROV_MDIX_AUTO; + break; + } + + return phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_RESVD_VEND_PROV, + MDIO_AN_RESVD_VEND_PROV_MDIX_MASK, val); +} + static int aqr_config_aneg(struct phy_device *phydev) { bool changed = false; u16 reg; int ret; + ret = aqr_set_mdix(phydev, phydev->mdix_ctrl); + if (ret < 0) + return ret; + if (ret > 0) + changed = true; + if (phydev->autoneg == AUTONEG_DISABLE) return genphy_c45_pma_setup_forced(phydev); @@ -278,6 +315,21 @@ static int aqr_read_status(struct phy_device *phydev) val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF); } + val = genphy_c45_aneg_done(phydev); + if (val < 0) + return val; + if (val) { + val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RESVD_VEND_STATUS1); + if (val < 0) + return val; + if (val & MDIO_AN_RESVD_VEND_STATUS1_MDIX) + phydev->mdix = ETH_TP_MDI_X; + else + phydev->mdix = ETH_TP_MDI; + } else { + phydev->mdix = ETH_TP_MDI_INVALID; + } + return genphy_c45_read_status(phydev); } -- cgit