1 From 31afd6bc55cc0093c3e5b0a368319e423d4de8ea Mon Sep 17 00:00:00 2001
2 From: Christian Marangi <ansuelsmth@gmail.com>
3 Date: Sat, 17 May 2025 22:13:45 +0200
4 Subject: [PATCH] net: phy: pass PHY driver to .match_phy_device OP
6 Pass PHY driver pointer to .match_phy_device OP in addition to phydev.
7 Having access to the PHY driver struct might be useful to check the
8 PHY ID of the driver is being matched for in case the PHY ID scanned in
9 the phydev is not consistent.
11 A scenario for this is a PHY that change PHY ID after a firmware is
12 loaded, in such case, the PHY ID stored in PHY device struct is not
13 valid anymore and PHY will manually scan the ID in the match_phy_device
16 Having the PHY driver info is also useful for those PHY driver that
17 implement multiple simple .match_phy_device OP to match specific MMD PHY
18 ID. With this extra info if the parsing logic is the same, the matching
19 function can be generalized by using the phy_id in the PHY driver
20 instead of hardcoding.
22 Rust wrapper callback is updated to align to the new match_phy_device
25 Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
26 Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
27 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
28 Reviewed-by: Benno Lossin <lossin@kernel.org> # for Rust
29 Reviewed-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
30 Link: https://patch.msgid.link/20250517201353.5137-2-ansuelsmth@gmail.com
31 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
33 drivers/net/phy/bcm87xx.c | 6 ++++--
34 drivers/net/phy/icplus.c | 6 ++++--
35 drivers/net/phy/marvell10g.c | 12 ++++++++----
36 drivers/net/phy/micrel.c | 6 ++++--
37 drivers/net/phy/nxp-c45-tja11xx.c | 12 ++++++++----
38 drivers/net/phy/nxp-tja11xx.c | 6 ++++--
39 drivers/net/phy/phy_device.c | 2 +-
40 drivers/net/phy/realtek/realtek_main.c | 27 +++++++++++++++++---------
41 drivers/net/phy/teranetics.c | 3 ++-
42 include/linux/phy.h | 3 ++-
43 rust/kernel/net/phy.rs | 1 +
44 11 files changed, 56 insertions(+), 28 deletions(-)
46 --- a/drivers/net/phy/bcm87xx.c
47 +++ b/drivers/net/phy/bcm87xx.c
48 @@ -185,12 +185,14 @@ static irqreturn_t bcm87xx_handle_interr
52 -static int bcm8706_match_phy_device(struct phy_device *phydev)
53 +static int bcm8706_match_phy_device(struct phy_device *phydev,
54 + const struct phy_driver *phydrv)
56 return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8706;
59 -static int bcm8727_match_phy_device(struct phy_device *phydev)
60 +static int bcm8727_match_phy_device(struct phy_device *phydev,
61 + const struct phy_driver *phydrv)
63 return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8727;
65 --- a/drivers/net/phy/icplus.c
66 +++ b/drivers/net/phy/icplus.c
67 @@ -520,12 +520,14 @@ static int ip101a_g_match_phy_device(str
68 return ip101a == !ret;
71 -static int ip101a_match_phy_device(struct phy_device *phydev)
72 +static int ip101a_match_phy_device(struct phy_device *phydev,
73 + const struct phy_driver *phydrv)
75 return ip101a_g_match_phy_device(phydev, true);
78 -static int ip101g_match_phy_device(struct phy_device *phydev)
79 +static int ip101g_match_phy_device(struct phy_device *phydev,
80 + const struct phy_driver *phydrv)
82 return ip101a_g_match_phy_device(phydev, false);
84 --- a/drivers/net/phy/marvell10g.c
85 +++ b/drivers/net/phy/marvell10g.c
86 @@ -1284,7 +1284,8 @@ static int mv3310_get_number_of_ports(st
90 -static int mv3310_match_phy_device(struct phy_device *phydev)
91 +static int mv3310_match_phy_device(struct phy_device *phydev,
92 + const struct phy_driver *phydrv)
94 if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
95 MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310)
96 @@ -1293,7 +1294,8 @@ static int mv3310_match_phy_device(struc
97 return mv3310_get_number_of_ports(phydev) == 1;
100 -static int mv3340_match_phy_device(struct phy_device *phydev)
101 +static int mv3340_match_phy_device(struct phy_device *phydev,
102 + const struct phy_driver *phydrv)
104 if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
105 MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310)
106 @@ -1317,12 +1319,14 @@ static int mv211x_match_phy_device(struc
107 return !!(val & MDIO_PCS_SPEED_5G) == has_5g;
110 -static int mv2110_match_phy_device(struct phy_device *phydev)
111 +static int mv2110_match_phy_device(struct phy_device *phydev,
112 + const struct phy_driver *phydrv)
114 return mv211x_match_phy_device(phydev, true);
117 -static int mv2111_match_phy_device(struct phy_device *phydev)
118 +static int mv2111_match_phy_device(struct phy_device *phydev,
119 + const struct phy_driver *phydrv)
121 return mv211x_match_phy_device(phydev, false);
123 --- a/drivers/net/phy/micrel.c
124 +++ b/drivers/net/phy/micrel.c
125 @@ -768,7 +768,8 @@ static int ksz8051_ksz8795_match_phy_dev
129 -static int ksz8051_match_phy_device(struct phy_device *phydev)
130 +static int ksz8051_match_phy_device(struct phy_device *phydev,
131 + const struct phy_driver *phydrv)
133 return ksz8051_ksz8795_match_phy_device(phydev, true);
135 @@ -888,7 +889,8 @@ static int ksz8061_config_init(struct ph
136 return kszphy_config_init(phydev);
139 -static int ksz8795_match_phy_device(struct phy_device *phydev)
140 +static int ksz8795_match_phy_device(struct phy_device *phydev,
141 + const struct phy_driver *phydrv)
143 return ksz8051_ksz8795_match_phy_device(phydev, false);
145 --- a/drivers/net/phy/nxp-c45-tja11xx.c
146 +++ b/drivers/net/phy/nxp-c45-tja11xx.c
147 @@ -1944,13 +1944,15 @@ static int nxp_c45_macsec_ability(struct
148 return macsec_ability;
151 -static int tja1103_match_phy_device(struct phy_device *phydev)
152 +static int tja1103_match_phy_device(struct phy_device *phydev,
153 + const struct phy_driver *phydrv)
155 return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) &&
156 !nxp_c45_macsec_ability(phydev);
159 -static int tja1104_match_phy_device(struct phy_device *phydev)
160 +static int tja1104_match_phy_device(struct phy_device *phydev,
161 + const struct phy_driver *phydrv)
163 return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) &&
164 nxp_c45_macsec_ability(phydev);
165 --- a/drivers/net/phy/nxp-tja11xx.c
166 +++ b/drivers/net/phy/nxp-tja11xx.c
167 @@ -646,12 +646,14 @@ static int tja1102_match_phy_device(stru
171 -static int tja1102_p0_match_phy_device(struct phy_device *phydev)
172 +static int tja1102_p0_match_phy_device(struct phy_device *phydev,
173 + const struct phy_driver *phydrv)
175 return tja1102_match_phy_device(phydev, true);
178 -static int tja1102_p1_match_phy_device(struct phy_device *phydev)
179 +static int tja1102_p1_match_phy_device(struct phy_device *phydev,
180 + const struct phy_driver *phydrv)
182 return tja1102_match_phy_device(phydev, false);
184 --- a/drivers/net/phy/phy_device.c
185 +++ b/drivers/net/phy/phy_device.c
186 @@ -600,7 +600,7 @@ static int phy_bus_match(struct device *
189 if (phydrv->match_phy_device)
190 - return phydrv->match_phy_device(phydev);
191 + return phydrv->match_phy_device(phydev, phydrv);
193 if (phydev->is_c45) {
194 for (i = 1; i < num_ids; i++) {
195 --- a/drivers/net/phy/realtek/realtek_main.c
196 +++ b/drivers/net/phy/realtek/realtek_main.c
197 @@ -1343,13 +1343,15 @@ static bool rtlgen_supports_mmd(struct p
201 -static int rtlgen_match_phy_device(struct phy_device *phydev)
202 +static int rtlgen_match_phy_device(struct phy_device *phydev,
203 + const struct phy_driver *phydrv)
205 return phydev->phy_id == RTL_GENERIC_PHYID &&
206 !rtlgen_supports_2_5gbps(phydev);
209 -static int rtl8226_match_phy_device(struct phy_device *phydev)
210 +static int rtl8226_match_phy_device(struct phy_device *phydev,
211 + const struct phy_driver *phydrv)
213 return phydev->phy_id == RTL_GENERIC_PHYID &&
214 rtlgen_supports_2_5gbps(phydev) &&
215 @@ -1365,32 +1367,38 @@ static int rtlgen_is_c45_match(struct ph
216 return !is_c45 && (id == phydev->phy_id);
219 -static int rtl8221b_match_phy_device(struct phy_device *phydev)
220 +static int rtl8221b_match_phy_device(struct phy_device *phydev,
221 + const struct phy_driver *phydrv)
223 return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
226 -static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
227 +static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev,
228 + const struct phy_driver *phydrv)
230 return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
233 -static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev)
234 +static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev,
235 + const struct phy_driver *phydrv)
237 return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
240 -static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev)
241 +static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev,
242 + const struct phy_driver *phydrv)
244 return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false);
247 -static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
248 +static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev,
249 + const struct phy_driver *phydrv)
251 return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
254 -static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev)
255 +static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev,
256 + const struct phy_driver *phydrv)
260 @@ -1409,7 +1417,8 @@ static int rtl_internal_nbaset_match_phy
261 return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev);
264 -static int rtl8251b_c45_match_phy_device(struct phy_device *phydev)
265 +static int rtl8251b_c45_match_phy_device(struct phy_device *phydev,
266 + const struct phy_driver *phydrv)
268 return rtlgen_is_c45_match(phydev, RTL_8251B, true);
270 --- a/drivers/net/phy/teranetics.c
271 +++ b/drivers/net/phy/teranetics.c
272 @@ -67,7 +67,8 @@ static int teranetics_read_status(struct
276 -static int teranetics_match_phy_device(struct phy_device *phydev)
277 +static int teranetics_match_phy_device(struct phy_device *phydev,
278 + const struct phy_driver *phydrv)
280 return phydev->c45_ids.device_ids[3] == PHY_ID_TN2020;
282 --- a/include/linux/phy.h
283 +++ b/include/linux/phy.h
284 @@ -1004,7 +1004,8 @@ struct phy_driver {
285 * driver for the given phydev. If NULL, matching is based on
286 * phy_id and phy_id_mask.
288 - int (*match_phy_device)(struct phy_device *phydev);
289 + int (*match_phy_device)(struct phy_device *phydev,
290 + const struct phy_driver *phydrv);
293 * @set_wol: Some devices (e.g. qnap TS-119P II) require PHY
294 --- a/rust/kernel/net/phy.rs
295 +++ b/rust/kernel/net/phy.rs
296 @@ -421,6 +421,7 @@ impl<T: Driver> Adapter<T> {
297 /// `phydev` must be passed by the corresponding callback in `phy_driver`.
298 unsafe extern "C" fn match_phy_device_callback(
299 phydev: *mut bindings::phy_device,
300 + _phydrv: *const bindings::phy_driver,
301 ) -> crate::ffi::c_int {
302 // SAFETY: This callback is called only in contexts
303 // where we hold `phy_device->lock`, so the accessors on