realtek: phy: drop internal RTL8218B firmware
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Thu, 5 Feb 2026 18:45:22 +0000 (19:45 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 7 Feb 2026 16:39:38 +0000 (17:39 +0100)
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 <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/21885
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c
target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h [deleted file]
target/linux/realtek/files/firmware/rtl838x_phy/rtl838x_8380.fw [deleted file]
target/linux/realtek/rtl838x/config-6.12

index 3c0cb7b3e5b15acc9062a488690ace2ddabf065c..1c18d70db0a3f904e130802904d3ec884e60ae33 100644 (file)
@@ -15,8 +15,6 @@
 #include <linux/mii.h>
 #include <linux/mdio.h>
 
-#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
 
 #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 (file)
index a446570..0000000
+++ /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 (file)
index ef84c71..0000000
Binary files a/target/linux/realtek/files/firmware/rtl838x_phy/rtl838x_8380.fw and /dev/null differ
index 70b8598e17d93bb1a0ffde9750c7878151ea63c8..538b44ce186c497d2b792063ac73871a5f82c93b 100644 (file)
@@ -57,8 +57,6 @@ CONFIG_DTC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_EARLY_PRINTK_8250=y
 CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXTRA_FIRMWARE="rtl838x_phy/rtl838x_8380.fw"
-CONFIG_EXTRA_FIRMWARE_DIR="firmware"
 CONFIG_FIXED_PHY=y
 CONFIG_FORCE_NR_CPUS=y
 CONFIG_FS_IOMAP=y