1 // SPDX-License-Identifier: GPL-2.0+
3 * Core PHY library, taken from phy.c
5 #include <linux/export.h>
10 * phy_speed_to_str - Return a string representing the PHY link speed
12 * @speed: Speed of the link
14 const char *phy_speed_to_str(int speed)
16 BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS != 92,
17 "Enum ethtool_link_mode_bit_indices and phylib are out of sync. "
18 "If a speed or mode has been added please update phy_speed_to_str "
19 "and the PHY settings array.\n");
55 return "Unsupported (update phy-core.c)";
58 EXPORT_SYMBOL_GPL(phy_speed_to_str);
61 * phy_duplex_to_str - Return string describing the duplex
63 * @duplex: Duplex setting to describe
65 const char *phy_duplex_to_str(unsigned int duplex)
67 if (duplex == DUPLEX_HALF)
69 if (duplex == DUPLEX_FULL)
71 if (duplex == DUPLEX_UNKNOWN)
73 return "Unsupported (update phy-core.c)";
75 EXPORT_SYMBOL_GPL(phy_duplex_to_str);
77 /* A mapping of all SUPPORTED settings to speed/duplex. This table
78 * must be grouped by speed and sorted in descending match priority
79 * - iow, descending speed. */
81 #define PHY_SETTING(s, d, b) { .speed = SPEED_ ## s, .duplex = DUPLEX_ ## d, \
82 .bit = ETHTOOL_LINK_MODE_ ## b ## _BIT}
84 static const struct phy_setting settings[] = {
86 PHY_SETTING( 400000, FULL, 400000baseCR8_Full ),
87 PHY_SETTING( 400000, FULL, 400000baseKR8_Full ),
88 PHY_SETTING( 400000, FULL, 400000baseLR8_ER8_FR8_Full ),
89 PHY_SETTING( 400000, FULL, 400000baseDR8_Full ),
90 PHY_SETTING( 400000, FULL, 400000baseSR8_Full ),
91 PHY_SETTING( 400000, FULL, 400000baseCR4_Full ),
92 PHY_SETTING( 400000, FULL, 400000baseKR4_Full ),
93 PHY_SETTING( 400000, FULL, 400000baseLR4_ER4_FR4_Full ),
94 PHY_SETTING( 400000, FULL, 400000baseDR4_Full ),
95 PHY_SETTING( 400000, FULL, 400000baseSR4_Full ),
97 PHY_SETTING( 200000, FULL, 200000baseCR4_Full ),
98 PHY_SETTING( 200000, FULL, 200000baseKR4_Full ),
99 PHY_SETTING( 200000, FULL, 200000baseLR4_ER4_FR4_Full ),
100 PHY_SETTING( 200000, FULL, 200000baseDR4_Full ),
101 PHY_SETTING( 200000, FULL, 200000baseSR4_Full ),
102 PHY_SETTING( 200000, FULL, 200000baseCR2_Full ),
103 PHY_SETTING( 200000, FULL, 200000baseKR2_Full ),
104 PHY_SETTING( 200000, FULL, 200000baseLR2_ER2_FR2_Full ),
105 PHY_SETTING( 200000, FULL, 200000baseDR2_Full ),
106 PHY_SETTING( 200000, FULL, 200000baseSR2_Full ),
108 PHY_SETTING( 100000, FULL, 100000baseCR4_Full ),
109 PHY_SETTING( 100000, FULL, 100000baseKR4_Full ),
110 PHY_SETTING( 100000, FULL, 100000baseLR4_ER4_Full ),
111 PHY_SETTING( 100000, FULL, 100000baseSR4_Full ),
112 PHY_SETTING( 100000, FULL, 100000baseCR2_Full ),
113 PHY_SETTING( 100000, FULL, 100000baseKR2_Full ),
114 PHY_SETTING( 100000, FULL, 100000baseLR2_ER2_FR2_Full ),
115 PHY_SETTING( 100000, FULL, 100000baseDR2_Full ),
116 PHY_SETTING( 100000, FULL, 100000baseSR2_Full ),
117 PHY_SETTING( 100000, FULL, 100000baseCR_Full ),
118 PHY_SETTING( 100000, FULL, 100000baseKR_Full ),
119 PHY_SETTING( 100000, FULL, 100000baseLR_ER_FR_Full ),
120 PHY_SETTING( 100000, FULL, 100000baseDR_Full ),
121 PHY_SETTING( 100000, FULL, 100000baseSR_Full ),
123 PHY_SETTING( 56000, FULL, 56000baseCR4_Full ),
124 PHY_SETTING( 56000, FULL, 56000baseKR4_Full ),
125 PHY_SETTING( 56000, FULL, 56000baseLR4_Full ),
126 PHY_SETTING( 56000, FULL, 56000baseSR4_Full ),
128 PHY_SETTING( 50000, FULL, 50000baseCR2_Full ),
129 PHY_SETTING( 50000, FULL, 50000baseKR2_Full ),
130 PHY_SETTING( 50000, FULL, 50000baseSR2_Full ),
131 PHY_SETTING( 50000, FULL, 50000baseCR_Full ),
132 PHY_SETTING( 50000, FULL, 50000baseKR_Full ),
133 PHY_SETTING( 50000, FULL, 50000baseLR_ER_FR_Full ),
134 PHY_SETTING( 50000, FULL, 50000baseDR_Full ),
135 PHY_SETTING( 50000, FULL, 50000baseSR_Full ),
137 PHY_SETTING( 40000, FULL, 40000baseCR4_Full ),
138 PHY_SETTING( 40000, FULL, 40000baseKR4_Full ),
139 PHY_SETTING( 40000, FULL, 40000baseLR4_Full ),
140 PHY_SETTING( 40000, FULL, 40000baseSR4_Full ),
142 PHY_SETTING( 25000, FULL, 25000baseCR_Full ),
143 PHY_SETTING( 25000, FULL, 25000baseKR_Full ),
144 PHY_SETTING( 25000, FULL, 25000baseSR_Full ),
146 PHY_SETTING( 20000, FULL, 20000baseKR2_Full ),
147 PHY_SETTING( 20000, FULL, 20000baseMLD2_Full ),
149 PHY_SETTING( 10000, FULL, 10000baseCR_Full ),
150 PHY_SETTING( 10000, FULL, 10000baseER_Full ),
151 PHY_SETTING( 10000, FULL, 10000baseKR_Full ),
152 PHY_SETTING( 10000, FULL, 10000baseKX4_Full ),
153 PHY_SETTING( 10000, FULL, 10000baseLR_Full ),
154 PHY_SETTING( 10000, FULL, 10000baseLRM_Full ),
155 PHY_SETTING( 10000, FULL, 10000baseR_FEC ),
156 PHY_SETTING( 10000, FULL, 10000baseSR_Full ),
157 PHY_SETTING( 10000, FULL, 10000baseT_Full ),
159 PHY_SETTING( 5000, FULL, 5000baseT_Full ),
161 PHY_SETTING( 2500, FULL, 2500baseT_Full ),
162 PHY_SETTING( 2500, FULL, 2500baseX_Full ),
164 PHY_SETTING( 1000, FULL, 1000baseT_Full ),
165 PHY_SETTING( 1000, HALF, 1000baseT_Half ),
166 PHY_SETTING( 1000, FULL, 1000baseT1_Full ),
167 PHY_SETTING( 1000, FULL, 1000baseX_Full ),
168 PHY_SETTING( 1000, FULL, 1000baseKX_Full ),
170 PHY_SETTING( 100, FULL, 100baseT_Full ),
171 PHY_SETTING( 100, FULL, 100baseT1_Full ),
172 PHY_SETTING( 100, HALF, 100baseT_Half ),
173 PHY_SETTING( 100, HALF, 100baseFX_Half ),
174 PHY_SETTING( 100, FULL, 100baseFX_Full ),
176 PHY_SETTING( 10, FULL, 10baseT_Full ),
177 PHY_SETTING( 10, HALF, 10baseT_Half ),
182 * phy_lookup_setting - lookup a PHY setting
183 * @speed: speed to match
184 * @duplex: duplex to match
185 * @mask: allowed link modes
186 * @exact: an exact match is required
188 * Search the settings array for a setting that matches the speed and
189 * duplex, and which is supported.
191 * If @exact is unset, either an exact match or %NULL for no match will
194 * If @exact is set, an exact match, the fastest supported setting at
195 * or below the specified speed, the slowest supported setting, or if
196 * they all fail, %NULL will be returned.
198 const struct phy_setting *
199 phy_lookup_setting(int speed, int duplex, const unsigned long *mask, bool exact)
201 const struct phy_setting *p, *match = NULL, *last = NULL;
204 for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
205 if (p->bit < __ETHTOOL_LINK_MODE_MASK_NBITS &&
206 test_bit(p->bit, mask)) {
208 if (p->speed == speed && p->duplex == duplex) {
209 /* Exact match for speed and duplex */
213 if (!match && p->speed <= speed)
217 if (p->speed < speed)
223 if (!match && !exact)
228 EXPORT_SYMBOL_GPL(phy_lookup_setting);
230 size_t phy_speeds(unsigned int *speeds, size_t size,
236 for (i = 0, count = 0; i < ARRAY_SIZE(settings) && count < size; i++)
237 if (settings[i].bit < __ETHTOOL_LINK_MODE_MASK_NBITS &&
238 test_bit(settings[i].bit, mask) &&
239 (count == 0 || speeds[count - 1] != settings[i].speed))
240 speeds[count++] = settings[i].speed;
245 static int __set_linkmode_max_speed(u32 max_speed, unsigned long *addr)
247 const struct phy_setting *p;
250 for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
251 if (p->speed > max_speed)
252 linkmode_clear_bit(p->bit, addr);
260 static int __set_phy_supported(struct phy_device *phydev, u32 max_speed)
262 return __set_linkmode_max_speed(max_speed, phydev->supported);
266 * phy_set_max_speed - Set the maximum speed the PHY should support
268 * @phydev: The phy_device struct
269 * @max_speed: Maximum speed
271 * The PHY might be more capable than the MAC. For example a Fast Ethernet
272 * is connected to a 1G PHY. This function allows the MAC to indicate its
273 * maximum speed, and so limit what the PHY will advertise.
275 int phy_set_max_speed(struct phy_device *phydev, u32 max_speed)
279 err = __set_phy_supported(phydev, max_speed);
283 phy_advertise_supported(phydev);
287 EXPORT_SYMBOL(phy_set_max_speed);
289 void of_set_phy_supported(struct phy_device *phydev)
291 struct device_node *node = phydev->mdio.dev.of_node;
294 if (!IS_ENABLED(CONFIG_OF_MDIO))
300 if (!of_property_read_u32(node, "max-speed", &max_speed))
301 __set_phy_supported(phydev, max_speed);
304 void of_set_phy_eee_broken(struct phy_device *phydev)
306 struct device_node *node = phydev->mdio.dev.of_node;
309 if (!IS_ENABLED(CONFIG_OF_MDIO))
315 if (of_property_read_bool(node, "eee-broken-100tx"))
316 broken |= MDIO_EEE_100TX;
317 if (of_property_read_bool(node, "eee-broken-1000t"))
318 broken |= MDIO_EEE_1000T;
319 if (of_property_read_bool(node, "eee-broken-10gt"))
320 broken |= MDIO_EEE_10GT;
321 if (of_property_read_bool(node, "eee-broken-1000kx"))
322 broken |= MDIO_EEE_1000KX;
323 if (of_property_read_bool(node, "eee-broken-10gkx4"))
324 broken |= MDIO_EEE_10GKX4;
325 if (of_property_read_bool(node, "eee-broken-10gkr"))
326 broken |= MDIO_EEE_10GKR;
328 phydev->eee_broken_modes = broken;
332 * phy_resolve_aneg_pause - Determine pause autoneg results
334 * @phydev: The phy_device struct
336 * Once autoneg has completed the local pause settings can be
337 * resolved. Determine if pause and asymmetric pause should be used
341 void phy_resolve_aneg_pause(struct phy_device *phydev)
343 if (phydev->duplex == DUPLEX_FULL) {
344 phydev->pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
345 phydev->lp_advertising);
346 phydev->asym_pause = linkmode_test_bit(
347 ETHTOOL_LINK_MODE_Asym_Pause_BIT,
348 phydev->lp_advertising);
351 EXPORT_SYMBOL_GPL(phy_resolve_aneg_pause);
354 * phy_resolve_aneg_linkmode - resolve the advertisements into PHY settings
355 * @phydev: The phy_device struct
357 * Resolve our and the link partner advertisements into their corresponding
358 * speed and duplex. If full duplex was negotiated, extract the pause mode
359 * from the link partner mask.
361 void phy_resolve_aneg_linkmode(struct phy_device *phydev)
363 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
366 linkmode_and(common, phydev->lp_advertising, phydev->advertising);
368 for (i = 0; i < ARRAY_SIZE(settings); i++)
369 if (test_bit(settings[i].bit, common)) {
370 phydev->speed = settings[i].speed;
371 phydev->duplex = settings[i].duplex;
375 phy_resolve_aneg_pause(phydev);
377 EXPORT_SYMBOL_GPL(phy_resolve_aneg_linkmode);
380 * phy_check_downshift - check whether downshift occurred
381 * @phydev: The phy_device struct
383 * Check whether a downshift to a lower speed occurred. If this should be the
384 * case warn the user.
385 * Prerequisite for detecting downshift is that PHY driver implements the
386 * read_status callback and sets phydev->speed to the actual link speed.
388 void phy_check_downshift(struct phy_device *phydev)
390 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
391 int i, speed = SPEED_UNKNOWN;
393 phydev->downshifted_rate = 0;
395 if (phydev->autoneg == AUTONEG_DISABLE ||
396 phydev->speed == SPEED_UNKNOWN)
399 linkmode_and(common, phydev->lp_advertising, phydev->advertising);
401 for (i = 0; i < ARRAY_SIZE(settings); i++)
402 if (test_bit(settings[i].bit, common)) {
403 speed = settings[i].speed;
407 if (speed == SPEED_UNKNOWN || phydev->speed >= speed)
410 phydev_warn(phydev, "Downshift occurred from negotiated speed %s to actual speed %s, check cabling!\n",
411 phy_speed_to_str(speed), phy_speed_to_str(phydev->speed));
413 phydev->downshifted_rate = 1;
415 EXPORT_SYMBOL_GPL(phy_check_downshift);
417 static int phy_resolve_min_speed(struct phy_device *phydev, bool fdx_only)
419 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
420 int i = ARRAY_SIZE(settings);
422 linkmode_and(common, phydev->lp_advertising, phydev->advertising);
425 if (test_bit(settings[i].bit, common)) {
426 if (fdx_only && settings[i].duplex != DUPLEX_FULL)
428 return settings[i].speed;
432 return SPEED_UNKNOWN;
435 int phy_speed_down_core(struct phy_device *phydev)
437 int min_common_speed = phy_resolve_min_speed(phydev, true);
439 if (min_common_speed == SPEED_UNKNOWN)
442 return __set_linkmode_max_speed(min_common_speed, phydev->advertising);
445 static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
448 /* Write the desired MMD Devad */
449 __mdiobus_write(bus, phy_addr, MII_MMD_CTRL, devad);
451 /* Write the desired MMD register address */
452 __mdiobus_write(bus, phy_addr, MII_MMD_DATA, regnum);
454 /* Select the Function : DATA with no post increment */
455 __mdiobus_write(bus, phy_addr, MII_MMD_CTRL,
456 devad | MII_MMD_CTRL_NOINCR);
460 * __phy_read_mmd - Convenience function for reading a register
461 * from an MMD on a given PHY.
462 * @phydev: The phy_device struct
463 * @devad: The MMD to read from (0..31)
464 * @regnum: The register on the MMD to read (0..65535)
466 * Same rules as for __phy_read();
468 int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
472 if (regnum > (u16)~0 || devad > 32)
475 if (phydev->drv && phydev->drv->read_mmd) {
476 val = phydev->drv->read_mmd(phydev, devad, regnum);
477 } else if (phydev->is_c45) {
478 val = __mdiobus_c45_read(phydev->mdio.bus, phydev->mdio.addr,
481 struct mii_bus *bus = phydev->mdio.bus;
482 int phy_addr = phydev->mdio.addr;
484 mmd_phy_indirect(bus, phy_addr, devad, regnum);
486 /* Read the content of the MMD's selected register */
487 val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
491 EXPORT_SYMBOL(__phy_read_mmd);
494 * phy_read_mmd - Convenience function for reading a register
495 * from an MMD on a given PHY.
496 * @phydev: The phy_device struct
497 * @devad: The MMD to read from
498 * @regnum: The register on the MMD to read
500 * Same rules as for phy_read();
502 int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
506 phy_lock_mdio_bus(phydev);
507 ret = __phy_read_mmd(phydev, devad, regnum);
508 phy_unlock_mdio_bus(phydev);
512 EXPORT_SYMBOL(phy_read_mmd);
515 * __phy_write_mmd - Convenience function for writing a register
516 * on an MMD on a given PHY.
517 * @phydev: The phy_device struct
518 * @devad: The MMD to read from
519 * @regnum: The register on the MMD to read
520 * @val: value to write to @regnum
522 * Same rules as for __phy_write();
524 int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
528 if (regnum > (u16)~0 || devad > 32)
531 if (phydev->drv && phydev->drv->write_mmd) {
532 ret = phydev->drv->write_mmd(phydev, devad, regnum, val);
533 } else if (phydev->is_c45) {
534 ret = __mdiobus_c45_write(phydev->mdio.bus, phydev->mdio.addr,
537 struct mii_bus *bus = phydev->mdio.bus;
538 int phy_addr = phydev->mdio.addr;
540 mmd_phy_indirect(bus, phy_addr, devad, regnum);
542 /* Write the data into MMD's selected register */
543 __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);
549 EXPORT_SYMBOL(__phy_write_mmd);
552 * phy_write_mmd - Convenience function for writing a register
553 * on an MMD on a given PHY.
554 * @phydev: The phy_device struct
555 * @devad: The MMD to read from
556 * @regnum: The register on the MMD to read
557 * @val: value to write to @regnum
559 * Same rules as for phy_write();
561 int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
565 phy_lock_mdio_bus(phydev);
566 ret = __phy_write_mmd(phydev, devad, regnum, val);
567 phy_unlock_mdio_bus(phydev);
571 EXPORT_SYMBOL(phy_write_mmd);
574 * phy_modify_changed - Function for modifying a PHY register
575 * @phydev: the phy_device struct
576 * @regnum: register number to modify
577 * @mask: bit mask of bits to clear
578 * @set: new value of bits set in mask to write to @regnum
580 * NOTE: MUST NOT be called from interrupt context,
581 * because the bus read/write functions may wait for an interrupt
582 * to conclude the operation.
584 * Returns negative errno, 0 if there was no change, and 1 in case of change
586 int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
590 phy_lock_mdio_bus(phydev);
591 ret = __phy_modify_changed(phydev, regnum, mask, set);
592 phy_unlock_mdio_bus(phydev);
596 EXPORT_SYMBOL_GPL(phy_modify_changed);
599 * __phy_modify - Convenience function for modifying a PHY register
600 * @phydev: the phy_device struct
601 * @regnum: register number to modify
602 * @mask: bit mask of bits to clear
603 * @set: new value of bits set in mask to write to @regnum
605 * NOTE: MUST NOT be called from interrupt context,
606 * because the bus read/write functions may wait for an interrupt
607 * to conclude the operation.
609 int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
613 ret = __phy_modify_changed(phydev, regnum, mask, set);
615 return ret < 0 ? ret : 0;
617 EXPORT_SYMBOL_GPL(__phy_modify);
620 * phy_modify - Convenience function for modifying a given PHY register
621 * @phydev: the phy_device struct
622 * @regnum: register number to write
623 * @mask: bit mask of bits to clear
624 * @set: new value of bits set in mask to write to @regnum
626 * NOTE: MUST NOT be called from interrupt context,
627 * because the bus read/write functions may wait for an interrupt
628 * to conclude the operation.
630 int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
634 phy_lock_mdio_bus(phydev);
635 ret = __phy_modify(phydev, regnum, mask, set);
636 phy_unlock_mdio_bus(phydev);
640 EXPORT_SYMBOL_GPL(phy_modify);
643 * __phy_modify_mmd_changed - Function for modifying a register on MMD
644 * @phydev: the phy_device struct
645 * @devad: the MMD containing register to modify
646 * @regnum: register number to modify
647 * @mask: bit mask of bits to clear
648 * @set: new value of bits set in mask to write to @regnum
650 * Unlocked helper function which allows a MMD register to be modified as
651 * new register value = (old register value & ~mask) | set
653 * Returns negative errno, 0 if there was no change, and 1 in case of change
655 int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
660 ret = __phy_read_mmd(phydev, devad, regnum);
664 new = (ret & ~mask) | set;
668 ret = __phy_write_mmd(phydev, devad, regnum, new);
670 return ret < 0 ? ret : 1;
672 EXPORT_SYMBOL_GPL(__phy_modify_mmd_changed);
675 * phy_modify_mmd_changed - Function for modifying a register on MMD
676 * @phydev: the phy_device struct
677 * @devad: the MMD containing register to modify
678 * @regnum: register number to modify
679 * @mask: bit mask of bits to clear
680 * @set: new value of bits set in mask to write to @regnum
682 * NOTE: MUST NOT be called from interrupt context,
683 * because the bus read/write functions may wait for an interrupt
684 * to conclude the operation.
686 * Returns negative errno, 0 if there was no change, and 1 in case of change
688 int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
693 phy_lock_mdio_bus(phydev);
694 ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
695 phy_unlock_mdio_bus(phydev);
699 EXPORT_SYMBOL_GPL(phy_modify_mmd_changed);
702 * __phy_modify_mmd - Convenience function for modifying a register on MMD
703 * @phydev: the phy_device struct
704 * @devad: the MMD containing register to modify
705 * @regnum: register number to modify
706 * @mask: bit mask of bits to clear
707 * @set: new value of bits set in mask to write to @regnum
709 * NOTE: MUST NOT be called from interrupt context,
710 * because the bus read/write functions may wait for an interrupt
711 * to conclude the operation.
713 int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
718 ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
720 return ret < 0 ? ret : 0;
722 EXPORT_SYMBOL_GPL(__phy_modify_mmd);
725 * phy_modify_mmd - Convenience function for modifying a register on MMD
726 * @phydev: the phy_device struct
727 * @devad: the MMD containing register to modify
728 * @regnum: register number to modify
729 * @mask: bit mask of bits to clear
730 * @set: new value of bits set in mask to write to @regnum
732 * NOTE: MUST NOT be called from interrupt context,
733 * because the bus read/write functions may wait for an interrupt
734 * to conclude the operation.
736 int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
741 phy_lock_mdio_bus(phydev);
742 ret = __phy_modify_mmd(phydev, devad, regnum, mask, set);
743 phy_unlock_mdio_bus(phydev);
747 EXPORT_SYMBOL_GPL(phy_modify_mmd);
749 static int __phy_read_page(struct phy_device *phydev)
751 if (WARN_ONCE(!phydev->drv->read_page, "read_page callback not available, PHY driver not loaded?\n"))
754 return phydev->drv->read_page(phydev);
757 static int __phy_write_page(struct phy_device *phydev, int page)
759 if (WARN_ONCE(!phydev->drv->write_page, "write_page callback not available, PHY driver not loaded?\n"))
762 return phydev->drv->write_page(phydev, page);
766 * phy_save_page() - take the bus lock and save the current page
767 * @phydev: a pointer to a &struct phy_device
769 * Take the MDIO bus lock, and return the current page number. On error,
770 * returns a negative errno. phy_restore_page() must always be called
771 * after this, irrespective of success or failure of this call.
773 int phy_save_page(struct phy_device *phydev)
775 phy_lock_mdio_bus(phydev);
776 return __phy_read_page(phydev);
778 EXPORT_SYMBOL_GPL(phy_save_page);
781 * phy_select_page() - take the bus lock, save the current page, and set a page
782 * @phydev: a pointer to a &struct phy_device
783 * @page: desired page
785 * Take the MDIO bus lock to protect against concurrent access, save the
786 * current PHY page, and set the current page. On error, returns a
787 * negative errno, otherwise returns the previous page number.
788 * phy_restore_page() must always be called after this, irrespective
789 * of success or failure of this call.
791 int phy_select_page(struct phy_device *phydev, int page)
795 oldpage = ret = phy_save_page(phydev);
799 if (oldpage != page) {
800 ret = __phy_write_page(phydev, page);
807 EXPORT_SYMBOL_GPL(phy_select_page);
810 * phy_restore_page() - restore the page register and release the bus lock
811 * @phydev: a pointer to a &struct phy_device
812 * @oldpage: the old page, return value from phy_save_page() or phy_select_page()
813 * @ret: operation's return code
815 * Release the MDIO bus lock, restoring @oldpage if it is a valid page.
816 * This function propagates the earliest error code from the group of
820 * @oldpage if it was a negative value, otherwise
821 * @ret if it was a negative errno value, otherwise
822 * phy_write_page()'s negative value if it were in error, otherwise
825 int phy_restore_page(struct phy_device *phydev, int oldpage, int ret)
830 r = __phy_write_page(phydev, oldpage);
832 /* Propagate the operation return code if the page write
835 if (ret >= 0 && r < 0)
838 /* Propagate the phy page selection error code */
842 phy_unlock_mdio_bus(phydev);
846 EXPORT_SYMBOL_GPL(phy_restore_page);
849 * phy_read_paged() - Convenience function for reading a paged register
850 * @phydev: a pointer to a &struct phy_device
851 * @page: the page for the phy
852 * @regnum: register number
854 * Same rules as for phy_read().
856 int phy_read_paged(struct phy_device *phydev, int page, u32 regnum)
858 int ret = 0, oldpage;
860 oldpage = phy_select_page(phydev, page);
862 ret = __phy_read(phydev, regnum);
864 return phy_restore_page(phydev, oldpage, ret);
866 EXPORT_SYMBOL(phy_read_paged);
869 * phy_write_paged() - Convenience function for writing a paged register
870 * @phydev: a pointer to a &struct phy_device
871 * @page: the page for the phy
872 * @regnum: register number
873 * @val: value to write
875 * Same rules as for phy_write().
877 int phy_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val)
879 int ret = 0, oldpage;
881 oldpage = phy_select_page(phydev, page);
883 ret = __phy_write(phydev, regnum, val);
885 return phy_restore_page(phydev, oldpage, ret);
887 EXPORT_SYMBOL(phy_write_paged);
890 * phy_modify_paged_changed() - Function for modifying a paged register
891 * @phydev: a pointer to a &struct phy_device
892 * @page: the page for the phy
893 * @regnum: register number
894 * @mask: bit mask of bits to clear
895 * @set: bit mask of bits to set
897 * Returns negative errno, 0 if there was no change, and 1 in case of change
899 int phy_modify_paged_changed(struct phy_device *phydev, int page, u32 regnum,
902 int ret = 0, oldpage;
904 oldpage = phy_select_page(phydev, page);
906 ret = __phy_modify_changed(phydev, regnum, mask, set);
908 return phy_restore_page(phydev, oldpage, ret);
910 EXPORT_SYMBOL(phy_modify_paged_changed);
913 * phy_modify_paged() - Convenience function for modifying a paged register
914 * @phydev: a pointer to a &struct phy_device
915 * @page: the page for the phy
916 * @regnum: register number
917 * @mask: bit mask of bits to clear
918 * @set: bit mask of bits to set
920 * Same rules as for phy_read() and phy_write().
922 int phy_modify_paged(struct phy_device *phydev, int page, u32 regnum,
925 int ret = phy_modify_paged_changed(phydev, page, regnum, mask, set);
927 return ret < 0 ? ret : 0;
929 EXPORT_SYMBOL(phy_modify_paged);