From 663117327a39d1ad8be79d3c6451173c37e97c56 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 8 Jul 2024 09:50:20 +0200 Subject: [PATCH 1/4] net: phy: aquantia: rename and export aqr107_wait_reset_complete() This function is quite generic in this driver and not limited to aqr107. We will use it outside its current compilation unit soon so rename it and declare it in the header. Signed-off-by: Bartosz Golaszewski Signed-off-by: David S. Miller --- drivers/net/phy/aquantia/aquantia.h | 2 ++ drivers/net/phy/aquantia/aquantia_main.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/phy/aquantia/aquantia.h b/drivers/net/phy/aquantia/aquantia.h index 0bca28ec3332..2465345081f8 100644 --- a/drivers/net/phy/aquantia/aquantia.h +++ b/drivers/net/phy/aquantia/aquantia.h @@ -201,4 +201,6 @@ int aqr_phy_led_hw_control_set(struct phy_device *phydev, u8 index, int aqr_phy_led_active_low_set(struct phy_device *phydev, int index, bool enable); int aqr_phy_led_polarity_set(struct phy_device *phydev, int index, unsigned long modes); +int aqr_wait_reset_complete(struct phy_device *phydev); + #endif /* AQUANTIA_H */ diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c index 6c14355744b7..974795bd0860 100644 --- a/drivers/net/phy/aquantia/aquantia_main.c +++ b/drivers/net/phy/aquantia/aquantia_main.c @@ -441,7 +441,7 @@ static int aqr107_set_tunable(struct phy_device *phydev, * The chip also provides a "reset completed" bit, but it's cleared after * read. Therefore function would time out if called again. */ -static int aqr107_wait_reset_complete(struct phy_device *phydev) +int aqr_wait_reset_complete(struct phy_device *phydev) { int val; @@ -494,7 +494,7 @@ static int aqr107_config_init(struct phy_device *phydev) WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII, "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n"); - ret = aqr107_wait_reset_complete(phydev); + ret = aqr_wait_reset_complete(phydev); if (!ret) aqr107_chip_info(phydev); @@ -522,7 +522,7 @@ static int aqcs109_config_init(struct phy_device *phydev) phydev->interface != PHY_INTERFACE_MODE_2500BASEX) return -ENODEV; - ret = aqr107_wait_reset_complete(phydev); + ret = aqr_wait_reset_complete(phydev); if (!ret) aqr107_chip_info(phydev); From ad649a1fac37e390de5b4211b902ec666c4cd202 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 8 Jul 2024 09:50:21 +0200 Subject: [PATCH 2/4] net: phy: aquantia: wait for FW reset before checking the vendor ID Checking the firmware register before it complete the boot process makes no sense, it will report 0 even if FW is available from internal memory. Always wait for FW to boot before continuing or we'll unnecessarily try to load it from nvmem/filesystem and fail. Signed-off-by: Bartosz Golaszewski Signed-off-by: David S. Miller --- drivers/net/phy/aquantia/aquantia_firmware.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/phy/aquantia/aquantia_firmware.c b/drivers/net/phy/aquantia/aquantia_firmware.c index 0c9640ef153b..524627a36c6f 100644 --- a/drivers/net/phy/aquantia/aquantia_firmware.c +++ b/drivers/net/phy/aquantia/aquantia_firmware.c @@ -353,6 +353,10 @@ int aqr_firmware_load(struct phy_device *phydev) { int ret; + ret = aqr_wait_reset_complete(phydev); + if (ret) + return ret; + /* Check if the firmware is not already loaded by pooling * the current version returned by the PHY. If 0 is returned, * no firmware is loaded. From 708405f3e56e3bee086f46a43398ee300c36a1d8 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 8 Jul 2024 09:50:22 +0200 Subject: [PATCH 3/4] net: phy: aquantia: wait for the GLOBAL_CFG to start returning real values When the PHY is first coming up (or resuming from suspend), it's possible that although the FW status shows as running, we still see zeroes in the GLOBAL_CFG set of registers and cannot determine available modes. Since all models support 10M, add a poll and wait the config to become available. Signed-off-by: Bartosz Golaszewski Signed-off-by: David S. Miller --- drivers/net/phy/aquantia/aquantia_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c index 974795bd0860..2c8ba2725a91 100644 --- a/drivers/net/phy/aquantia/aquantia_main.c +++ b/drivers/net/phy/aquantia/aquantia_main.c @@ -652,7 +652,13 @@ static int aqr107_fill_interface_modes(struct phy_device *phydev) unsigned long *possible = phydev->possible_interfaces; unsigned int serdes_mode, rate_adapt; phy_interface_t interface; - int i, val; + int i, val, ret; + + ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, + VEND1_GLOBAL_CFG_10M, val, val != 0, + 1000, 100000, false); + if (ret) + return ret; /* Walk the media-speed configuration registers to determine which * host-side serdes modes may be used by the PHY depending on the From 0ebc581f8a4b7e992bd3bab4d3ad4783245ad09c Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 8 Jul 2024 09:50:23 +0200 Subject: [PATCH 4/4] net: phy: aquantia: add support for aqr115c Add support for a new model to the Aquantia driver. This PHY supports 2.5 gigabit speeds. The PHY mode is referred to by the manufacturer as Overclocked SGMII (OCSGMII) but this actually is just 2500BASEX without in-band signalling so reuse the existing mode to avoid changing the uAPI. Signed-off-by: Bartosz Golaszewski Signed-off-by: David S. Miller --- drivers/net/phy/aquantia/aquantia_main.c | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c index 2c8ba2725a91..d12e35374231 100644 --- a/drivers/net/phy/aquantia/aquantia_main.c +++ b/drivers/net/phy/aquantia/aquantia_main.c @@ -29,6 +29,7 @@ #define PHY_ID_AQR113 0x31c31c40 #define PHY_ID_AQR113C 0x31c31c12 #define PHY_ID_AQR114C 0x31c31c22 +#define PHY_ID_AQR115C 0x31c31c33 #define PHY_ID_AQR813 0x31c31cb2 #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 @@ -1005,6 +1006,30 @@ static struct phy_driver aqr_driver[] = { .led_hw_control_get = aqr_phy_led_hw_control_get, .led_polarity_set = aqr_phy_led_polarity_set, }, +{ + PHY_ID_MATCH_MODEL(PHY_ID_AQR115C), + .name = "Aquantia AQR115C", + .probe = aqr107_probe, + .get_rate_matching = aqr107_get_rate_matching, + .config_init = aqr113c_config_init, + .config_aneg = aqr_config_aneg, + .config_intr = aqr_config_intr, + .handle_interrupt = aqr_handle_interrupt, + .read_status = aqr107_read_status, + .get_tunable = aqr107_get_tunable, + .set_tunable = aqr107_set_tunable, + .suspend = aqr107_suspend, + .resume = aqr107_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, +}, { PHY_ID_MATCH_MODEL(PHY_ID_AQR813), .name = "Aquantia AQR813", @@ -1048,6 +1073,7 @@ static struct mdio_device_id __maybe_unused aqr_tbl[] = { { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) }, { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, { PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) }, + { PHY_ID_MATCH_MODEL(PHY_ID_AQR115C) }, { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, { } };