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