* [PATCH net-next 01/15] net: phy: aquantia: rename AQR412 to AQR412C and add real AQR412
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:35 ` Andrew Lunn
2025-08-21 15:20 ` [PATCH net-next 02/15] net: phy: aquantia: merge aqr113c_fill_interface_modes() into aqr107_fill_interface_modes() Vladimir Oltean
` (15 subsequent siblings)
16 siblings, 1 reply; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
I have noticed from schematics and firmware images that the PHY for
which I've previously added support in commit 973fbe68df39 ("net: phy:
aquantia: add AQR112 and AQR412 PHY IDs") is actually an AQR412C, not
AQR412.
These are actually PHYs from the same generation, and Marvell documents
them as differing only in the size of the FCCSP package: 19x19 mm for
the AQR412, vs 14x12mm for the Compact AQR412C.
I don't think there is any point in backporting this to stable kernels,
since the PHYs are identical in capabilities, and no functional
difference is expected regardless of how the PHY is identified.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 77a48635d7bf..52facd318c83 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -26,7 +26,8 @@
#define PHY_ID_AQR111 0x03a1b610
#define PHY_ID_AQR111B0 0x03a1b612
#define PHY_ID_AQR112 0x03a1b662
-#define PHY_ID_AQR412 0x03a1b712
+#define PHY_ID_AQR412 0x03a1b6f2
+#define PHY_ID_AQR412C 0x03a1b712
#define PHY_ID_AQR113 0x31c31c40
#define PHY_ID_AQR113C 0x31c31c12
#define PHY_ID_AQR114C 0x31c31c22
@@ -1308,6 +1309,24 @@ static struct phy_driver aqr_driver[] = {
.get_stats = aqr107_get_stats,
.link_change_notify = aqr107_link_change_notify,
},
+{
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR412C),
+ .name = "Aquantia AQR412C",
+ .probe = aqr107_probe,
+ .config_aneg = aqr_config_aneg,
+ .config_intr = aqr_config_intr,
+ .handle_interrupt = aqr_handle_interrupt,
+ .get_tunable = aqr107_get_tunable,
+ .set_tunable = aqr107_set_tunable,
+ .suspend = aqr107_suspend,
+ .resume = aqr107_resume,
+ .read_status = aqr107_read_status,
+ .get_rate_matching = aqr107_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,
+},
{
PHY_ID_MATCH_MODEL(PHY_ID_AQR113),
.name = "Aquantia AQR113",
@@ -1446,6 +1465,7 @@ static const struct mdio_device_id __maybe_unused aqr_tbl[] = {
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR412C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) },
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 01/15] net: phy: aquantia: rename AQR412 to AQR412C and add real AQR412
2025-08-21 15:20 ` [PATCH net-next 01/15] net: phy: aquantia: rename AQR412 to AQR412C and add real AQR412 Vladimir Oltean
@ 2025-08-21 15:35 ` Andrew Lunn
0 siblings, 0 replies; 22+ messages in thread
From: Andrew Lunn @ 2025-08-21 15:35 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
On Thu, Aug 21, 2025 at 06:20:08PM +0300, Vladimir Oltean wrote:
> I have noticed from schematics and firmware images that the PHY for
> which I've previously added support in commit 973fbe68df39 ("net: phy:
> aquantia: add AQR112 and AQR412 PHY IDs") is actually an AQR412C, not
> AQR412.
>
> These are actually PHYs from the same generation, and Marvell documents
> them as differing only in the size of the FCCSP package: 19x19 mm for
> the AQR412, vs 14x12mm for the Compact AQR412C.
>
> I don't think there is any point in backporting this to stable kernels,
> since the PHYs are identical in capabilities, and no functional
> difference is expected regardless of how the PHY is identified.
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH net-next 02/15] net: phy: aquantia: merge aqr113c_fill_interface_modes() into aqr107_fill_interface_modes()
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 01/15] net: phy: aquantia: rename AQR412 to AQR412C and add real AQR412 Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 16:20 ` Andrew Lunn
2025-08-21 15:20 ` [PATCH net-next 03/15] net: phy: aquantia: reorder AQR113C PMD Global Transmit Disable bit clearing with supported_interfaces Vladimir Oltean
` (14 subsequent siblings)
16 siblings, 1 reply; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
I'm unsure whether intentionate or not, but I think the (partially
observed) naming convention in this driver is that function prefixes
denote the earliest generation when a feature is available. In case of
aqr107_fill_interface_modes(), that means that the GLOBAL_CFG registers
are a Gen2 feature. Supporting evidence: the AQR105, a Gen1 PHY, does
not have these registers, thus the function is not named aqr105_*.
Based on this inferred naming scheme, I am proposing a refinement of
commit a7f3abcf6357 ("net: phy: aquantia: only poll GLOBAL_CFG regs on
aqr113, aqr113c and aqr115c") which introduced aqr113c_fill_interface_modes(),
suggesting this may be a Gen4 PHY feature.
The long-term goal is for aqr107_config_init() to tail-call
aqr107_fill_interface_modes(), such that the latter function is also
called by AQR107 itself, and many other PHY drivers. Currently it can't,
because aqr113c_config_init() calls aqr107_config_init() and then
aqr113c_fill_interface_modes(). So this would lead to a duplicate call
to aqr107_fill_interface_modes() for AQR113C.
Centralize the reading of GLOBAL_CFG registers in the AQR107 method, and
create a boolean, set to true by AQR113C, which tests whether waiting
for a non-zero value in the GLOBAL_CFG_100M register is necessary.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia.h | 1 +
drivers/net/phy/aquantia/aquantia_main.c | 41 ++++++++++++------------
2 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia.h b/drivers/net/phy/aquantia/aquantia.h
index 0c78bfabace5..67ec6f7484af 100644
--- a/drivers/net/phy/aquantia/aquantia.h
+++ b/drivers/net/phy/aquantia/aquantia.h
@@ -178,6 +178,7 @@ struct aqr107_priv {
u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
unsigned long leds_active_low;
unsigned long leds_active_high;
+ bool wait_on_global_cfg;
};
#if IS_REACHABLE(CONFIG_HWMON)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 52facd318c83..b9b58c6ce686 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -991,9 +991,24 @@ static const u16 aqr_global_cfg_regs[] = {
static int aqr107_fill_interface_modes(struct phy_device *phydev)
{
unsigned long *possible = phydev->possible_interfaces;
+ struct aqr107_priv *priv = phydev->priv;
unsigned int serdes_mode, rate_adapt;
phy_interface_t interface;
- int i, val;
+ int i, val, ret;
+
+ /* It's been observed on some models that - when coming out of suspend
+ * - the FW signals that the PHY is ready but the GLOBAL_CFG registers
+ * continue on returning zeroes for some time. Let's poll the 100M
+ * register until it returns a real value as both 113c and 115c support
+ * this mode.
+ */
+ if (priv->wait_on_global_cfg) {
+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+ VEND1_GLOBAL_CFG_100M, 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
@@ -1042,25 +1057,6 @@ static int aqr107_fill_interface_modes(struct phy_device *phydev)
return 0;
}
-static int aqr113c_fill_interface_modes(struct phy_device *phydev)
-{
- int val, ret;
-
- /* It's been observed on some models that - when coming out of suspend
- * - the FW signals that the PHY is ready but the GLOBAL_CFG registers
- * continue on returning zeroes for some time. Let's poll the 100M
- * register until it returns a real value as both 113c and 115c support
- * this mode.
- */
- ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
- VEND1_GLOBAL_CFG_100M, val, val != 0,
- 1000, 100000, false);
- if (ret)
- return ret;
-
- return aqr107_fill_interface_modes(phydev);
-}
-
static int aqr115c_get_features(struct phy_device *phydev)
{
unsigned long *supported = phydev->supported;
@@ -1088,8 +1084,11 @@ static int aqr111_get_features(struct phy_device *phydev)
static int aqr113c_config_init(struct phy_device *phydev)
{
+ struct aqr107_priv *priv = phydev->priv;
int ret;
+ priv->wait_on_global_cfg = true;
+
ret = aqr107_config_init(phydev);
if (ret < 0)
return ret;
@@ -1103,7 +1102,7 @@ static int aqr113c_config_init(struct phy_device *phydev)
if (ret)
return ret;
- return aqr113c_fill_interface_modes(phydev);
+ return aqr107_fill_interface_modes(phydev);
}
static int aqr107_probe(struct phy_device *phydev)
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 02/15] net: phy: aquantia: merge aqr113c_fill_interface_modes() into aqr107_fill_interface_modes()
2025-08-21 15:20 ` [PATCH net-next 02/15] net: phy: aquantia: merge aqr113c_fill_interface_modes() into aqr107_fill_interface_modes() Vladimir Oltean
@ 2025-08-21 16:20 ` Andrew Lunn
0 siblings, 0 replies; 22+ messages in thread
From: Andrew Lunn @ 2025-08-21 16:20 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
On Thu, Aug 21, 2025 at 06:20:09PM +0300, Vladimir Oltean wrote:
> I'm unsure whether intentionate or not, but I think the (partially
> observed) naming convention in this driver is that function prefixes
> denote the earliest generation when a feature is available. In case of
> aqr107_fill_interface_modes(), that means that the GLOBAL_CFG registers
> are a Gen2 feature. Supporting evidence: the AQR105, a Gen1 PHY, does
> not have these registers, thus the function is not named aqr105_*.
That is reasonably common. The Marvell PHY and DSA driver use the
same.
The other option would be to use gen1_, gen2_, gen3_ prefixes.
The Broadcom PHY uses an odd naming scheme, 28nm_, 16nm_, which i
assume is the silicon gate size of the generation.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH net-next 03/15] net: phy: aquantia: reorder AQR113C PMD Global Transmit Disable bit clearing with supported_interfaces
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 01/15] net: phy: aquantia: rename AQR412 to AQR412C and add real AQR412 Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 02/15] net: phy: aquantia: merge aqr113c_fill_interface_modes() into aqr107_fill_interface_modes() Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 16:21 ` Andrew Lunn
2025-08-21 15:20 ` [PATCH net-next 04/15] net: phy: aquantia: rename some aqr107 functions according to generation Vladimir Oltean
` (13 subsequent siblings)
16 siblings, 1 reply; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
Introduced in commit bed90b06b681 ("net: phy: aquantia: clear PMD Global
Transmit Disable bit during init"), the clearing of MDIO_PMA_TXDIS plus
the call to aqr107_wait_processor_intensive_op() are only by chance
placed between aqr107_config_init() and aqr107_fill_interface_modes().
In other words, aqr107_fill_interface_modes() does not depend in any way
on these 2 operations.
I am only 90% sure of that, and I intend to move aqr107_fill_interface_modes()
to be a part of aqr107_config_init() in the future. So to isolate the
issue for blame attribution purposes, make these 2 functions adjacent to
each other again.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index b9b58c6ce686..7ac0b685a317 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -1093,16 +1093,16 @@ static int aqr113c_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
- ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,
- MDIO_PMD_TXDIS_GLOBAL);
+ ret = aqr107_fill_interface_modes(phydev);
if (ret)
return ret;
- ret = aqr107_wait_processor_intensive_op(phydev);
+ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,
+ MDIO_PMD_TXDIS_GLOBAL);
if (ret)
return ret;
- return aqr107_fill_interface_modes(phydev);
+ return aqr107_wait_processor_intensive_op(phydev);
}
static int aqr107_probe(struct phy_device *phydev)
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 03/15] net: phy: aquantia: reorder AQR113C PMD Global Transmit Disable bit clearing with supported_interfaces
2025-08-21 15:20 ` [PATCH net-next 03/15] net: phy: aquantia: reorder AQR113C PMD Global Transmit Disable bit clearing with supported_interfaces Vladimir Oltean
@ 2025-08-21 16:21 ` Andrew Lunn
0 siblings, 0 replies; 22+ messages in thread
From: Andrew Lunn @ 2025-08-21 16:21 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
On Thu, Aug 21, 2025 at 06:20:10PM +0300, Vladimir Oltean wrote:
> Introduced in commit bed90b06b681 ("net: phy: aquantia: clear PMD Global
> Transmit Disable bit during init"), the clearing of MDIO_PMA_TXDIS plus
> the call to aqr107_wait_processor_intensive_op() are only by chance
> placed between aqr107_config_init() and aqr107_fill_interface_modes().
> In other words, aqr107_fill_interface_modes() does not depend in any way
> on these 2 operations.
>
> I am only 90% sure of that, and I intend to move aqr107_fill_interface_modes()
> to be a part of aqr107_config_init() in the future. So to isolate the
> issue for blame attribution purposes, make these 2 functions adjacent to
> each other again.
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH net-next 04/15] net: phy: aquantia: rename some aqr107 functions according to generation
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (2 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 03/15] net: phy: aquantia: reorder AQR113C PMD Global Transmit Disable bit clearing with supported_interfaces Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 05/15] net: phy: aquantia: fill supported_interfaces for all aqr_gen2_config_init() callers Vladimir Oltean
` (12 subsequent siblings)
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
Establish a more intuitive function naming convention in this driver.
A GenX PHY must only call aqr_genY_ functions, where Y <= X.
Loosely speaking, aqr107_ is representative of Gen2 and above, except for:
- aqr107_config_init()
- aqr107_suspend()
- aqr107_resume()
- aqr107_wait_processor_intensive_op()
which are also called by AQR105, so these are renamed to Gen1.
Actually aqr107_config_init() is renamed to aqr_gen1_config_init() when
called by AQR105, and aqr_gen2_config_init() when called by all other
PHYs. The Gen2 function calls the Gen1 function, so there is no
functional change. This prefaces further Gen2-specific initialization
steps which must be omitted for AQR105. These will be added to
aqr_gen2_config_init().
In fact, many PHY drivers call an aqr*_config_init() beneath their
generation's feature set: AQR114C is a Gen4 PHY which calls
aqr_gen2_config_init(), even though AQR113C, also a Gen4 PHY which
differs only in maximum link speed, calls the richer
aqr113c_config_init() which also sets phydev->possible_interfaces.
Many of the more subtle inconsistencies of this kind will be fixed up in
later changes.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 117 ++++++++++++-----------
1 file changed, 61 insertions(+), 56 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 7ac0b685a317..8136f7843a37 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -811,7 +811,7 @@ static int aqr107_config_mdi(struct phy_device *phydev)
mdi_conf | PMAPMD_RSVD_VEND_PROV_MDI_FORCE);
}
-static int aqr107_config_init(struct phy_device *phydev)
+static int aqr_gen1_config_init(struct phy_device *phydev)
{
struct aqr107_priv *priv = phydev->priv;
u32 led_idx;
@@ -860,6 +860,11 @@ static int aqr107_config_init(struct phy_device *phydev)
return 0;
}
+static int aqr_gen2_config_init(struct phy_device *phydev)
+{
+ return aqr_gen1_config_init(phydev);
+}
+
static int aqcs109_config_init(struct phy_device *phydev)
{
int ret;
@@ -921,7 +926,7 @@ static void aqr107_link_change_notify(struct phy_device *phydev)
phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");
}
-static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)
+static int aqr_gen1_wait_processor_intensive_op(struct phy_device *phydev)
{
int val, err;
@@ -945,8 +950,8 @@ static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)
return 0;
}
-static int aqr107_get_rate_matching(struct phy_device *phydev,
- phy_interface_t iface)
+static int aqr_gen2_get_rate_matching(struct phy_device *phydev,
+ phy_interface_t iface)
{
if (iface == PHY_INTERFACE_MODE_10GBASER ||
iface == PHY_INTERFACE_MODE_2500BASEX ||
@@ -955,7 +960,7 @@ static int aqr107_get_rate_matching(struct phy_device *phydev,
return RATE_MATCH_NONE;
}
-static int aqr107_suspend(struct phy_device *phydev)
+static int aqr_gen1_suspend(struct phy_device *phydev)
{
int err;
@@ -964,10 +969,10 @@ static int aqr107_suspend(struct phy_device *phydev)
if (err)
return err;
- return aqr107_wait_processor_intensive_op(phydev);
+ return aqr_gen1_wait_processor_intensive_op(phydev);
}
-static int aqr107_resume(struct phy_device *phydev)
+static int aqr_gen1_resume(struct phy_device *phydev)
{
int err;
@@ -976,7 +981,7 @@ static int aqr107_resume(struct phy_device *phydev)
if (err)
return err;
- return aqr107_wait_processor_intensive_op(phydev);
+ return aqr_gen1_wait_processor_intensive_op(phydev);
}
static const u16 aqr_global_cfg_regs[] = {
@@ -988,7 +993,7 @@ static const u16 aqr_global_cfg_regs[] = {
VEND1_GLOBAL_CFG_10G
};
-static int aqr107_fill_interface_modes(struct phy_device *phydev)
+static int aqr_gen2_fill_interface_modes(struct phy_device *phydev)
{
unsigned long *possible = phydev->possible_interfaces;
struct aqr107_priv *priv = phydev->priv;
@@ -1089,11 +1094,11 @@ static int aqr113c_config_init(struct phy_device *phydev)
priv->wait_on_global_cfg = true;
- ret = aqr107_config_init(phydev);
+ ret = aqr_gen2_config_init(phydev);
if (ret < 0)
return ret;
- ret = aqr107_fill_interface_modes(phydev);
+ ret = aqr_gen2_fill_interface_modes(phydev);
if (ret)
return ret;
@@ -1102,7 +1107,7 @@ static int aqr113c_config_init(struct phy_device *phydev)
if (ret)
return ret;
- return aqr107_wait_processor_intensive_op(phydev);
+ return aqr_gen1_wait_processor_intensive_op(phydev);
}
static int aqr107_probe(struct phy_device *phydev)
@@ -1144,13 +1149,13 @@ static struct phy_driver aqr_driver[] = {
.name = "Aquantia AQR105",
.get_features = aqr105_get_features,
.probe = aqr107_probe,
- .config_init = aqr107_config_init,
+ .config_init = aqr_gen1_config_init,
.config_aneg = aqr105_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
.read_status = aqr105_read_status,
- .suspend = aqr107_suspend,
- .resume = aqr107_resume,
+ .suspend = aqr_gen1_suspend,
+ .resume = aqr_gen1_resume,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_AQR106),
@@ -1164,16 +1169,16 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR107),
.name = "Aquantia AQR107",
.probe = aqr107_probe,
- .get_rate_matching = aqr107_get_rate_matching,
- .config_init = aqr107_config_init,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
+ .config_init = aqr_gen2_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,
+ .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,
@@ -1188,7 +1193,7 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
.name = "Aquantia AQCS109",
.probe = aqr107_probe,
- .get_rate_matching = aqr107_get_rate_matching,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
.config_init = aqcs109_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
@@ -1196,8 +1201,8 @@ static struct phy_driver aqr_driver[] = {
.read_status = aqr107_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
- .suspend = aqr107_suspend,
- .resume = aqr107_resume,
+ .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,
@@ -1213,16 +1218,16 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR111),
.name = "Aquantia AQR111",
.probe = aqr107_probe,
- .get_rate_matching = aqr107_get_rate_matching,
- .config_init = aqr107_config_init,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
+ .config_init = aqr_gen2_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,
+ .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,
@@ -1238,16 +1243,16 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0),
.name = "Aquantia AQR111B0",
.probe = aqr107_probe,
- .get_rate_matching = aqr107_get_rate_matching,
- .config_init = aqr107_config_init,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
+ .config_init = aqr_gen2_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,
+ .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,
@@ -1276,10 +1281,10 @@ static struct phy_driver aqr_driver[] = {
.handle_interrupt = aqr_handle_interrupt,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
- .suspend = aqr107_suspend,
- .resume = aqr107_resume,
+ .suspend = aqr_gen1_suspend,
+ .resume = aqr_gen1_resume,
.read_status = aqr107_read_status,
- .get_rate_matching = aqr107_get_rate_matching,
+ .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,
@@ -1299,10 +1304,10 @@ static struct phy_driver aqr_driver[] = {
.handle_interrupt = aqr_handle_interrupt,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
- .suspend = aqr107_suspend,
- .resume = aqr107_resume,
+ .suspend = aqr_gen1_suspend,
+ .resume = aqr_gen1_resume,
.read_status = aqr107_read_status,
- .get_rate_matching = aqr107_get_rate_matching,
+ .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,
@@ -1317,10 +1322,10 @@ static struct phy_driver aqr_driver[] = {
.handle_interrupt = aqr_handle_interrupt,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
- .suspend = aqr107_suspend,
- .resume = aqr107_resume,
+ .suspend = aqr_gen1_suspend,
+ .resume = aqr_gen1_resume,
.read_status = aqr107_read_status,
- .get_rate_matching = aqr107_get_rate_matching,
+ .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,
@@ -1330,7 +1335,7 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR113),
.name = "Aquantia AQR113",
.probe = aqr107_probe,
- .get_rate_matching = aqr107_get_rate_matching,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
.config_init = aqr113c_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
@@ -1338,8 +1343,8 @@ static struct phy_driver aqr_driver[] = {
.read_status = aqr107_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
- .suspend = aqr107_suspend,
- .resume = aqr107_resume,
+ .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,
@@ -1354,7 +1359,7 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
.name = "Aquantia AQR113C",
.probe = aqr107_probe,
- .get_rate_matching = aqr107_get_rate_matching,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
.config_init = aqr113c_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
@@ -1362,8 +1367,8 @@ static struct phy_driver aqr_driver[] = {
.read_status = aqr107_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
- .suspend = aqr107_suspend,
- .resume = aqr107_resume,
+ .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,
@@ -1378,16 +1383,16 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR114C),
.name = "Aquantia AQR114C",
.probe = aqr107_probe,
- .get_rate_matching = aqr107_get_rate_matching,
- .config_init = aqr107_config_init,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
+ .config_init = aqr_gen2_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,
+ .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,
@@ -1403,7 +1408,7 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR115C),
.name = "Aquantia AQR115C",
.probe = aqr107_probe,
- .get_rate_matching = aqr107_get_rate_matching,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
.config_init = aqr113c_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
@@ -1411,8 +1416,8 @@ static struct phy_driver aqr_driver[] = {
.read_status = aqr107_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
- .suspend = aqr107_suspend,
- .resume = aqr107_resume,
+ .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,
@@ -1428,16 +1433,16 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR813),
.name = "Aquantia AQR813",
.probe = aqr107_probe,
- .get_rate_matching = aqr107_get_rate_matching,
- .config_init = aqr107_config_init,
+ .get_rate_matching = aqr_gen2_get_rate_matching,
+ .config_init = aqr_gen2_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,
+ .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,
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH net-next 05/15] net: phy: aquantia: fill supported_interfaces for all aqr_gen2_config_init() callers
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (3 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 04/15] net: phy: aquantia: rename some aqr107 functions according to generation Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 06/15] net: phy: aquantia: save a local shadow of GLOBAL_CFG register values Vladimir Oltean
` (11 subsequent siblings)
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
Since aqr_gen2_config_init() and aqr_gen2_fill_interface_modes() refer to
the feature set common to the same generation, it means all callers of
aqr_gen2_config_init() also support the Global System Configuration
registers at addresses 1E.31B -> 1E.31F, and these should be read by the
driver to figure out the list of supported interfaces for phylink.
This affects the following PHYs supported by this driver:
- Gen2: AQR107
- Gen3: AQR111, AQR111B0
- Gen4: AQR114C, AQR813.
AQR113C, a Gen4 PHY, has unmodified logic after this change, because
currently, the aqr_gen2_fill_interface_modes() call is chained after
aqr_gen2_config_init(), and after this patch, it is tail-called from the
latter function, leading to the same code flow.
At the same time, move aqr_gen2_fill_interface_modes() upwards of its
new caller, aqr_gen2_config_init(), to avoid a forward declaration.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 168 ++++++++++++-----------
1 file changed, 85 insertions(+), 83 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 8136f7843a37..21fdbda2a0e0 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -860,9 +860,93 @@ static int aqr_gen1_config_init(struct phy_device *phydev)
return 0;
}
+static const u16 aqr_global_cfg_regs[] = {
+ VEND1_GLOBAL_CFG_10M,
+ VEND1_GLOBAL_CFG_100M,
+ VEND1_GLOBAL_CFG_1G,
+ VEND1_GLOBAL_CFG_2_5G,
+ VEND1_GLOBAL_CFG_5G,
+ VEND1_GLOBAL_CFG_10G,
+};
+
+static int aqr_gen2_fill_interface_modes(struct phy_device *phydev)
+{
+ unsigned long *possible = phydev->possible_interfaces;
+ struct aqr107_priv *priv = phydev->priv;
+ unsigned int serdes_mode, rate_adapt;
+ phy_interface_t interface;
+ int i, val, ret;
+
+ /* It's been observed on some models that - when coming out of suspend
+ * - the FW signals that the PHY is ready but the GLOBAL_CFG registers
+ * continue on returning zeroes for some time. Let's poll the 100M
+ * register until it returns a real value as both 113c and 115c support
+ * this mode.
+ */
+ if (priv->wait_on_global_cfg) {
+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+ VEND1_GLOBAL_CFG_100M, 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
+ * negotiated media speed.
+ */
+ for (i = 0; i < ARRAY_SIZE(aqr_global_cfg_regs); i++) {
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
+ aqr_global_cfg_regs[i]);
+ if (val < 0)
+ return val;
+
+ serdes_mode = FIELD_GET(VEND1_GLOBAL_CFG_SERDES_MODE, val);
+ rate_adapt = FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val);
+
+ switch (serdes_mode) {
+ case VEND1_GLOBAL_CFG_SERDES_MODE_XFI:
+ if (rate_adapt == VEND1_GLOBAL_CFG_RATE_ADAPT_USX)
+ interface = PHY_INTERFACE_MODE_USXGMII;
+ else
+ interface = PHY_INTERFACE_MODE_10GBASER;
+ break;
+
+ case VEND1_GLOBAL_CFG_SERDES_MODE_XFI5G:
+ interface = PHY_INTERFACE_MODE_5GBASER;
+ break;
+
+ case VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII:
+ interface = PHY_INTERFACE_MODE_2500BASEX;
+ break;
+
+ case VEND1_GLOBAL_CFG_SERDES_MODE_SGMII:
+ interface = PHY_INTERFACE_MODE_SGMII;
+ break;
+
+ default:
+ phydev_warn(phydev, "unrecognised serdes mode %u\n",
+ serdes_mode);
+ interface = PHY_INTERFACE_MODE_NA;
+ break;
+ }
+
+ if (interface != PHY_INTERFACE_MODE_NA)
+ __set_bit(interface, possible);
+ }
+
+ return 0;
+}
+
static int aqr_gen2_config_init(struct phy_device *phydev)
{
- return aqr_gen1_config_init(phydev);
+ int ret;
+
+ ret = aqr_gen1_config_init(phydev);
+ if (ret)
+ return ret;
+
+ return aqr_gen2_fill_interface_modes(phydev);
}
static int aqcs109_config_init(struct phy_device *phydev)
@@ -984,84 +1068,6 @@ static int aqr_gen1_resume(struct phy_device *phydev)
return aqr_gen1_wait_processor_intensive_op(phydev);
}
-static const u16 aqr_global_cfg_regs[] = {
- VEND1_GLOBAL_CFG_10M,
- VEND1_GLOBAL_CFG_100M,
- VEND1_GLOBAL_CFG_1G,
- VEND1_GLOBAL_CFG_2_5G,
- VEND1_GLOBAL_CFG_5G,
- VEND1_GLOBAL_CFG_10G
-};
-
-static int aqr_gen2_fill_interface_modes(struct phy_device *phydev)
-{
- unsigned long *possible = phydev->possible_interfaces;
- struct aqr107_priv *priv = phydev->priv;
- unsigned int serdes_mode, rate_adapt;
- phy_interface_t interface;
- int i, val, ret;
-
- /* It's been observed on some models that - when coming out of suspend
- * - the FW signals that the PHY is ready but the GLOBAL_CFG registers
- * continue on returning zeroes for some time. Let's poll the 100M
- * register until it returns a real value as both 113c and 115c support
- * this mode.
- */
- if (priv->wait_on_global_cfg) {
- ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
- VEND1_GLOBAL_CFG_100M, 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
- * negotiated media speed.
- */
- for (i = 0; i < ARRAY_SIZE(aqr_global_cfg_regs); i++) {
- val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
- aqr_global_cfg_regs[i]);
- if (val < 0)
- return val;
-
- serdes_mode = FIELD_GET(VEND1_GLOBAL_CFG_SERDES_MODE, val);
- rate_adapt = FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val);
-
- switch (serdes_mode) {
- case VEND1_GLOBAL_CFG_SERDES_MODE_XFI:
- if (rate_adapt == VEND1_GLOBAL_CFG_RATE_ADAPT_USX)
- interface = PHY_INTERFACE_MODE_USXGMII;
- else
- interface = PHY_INTERFACE_MODE_10GBASER;
- break;
-
- case VEND1_GLOBAL_CFG_SERDES_MODE_XFI5G:
- interface = PHY_INTERFACE_MODE_5GBASER;
- break;
-
- case VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII:
- interface = PHY_INTERFACE_MODE_2500BASEX;
- break;
-
- case VEND1_GLOBAL_CFG_SERDES_MODE_SGMII:
- interface = PHY_INTERFACE_MODE_SGMII;
- break;
-
- default:
- phydev_warn(phydev, "unrecognised serdes mode %u\n",
- serdes_mode);
- interface = PHY_INTERFACE_MODE_NA;
- break;
- }
-
- if (interface != PHY_INTERFACE_MODE_NA)
- __set_bit(interface, possible);
- }
-
- return 0;
-}
-
static int aqr115c_get_features(struct phy_device *phydev)
{
unsigned long *supported = phydev->supported;
@@ -1098,10 +1104,6 @@ static int aqr113c_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
- ret = aqr_gen2_fill_interface_modes(phydev);
- if (ret)
- return ret;
-
ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,
MDIO_PMD_TXDIS_GLOBAL);
if (ret)
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH net-next 06/15] net: phy: aquantia: save a local shadow of GLOBAL_CFG register values
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (4 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 05/15] net: phy: aquantia: fill supported_interfaces for all aqr_gen2_config_init() callers Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 07/15] net: phy: aquantia: remove handling for get_rate_matching(PHY_INTERFACE_MODE_NA) Vladimir Oltean
` (10 subsequent siblings)
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
Currently, aqr_gen2_fill_interface_modes() reads VEND1_GLOBAL_CFG_*
registers to populate phydev->supported_interfaces. But this is not
the only place which needs to read these registers. There is also
aqr107_read_rate().
Based on the premise that these values are statically set by firmware
and the driver only needs to read them, the proposal is to read them
only once, at config_init() time, and use the cached values also in
aqr107_read_rate().
This patch only refactors the aqr_gen2_fill_interface_modes() code to
save the registers to driver memory, and to populate supported_interfaces
based on that.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia.h | 27 +++++++
drivers/net/phy/aquantia/aquantia_main.c | 91 ++++++++++++++++--------
2 files changed, 87 insertions(+), 31 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia.h b/drivers/net/phy/aquantia/aquantia.h
index 67ec6f7484af..492052cf1e6e 100644
--- a/drivers/net/phy/aquantia/aquantia.h
+++ b/drivers/net/phy/aquantia/aquantia.h
@@ -174,11 +174,38 @@ static const struct aqr107_hw_stat aqr107_hw_stats[] = {
#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
+static const struct {
+ int speed;
+ u16 reg;
+} aqr_global_cfg_regs[] = {
+ { SPEED_10, VEND1_GLOBAL_CFG_10M, },
+ { SPEED_100, VEND1_GLOBAL_CFG_100M, },
+ { SPEED_1000, VEND1_GLOBAL_CFG_1G, },
+ { SPEED_2500, VEND1_GLOBAL_CFG_2_5G, },
+ { SPEED_5000, VEND1_GLOBAL_CFG_5G, },
+ { SPEED_10000, VEND1_GLOBAL_CFG_10G, },
+};
+
+#define AQR_NUM_GLOBAL_CFG ARRAY_SIZE(aqr_global_cfg_regs)
+
+enum aqr_rate_adaptation {
+ AQR_RATE_ADAPT_NONE,
+ AQR_RATE_ADAPT_USX,
+ AQR_RATE_ADAPT_PAUSE,
+};
+
+struct aqr_global_syscfg {
+ int speed;
+ phy_interface_t interface;
+ enum aqr_rate_adaptation rate_adapt;
+};
+
struct aqr107_priv {
u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
unsigned long leds_active_low;
unsigned long leds_active_high;
bool wait_on_global_cfg;
+ struct aqr_global_syscfg global_cfg[AQR_NUM_GLOBAL_CFG];
};
#if IS_REACHABLE(CONFIG_HWMON)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 21fdbda2a0e0..9d704b7e3dc8 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -860,44 +860,24 @@ static int aqr_gen1_config_init(struct phy_device *phydev)
return 0;
}
-static const u16 aqr_global_cfg_regs[] = {
- VEND1_GLOBAL_CFG_10M,
- VEND1_GLOBAL_CFG_100M,
- VEND1_GLOBAL_CFG_1G,
- VEND1_GLOBAL_CFG_2_5G,
- VEND1_GLOBAL_CFG_5G,
- VEND1_GLOBAL_CFG_10G,
-};
-
-static int aqr_gen2_fill_interface_modes(struct phy_device *phydev)
+/* Walk the media-speed configuration registers to determine which
+ * host-side serdes modes may be used by the PHY depending on the
+ * negotiated media speed.
+ */
+static int aqr_gen2_read_global_syscfg(struct phy_device *phydev)
{
- unsigned long *possible = phydev->possible_interfaces;
struct aqr107_priv *priv = phydev->priv;
unsigned int serdes_mode, rate_adapt;
phy_interface_t interface;
- int i, val, ret;
+ int i, val;
- /* It's been observed on some models that - when coming out of suspend
- * - the FW signals that the PHY is ready but the GLOBAL_CFG registers
- * continue on returning zeroes for some time. Let's poll the 100M
- * register until it returns a real value as both 113c and 115c support
- * this mode.
- */
- if (priv->wait_on_global_cfg) {
- ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
- VEND1_GLOBAL_CFG_100M, val,
- val != 0, 1000, 100000, false);
- if (ret)
- return ret;
- }
+ for (i = 0; i < AQR_NUM_GLOBAL_CFG; i++) {
+ struct aqr_global_syscfg *syscfg = &priv->global_cfg[i];
+
+ syscfg->speed = aqr_global_cfg_regs[i].speed;
- /* Walk the media-speed configuration registers to determine which
- * host-side serdes modes may be used by the PHY depending on the
- * negotiated media speed.
- */
- for (i = 0; i < ARRAY_SIZE(aqr_global_cfg_regs); i++) {
val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
- aqr_global_cfg_regs[i]);
+ aqr_global_cfg_regs[i].reg);
if (val < 0)
return val;
@@ -931,6 +911,55 @@ static int aqr_gen2_fill_interface_modes(struct phy_device *phydev)
break;
}
+ syscfg->interface = interface;
+
+ switch (rate_adapt) {
+ case VEND1_GLOBAL_CFG_RATE_ADAPT_NONE:
+ syscfg->rate_adapt = AQR_RATE_ADAPT_NONE;
+ break;
+ case VEND1_GLOBAL_CFG_RATE_ADAPT_USX:
+ syscfg->rate_adapt = AQR_RATE_ADAPT_USX;
+ break;
+ case VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE:
+ syscfg->rate_adapt = AQR_RATE_ADAPT_PAUSE;
+ break;
+ default:
+ phydev_warn(phydev, "unrecognized rate adapt mode %u\n",
+ rate_adapt);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int aqr_gen2_fill_interface_modes(struct phy_device *phydev)
+{
+ unsigned long *possible = phydev->possible_interfaces;
+ struct aqr107_priv *priv = phydev->priv;
+ phy_interface_t interface;
+ int i, val, ret;
+
+ /* It's been observed on some models that - when coming out of suspend
+ * - the FW signals that the PHY is ready but the GLOBAL_CFG registers
+ * continue on returning zeroes for some time. Let's poll the 100M
+ * register until it returns a real value as both 113c and 115c support
+ * this mode.
+ */
+ if (priv->wait_on_global_cfg) {
+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+ VEND1_GLOBAL_CFG_100M, val,
+ val != 0, 1000, 100000, false);
+ if (ret)
+ return ret;
+ }
+
+ ret = aqr_gen2_read_global_syscfg(phydev);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < AQR_NUM_GLOBAL_CFG; i++) {
+ interface = priv->global_cfg[i].interface;
if (interface != PHY_INTERFACE_MODE_NA)
__set_bit(interface, possible);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH net-next 07/15] net: phy: aquantia: remove handling for get_rate_matching(PHY_INTERFACE_MODE_NA)
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (5 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 06/15] net: phy: aquantia: save a local shadow of GLOBAL_CFG register values Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-22 3:22 ` Andrew Lunn
2025-08-21 15:20 ` [PATCH net-next 08/15] net: phy: aquantia: use cached GLOBAL_CFG registers in aqr107_read_rate() Vladimir Oltean
` (9 subsequent siblings)
16 siblings, 1 reply; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
After commit 7642cc28fd37 ("net: phylink: fix PHY validation with rate
adaption"), the API contract changed and PHY drivers are no longer
required to respond to the .get_rate_matching() method for
PHY_INTERFACE_MODE_NA. This was later followed up by documentation
commit 6d4cfcf97986 ("net: phy: Update documentation for
get_rate_matching").
As such, handling PHY_INTERFACE_MODE_NA in the Aquantia PHY driver
implementation of this method is unnecessary and confusing. Remove it.
Cc: Sean Anderson <sean.anderson@seco.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 9d704b7e3dc8..0f20ed6f96d8 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -1067,8 +1067,7 @@ static int aqr_gen2_get_rate_matching(struct phy_device *phydev,
phy_interface_t iface)
{
if (iface == PHY_INTERFACE_MODE_10GBASER ||
- iface == PHY_INTERFACE_MODE_2500BASEX ||
- iface == PHY_INTERFACE_MODE_NA)
+ iface == PHY_INTERFACE_MODE_2500BASEX)
return RATE_MATCH_PAUSE;
return RATE_MATCH_NONE;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 07/15] net: phy: aquantia: remove handling for get_rate_matching(PHY_INTERFACE_MODE_NA)
2025-08-21 15:20 ` [PATCH net-next 07/15] net: phy: aquantia: remove handling for get_rate_matching(PHY_INTERFACE_MODE_NA) Vladimir Oltean
@ 2025-08-22 3:22 ` Andrew Lunn
0 siblings, 0 replies; 22+ messages in thread
From: Andrew Lunn @ 2025-08-22 3:22 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
On Thu, Aug 21, 2025 at 06:20:14PM +0300, Vladimir Oltean wrote:
> After commit 7642cc28fd37 ("net: phylink: fix PHY validation with rate
> adaption"), the API contract changed and PHY drivers are no longer
> required to respond to the .get_rate_matching() method for
> PHY_INTERFACE_MODE_NA. This was later followed up by documentation
> commit 6d4cfcf97986 ("net: phy: Update documentation for
> get_rate_matching").
>
> As such, handling PHY_INTERFACE_MODE_NA in the Aquantia PHY driver
> implementation of this method is unnecessary and confusing. Remove it.
>
> Cc: Sean Anderson <sean.anderson@seco.com>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH net-next 08/15] net: phy: aquantia: use cached GLOBAL_CFG registers in aqr107_read_rate()
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (6 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 07/15] net: phy: aquantia: remove handling for get_rate_matching(PHY_INTERFACE_MODE_NA) Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 09/15] net: phy: aquantia: merge and rename aqr105_read_status() and aqr107_read_status() Vladimir Oltean
` (8 subsequent siblings)
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
aqr107_read_rate() - called from aqr107_read_status() even periodically
if there is no PHY IRQ - currently reads GLOBAL_CFG registers to
determine what kind of rate adaptation is in use for the current
phydev->speed. However, GLOBAL_CFG registers are runtime invariants, so
accessing the slow MDIO bus is unnecessary.
Reimplement aqr107_read_rate() by reading from the
priv->global_cfg[i].rade_adapt variables (where i is the entry
corresponding to the current phydev->speed).
Making this change also helps disentangle the code delta between
aqr105_read_rate() and aqr107_read_rate(). They are now identical up to
the code snippet which iterates over priv->global_cfg[]. This will help
eliminate the duplicate code in the upcoming patch.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 29 +++++++++++-------------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 0f20ed6f96d8..4795987ef61b 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -568,8 +568,8 @@ static int aqr105_read_status(struct phy_device *phydev)
static int aqr107_read_rate(struct phy_device *phydev)
{
- u32 config_reg;
- int val;
+ struct aqr107_priv *priv = phydev->priv;
+ int i, val;
val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);
if (val < 0)
@@ -583,42 +583,39 @@ static int aqr107_read_rate(struct phy_device *phydev)
switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {
case MDIO_AN_TX_VEND_STATUS1_10BASET:
phydev->speed = SPEED_10;
- config_reg = VEND1_GLOBAL_CFG_10M;
break;
case MDIO_AN_TX_VEND_STATUS1_100BASETX:
phydev->speed = SPEED_100;
- config_reg = VEND1_GLOBAL_CFG_100M;
break;
case MDIO_AN_TX_VEND_STATUS1_1000BASET:
phydev->speed = SPEED_1000;
- config_reg = VEND1_GLOBAL_CFG_1G;
break;
case MDIO_AN_TX_VEND_STATUS1_2500BASET:
phydev->speed = SPEED_2500;
- config_reg = VEND1_GLOBAL_CFG_2_5G;
break;
case MDIO_AN_TX_VEND_STATUS1_5000BASET:
phydev->speed = SPEED_5000;
- config_reg = VEND1_GLOBAL_CFG_5G;
break;
case MDIO_AN_TX_VEND_STATUS1_10GBASET:
phydev->speed = SPEED_10000;
- config_reg = VEND1_GLOBAL_CFG_10G;
break;
default:
phydev->speed = SPEED_UNKNOWN;
return 0;
}
- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg);
- if (val < 0)
- return val;
+ for (i = 0; i < AQR_NUM_GLOBAL_CFG; i++) {
+ struct aqr_global_syscfg *syscfg = &priv->global_cfg[i];
- if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) ==
- VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE)
- phydev->rate_matching = RATE_MATCH_PAUSE;
- else
- phydev->rate_matching = RATE_MATCH_NONE;
+ if (syscfg->speed != phydev->speed)
+ continue;
+
+ if (syscfg->rate_adapt == AQR_RATE_ADAPT_PAUSE)
+ phydev->rate_matching = RATE_MATCH_PAUSE;
+ else
+ phydev->rate_matching = RATE_MATCH_NONE;
+ break;
+ }
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH net-next 09/15] net: phy: aquantia: merge and rename aqr105_read_status() and aqr107_read_status()
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (7 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 08/15] net: phy: aquantia: use cached GLOBAL_CFG registers in aqr107_read_rate() Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 10/15] net: phy: aquantia: call aqr_gen2_fill_interface_modes() for AQCS109 Vladimir Oltean
` (7 subsequent siblings)
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
aqr105_read_status() and aqr107_read_status() are very similar.
In fact, they are identical, save from a code snippet accessing a Gen2
feature (rate adaptation), placed at the end of aqr107_read_rate(), and
absent from aqr105_read_rate().
The code structure is:
aqr105_read_status() aqr107_read_status()
-> aqr105_read_rate() -> aqr107_read_rate()
After the recent change "net: phy: aquantia: use cached GLOBAL_CFG
registers in aqr107_read_rate()", it is absolutely trivial to
restructure the code as follows:
aqr_gen2_read_status()
-> aqr_gen1_read_status()
-> Gen2-specific stuff (read GLOBAL_CFG registers to set rate_matching)
Doing so reduces code duplication.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 131 ++++-------------------
1 file changed, 21 insertions(+), 110 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 4795987ef61b..e3a18fc1b52a 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -466,7 +466,7 @@ static int aqr105_config_aneg(struct phy_device *phydev)
return genphy_c45_check_and_restart_aneg(phydev, changed);
}
-static int aqr105_read_rate(struct phy_device *phydev)
+static int aqr_gen1_read_rate(struct phy_device *phydev)
{
int val;
@@ -505,7 +505,7 @@ static int aqr105_read_rate(struct phy_device *phydev)
return 0;
}
-static int aqr105_read_status(struct phy_device *phydev)
+static int aqr_gen1_read_status(struct phy_device *phydev)
{
int ret;
int val;
@@ -563,46 +563,17 @@ static int aqr105_read_status(struct phy_device *phydev)
}
/* Read rate from vendor register */
- return aqr105_read_rate(phydev);
+ return aqr_gen1_read_rate(phydev);
}
-static int aqr107_read_rate(struct phy_device *phydev)
+static int aqr_gen2_read_status(struct phy_device *phydev)
{
struct aqr107_priv *priv = phydev->priv;
- int i, val;
-
- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);
- if (val < 0)
- return val;
-
- if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)
- phydev->duplex = DUPLEX_FULL;
- else
- phydev->duplex = DUPLEX_HALF;
+ int i, ret;
- switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {
- case MDIO_AN_TX_VEND_STATUS1_10BASET:
- phydev->speed = SPEED_10;
- break;
- case MDIO_AN_TX_VEND_STATUS1_100BASETX:
- phydev->speed = SPEED_100;
- break;
- case MDIO_AN_TX_VEND_STATUS1_1000BASET:
- phydev->speed = SPEED_1000;
- break;
- case MDIO_AN_TX_VEND_STATUS1_2500BASET:
- phydev->speed = SPEED_2500;
- break;
- case MDIO_AN_TX_VEND_STATUS1_5000BASET:
- phydev->speed = SPEED_5000;
- break;
- case MDIO_AN_TX_VEND_STATUS1_10GBASET:
- phydev->speed = SPEED_10000;
- break;
- default:
- phydev->speed = SPEED_UNKNOWN;
- return 0;
- }
+ ret = aqr_gen1_read_status(phydev);
+ if (ret)
+ return ret;
for (i = 0; i < AQR_NUM_GLOBAL_CFG; i++) {
struct aqr_global_syscfg *syscfg = &priv->global_cfg[i];
@@ -620,66 +591,6 @@ static int aqr107_read_rate(struct phy_device *phydev)
return 0;
}
-static int aqr107_read_status(struct phy_device *phydev)
-{
- int val, ret;
-
- ret = aqr_read_status(phydev);
- if (ret)
- return ret;
-
- if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
- return 0;
-
- /* The status register is not immediately correct on line side link up.
- * Poll periodically until it reflects the correct ON state.
- * Only return fail for read error, timeout defaults to OFF state.
- */
- ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PHYXS,
- MDIO_PHYXS_VEND_IF_STATUS, val,
- (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val) !=
- MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF),
- AQR107_OP_IN_PROG_SLEEP,
- AQR107_OP_IN_PROG_TIMEOUT, false);
- if (ret && ret != -ETIMEDOUT)
- return ret;
-
- switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
- phydev->interface = PHY_INTERFACE_MODE_10GKR;
- break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX:
- phydev->interface = PHY_INTERFACE_MODE_1000BASEKX;
- break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
- phydev->interface = PHY_INTERFACE_MODE_10GBASER;
- break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:
- phydev->interface = PHY_INTERFACE_MODE_USXGMII;
- break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI:
- phydev->interface = PHY_INTERFACE_MODE_XAUI;
- break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
- phydev->interface = PHY_INTERFACE_MODE_SGMII;
- break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI:
- phydev->interface = PHY_INTERFACE_MODE_RXAUI;
- break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
- break;
- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF:
- default:
- phydev->link = false;
- phydev->interface = PHY_INTERFACE_MODE_NA;
- break;
- }
-
- /* Read possibly downshifted rate from vendor register */
- return aqr107_read_rate(phydev);
-}
-
static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)
{
int val, cnt, enable;
@@ -1180,7 +1091,7 @@ static struct phy_driver aqr_driver[] = {
.config_aneg = aqr105_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr105_read_status,
+ .read_status = aqr_gen1_read_status,
.suspend = aqr_gen1_suspend,
.resume = aqr_gen1_resume,
},
@@ -1201,7 +1112,7 @@ static struct phy_driver aqr_driver[] = {
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr107_read_status,
+ .read_status = aqr_gen2_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
@@ -1225,7 +1136,7 @@ static struct phy_driver aqr_driver[] = {
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr107_read_status,
+ .read_status = aqr_gen2_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
@@ -1250,7 +1161,7 @@ static struct phy_driver aqr_driver[] = {
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr107_read_status,
+ .read_status = aqr_gen2_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
@@ -1275,7 +1186,7 @@ static struct phy_driver aqr_driver[] = {
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr107_read_status,
+ .read_status = aqr_gen2_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
@@ -1310,7 +1221,7 @@ static struct phy_driver aqr_driver[] = {
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
.resume = aqr_gen1_resume,
- .read_status = aqr107_read_status,
+ .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,
@@ -1333,7 +1244,7 @@ static struct phy_driver aqr_driver[] = {
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
.resume = aqr_gen1_resume,
- .read_status = aqr107_read_status,
+ .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,
@@ -1351,7 +1262,7 @@ static struct phy_driver aqr_driver[] = {
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
.resume = aqr_gen1_resume,
- .read_status = aqr107_read_status,
+ .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,
@@ -1367,7 +1278,7 @@ static struct phy_driver aqr_driver[] = {
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr107_read_status,
+ .read_status = aqr_gen2_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
@@ -1391,7 +1302,7 @@ static struct phy_driver aqr_driver[] = {
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr107_read_status,
+ .read_status = aqr_gen2_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
@@ -1415,7 +1326,7 @@ static struct phy_driver aqr_driver[] = {
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr107_read_status,
+ .read_status = aqr_gen2_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
@@ -1440,7 +1351,7 @@ static struct phy_driver aqr_driver[] = {
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr107_read_status,
+ .read_status = aqr_gen2_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
@@ -1465,7 +1376,7 @@ static struct phy_driver aqr_driver[] = {
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
- .read_status = aqr107_read_status,
+ .read_status = aqr_gen2_read_status,
.get_tunable = aqr107_get_tunable,
.set_tunable = aqr107_set_tunable,
.suspend = aqr_gen1_suspend,
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH net-next 10/15] net: phy: aquantia: call aqr_gen2_fill_interface_modes() for AQCS109
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (8 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 09/15] net: phy: aquantia: merge and rename aqr105_read_status() and aqr107_read_status() Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 11/15] net: phy: aquantia: call aqr_gen3_config_init() for AQR112 and AQR412(C) Vladimir Oltean
` (6 subsequent siblings)
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
I don't have documentation or hardware to test, but according to commit
99c864667c9f ("net: phy: aquantia: add support for AQCS109"), "From
software point of view, it should be almost equivalent to AQR107."
I am relatively confident that the GLOBAL_CFG registers read by
aqr_gen2_fill_interface_modes() are supported, because
aqr_gen2_read_status(), currently used by AQCS109, also reads them, and
I'm unaware of any reported problem.
The change is necessary because a future patch will introduce a
requirement for all aqr_gen2_read_status() callers to have previously
called aqr_gen2_read_global_syscfg(). This is done through
aqr_gen2_fill_interface_modes().
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index e3a18fc1b52a..a7b1862e8a26 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -899,7 +899,11 @@ static int aqcs109_config_init(struct phy_device *phydev)
if (!ret)
aqr107_chip_info(phydev);
- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
+ ret = aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
+ if (ret)
+ return ret;
+
+ return aqr_gen2_fill_interface_modes(phydev);
}
static void aqr107_link_change_notify(struct phy_device *phydev)
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH net-next 11/15] net: phy: aquantia: call aqr_gen3_config_init() for AQR112 and AQR412(C)
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (9 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 10/15] net: phy: aquantia: call aqr_gen2_fill_interface_modes() for AQCS109 Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 12/15] net: phy: aquantia: reimplement aqcs109_config_init() as aqr_gen2_config_init() Vladimir Oltean
` (5 subsequent siblings)
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
The AQrate Gen3 PHYs are AQR111(C), AQR112(C), and their multi-port
variants, like AQR411(C), AQR412(C).
Currently, AQR112, AQR412 and AQR412C are Gen3 PHYs supported by the
driver which have no config_init() implementation. I have hardware and
documentation that confirms they are compatible with the operations done
in aqr_gen2_config_init(), a Gen2-level function.
This is needed as a preparation for reading cached registers in
aqr_gen2_read_status(), which is a function that these PHYs already call.
The initial reading is done from:
aqr_gen2_config_init()
-> aqr_gen2_fill_interface_modes()
-> aqr_gen2_read_global_syscfg()
thus the need for them to also call aqr_gen2_config_init(), in order for
the cached register values to be available.
In expectation of Gen3-specific features, introduce aqr_gen3_config_init()
which calls aqr_gen2_config_init(). Also modify the AQR111 silicon
variants to call their generation-appropriate init function. No
functional change for these, hence the minor mention.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index a7b1862e8a26..00bfbea81b8b 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -886,6 +886,11 @@ static int aqr_gen2_config_init(struct phy_device *phydev)
return aqr_gen2_fill_interface_modes(phydev);
}
+static int aqr_gen3_config_init(struct phy_device *phydev)
+{
+ return aqr_gen2_config_init(phydev);
+}
+
static int aqcs109_config_init(struct phy_device *phydev)
{
int ret;
@@ -1161,7 +1166,7 @@ static struct phy_driver aqr_driver[] = {
.name = "Aquantia AQR111",
.probe = aqr107_probe,
.get_rate_matching = aqr_gen2_get_rate_matching,
- .config_init = aqr_gen2_config_init,
+ .config_init = aqr_gen3_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
@@ -1186,7 +1191,7 @@ static struct phy_driver aqr_driver[] = {
.name = "Aquantia AQR111B0",
.probe = aqr107_probe,
.get_rate_matching = aqr_gen2_get_rate_matching,
- .config_init = aqr_gen2_config_init,
+ .config_init = aqr_gen3_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
@@ -1218,6 +1223,7 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR112),
.name = "Aquantia AQR112",
.probe = aqr107_probe,
+ .config_init = aqr_gen3_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
@@ -1241,6 +1247,7 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR412),
.name = "Aquantia AQR412",
.probe = aqr107_probe,
+ .config_init = aqr_gen3_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
@@ -1259,6 +1266,7 @@ static struct phy_driver aqr_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_AQR412C),
.name = "Aquantia AQR412C",
.probe = aqr107_probe,
+ .config_init = aqr_gen3_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH net-next 12/15] net: phy: aquantia: reimplement aqcs109_config_init() as aqr_gen2_config_init()
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (10 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 11/15] net: phy: aquantia: call aqr_gen3_config_init() for AQR112 and AQR412(C) Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 13/15] net: phy: aquantia: rename aqr113c_config_init() to aqr_gen4_config_init() Vladimir Oltean
` (4 subsequent siblings)
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
I lack documentation for AQCS109, but from commit 99c864667c9f ("net:
phy: aquantia: add support for AQCS109"), it is known that "From
software point of view, it should be almost equivalent to AQR107."
Based on further conjecture of the device numbering scheme, I am
treating it as similar to AQR109 (a Gen2 PHY capable of to 2.5G).
Its current instructions are also present in other init sequences as
below:
- aqr_wait_reset_complete() ... aqr107_chip_info() as well as
aqr107_set_downshift() are in aqr_gen1_config_init()
- aqr_gen2_fill_interface_modes() is in aqr_gen2_config_init()
So it would be good to centralize this implementation by just calling
aqr_gen2_config_init().
In practice this completes support for the following features, which are
present on AQR109 already:
- Potentially reverse MDI lane order via "marvell,mdi-cfg-order"
- Restore polarity of active-high and active-low LEDs after reset.
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 00bfbea81b8b..52d434283a32 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -893,22 +893,12 @@ static int aqr_gen3_config_init(struct phy_device *phydev)
static int aqcs109_config_init(struct phy_device *phydev)
{
- int ret;
-
/* Check that the PHY interface type is compatible */
if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
phydev->interface != PHY_INTERFACE_MODE_2500BASEX)
return -ENODEV;
- ret = aqr_wait_reset_complete(phydev);
- if (!ret)
- aqr107_chip_info(phydev);
-
- ret = aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
- if (ret)
- return ret;
-
- return aqr_gen2_fill_interface_modes(phydev);
+ return aqr_gen2_config_init(phydev);
}
static void aqr107_link_change_notify(struct phy_device *phydev)
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH net-next 13/15] net: phy: aquantia: rename aqr113c_config_init() to aqr_gen4_config_init()
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (11 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 12/15] net: phy: aquantia: reimplement aqcs109_config_init() as aqr_gen2_config_init() Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 14/15] net: phy: aquantia: promote AQR813 and AQR114C " Vladimir Oltean
` (3 subsequent siblings)
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
aqr113c_config_init() is called by AQR113, AQR113C, AQR115C, all Gen4
PHYs. Thus, rename this to aqr_gen4_config_init().
Currently, aqr113c_config_init() calls aqr_gen2_config_init(). Since
we've established that these are Gen4 PHYs, it makes sense to inherit
the Gen3 feature set as well. Currently, aqr_gen3_config_init() just
calls aqr_gen2_config_init(), so we can safely make this extra
modification and expect no functional change.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 52d434283a32..eb4409fdad34 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -1028,14 +1028,14 @@ static int aqr111_get_features(struct phy_device *phydev)
return 0;
}
-static int aqr113c_config_init(struct phy_device *phydev)
+static int aqr_gen4_config_init(struct phy_device *phydev)
{
struct aqr107_priv *priv = phydev->priv;
int ret;
priv->wait_on_global_cfg = true;
- ret = aqr_gen2_config_init(phydev);
+ ret = aqr_gen3_config_init(phydev);
if (ret < 0)
return ret;
@@ -1276,7 +1276,7 @@ static struct phy_driver aqr_driver[] = {
.name = "Aquantia AQR113",
.probe = aqr107_probe,
.get_rate_matching = aqr_gen2_get_rate_matching,
- .config_init = aqr113c_config_init,
+ .config_init = aqr_gen4_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
@@ -1300,7 +1300,7 @@ static struct phy_driver aqr_driver[] = {
.name = "Aquantia AQR113C",
.probe = aqr107_probe,
.get_rate_matching = aqr_gen2_get_rate_matching,
- .config_init = aqr113c_config_init,
+ .config_init = aqr_gen4_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
@@ -1349,7 +1349,7 @@ static struct phy_driver aqr_driver[] = {
.name = "Aquantia AQR115C",
.probe = aqr107_probe,
.get_rate_matching = aqr_gen2_get_rate_matching,
- .config_init = aqr113c_config_init,
+ .config_init = aqr_gen4_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH net-next 14/15] net: phy: aquantia: promote AQR813 and AQR114C to aqr_gen4_config_init()
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (12 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 13/15] net: phy: aquantia: rename aqr113c_config_init() to aqr_gen4_config_init() Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-21 15:20 ` [PATCH net-next 15/15] net: phy: aquantia: add support for AQR115 Vladimir Oltean
` (2 subsequent siblings)
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
I'm not sure whether there is any similar real-life problem on AQR813
and AQR114C as were seen on the PHYs that these commit were written for:
- a7f3abcf6357 ("net: phy: aquantia: only poll GLOBAL_CFG regs on
aqr113, aqr113c and aqr115c")
- bed90b06b681 ("net: phy: aquantia: clear PMD Global Transmit Disable
bit during init")
but the inconsistency in handling between PHYs of the same generation is
striking. Apart from different firmware builds with different
provisioning, the only difference between these PHYs should be the max
link speed and/or the number of ports.
Let's try and see if there's any problem if all PHYs from the same
generation use the same config_init() method.
Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Cc: Robert Marko <robimarko@gmail.com>
Cc: Paweł Owoc <frut3k7@gmail.com>
Cc: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index eb4409fdad34..dd83205a8869 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -1324,7 +1324,7 @@ static struct phy_driver aqr_driver[] = {
.name = "Aquantia AQR114C",
.probe = aqr107_probe,
.get_rate_matching = aqr_gen2_get_rate_matching,
- .config_init = aqr_gen2_config_init,
+ .config_init = aqr_gen4_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
@@ -1374,7 +1374,7 @@ static struct phy_driver aqr_driver[] = {
.name = "Aquantia AQR813",
.probe = aqr107_probe,
.get_rate_matching = aqr_gen2_get_rate_matching,
- .config_init = aqr_gen2_config_init,
+ .config_init = aqr_gen4_config_init,
.config_aneg = aqr_config_aneg,
.config_intr = aqr_config_intr,
.handle_interrupt = aqr_handle_interrupt,
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH net-next 15/15] net: phy: aquantia: add support for AQR115
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (13 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 14/15] net: phy: aquantia: promote AQR813 and AQR114C " Vladimir Oltean
@ 2025-08-21 15:20 ` Vladimir Oltean
2025-08-25 17:53 ` [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Jakub Kicinski
2025-08-25 18:00 ` patchwork-bot+netdevbpf
16 siblings, 0 replies; 22+ messages in thread
From: Vladimir Oltean @ 2025-08-21 15:20 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
From: Camelia Groza <camelia.groza@nxp.com>
AQR115 is similar to the already supported AQR115C, having speeds up to
2.5Gbps. In fact, the two differ only in the FCBGA package size (7x11mm
vs 7x7mm for the Compact variant). So it makes sense that the feature
set is identical for the 2 drivers.
This PHY is present on the newest PCB revision E (v4.0) of the NXP
LS1046A-RDB, having replaced the RTL8211FS SGMII PHY going to fm1-mac5.
Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/phy/aquantia/aquantia_main.c | 27 ++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index dd83205a8869..8516690e34db 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -31,6 +31,7 @@
#define PHY_ID_AQR113 0x31c31c40
#define PHY_ID_AQR113C 0x31c31c12
#define PHY_ID_AQR114C 0x31c31c22
+#define PHY_ID_AQR115 0x31c31c63
#define PHY_ID_AQR115C 0x31c31c33
#define PHY_ID_AQR813 0x31c31cb2
@@ -1344,6 +1345,31 @@ 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_AQR115),
+ .name = "Aquantia AQR115",
+ .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,
+ .get_features = aqr115c_get_features,
+ .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_AQR115C),
.name = "Aquantia AQR115C",
@@ -1413,6 +1439,7 @@ static const 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_AQR115) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR115C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
{ }
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (14 preceding siblings ...)
2025-08-21 15:20 ` [PATCH net-next 15/15] net: phy: aquantia: add support for AQR115 Vladimir Oltean
@ 2025-08-25 17:53 ` Jakub Kicinski
2025-08-25 18:00 ` patchwork-bot+netdevbpf
16 siblings, 0 replies; 22+ messages in thread
From: Jakub Kicinski @ 2025-08-25 17:53 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Andrew Lunn, Heiner Kallweit, Russell King,
David S. Miller, Eric Dumazet, Paolo Abeni, Daniel Golle,
linux-kernel, Nikita Yushchenko, Bartosz Golaszewski,
Robert Marko, Paweł Owoc, Sean Anderson, Jon Hunter
On Thu, 21 Aug 2025 18:20:07 +0300 Vladimir Oltean wrote:
> Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
> Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Cc: Robert Marko <robimarko@gmail.com>
> Cc: Paweł Owoc <frut3k7@gmail.com>
> Cc: Sean Anderson <sean.anderson@seco.com>
I feel like the chances of getting this properly tested are slim.
Let's apply and find out..
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1
2025-08-21 15:20 [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Vladimir Oltean
` (15 preceding siblings ...)
2025-08-25 17:53 ` [PATCH net-next 00/15] Aquantia PHY driver consolidation - part 1 Jakub Kicinski
@ 2025-08-25 18:00 ` patchwork-bot+netdevbpf
16 siblings, 0 replies; 22+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-08-25 18:00 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
daniel, linux-kernel, nikita.yoush, bartosz.golaszewski,
robimarko, frut3k7, sean.anderson, jonathanh
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 21 Aug 2025 18:20:07 +0300 you wrote:
> This started out as an effort to add some new features hinging on the
> VEND1_GLOBAL_CFG_* registers, but I quickly started to notice that the
> Aquantia PHY driver has a large code base, but individual PHYs only
> implement arbitrary subsets of it.
>
> The table below lists the PHYs known to me to have the
> VEND1_GLOBAL_CFG_* registers.
>
> [...]
Here is the summary with links:
- [net-next,01/15] net: phy: aquantia: rename AQR412 to AQR412C and add real AQR412
https://git.kernel.org/netdev/net-next/c/7cd3597b8f6f
- [net-next,02/15] net: phy: aquantia: merge aqr113c_fill_interface_modes() into aqr107_fill_interface_modes()
https://git.kernel.org/netdev/net-next/c/a31b1c1591e8
- [net-next,03/15] net: phy: aquantia: reorder AQR113C PMD Global Transmit Disable bit clearing with supported_interfaces
https://git.kernel.org/netdev/net-next/c/5433fbc3adcd
- [net-next,04/15] net: phy: aquantia: rename some aqr107 functions according to generation
https://git.kernel.org/netdev/net-next/c/9731bcf202e6
- [net-next,05/15] net: phy: aquantia: fill supported_interfaces for all aqr_gen2_config_init() callers
https://git.kernel.org/netdev/net-next/c/ab1dfcb5bce1
- [net-next,06/15] net: phy: aquantia: save a local shadow of GLOBAL_CFG register values
https://git.kernel.org/netdev/net-next/c/08048ba4285e
- [net-next,07/15] net: phy: aquantia: remove handling for get_rate_matching(PHY_INTERFACE_MODE_NA)
https://git.kernel.org/netdev/net-next/c/6fa022088b60
- [net-next,08/15] net: phy: aquantia: use cached GLOBAL_CFG registers in aqr107_read_rate()
https://git.kernel.org/netdev/net-next/c/832b63c70ef0
- [net-next,09/15] net: phy: aquantia: merge and rename aqr105_read_status() and aqr107_read_status()
https://git.kernel.org/netdev/net-next/c/c03c97e55f62
- [net-next,10/15] net: phy: aquantia: call aqr_gen2_fill_interface_modes() for AQCS109
https://git.kernel.org/netdev/net-next/c/02a7f5a92545
- [net-next,11/15] net: phy: aquantia: call aqr_gen3_config_init() for AQR112 and AQR412(C)
https://git.kernel.org/netdev/net-next/c/2d9503217520
- [net-next,12/15] net: phy: aquantia: reimplement aqcs109_config_init() as aqr_gen2_config_init()
https://git.kernel.org/netdev/net-next/c/ed1106f7f926
- [net-next,13/15] net: phy: aquantia: rename aqr113c_config_init() to aqr_gen4_config_init()
https://git.kernel.org/netdev/net-next/c/3c904dd67f50
- [net-next,14/15] net: phy: aquantia: promote AQR813 and AQR114C to aqr_gen4_config_init()
https://git.kernel.org/netdev/net-next/c/9dfe80a8157b
- [net-next,15/15] net: phy: aquantia: add support for AQR115
https://git.kernel.org/netdev/net-next/c/fb4b9f13718c
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 22+ messages in thread