1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Core PHY library, taken from phy.c
4 */
5#include <linux/export.h>
6#include <linux/phy.h>
7#include <linux/of.h>
8
9#include "phylib.h"
10#include "phylib-internal.h"
11#include "phy-caps.h"
12
13/**
14 * phy_speed_to_str - Return a string representing the PHY link speed
15 *
16 * @speed: Speed of the link
17 */
18const char *phy_speed_to_str(int speed)
19{
20 BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS != 121,
21 "Enum ethtool_link_mode_bit_indices and phylib are out of sync. "
22 "If a speed or mode has been added please update phy_speed_to_str "
23 "and the PHY settings array.\n");
24
25 switch (speed) {
26 case SPEED_10:
27 return "10Mbps";
28 case SPEED_100:
29 return "100Mbps";
30 case SPEED_1000:
31 return "1Gbps";
32 case SPEED_2500:
33 return "2.5Gbps";
34 case SPEED_5000:
35 return "5Gbps";
36 case SPEED_10000:
37 return "10Gbps";
38 case SPEED_14000:
39 return "14Gbps";
40 case SPEED_20000:
41 return "20Gbps";
42 case SPEED_25000:
43 return "25Gbps";
44 case SPEED_40000:
45 return "40Gbps";
46 case SPEED_50000:
47 return "50Gbps";
48 case SPEED_56000:
49 return "56Gbps";
50 case SPEED_100000:
51 return "100Gbps";
52 case SPEED_200000:
53 return "200Gbps";
54 case SPEED_400000:
55 return "400Gbps";
56 case SPEED_800000:
57 return "800Gbps";
58 case SPEED_UNKNOWN:
59 return "Unknown";
60 default:
61 return "Unsupported (update phy-core.c)";
62 }
63}
64EXPORT_SYMBOL_GPL(phy_speed_to_str);
65
66/**
67 * phy_duplex_to_str - Return string describing the duplex
68 *
69 * @duplex: Duplex setting to describe
70 */
71const char *phy_duplex_to_str(unsigned int duplex)
72{
73 if (duplex == DUPLEX_HALF)
74 return "Half";
75 if (duplex == DUPLEX_FULL)
76 return "Full";
77 if (duplex == DUPLEX_UNKNOWN)
78 return "Unknown";
79 return "Unsupported (update phy-core.c)";
80}
81EXPORT_SYMBOL_GPL(phy_duplex_to_str);
82
83/**
84 * phy_rate_matching_to_str - Return a string describing the rate matching
85 *
86 * @rate_matching: Type of rate matching to describe
87 */
88const char *phy_rate_matching_to_str(int rate_matching)
89{
90 switch (rate_matching) {
91 case RATE_MATCH_NONE:
92 return "none";
93 case RATE_MATCH_PAUSE:
94 return "pause";
95 case RATE_MATCH_CRS:
96 return "crs";
97 case RATE_MATCH_OPEN_LOOP:
98 return "open-loop";
99 }
100 return "Unsupported (update phy-core.c)";
101}
102EXPORT_SYMBOL_GPL(phy_rate_matching_to_str);
103
104/**
105 * phy_interface_num_ports - Return the number of links that can be carried by
106 * a given MAC-PHY physical link. Returns 0 if this is
107 * unknown, the number of links else.
108 *
109 * @interface: The interface mode we want to get the number of ports
110 */
111int phy_interface_num_ports(phy_interface_t interface)
112{
113 switch (interface) {
114 case PHY_INTERFACE_MODE_NA:
115 return 0;
116 case PHY_INTERFACE_MODE_INTERNAL:
117 case PHY_INTERFACE_MODE_MII:
118 case PHY_INTERFACE_MODE_MIILITE:
119 case PHY_INTERFACE_MODE_GMII:
120 case PHY_INTERFACE_MODE_TBI:
121 case PHY_INTERFACE_MODE_REVMII:
122 case PHY_INTERFACE_MODE_RMII:
123 case PHY_INTERFACE_MODE_REVRMII:
124 case PHY_INTERFACE_MODE_RGMII:
125 case PHY_INTERFACE_MODE_RGMII_ID:
126 case PHY_INTERFACE_MODE_RGMII_RXID:
127 case PHY_INTERFACE_MODE_RGMII_TXID:
128 case PHY_INTERFACE_MODE_RTBI:
129 case PHY_INTERFACE_MODE_XGMII:
130 case PHY_INTERFACE_MODE_XLGMII:
131 case PHY_INTERFACE_MODE_MOCA:
132 case PHY_INTERFACE_MODE_TRGMII:
133 case PHY_INTERFACE_MODE_USXGMII:
134 case PHY_INTERFACE_MODE_SGMII:
135 case PHY_INTERFACE_MODE_SMII:
136 case PHY_INTERFACE_MODE_1000BASEX:
137 case PHY_INTERFACE_MODE_2500BASEX:
138 case PHY_INTERFACE_MODE_5GBASER:
139 case PHY_INTERFACE_MODE_10GBASER:
140 case PHY_INTERFACE_MODE_25GBASER:
141 case PHY_INTERFACE_MODE_10GKR:
142 case PHY_INTERFACE_MODE_100BASEX:
143 case PHY_INTERFACE_MODE_RXAUI:
144 case PHY_INTERFACE_MODE_XAUI:
145 case PHY_INTERFACE_MODE_1000BASEKX:
146 case PHY_INTERFACE_MODE_50GBASER:
147 case PHY_INTERFACE_MODE_LAUI:
148 case PHY_INTERFACE_MODE_100GBASEP:
149 return 1;
150 case PHY_INTERFACE_MODE_QSGMII:
151 case PHY_INTERFACE_MODE_QUSGMII:
152 case PHY_INTERFACE_MODE_10G_QXGMII:
153 return 4;
154 case PHY_INTERFACE_MODE_PSGMII:
155 return 5;
156 case PHY_INTERFACE_MODE_MAX:
157 WARN_ONCE(1, "PHY_INTERFACE_MODE_MAX isn't a valid interface mode");
158 return 0;
159 }
160 return 0;
161}
162EXPORT_SYMBOL_GPL(phy_interface_num_ports);
163
164static void __set_phy_supported(struct phy_device *phydev, u32 max_speed)
165{
166 phy_caps_linkmode_max_speed(max_speed, linkmodes: phydev->supported);
167}
168
169/**
170 * phy_set_max_speed - Set the maximum speed the PHY should support
171 *
172 * @phydev: The phy_device struct
173 * @max_speed: Maximum speed
174 *
175 * The PHY might be more capable than the MAC. For example a Fast Ethernet
176 * is connected to a 1G PHY. This function allows the MAC to indicate its
177 * maximum speed, and so limit what the PHY will advertise.
178 */
179void phy_set_max_speed(struct phy_device *phydev, u32 max_speed)
180{
181 __set_phy_supported(phydev, max_speed);
182
183 phy_advertise_supported(phydev);
184}
185EXPORT_SYMBOL(phy_set_max_speed);
186
187void of_set_phy_supported(struct phy_device *phydev)
188{
189 struct device_node *node = phydev->mdio.dev.of_node;
190 u32 max_speed;
191
192 if (!IS_ENABLED(CONFIG_OF_MDIO))
193 return;
194
195 if (!node)
196 return;
197
198 if (!of_property_read_u32(np: node, propname: "max-speed", out_value: &max_speed))
199 __set_phy_supported(phydev, max_speed);
200}
201
202void of_set_phy_eee_broken(struct phy_device *phydev)
203{
204 struct device_node *node = phydev->mdio.dev.of_node;
205 unsigned long *modes = phydev->eee_disabled_modes;
206
207 if (!IS_ENABLED(CONFIG_OF_MDIO) || !node)
208 return;
209
210 linkmode_zero(dst: modes);
211
212 if (of_property_read_bool(np: node, propname: "eee-broken-100tx"))
213 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, modes);
214 if (of_property_read_bool(np: node, propname: "eee-broken-1000t"))
215 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, modes);
216 if (of_property_read_bool(np: node, propname: "eee-broken-10gt"))
217 linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, modes);
218 if (of_property_read_bool(np: node, propname: "eee-broken-1000kx"))
219 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, modes);
220 if (of_property_read_bool(np: node, propname: "eee-broken-10gkx4"))
221 linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, modes);
222 if (of_property_read_bool(np: node, propname: "eee-broken-10gkr"))
223 linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, modes);
224}
225
226/**
227 * of_set_phy_timing_role - Set the master/slave mode of the PHY
228 *
229 * @phydev: The phy_device struct
230 *
231 * Set master/slave configuration of the PHY based on the device tree.
232 */
233void of_set_phy_timing_role(struct phy_device *phydev)
234{
235 struct device_node *node = phydev->mdio.dev.of_node;
236 const char *master;
237
238 if (!IS_ENABLED(CONFIG_OF_MDIO))
239 return;
240
241 if (!node)
242 return;
243
244 if (of_property_read_string(np: node, propname: "timing-role", out_string: &master))
245 return;
246
247 if (strcmp(master, "forced-master") == 0)
248 phydev->master_slave_set = MASTER_SLAVE_CFG_MASTER_FORCE;
249 else if (strcmp(master, "forced-slave") == 0)
250 phydev->master_slave_set = MASTER_SLAVE_CFG_SLAVE_FORCE;
251 else if (strcmp(master, "preferred-master") == 0)
252 phydev->master_slave_set = MASTER_SLAVE_CFG_MASTER_PREFERRED;
253 else if (strcmp(master, "preferred-slave") == 0)
254 phydev->master_slave_set = MASTER_SLAVE_CFG_SLAVE_PREFERRED;
255 else
256 phydev_warn(phydev, "Unknown master-slave mode %s\n", master);
257}
258
259/**
260 * phy_resolve_aneg_pause - Determine pause autoneg results
261 *
262 * @phydev: The phy_device struct
263 *
264 * Once autoneg has completed the local pause settings can be
265 * resolved. Determine if pause and asymmetric pause should be used
266 * by the MAC.
267 */
268
269void phy_resolve_aneg_pause(struct phy_device *phydev)
270{
271 if (phydev->duplex == DUPLEX_FULL) {
272 phydev->pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
273 phydev->lp_advertising);
274 phydev->asym_pause = linkmode_test_bit(
275 ETHTOOL_LINK_MODE_Asym_Pause_BIT,
276 phydev->lp_advertising);
277 }
278}
279EXPORT_SYMBOL_GPL(phy_resolve_aneg_pause);
280
281/**
282 * phy_resolve_aneg_linkmode - resolve the advertisements into PHY settings
283 * @phydev: The phy_device struct
284 *
285 * Resolve our and the link partner advertisements into their corresponding
286 * speed and duplex. If full duplex was negotiated, extract the pause mode
287 * from the link partner mask.
288 */
289void phy_resolve_aneg_linkmode(struct phy_device *phydev)
290{
291 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
292 const struct link_capabilities *c;
293
294 linkmode_and(dst: common, a: phydev->lp_advertising, b: phydev->advertising);
295
296 c = phy_caps_lookup_by_linkmode(linkmodes: common);
297 if (c) {
298 phydev->speed = c->speed;
299 phydev->duplex = c->duplex;
300 }
301
302 phy_resolve_aneg_pause(phydev);
303}
304EXPORT_SYMBOL_GPL(phy_resolve_aneg_linkmode);
305
306/**
307 * phy_check_downshift - check whether downshift occurred
308 * @phydev: The phy_device struct
309 *
310 * Check whether a downshift to a lower speed occurred. If this should be the
311 * case warn the user.
312 * Prerequisite for detecting downshift is that PHY driver implements the
313 * read_status callback and sets phydev->speed to the actual link speed.
314 */
315void phy_check_downshift(struct phy_device *phydev)
316{
317 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
318 const struct link_capabilities *c;
319 int speed = SPEED_UNKNOWN;
320
321 phydev->downshifted_rate = 0;
322
323 if (phydev->autoneg == AUTONEG_DISABLE ||
324 phydev->speed == SPEED_UNKNOWN)
325 return;
326
327 linkmode_and(dst: common, a: phydev->lp_advertising, b: phydev->advertising);
328
329 c = phy_caps_lookup_by_linkmode(linkmodes: common);
330 if (c)
331 speed = c->speed;
332
333 if (speed == SPEED_UNKNOWN || phydev->speed >= speed)
334 return;
335
336 phydev_warn(phydev, "Downshift occurred from negotiated speed %s to actual speed %s, check cabling!\n",
337 phy_speed_to_str(speed), phy_speed_to_str(phydev->speed));
338
339 phydev->downshifted_rate = 1;
340}
341
342static int phy_resolve_min_speed(struct phy_device *phydev, bool fdx_only)
343{
344 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
345 const struct link_capabilities *c;
346
347 linkmode_and(dst: common, a: phydev->lp_advertising, b: phydev->advertising);
348
349 c = phy_caps_lookup_by_linkmode_rev(linkmodes: common, fdx_only);
350 if (c)
351 return c->speed;
352
353 return SPEED_UNKNOWN;
354}
355
356int phy_speed_down_core(struct phy_device *phydev)
357{
358 int min_common_speed = phy_resolve_min_speed(phydev, fdx_only: true);
359
360 if (min_common_speed == SPEED_UNKNOWN)
361 return -EINVAL;
362
363 phy_caps_linkmode_max_speed(max_speed: min_common_speed, linkmodes: phydev->advertising);
364
365 return 0;
366}
367
368static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
369 u16 regnum)
370{
371 /* Write the desired MMD Devad */
372 __mdiobus_write(bus, addr: phy_addr, MII_MMD_CTRL, val: devad);
373
374 /* Write the desired MMD register address */
375 __mdiobus_write(bus, addr: phy_addr, MII_MMD_DATA, val: regnum);
376
377 /* Select the Function : DATA with no post increment */
378 __mdiobus_write(bus, addr: phy_addr, MII_MMD_CTRL,
379 val: devad | MII_MMD_CTRL_NOINCR);
380}
381
382int mmd_phy_read(struct mii_bus *bus, int phy_addr, bool is_c45,
383 int devad, u32 regnum)
384{
385 if (is_c45)
386 return __mdiobus_c45_read(bus, addr: phy_addr, devad, regnum);
387
388 mmd_phy_indirect(bus, phy_addr, devad, regnum);
389 /* Read the content of the MMD's selected register */
390 return __mdiobus_read(bus, addr: phy_addr, MII_MMD_DATA);
391}
392EXPORT_SYMBOL_GPL(mmd_phy_read);
393
394int mmd_phy_write(struct mii_bus *bus, int phy_addr, bool is_c45,
395 int devad, u32 regnum, u16 val)
396{
397 if (is_c45)
398 return __mdiobus_c45_write(bus, addr: phy_addr, devad, regnum, val);
399
400 mmd_phy_indirect(bus, phy_addr, devad, regnum);
401 /* Write the data into MMD's selected register */
402 return __mdiobus_write(bus, addr: phy_addr, MII_MMD_DATA, val);
403}
404EXPORT_SYMBOL_GPL(mmd_phy_write);
405
406/**
407 * __phy_read_mmd - Convenience function for reading a register
408 * from an MMD on a given PHY.
409 * @phydev: The phy_device struct
410 * @devad: The MMD to read from (0..31)
411 * @regnum: The register on the MMD to read (0..65535)
412 *
413 * Same rules as for __phy_read();
414 */
415int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
416{
417 if (regnum > (u16)~0 || devad > 32)
418 return -EINVAL;
419
420 if (phydev->drv && phydev->drv->read_mmd)
421 return phydev->drv->read_mmd(phydev, devad, regnum);
422
423 return mmd_phy_read(phydev->mdio.bus, phydev->mdio.addr,
424 phydev->is_c45, devad, regnum);
425}
426EXPORT_SYMBOL(__phy_read_mmd);
427
428/**
429 * phy_read_mmd - Convenience function for reading a register
430 * from an MMD on a given PHY.
431 * @phydev: The phy_device struct
432 * @devad: The MMD to read from
433 * @regnum: The register on the MMD to read
434 *
435 * Same rules as for phy_read();
436 */
437int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
438{
439 int ret;
440
441 phy_lock_mdio_bus(phydev);
442 ret = __phy_read_mmd(phydev, devad, regnum);
443 phy_unlock_mdio_bus(phydev);
444
445 return ret;
446}
447EXPORT_SYMBOL(phy_read_mmd);
448
449/**
450 * __phy_write_mmd - Convenience function for writing a register
451 * on an MMD on a given PHY.
452 * @phydev: The phy_device struct
453 * @devad: The MMD to read from
454 * @regnum: The register on the MMD to read
455 * @val: value to write to @regnum
456 *
457 * Same rules as for __phy_write();
458 */
459int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
460{
461 if (regnum > (u16)~0 || devad > 32)
462 return -EINVAL;
463
464 if (phydev->drv && phydev->drv->write_mmd)
465 return phydev->drv->write_mmd(phydev, devad, regnum, val);
466
467 return mmd_phy_write(phydev->mdio.bus, phydev->mdio.addr,
468 phydev->is_c45, devad, regnum, val);
469}
470EXPORT_SYMBOL(__phy_write_mmd);
471
472/**
473 * phy_write_mmd - Convenience function for writing a register
474 * on an MMD on a given PHY.
475 * @phydev: The phy_device struct
476 * @devad: The MMD to read from
477 * @regnum: The register on the MMD to read
478 * @val: value to write to @regnum
479 *
480 * Same rules as for phy_write();
481 */
482int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
483{
484 int ret;
485
486 phy_lock_mdio_bus(phydev);
487 ret = __phy_write_mmd(phydev, devad, regnum, val);
488 phy_unlock_mdio_bus(phydev);
489
490 return ret;
491}
492EXPORT_SYMBOL(phy_write_mmd);
493
494/**
495 * phy_modify_changed - Function for modifying a PHY register
496 * @phydev: the phy_device struct
497 * @regnum: register number to modify
498 * @mask: bit mask of bits to clear
499 * @set: new value of bits set in mask to write to @regnum
500 *
501 * NOTE: MUST NOT be called from interrupt context,
502 * because the bus read/write functions may wait for an interrupt
503 * to conclude the operation.
504 *
505 * Returns negative errno, 0 if there was no change, and 1 in case of change
506 */
507int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
508{
509 int ret;
510
511 phy_lock_mdio_bus(phydev);
512 ret = __phy_modify_changed(phydev, regnum, mask, set);
513 phy_unlock_mdio_bus(phydev);
514
515 return ret;
516}
517EXPORT_SYMBOL_GPL(phy_modify_changed);
518
519/**
520 * __phy_modify - Convenience function for modifying a PHY register
521 * @phydev: the phy_device struct
522 * @regnum: register number to modify
523 * @mask: bit mask of bits to clear
524 * @set: new value of bits set in mask to write to @regnum
525 *
526 * NOTE: MUST NOT be called from interrupt context,
527 * because the bus read/write functions may wait for an interrupt
528 * to conclude the operation.
529 */
530int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
531{
532 int ret;
533
534 ret = __phy_modify_changed(phydev, regnum, mask, set);
535
536 return ret < 0 ? ret : 0;
537}
538EXPORT_SYMBOL_GPL(__phy_modify);
539
540/**
541 * phy_modify - Convenience function for modifying a given PHY register
542 * @phydev: the phy_device struct
543 * @regnum: register number to write
544 * @mask: bit mask of bits to clear
545 * @set: new value of bits set in mask to write to @regnum
546 *
547 * NOTE: MUST NOT be called from interrupt context,
548 * because the bus read/write functions may wait for an interrupt
549 * to conclude the operation.
550 */
551int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
552{
553 int ret;
554
555 phy_lock_mdio_bus(phydev);
556 ret = __phy_modify(phydev, regnum, mask, set);
557 phy_unlock_mdio_bus(phydev);
558
559 return ret;
560}
561EXPORT_SYMBOL_GPL(phy_modify);
562
563/**
564 * __phy_modify_mmd_changed - Function for modifying a register on MMD
565 * @phydev: the phy_device struct
566 * @devad: the MMD containing register to modify
567 * @regnum: register number to modify
568 * @mask: bit mask of bits to clear
569 * @set: new value of bits set in mask to write to @regnum
570 *
571 * Unlocked helper function which allows a MMD register to be modified as
572 * new register value = (old register value & ~mask) | set
573 *
574 * Returns negative errno, 0 if there was no change, and 1 in case of change
575 */
576int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
577 u16 mask, u16 set)
578{
579 int new, ret;
580
581 ret = __phy_read_mmd(phydev, devad, regnum);
582 if (ret < 0)
583 return ret;
584
585 new = (ret & ~mask) | set;
586 if (new == ret)
587 return 0;
588
589 ret = __phy_write_mmd(phydev, devad, regnum, new);
590
591 return ret < 0 ? ret : 1;
592}
593EXPORT_SYMBOL_GPL(__phy_modify_mmd_changed);
594
595/**
596 * phy_modify_mmd_changed - Function for modifying a register on MMD
597 * @phydev: the phy_device struct
598 * @devad: the MMD containing register to modify
599 * @regnum: register number to modify
600 * @mask: bit mask of bits to clear
601 * @set: new value of bits set in mask to write to @regnum
602 *
603 * NOTE: MUST NOT be called from interrupt context,
604 * because the bus read/write functions may wait for an interrupt
605 * to conclude the operation.
606 *
607 * Returns negative errno, 0 if there was no change, and 1 in case of change
608 */
609int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
610 u16 mask, u16 set)
611{
612 int ret;
613
614 phy_lock_mdio_bus(phydev);
615 ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
616 phy_unlock_mdio_bus(phydev);
617
618 return ret;
619}
620EXPORT_SYMBOL_GPL(phy_modify_mmd_changed);
621
622/**
623 * __phy_modify_mmd - Convenience function for modifying a register on MMD
624 * @phydev: the phy_device struct
625 * @devad: the MMD containing register to modify
626 * @regnum: register number to modify
627 * @mask: bit mask of bits to clear
628 * @set: new value of bits set in mask to write to @regnum
629 *
630 * NOTE: MUST NOT be called from interrupt context,
631 * because the bus read/write functions may wait for an interrupt
632 * to conclude the operation.
633 */
634int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
635 u16 mask, u16 set)
636{
637 int ret;
638
639 ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
640
641 return ret < 0 ? ret : 0;
642}
643EXPORT_SYMBOL_GPL(__phy_modify_mmd);
644
645/**
646 * phy_modify_mmd - Convenience function for modifying a register on MMD
647 * @phydev: the phy_device struct
648 * @devad: the MMD containing register to modify
649 * @regnum: register number to modify
650 * @mask: bit mask of bits to clear
651 * @set: new value of bits set in mask to write to @regnum
652 *
653 * NOTE: MUST NOT be called from interrupt context,
654 * because the bus read/write functions may wait for an interrupt
655 * to conclude the operation.
656 */
657int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
658 u16 mask, u16 set)
659{
660 int ret;
661
662 phy_lock_mdio_bus(phydev);
663 ret = __phy_modify_mmd(phydev, devad, regnum, mask, set);
664 phy_unlock_mdio_bus(phydev);
665
666 return ret;
667}
668EXPORT_SYMBOL_GPL(phy_modify_mmd);
669
670static int __phy_read_page(struct phy_device *phydev)
671{
672 if (WARN_ONCE(!phydev->drv->read_page, "read_page callback not available, PHY driver not loaded?\n"))
673 return -EOPNOTSUPP;
674
675 return phydev->drv->read_page(phydev);
676}
677
678static int __phy_write_page(struct phy_device *phydev, int page)
679{
680 if (WARN_ONCE(!phydev->drv->write_page, "write_page callback not available, PHY driver not loaded?\n"))
681 return -EOPNOTSUPP;
682
683 return phydev->drv->write_page(phydev, page);
684}
685
686/**
687 * phy_save_page() - take the bus lock and save the current page
688 * @phydev: a pointer to a &struct phy_device
689 *
690 * Take the MDIO bus lock, and return the current page number. On error,
691 * returns a negative errno. phy_restore_page() must always be called
692 * after this, irrespective of success or failure of this call.
693 */
694int phy_save_page(struct phy_device *phydev)
695{
696 phy_lock_mdio_bus(phydev);
697 return __phy_read_page(phydev);
698}
699EXPORT_SYMBOL_GPL(phy_save_page);
700
701/**
702 * phy_select_page() - take the bus lock, save the current page, and set a page
703 * @phydev: a pointer to a &struct phy_device
704 * @page: desired page
705 *
706 * Take the MDIO bus lock to protect against concurrent access, save the
707 * current PHY page, and set the current page. On error, returns a
708 * negative errno, otherwise returns the previous page number.
709 * phy_restore_page() must always be called after this, irrespective
710 * of success or failure of this call.
711 */
712int phy_select_page(struct phy_device *phydev, int page)
713{
714 int ret, oldpage;
715
716 oldpage = ret = phy_save_page(phydev);
717 if (ret < 0)
718 return ret;
719
720 if (oldpage != page) {
721 ret = __phy_write_page(phydev, page);
722 if (ret < 0)
723 return ret;
724 }
725
726 return oldpage;
727}
728EXPORT_SYMBOL_GPL(phy_select_page);
729
730/**
731 * phy_restore_page() - restore the page register and release the bus lock
732 * @phydev: a pointer to a &struct phy_device
733 * @oldpage: the old page, return value from phy_save_page() or phy_select_page()
734 * @ret: operation's return code
735 *
736 * Release the MDIO bus lock, restoring @oldpage if it is a valid page.
737 * This function propagates the earliest error code from the group of
738 * operations.
739 *
740 * Returns:
741 * @oldpage if it was a negative value, otherwise
742 * @ret if it was a negative errno value, otherwise
743 * phy_write_page()'s negative value if it were in error, otherwise
744 * @ret.
745 */
746int phy_restore_page(struct phy_device *phydev, int oldpage, int ret)
747{
748 int r;
749
750 if (oldpage >= 0) {
751 r = __phy_write_page(phydev, page: oldpage);
752
753 /* Propagate the operation return code if the page write
754 * was successful.
755 */
756 if (ret >= 0 && r < 0)
757 ret = r;
758 } else {
759 /* Propagate the phy page selection error code */
760 ret = oldpage;
761 }
762
763 phy_unlock_mdio_bus(phydev);
764
765 return ret;
766}
767EXPORT_SYMBOL_GPL(phy_restore_page);
768
769/**
770 * phy_read_paged() - Convenience function for reading a paged register
771 * @phydev: a pointer to a &struct phy_device
772 * @page: the page for the phy
773 * @regnum: register number
774 *
775 * Same rules as for phy_read().
776 */
777int phy_read_paged(struct phy_device *phydev, int page, u32 regnum)
778{
779 int ret = 0, oldpage;
780
781 oldpage = phy_select_page(phydev, page);
782 if (oldpage >= 0)
783 ret = __phy_read(phydev, regnum);
784
785 return phy_restore_page(phydev, oldpage, ret);
786}
787EXPORT_SYMBOL(phy_read_paged);
788
789/**
790 * phy_write_paged() - Convenience function for writing a paged register
791 * @phydev: a pointer to a &struct phy_device
792 * @page: the page for the phy
793 * @regnum: register number
794 * @val: value to write
795 *
796 * Same rules as for phy_write().
797 */
798int phy_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val)
799{
800 int ret = 0, oldpage;
801
802 oldpage = phy_select_page(phydev, page);
803 if (oldpage >= 0)
804 ret = __phy_write(phydev, regnum, val);
805
806 return phy_restore_page(phydev, oldpage, ret);
807}
808EXPORT_SYMBOL(phy_write_paged);
809
810/**
811 * phy_modify_paged_changed() - Function for modifying a paged register
812 * @phydev: a pointer to a &struct phy_device
813 * @page: the page for the phy
814 * @regnum: register number
815 * @mask: bit mask of bits to clear
816 * @set: bit mask of bits to set
817 *
818 * Returns negative errno, 0 if there was no change, and 1 in case of change
819 */
820int phy_modify_paged_changed(struct phy_device *phydev, int page, u32 regnum,
821 u16 mask, u16 set)
822{
823 int ret = 0, oldpage;
824
825 oldpage = phy_select_page(phydev, page);
826 if (oldpage >= 0)
827 ret = __phy_modify_changed(phydev, regnum, mask, set);
828
829 return phy_restore_page(phydev, oldpage, ret);
830}
831EXPORT_SYMBOL(phy_modify_paged_changed);
832
833/**
834 * phy_modify_paged() - Convenience function for modifying a paged register
835 * @phydev: a pointer to a &struct phy_device
836 * @page: the page for the phy
837 * @regnum: register number
838 * @mask: bit mask of bits to clear
839 * @set: bit mask of bits to set
840 *
841 * Same rules as for phy_read() and phy_write().
842 */
843int phy_modify_paged(struct phy_device *phydev, int page, u32 regnum,
844 u16 mask, u16 set)
845{
846 int ret = phy_modify_paged_changed(phydev, page, regnum, mask, set);
847
848 return ret < 0 ? ret : 0;
849}
850EXPORT_SYMBOL(phy_modify_paged);
851