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

net: phy: pass PHY driver to .match_phy_device OP

Pass PHY driver pointer to .match_phy_device OP in addition to phydev.
Having access to the PHY driver struct might be useful to check the
PHY ID of the driver is being matched for in case the PHY ID scanned in
the phydev is not consistent.

A scenario for this is a PHY that change PHY ID after a firmware is
loaded, in such case, the PHY ID stored in PHY device struct is not
valid anymore and PHY will manually scan the ID in the match_phy_device
function.

Having the PHY driver info is also useful for those PHY driver that
implement multiple simple .match_phy_device OP to match specific MMD PHY
ID. With this extra info if the parsing logic is the same, the matching
function can be generalized by using the phy_id in the PHY driver
instead of hardcoding.

Rust wrapper callback is updated to align to the new match_phy_device
arguments.

Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Benno Lossin <lossin@kernel.org> # for Rust
Reviewed-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Link: https://patch.msgid.link/20250517201353.5137-2-ansuelsmth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Christian Marangi and committed by
Jakub Kicinski
31afd6bc d42d4407

+56 -28
+4 -2
drivers/net/phy/bcm87xx.c
··· 185 185 return IRQ_HANDLED; 186 186 } 187 187 188 - static int bcm8706_match_phy_device(struct phy_device *phydev) 188 + static int bcm8706_match_phy_device(struct phy_device *phydev, 189 + const struct phy_driver *phydrv) 189 190 { 190 191 return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8706; 191 192 } 192 193 193 - static int bcm8727_match_phy_device(struct phy_device *phydev) 194 + static int bcm8727_match_phy_device(struct phy_device *phydev, 195 + const struct phy_driver *phydrv) 194 196 { 195 197 return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8727; 196 198 }
+4 -2
drivers/net/phy/icplus.c
··· 520 520 return ip101a == !ret; 521 521 } 522 522 523 - static int ip101a_match_phy_device(struct phy_device *phydev) 523 + static int ip101a_match_phy_device(struct phy_device *phydev, 524 + const struct phy_driver *phydrv) 524 525 { 525 526 return ip101a_g_match_phy_device(phydev, true); 526 527 } 527 528 528 - static int ip101g_match_phy_device(struct phy_device *phydev) 529 + static int ip101g_match_phy_device(struct phy_device *phydev, 530 + const struct phy_driver *phydrv) 529 531 { 530 532 return ip101a_g_match_phy_device(phydev, false); 531 533 }
+8 -4
drivers/net/phy/marvell10g.c
··· 1264 1264 return ret + 1; 1265 1265 } 1266 1266 1267 - static int mv3310_match_phy_device(struct phy_device *phydev) 1267 + static int mv3310_match_phy_device(struct phy_device *phydev, 1268 + const struct phy_driver *phydrv) 1268 1269 { 1269 1270 if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & 1270 1271 MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310) ··· 1274 1273 return mv3310_get_number_of_ports(phydev) == 1; 1275 1274 } 1276 1275 1277 - static int mv3340_match_phy_device(struct phy_device *phydev) 1276 + static int mv3340_match_phy_device(struct phy_device *phydev, 1277 + const struct phy_driver *phydrv) 1278 1278 { 1279 1279 if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & 1280 1280 MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310) ··· 1299 1297 return !!(val & MDIO_PCS_SPEED_5G) == has_5g; 1300 1298 } 1301 1299 1302 - static int mv2110_match_phy_device(struct phy_device *phydev) 1300 + static int mv2110_match_phy_device(struct phy_device *phydev, 1301 + const struct phy_driver *phydrv) 1303 1302 { 1304 1303 return mv211x_match_phy_device(phydev, true); 1305 1304 } 1306 1305 1307 - static int mv2111_match_phy_device(struct phy_device *phydev) 1306 + static int mv2111_match_phy_device(struct phy_device *phydev, 1307 + const struct phy_driver *phydrv) 1308 1308 { 1309 1309 return mv211x_match_phy_device(phydev, false); 1310 1310 }
+4 -2
drivers/net/phy/micrel.c
··· 768 768 return !ret; 769 769 } 770 770 771 - static int ksz8051_match_phy_device(struct phy_device *phydev) 771 + static int ksz8051_match_phy_device(struct phy_device *phydev, 772 + const struct phy_driver *phydrv) 772 773 { 773 774 return ksz8051_ksz8795_match_phy_device(phydev, true); 774 775 } ··· 889 888 return kszphy_config_init(phydev); 890 889 } 891 890 892 - static int ksz8795_match_phy_device(struct phy_device *phydev) 891 + static int ksz8795_match_phy_device(struct phy_device *phydev, 892 + const struct phy_driver *phydrv) 893 893 { 894 894 return ksz8051_ksz8795_match_phy_device(phydev, false); 895 895 }
+8 -4
drivers/net/phy/nxp-c45-tja11xx.c
··· 1966 1966 return macsec_ability; 1967 1967 } 1968 1968 1969 - static int tja1103_match_phy_device(struct phy_device *phydev) 1969 + static int tja1103_match_phy_device(struct phy_device *phydev, 1970 + const struct phy_driver *phydrv) 1970 1971 { 1971 1972 return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) && 1972 1973 !nxp_c45_macsec_ability(phydev); 1973 1974 } 1974 1975 1975 - static int tja1104_match_phy_device(struct phy_device *phydev) 1976 + static int tja1104_match_phy_device(struct phy_device *phydev, 1977 + const struct phy_driver *phydrv) 1976 1978 { 1977 1979 return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) && 1978 1980 nxp_c45_macsec_ability(phydev); 1979 1981 } 1980 1982 1981 - static int tja1120_match_phy_device(struct phy_device *phydev) 1983 + static int tja1120_match_phy_device(struct phy_device *phydev, 1984 + const struct phy_driver *phydrv) 1982 1985 { 1983 1986 return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1120, PHY_ID_MASK) && 1984 1987 !nxp_c45_macsec_ability(phydev); 1985 1988 } 1986 1989 1987 - static int tja1121_match_phy_device(struct phy_device *phydev) 1990 + static int tja1121_match_phy_device(struct phy_device *phydev, 1991 + const struct phy_driver *phydrv) 1988 1992 { 1989 1993 return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1120, PHY_ID_MASK) && 1990 1994 nxp_c45_macsec_ability(phydev);
+4 -2
drivers/net/phy/nxp-tja11xx.c
··· 651 651 return !ret; 652 652 } 653 653 654 - static int tja1102_p0_match_phy_device(struct phy_device *phydev) 654 + static int tja1102_p0_match_phy_device(struct phy_device *phydev, 655 + const struct phy_driver *phydrv) 655 656 { 656 657 return tja1102_match_phy_device(phydev, true); 657 658 } 658 659 659 - static int tja1102_p1_match_phy_device(struct phy_device *phydev) 660 + static int tja1102_p1_match_phy_device(struct phy_device *phydev, 661 + const struct phy_driver *phydrv) 660 662 { 661 663 return tja1102_match_phy_device(phydev, false); 662 664 }
+1 -1
drivers/net/phy/phy_device.c
··· 554 554 return 0; 555 555 556 556 if (phydrv->match_phy_device) 557 - return phydrv->match_phy_device(phydev); 557 + return phydrv->match_phy_device(phydev, phydrv); 558 558 559 559 if (phydev->is_c45) { 560 560 for (i = 1; i < num_ids; i++) {
+18 -9
drivers/net/phy/realtek/realtek_main.c
··· 1315 1315 return val > 0; 1316 1316 } 1317 1317 1318 - static int rtlgen_match_phy_device(struct phy_device *phydev) 1318 + static int rtlgen_match_phy_device(struct phy_device *phydev, 1319 + const struct phy_driver *phydrv) 1319 1320 { 1320 1321 return phydev->phy_id == RTL_GENERIC_PHYID && 1321 1322 !rtlgen_supports_2_5gbps(phydev); 1322 1323 } 1323 1324 1324 - static int rtl8226_match_phy_device(struct phy_device *phydev) 1325 + static int rtl8226_match_phy_device(struct phy_device *phydev, 1326 + const struct phy_driver *phydrv) 1325 1327 { 1326 1328 return phydev->phy_id == RTL_GENERIC_PHYID && 1327 1329 rtlgen_supports_2_5gbps(phydev) && ··· 1339 1337 return !is_c45 && (id == phydev->phy_id); 1340 1338 } 1341 1339 1342 - static int rtl8221b_match_phy_device(struct phy_device *phydev) 1340 + static int rtl8221b_match_phy_device(struct phy_device *phydev, 1341 + const struct phy_driver *phydrv) 1343 1342 { 1344 1343 return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev); 1345 1344 } 1346 1345 1347 - static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev) 1346 + static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev, 1347 + const struct phy_driver *phydrv) 1348 1348 { 1349 1349 return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false); 1350 1350 } 1351 1351 1352 - static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev) 1352 + static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev, 1353 + const struct phy_driver *phydrv) 1353 1354 { 1354 1355 return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true); 1355 1356 } 1356 1357 1357 - static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev) 1358 + static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev, 1359 + const struct phy_driver *phydrv) 1358 1360 { 1359 1361 return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false); 1360 1362 } 1361 1363 1362 - static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev) 1364 + static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev, 1365 + const struct phy_driver *phydrv) 1363 1366 { 1364 1367 return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true); 1365 1368 } 1366 1369 1367 - static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev) 1370 + static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev, 1371 + const struct phy_driver *phydrv) 1368 1372 { 1369 1373 if (phydev->is_c45) 1370 1374 return false; ··· 1389 1381 return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev); 1390 1382 } 1391 1383 1392 - static int rtl8251b_c45_match_phy_device(struct phy_device *phydev) 1384 + static int rtl8251b_c45_match_phy_device(struct phy_device *phydev, 1385 + const struct phy_driver *phydrv) 1393 1386 { 1394 1387 return rtlgen_is_c45_match(phydev, RTL_8251B, true); 1395 1388 }
+2 -1
drivers/net/phy/teranetics.c
··· 67 67 return 0; 68 68 } 69 69 70 - static int teranetics_match_phy_device(struct phy_device *phydev) 70 + static int teranetics_match_phy_device(struct phy_device *phydev, 71 + const struct phy_driver *phydrv) 71 72 { 72 73 return phydev->c45_ids.device_ids[3] == PHY_ID_TN2020; 73 74 }
+2 -1
include/linux/phy.h
··· 990 990 * driver for the given phydev. If NULL, matching is based on 991 991 * phy_id and phy_id_mask. 992 992 */ 993 - int (*match_phy_device)(struct phy_device *phydev); 993 + int (*match_phy_device)(struct phy_device *phydev, 994 + const struct phy_driver *phydrv); 994 995 995 996 /** 996 997 * @set_wol: Some devices (e.g. qnap TS-119P II) require PHY
+1
rust/kernel/net/phy.rs
··· 421 421 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 422 422 unsafe extern "C" fn match_phy_device_callback( 423 423 phydev: *mut bindings::phy_device, 424 + _phydrv: *const bindings::phy_driver, 424 425 ) -> crate::ffi::c_int { 425 426 // SAFETY: This callback is called only in contexts 426 427 // where we hold `phy_device->lock`, so the accessors on