From 27a2cbedf3b4bc8bf205ab6fadab06252a5fc245 Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Thu, 5 Feb 2026 19:45:22 +0100 Subject: [PATCH] realtek: phy: drop internal RTL8218B firmware The phy driver still uses the ancient unknown firmware file format for the internal RTL8218B of the RTL838x. Get rid of that and convert the initialization to the bare minimum. Signed-off-by: Markus Stockhausen Link: https://github.com/openwrt/openwrt/pull/21885 Signed-off-by: Hauke Mehrtens --- .../files-6.12/drivers/net/phy/rtl83xx-phy.c | 177 ++---------------- .../files-6.12/drivers/net/phy/rtl83xx-phy.h | 38 ---- .../firmware/rtl838x_phy/rtl838x_8380.fw | Bin 1184 -> 0 bytes target/linux/realtek/rtl838x/config-6.12 | 2 - 4 files changed, 14 insertions(+), 203 deletions(-) delete mode 100644 target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h delete mode 100644 target/linux/realtek/files/firmware/rtl838x_phy/rtl838x_8380.fw 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 3c0cb7b3e5b..1c18d70db0a 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 @@ -15,8 +15,6 @@ #include #include -#include "rtl83xx-phy.h" - /* * Realtek PHYs have three special page registers. Register 31 (page select) switches the * register pages and gives access to special registers that are mapped into register @@ -59,7 +57,18 @@ #define RTL8214FC_MEDIA_COPPER BIT(11) -static const struct firmware rtl838x_8380_fw; +#define PHY_ID_RTL8214C 0x001cc942 +#define PHY_ID_RTL8218B_E 0x001cc980 +#define PHY_ID_RTL8214_OR_8218 0x001cc981 +#define PHY_ID_RTL8218D 0x001cc983 +#define PHY_ID_RTL8218E 0x001cc984 +#define PHY_ID_RTL8218B_I 0x001cca40 + +/* These PHYs share the same id (0x001cc981) */ +#define PHY_IS_NOT_RTL821X 0 +#define PHY_IS_RTL8214FC 1 +#define PHY_IS_RTL8214FB 2 +#define PHY_IS_RTL8218B_E 3 struct rtl821x_shared_priv { int base_addr; @@ -171,16 +180,6 @@ static int rtl8214fc_match_phy_device(struct phy_device *phydev, return rtl821x_match_phy_device(phydev) == PHY_IS_RTL8214FC; } -static void rtl8380_int_phy_on_off(struct phy_device *phydev, bool on) -{ - phy_modify(phydev, 0, BMCR_PDOWN, on ? 0 : BMCR_PDOWN); -} - -static void rtl8380_phy_reset(struct phy_device *phydev) -{ - phy_modify(phydev, 0, BMCR_RESET, BMCR_RESET); -} - static int rtl821x_read_page(struct phy_device *phydev) { return __phy_read(phydev, RTL821x_PAGE_SELECT); @@ -191,139 +190,6 @@ static int rtl821x_write_page(struct phy_device *phydev, int page) return __phy_write(phydev, RTL821x_PAGE_SELECT, page); } -static struct fw_header *rtl838x_request_fw(struct phy_device *phydev, - const struct firmware *fw, - const char *name) -{ - struct device *dev = &phydev->mdio.dev; - int err; - struct fw_header *h; - u32 checksum, my_checksum; - - err = request_firmware(&fw, name, dev); - if (err < 0) - goto out; - - if (fw->size < sizeof(struct fw_header)) { - pr_err("Firmware size too small.\n"); - err = -EINVAL; - goto out; - } - - h = (struct fw_header *)fw->data; - pr_info("Firmware loaded. Size %d, magic: %08x\n", fw->size, h->magic); - - if (h->magic != 0x83808380) { - pr_err("Wrong firmware file: MAGIC mismatch.\n"); - goto out; - } - - checksum = h->checksum; - h->checksum = 0; - my_checksum = ~crc32(0xFFFFFFFFU, fw->data, fw->size); - if (checksum != my_checksum) { - pr_err("Firmware checksum mismatch.\n"); - err = -EINVAL; - goto out; - } - h->checksum = checksum; - - return h; -out: - dev_err(dev, "Unable to load firmware %s (%d)\n", name, err); - return NULL; -} - -static int rtl821x_prepare_patch(struct phy_device *phydev, int ports) -{ - struct phy_device *patchphy; - int tries = 50; - - for (int port = 0; port < ports; port++) { - patchphy = get_package_phy(phydev, port); - phy_write_paged(patchphy, RTL821X_PAGE_PATCH, 0x10, 0x10); - } - - for (int port = 0; port < ports; port++) { - patchphy = get_package_phy(phydev, port); - while (tries && !(phy_read_paged(patchphy, RTL821X_PAGE_STATE, 0x10) & 0x40)) { - tries--; - usleep_range(10000, 25000); - }; - } - - if (!tries) - phydev_err(get_package_phy(phydev, 0), "package not ready for patch.\n"); - - return tries ? 0 : -EIO; -} - -static int rtl8380_configure_int_rtl8218b(struct phy_device *phydev) -{ - u32 *rtl838x_6275B_intPhy_perport; - u32 *rtl8218b_6276B_hwEsd_perport; - struct phy_device *patchphy; - struct fw_header *h; - int ret; - u32 val; - - /* Read internal PHY ID */ - phy_write_paged(phydev, 31, 27, 0x0002); - val = phy_read_paged(phydev, 31, 28); - if (val != 0x6275) { - phydev_err(phydev, "Expected internal RTL8218B, found PHY-ID %x\n", val); - return -1; - } - - h = rtl838x_request_fw(phydev, &rtl838x_8380_fw, FIRMWARE_838X_8380_1); - if (!h) - return -1; - - if (h->phy != 0x83800000) { - phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n"); - return -1; - } - - rtl838x_6275B_intPhy_perport = (void *)h + sizeof(struct fw_header) + h->parts[8].start; - rtl8218b_6276B_hwEsd_perport = (void *)h + sizeof(struct fw_header) + h->parts[9].start; - - phydev_info(phydev, "patch\n"); - - val = phy_read(phydev, MII_BMCR); - if (val & BMCR_PDOWN) - rtl8380_int_phy_on_off(phydev, true); - else - rtl8380_phy_reset(phydev); - msleep(100); - - ret = rtl821x_prepare_patch(phydev, 8); - if (ret) - return ret; - - for (int port = 0; port < 8; port++) { - int i; - - patchphy = get_package_phy(phydev, port); - - i = 0; - while (rtl838x_6275B_intPhy_perport[i * 2]) { - phy_write_paged(patchphy, RTL838X_PAGE_RAW, - rtl838x_6275B_intPhy_perport[i * 2], - rtl838x_6275B_intPhy_perport[i * 2 + 1]); - i++; - } - i = 0; - while (rtl8218b_6276B_hwEsd_perport[i * 2]) { - phy_write_paged(patchphy, RTL838X_PAGE_RAW, - rtl8218b_6276B_hwEsd_perport[i * 2], - rtl8218b_6276B_hwEsd_perport[i * 2 + 1]); - i++; - } - } - - return 0; -} - static bool __rtl8214fc_media_is_fibre(struct phy_device *phydev) { struct phy_device *basephy = get_base_phy(phydev); @@ -575,21 +441,6 @@ static int rtl8214c_phy_probe(struct phy_device *phydev) return 0; } -static int rtl8218b_ext_phy_probe(struct phy_device *phydev) -{ - rtl821x_package_join(phydev, 8); - - return 0; -} - -static int rtl8218b_int_phy_probe(struct phy_device *phydev) -{ - if (rtl821x_package_join(phydev, 8) == RTL821X_JOIN_LAST) - return rtl8380_configure_int_rtl8218b(get_base_phy(phydev)); - - return 0; -} - static int rtl8218x_phy_probe(struct phy_device *phydev) { rtl821x_package_join(phydev, 8); @@ -801,7 +652,7 @@ static struct phy_driver rtl83xx_phy_driver[] = { .name = "Realtek RTL8218B (external)", .config_init = rtl8218b_config_init, .features = PHY_GBIT_FEATURES, - .probe = rtl8218b_ext_phy_probe, + .probe = rtl8218x_phy_probe, .read_mmd = rtl821x_read_mmd, .read_page = rtl821x_read_page, .resume = genphy_resume, @@ -814,7 +665,7 @@ static struct phy_driver rtl83xx_phy_driver[] = { .name = "Realtek RTL8218B (internal)", .config_init = rtl821x_config_init, .features = PHY_GBIT_FEATURES, - .probe = rtl8218b_int_phy_probe, + .probe = rtl8218x_phy_probe, .read_mmd = rtl821x_read_mmd, .read_page = rtl821x_read_page, .resume = genphy_resume, 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 deleted file mode 100644 index a446570f119..00000000000 --- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -struct __packed part { - u16 start; - u8 wordsize; - u8 words; -}; - -struct __packed fw_header { - u32 magic; - u32 phy; - u32 checksum; - u32 version; - struct part parts[10]; -}; - -/* TODO: fixed path? */ -/* NOTE: This firmware file contains both patch values for SerDes - * configuration and for the internal RTL8218B PHY of RTL838x. Because - * the SerDes setup has been moved to the PCS driver and the firmware - * file isn't used there, this was only kept for the PHY. As soon as - * this has been changed, this firmware file can be dropped completely. - */ -#define FIRMWARE_838X_8380_1 "rtl838x_phy/rtl838x_8380.fw" - -#define PHY_ID_RTL8214C 0x001cc942 -#define PHY_ID_RTL8218B_E 0x001cc980 -#define PHY_ID_RTL8214_OR_8218 0x001cc981 -#define PHY_ID_RTL8218D 0x001cc983 -#define PHY_ID_RTL8218E 0x001cc984 -#define PHY_ID_RTL8218B_I 0x001cca40 - -/* These PHYs share the same id (0x001cc981) */ -#define PHY_IS_NOT_RTL821X 0 -#define PHY_IS_RTL8214FC 1 -#define PHY_IS_RTL8214FB 2 -#define PHY_IS_RTL8218B_E 3 - diff --git a/target/linux/realtek/files/firmware/rtl838x_phy/rtl838x_8380.fw b/target/linux/realtek/files/firmware/rtl838x_phy/rtl838x_8380.fw deleted file mode 100644 index ef84c717533ef1ffe03326d0fbe6b0165c18d346..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 1184 zc-mc)F>4f26orp7!zd~kA*i5eP)iFzu@VG{Vk7tyEYhi{UF?=bA;J=e;}co_YK3Vr$VKY2(C&=NgYB(j~{Y zB-++WqUfY!DT(4K$Gqcp5+zr>E}eFqbDVWdNu9QI`=Yc3yRZlQZ~&VT=B4e2r4j7h zmG*dk3wB`-_Td0_mZV!(oe#UP2m5f)=m)NI*%~$@v#;Sz(|PxP`8UiSOEcfCVfIma z`^9?QXSHCiO07?x|17O7o6KilrQ>T}cmDYurq?$s&Pj1B_K&$982&jRN7%kfvBiwVDtuhR9V zU9ZGf>GRVE6MrTCLQ|JICHs~W`v&$6ZM6T_AAXnc2<_Y1z~cV3z76R02X zHS!&q_WFqW!S#RozK^c^oZi>ZRX)OmkB+-&cXe-J7xrKu4&XRHCO;-WCO;-WCO`hK zPSrmteU{Q^DSejGXDNM_{(DYGq+JVjuQqz;thv|kb%6B^b6@SR(&KT^_xp)?NV