diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c index 97b0b67b9900..1e670638dd1c 100644 --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c @@ -257,6 +257,8 @@ #define RTL_8251B 0x001cc862 #define RTL_8261C 0x001cc890 #define RTL_8261C_CG 0x001cc898 +#define RTL_8261CE_CG 0x001cc899 +#define RTL_8261D_VM 0x001cc89a #define RTL8261C_CE_MODEL 0x00 #define RTL8261D_MODEL 0x81 @@ -285,11 +287,15 @@ #define FW_MAIN_MAGIC 0x52544C38 #define FW_SUB_MAGIC_8261C 0x32363143 +#define FW_SUB_MAGIC_8261D 0x32363144 #define RTL8261X_POLL_TIMEOUT_MS 100 #define RTL8261X_MAX_MMD_DEV 31 #define RTL8261C_CE_FW_NAME "rtl_nic/rtl8261c.bin" +#define RTL8261D_FW_NAME "rtl_nic/rtl8261d.bin" + MODULE_FIRMWARE(RTL8261C_CE_FW_NAME); +MODULE_FIRMWARE(RTL8261D_FW_NAME); enum rtl8261x_fw_op { OP_WRITE = 0x00, /* Write */ @@ -341,6 +347,7 @@ struct rtl821x_priv { struct rtl8261x_priv { const char *fw_name; + u32 fw_sub_magic; bool fw_loaded; }; @@ -410,10 +417,13 @@ static int rtl8261x_probe(struct phy_device *phydev) switch (sub_phy_id) { case RTL8261C_CE_MODEL: priv->fw_name = RTL8261C_CE_FW_NAME; + priv->fw_sub_magic = FW_SUB_MAGIC_8261C; phydev_info(phydev, "RTL8261C detected (sub_id 0x%02x)\n", sub_phy_id); break; case RTL8261D_MODEL: + priv->fw_name = RTL8261D_FW_NAME; + priv->fw_sub_magic = FW_SUB_MAGIC_8261D; phydev_info(phydev, "RTL8261D detected (sub_id 0x%02x)\n", sub_phy_id); break; @@ -472,6 +482,7 @@ static int rtl8261x_read_status(struct phy_device *phydev) static int rtl8261x_verify_firmware(struct phy_device *phydev, const struct firmware *fw) { + struct rtl8261x_priv *priv = phydev->priv; const struct rtl8261x_fw_header *hdr; u32 main_magic, sub_magic; u32 calc_crc, file_crc; @@ -492,7 +503,7 @@ static int rtl8261x_verify_firmware(struct phy_device *phydev, const struct firm } sub_magic = le32_to_cpu(hdr->sub_magic); - if (sub_magic != FW_SUB_MAGIC_8261C) { + if (sub_magic != priv->fw_sub_magic) { phydev_err(phydev, "Invalid sub magic: 0x%08x\n", sub_magic); return -EINVAL; } @@ -3363,6 +3374,32 @@ static struct phy_driver realtek_drvs[] = { .soft_reset = genphy_c45_pma_soft_reset, .suspend = genphy_c45_pma_suspend, .resume = genphy_c45_pma_resume, + }, { + PHY_ID_MATCH_EXACT(RTL_8261CE_CG), + .name = "Realtek RTL8261CE 10Gbps PHY", + .probe = rtl8261x_probe, + .config_init = rtl8261x_config_init, + .get_features = rtl8261x_get_features, + .config_aneg = rtl8261x_config_aneg, + .read_status = rtl8261x_read_status, + .config_intr = rtl8261x_config_intr, + .handle_interrupt = rtl8261x_handle_interrupt, + .soft_reset = genphy_c45_pma_soft_reset, + .suspend = genphy_c45_pma_suspend, + .resume = genphy_c45_pma_resume, + }, { + PHY_ID_MATCH_EXACT(RTL_8261D_VM), + .name = "Realtek RTL8261D_VM 10Gbps PHY", + .probe = rtl8261x_probe, + .config_init = rtl8261x_config_init, + .get_features = rtl8261x_get_features, + .config_aneg = rtl8261x_config_aneg, + .read_status = rtl8261x_read_status, + .config_intr = rtl8261x_config_intr, + .handle_interrupt = rtl8261x_handle_interrupt, + .soft_reset = genphy_c45_pma_soft_reset, + .suspend = genphy_c45_pma_suspend, + .resume = genphy_c45_pma_resume, }, };