Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-phy-realtek-simplify-and-reunify-c22-c45-drivers'

Daniel Golle says:

====================
net: phy: realtek: simplify and reunify C22/C45 drivers

The RTL8221B PHY variants (VB-CG and VM-CG) were previously split into
separate C22 and C45 driver instances to support copper SFP modules
using the RollBall MDIO-over-I2C protocol, which only supports Clause-45
access. However, this split created significant code duplication and
complexity.

Commit 8af2136e77989 ("net: phy: realtek: add helper
RTL822X_VND2_C22_REG") exposed that RealTek PHYs map all standard
Clause-22 registers into MDIO_MMD_VEND2 at offset 0xa400.

With commit 1850ec20d6e71 ("net: phy: realtek: use paged access for
MDIO_MMD_VEND2 in C22 mode") it is now possible to access all MMD
registers transparently, regardless of whether the PHY is accessed via
C22 or C45 MDIO.

Further improve the translation logic for this register mapping, so a
single unified driver works efficiently with both access methods,
reducing code duplication.

The series also includes cleanup to remove unnecessary paged operations
on registers that aren't actually affected by page selection.

Testing was done on RTL8211F and RTL8221B-VB-CG (the latter in both
C22 and C45 modes).
====================

Link: https://patch.msgid.link/cover.1768275364.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+48 -76
+48 -76
drivers/net/phy/realtek/realtek_main.c
··· 68 68 #define RTL8211E_DELAY_MASK GENMASK(13, 11) 69 69 70 70 /* RTL8211F PHY configuration */ 71 - #define RTL8211F_PHYCR_PAGE 0xa43 72 71 #define RTL8211F_PHYCR1 0x18 73 72 #define RTL8211F_ALDPS_PLL_OFF BIT(1) 74 73 #define RTL8211F_ALDPS_ENABLE BIT(2) ··· 77 78 #define RTL8211F_CLKOUT_EN BIT(0) 78 79 #define RTL8211F_PHYCR2_PHY_EEE_ENABLE BIT(5) 79 80 80 - #define RTL8211F_INSR_PAGE 0xa43 81 81 #define RTL8211F_INSR 0x1d 82 82 83 83 /* RTL8211F LED configuration */ ··· 142 144 143 145 #define RTL822X_VND2_TO_PAGE(reg) ((reg) >> 4) 144 146 #define RTL822X_VND2_TO_PAGE_REG(reg) (16 + (((reg) & GENMASK(3, 0)) >> 1)) 147 + #define RTL822X_VND2_TO_C22_REG(reg) (((reg) - 0xa400) / 2) 145 148 #define RTL822X_VND2_C22_REG(reg) (0xa400 + 2 * (reg)) 146 149 147 150 #define RTL8221B_VND2_INER 0xa4d2 ··· 177 178 #define RTL9000A_GINMR 0x14 178 179 #define RTL9000A_GINMR_LINK_STATUS BIT(4) 179 180 180 - #define RTL_VND2_PHYSR 0xa434 181 - #define RTL_VND2_PHYSR_DUPLEX BIT(3) 182 - #define RTL_VND2_PHYSR_SPEEDL GENMASK(5, 4) 183 - #define RTL_VND2_PHYSR_SPEEDH GENMASK(10, 9) 184 - #define RTL_VND2_PHYSR_MASTER BIT(11) 185 - #define RTL_VND2_PHYSR_SPEED_MASK (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH) 181 + #define RTL_PHYSR MII_RESV2 182 + #define RTL_PHYSR_DUPLEX BIT(3) 183 + #define RTL_PHYSR_SPEEDL GENMASK(5, 4) 184 + #define RTL_PHYSR_SPEEDH GENMASK(10, 9) 185 + #define RTL_PHYSR_MASTER BIT(11) 186 + #define RTL_PHYSR_SPEED_MASK (RTL_PHYSR_SPEEDL | RTL_PHYSR_SPEEDH) 186 187 187 188 #define RTL_MDIO_PCS_EEE_ABLE 0xa5c4 188 189 #define RTL_MDIO_AN_EEE_ADV 0xa5d0 ··· 331 332 { 332 333 int err; 333 334 334 - err = phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR); 335 + err = phy_read(phydev, RTL8211F_INSR); 335 336 336 337 return (err < 0) ? err : 0; 337 338 } ··· 477 478 { 478 479 int irq_status; 479 480 480 - irq_status = phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR); 481 + irq_status = phy_read(phydev, RTL8211F_INSR); 481 482 if (irq_status < 0) { 482 483 phy_error(phydev); 483 484 return IRQ_NONE; ··· 668 669 RTL8211FVD_CLKOUT_REG, 669 670 RTL8211FVD_CLKOUT_EN, 0); 670 671 else 671 - ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, 672 - RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0); 672 + ret = phy_modify(phydev, RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 673 + 0); 673 674 if (ret) 674 675 return ret; 675 676 ··· 694 695 if (!priv->enable_aldps) 695 696 return 0; 696 697 697 - return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1, 698 - mask, mask); 698 + return phy_modify(phydev, RTL8211F_PHYCR1, mask, mask); 699 699 } 700 700 701 701 static int rtl8211f_config_phy_eee(struct phy_device *phydev) 702 702 { 703 703 /* Disable PHY-mode EEE so LPI is passed to the MAC */ 704 - return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2, 705 - RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0); 704 + return phy_modify(phydev, RTL8211F_PHYCR2, 705 + RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0); 706 706 } 707 707 708 708 static int rtl8211f_config_init(struct phy_device *phydev) ··· 767 769 goto err; 768 770 769 771 /* Read the INSR to clear any pending interrupt */ 770 - phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR); 772 + phy_read(phydev, RTL8211F_INSR); 771 773 772 774 /* Reset the WoL to ensure that an event is picked up. 773 775 * Unless we do this, even if we receive another packet, ··· 1100 1102 * 0: Half Duplex 1101 1103 * 1: Full Duplex 1102 1104 */ 1103 - if (val & RTL_VND2_PHYSR_DUPLEX) 1105 + if (val & RTL_PHYSR_DUPLEX) 1104 1106 phydev->duplex = DUPLEX_FULL; 1105 1107 else 1106 1108 phydev->duplex = DUPLEX_HALF; 1107 1109 1108 - switch (val & RTL_VND2_PHYSR_SPEED_MASK) { 1110 + switch (val & RTL_PHYSR_SPEED_MASK) { 1109 1111 case 0x0000: 1110 1112 phydev->speed = SPEED_10; 1111 1113 break; ··· 1133 1135 * 1: Master Mode 1134 1136 */ 1135 1137 if (phydev->speed >= 1000) { 1136 - if (val & RTL_VND2_PHYSR_MASTER) 1138 + if (val & RTL_PHYSR_MASTER) 1137 1139 phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER; 1138 1140 else 1139 1141 phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE; ··· 1153 1155 if (!phydev->link) 1154 1156 return 0; 1155 1157 1156 - val = phy_read_paged(phydev, RTL822X_VND2_TO_PAGE(RTL_VND2_PHYSR), 1157 - RTL822X_VND2_TO_PAGE_REG(RTL_VND2_PHYSR)); 1158 + val = phy_read(phydev, RTL_PHYSR); 1158 1159 if (val < 0) 1159 1160 return val; 1160 1161 ··· 1262 1265 return mmd_phy_read(phydev->mdio.bus, phydev->mdio.addr, 1263 1266 phydev->is_c45, devnum, reg); 1264 1267 1268 + /* Simplify access to C22-registers addressed inside MDIO_MMD_VEND2 */ 1269 + if (reg >= RTL822X_VND2_C22_REG(0) && 1270 + reg <= RTL822X_VND2_C22_REG(30)) 1271 + return __phy_read(phydev, RTL822X_VND2_TO_C22_REG(reg)); 1272 + 1265 1273 /* Use paged access for MDIO_MMD_VEND2 over Clause-22 */ 1266 1274 page = RTL822X_VND2_TO_PAGE(reg); 1267 1275 oldpage = __phy_read(phydev, RTL821x_PAGE_SELECT); ··· 1301 1299 if (devnum != MDIO_MMD_VEND2 || phydev->is_c45) 1302 1300 return mmd_phy_write(phydev->mdio.bus, phydev->mdio.addr, 1303 1301 phydev->is_c45, devnum, reg, val); 1302 + 1303 + /* Simplify access to C22-registers addressed inside MDIO_MMD_VEND2 */ 1304 + if (reg >= RTL822X_VND2_C22_REG(0) && 1305 + reg <= RTL822X_VND2_C22_REG(30)) 1306 + return __phy_write(phydev, RTL822X_VND2_TO_C22_REG(reg), val); 1304 1307 1305 1308 /* Use paged access for MDIO_MMD_VEND2 over Clause-22 */ 1306 1309 page = RTL822X_VND2_TO_PAGE(reg); ··· 1620 1613 } 1621 1614 1622 1615 /* Read actual speed from vendor register. */ 1623 - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR); 1616 + val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 1617 + RTL822X_VND2_C22_REG(RTL_PHYSR)); 1624 1618 if (val < 0) 1625 1619 return val; 1626 1620 ··· 1878 1870 return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev); 1879 1871 } 1880 1872 1881 - static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev, 1882 - const struct phy_driver *phydrv) 1873 + static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev, 1874 + const struct phy_driver *phydrv) 1883 1875 { 1884 - return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false); 1876 + return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true) || 1877 + rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false); 1885 1878 } 1886 1879 1887 - static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev, 1888 - const struct phy_driver *phydrv) 1880 + static int rtl8221b_vm_cg_match_phy_device(struct phy_device *phydev, 1881 + const struct phy_driver *phydrv) 1889 1882 { 1890 - return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true); 1891 - } 1892 - 1893 - static int rtl8221b_vm_cg_c22_match_phy_device(struct phy_device *phydev, 1894 - const struct phy_driver *phydrv) 1895 - { 1896 - return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, false); 1897 - } 1898 - 1899 - static int rtl8221b_vm_cg_c45_match_phy_device(struct phy_device *phydev, 1900 - const struct phy_driver *phydrv) 1901 - { 1902 - return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, true); 1883 + return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, true) || 1884 + rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, false); 1903 1885 } 1904 1886 1905 1887 static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev, ··· 2125 2127 if (!phydev->link) 2126 2128 return 0; 2127 2129 2128 - val = rtlgen_read_vend2(phydev, RTL_VND2_PHYSR); 2130 + val = phy_read(phydev, RTL_PHYSR); 2129 2131 if (val < 0) 2130 2132 return val; 2131 2133 ··· 2312 2314 .read_mmd = rtl822xb_read_mmd, 2313 2315 .write_mmd = rtl822xb_write_mmd, 2314 2316 }, { 2315 - .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device, 2316 - .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)", 2317 - .probe = rtl822x_probe, 2318 - .get_features = rtl822x_get_features, 2319 - .config_aneg = rtl822x_config_aneg, 2320 - .config_init = rtl822xb_config_init, 2321 - .inband_caps = rtl822x_inband_caps, 2322 - .config_inband = rtl822x_config_inband, 2323 - .get_rate_matching = rtl822xb_get_rate_matching, 2324 - .read_status = rtl822xb_read_status, 2325 - .suspend = genphy_suspend, 2326 - .resume = rtlgen_resume, 2327 - .read_page = rtl821x_read_page, 2328 - .write_page = rtl821x_write_page, 2329 - .read_mmd = rtl822xb_read_mmd, 2330 - .write_mmd = rtl822xb_write_mmd, 2331 - }, { 2332 - .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device, 2333 - .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)", 2317 + .match_phy_device = rtl8221b_vb_cg_match_phy_device, 2318 + .name = "RTL8221B-VB-CG 2.5Gbps PHY", 2334 2319 .config_intr = rtl8221b_config_intr, 2335 2320 .handle_interrupt = rtl8221b_handle_interrupt, 2336 2321 .probe = rtl822x_probe, ··· 2326 2345 .read_status = rtl822xb_c45_read_status, 2327 2346 .suspend = genphy_c45_pma_suspend, 2328 2347 .resume = rtlgen_c45_resume, 2329 - }, { 2330 - .match_phy_device = rtl8221b_vm_cg_c22_match_phy_device, 2331 - .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)", 2332 - .probe = rtl822x_probe, 2333 - .get_features = rtl822x_get_features, 2334 - .config_aneg = rtl822x_config_aneg, 2335 - .config_init = rtl822xb_config_init, 2336 - .inband_caps = rtl822x_inband_caps, 2337 - .config_inband = rtl822x_config_inband, 2338 - .get_rate_matching = rtl822xb_get_rate_matching, 2339 - .read_status = rtl822xb_read_status, 2340 - .suspend = genphy_suspend, 2341 - .resume = rtlgen_resume, 2342 2348 .read_page = rtl821x_read_page, 2343 2349 .write_page = rtl821x_write_page, 2344 2350 .read_mmd = rtl822xb_read_mmd, 2345 2351 .write_mmd = rtl822xb_write_mmd, 2346 2352 }, { 2347 - .match_phy_device = rtl8221b_vm_cg_c45_match_phy_device, 2348 - .name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)", 2353 + .match_phy_device = rtl8221b_vm_cg_match_phy_device, 2354 + .name = "RTL8221B-VM-CG 2.5Gbps PHY", 2349 2355 .config_intr = rtl8221b_config_intr, 2350 2356 .handle_interrupt = rtl8221b_handle_interrupt, 2351 2357 .probe = rtl822x_probe, ··· 2345 2377 .read_status = rtl822xb_c45_read_status, 2346 2378 .suspend = genphy_c45_pma_suspend, 2347 2379 .resume = rtlgen_c45_resume, 2380 + .read_page = rtl821x_read_page, 2381 + .write_page = rtl821x_write_page, 2382 + .read_mmd = rtl822xb_read_mmd, 2383 + .write_mmd = rtl822xb_write_mmd, 2348 2384 }, { 2349 2385 .match_phy_device = rtl8251b_c45_match_phy_device, 2350 2386 .name = "RTL8251B 5Gbps PHY",