[openwrt/openwrt] realtek: phy: late phy package patching
LEDE Commits
lede-commits at lists.infradead.org
Fri Aug 29 15:20:44 PDT 2025
hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/a1043fda8b77e096d225e43a3c6671d385d46176
commit a1043fda8b77e096d225e43a3c6671d385d46176
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Tue Aug 19 05:06:37 2025 -0400
realtek: phy: late phy package patching
Currently phy packages (like RTL8214x/RTL8218x) are patched and
initialized as soon as the first phy of the package is found.
In this situation the shared structure is not finalized because
devm_phy_package_join() has only been called for the first phy.
This is no issue as the patching directly hammers the bus addresses
for the follow-up phys.
In the future we want to simplify the package handling and allow
to access all phy_device structures from only one phy_device of
the package. With this we can use normal phy_read/phy_write.
Switch the probing logic to "late patching". With this we will
initialize the firmware of the package when the last phy of the
package has been found and thus the shared structure is complete.
Provide get_base_phy() as the first package helper that allows
to determine the first phy of the package from any other phy.
While we are here drop the shared structure that only repeats the
phy name and has no other use.
Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19810
Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
.../files-6.12/drivers/net/phy/rtl83xx-phy.c | 89 ++++++----------------
.../files-6.12/drivers/net/phy/rtl83xx-phy.h | 4 -
2 files changed, 25 insertions(+), 68 deletions(-)
diff --git a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c
index 1cf18b5ca3..01f24080b8 100644
--- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c
+++ b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c
@@ -106,6 +106,11 @@ static const struct firmware rtl838x_8380_fw;
static const struct firmware rtl838x_8214fc_fw;
static const struct firmware rtl838x_8218b_fw;
+static inline struct phy_device *get_base_phy(struct phy_device *phydev)
+{
+ return mdiobus_get_phy(phydev->mdio.bus, phydev->shared->base_addr);
+}
+
static u64 disable_polling(int port)
{
u64 saved_state;
@@ -3576,20 +3581,13 @@ static const struct sfp_upstream_ops rtl8214fc_sfp_ops = {
static int rtl8214fc_phy_probe(struct phy_device *phydev)
{
- struct device *dev = &phydev->mdio.dev;
- int addr = phydev->mdio.addr;
+ int base_addr = phydev->mdio.addr & ~3;
int ret = 0;
- /* All base addresses of the PHYs start at multiples of 8 */
- devm_phy_package_join(dev, phydev, addr & (~7),
- sizeof(struct rtl83xx_shared_private));
-
- if (!(addr % 8)) {
- struct rtl83xx_shared_private *shared = phydev->shared->priv;
- shared->name = "RTL8214FC";
- /* Configuration must be done while patching still possible */
+ devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
+ if (phydev->mdio.addr == base_addr + 3) {
if (soc_info.family == RTL8380_FAMILY_ID)
- ret = rtl8380_configure_rtl8214fc(phydev);
+ ret = rtl8380_configure_rtl8214fc(get_base_phy(phydev));
if (ret)
return ret;
}
@@ -3599,39 +3597,23 @@ static int rtl8214fc_phy_probe(struct phy_device *phydev)
static int rtl8214c_phy_probe(struct phy_device *phydev)
{
- struct device *dev = &phydev->mdio.dev;
- int addr = phydev->mdio.addr;
-
- /* All base addresses of the PHYs start at multiples of 8 */
- devm_phy_package_join(dev, phydev, addr & (~7),
- sizeof(struct rtl83xx_shared_private));
+ int base_addr = phydev->mdio.addr & ~3;
- if (!(addr % 8)) {
- struct rtl83xx_shared_private *shared = phydev->shared->priv;
- shared->name = "RTL8214C";
- /* Configuration must be done whil patching still possible */
- return rtl8380_configure_rtl8214c(phydev);
- }
+ devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
+ if (phydev->mdio.addr == base_addr + 3)
+ return rtl8380_configure_rtl8214c(get_base_phy(phydev));
return 0;
}
static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
{
- struct device *dev = &phydev->mdio.dev;
- int addr = phydev->mdio.addr;
+ int base_addr = phydev->mdio.addr & ~7;
- /* All base addresses of the PHYs start at multiples of 8 */
- devm_phy_package_join(dev, phydev, addr & (~7),
- sizeof(struct rtl83xx_shared_private));
-
- if (!(addr % 8)) {
- struct rtl83xx_shared_private *shared = phydev->shared->priv;
- shared->name = "RTL8218B (external)";
- if (soc_info.family == RTL8380_FAMILY_ID) {
- /* Configuration must be done while patching still possible */
- return rtl8380_configure_ext_rtl8218b(phydev);
- }
+ devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
+ if (phydev->mdio.addr == base_addr + 7) {
+ if (soc_info.family == RTL8380_FAMILY_ID)
+ return rtl8380_configure_ext_rtl8218b(get_base_phy(phydev));
}
return 0;
@@ -3639,46 +3621,25 @@ static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
static int rtl8218b_int_phy_probe(struct phy_device *phydev)
{
- struct device *dev = &phydev->mdio.dev;
- int addr = phydev->mdio.addr;
+ int base_addr = phydev->mdio.addr & ~7;
if (soc_info.family != RTL8380_FAMILY_ID)
return -ENODEV;
- if (addr >= 24)
+ if (base_addr >= 24)
return -ENODEV;
- pr_debug("%s: id: %d\n", __func__, addr);
- /* All base addresses of the PHYs start at multiples of 8 */
- devm_phy_package_join(dev, phydev, addr & (~7),
- sizeof(struct rtl83xx_shared_private));
-
- if (!(addr % 8)) {
- struct rtl83xx_shared_private *shared = phydev->shared->priv;
- shared->name = "RTL8218B (internal)";
- /* Configuration must be done while patching still possible */
- return rtl8380_configure_int_rtl8218b(phydev);
- }
+ devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
+ if (phydev->mdio.addr == base_addr + 7)
+ return rtl8380_configure_int_rtl8218b(get_base_phy(phydev));
return 0;
}
static int rtl8218d_phy_probe(struct phy_device *phydev)
{
- struct device *dev = &phydev->mdio.dev;
- int addr = phydev->mdio.addr;
+ int base_addr = phydev->mdio.addr & ~7;
- pr_debug("%s: id: %d\n", __func__, addr);
- /* All base addresses of the PHYs start at multiples of 8 */
- devm_phy_package_join(dev, phydev, addr & (~7),
- sizeof(struct rtl83xx_shared_private));
-
- /* All base addresses of the PHYs start at multiples of 8 */
- if (!(addr % 8)) {
- struct rtl83xx_shared_private *shared = phydev->shared->priv;
- shared->name = "RTL8218D";
- /* Configuration must be done while patching still possible */
-/* TODO: return configure_rtl8218d(phydev); */
- }
+ devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
return 0;
}
diff --git a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h
index 652e27a5c5..2f55fb0d90 100644
--- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h
+++ b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h
@@ -1,9 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-struct rtl83xx_shared_private {
- char *name;
-};
-
struct __attribute__ ((__packed__)) part {
uint16_t start;
uint8_t wordsize;
More information about the lede-commits
mailing list