]> git.ipfire.org Git - thirdparty/kernel/stable.git/blob - drivers/net/phy/phy-core.c
net: phy: add register modifying helpers returning 1 on change
[thirdparty/kernel/stable.git] / drivers / net / phy / phy-core.c
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
8 const char *phy_speed_to_str(int speed)
9 {
10 switch (speed) {
11 case SPEED_10:
12 return "10Mbps";
13 case SPEED_100:
14 return "100Mbps";
15 case SPEED_1000:
16 return "1Gbps";
17 case SPEED_2500:
18 return "2.5Gbps";
19 case SPEED_5000:
20 return "5Gbps";
21 case SPEED_10000:
22 return "10Gbps";
23 case SPEED_14000:
24 return "14Gbps";
25 case SPEED_20000:
26 return "20Gbps";
27 case SPEED_25000:
28 return "25Gbps";
29 case SPEED_40000:
30 return "40Gbps";
31 case SPEED_50000:
32 return "50Gbps";
33 case SPEED_56000:
34 return "56Gbps";
35 case SPEED_100000:
36 return "100Gbps";
37 case SPEED_UNKNOWN:
38 return "Unknown";
39 default:
40 return "Unsupported (update phy-core.c)";
41 }
42 }
43 EXPORT_SYMBOL_GPL(phy_speed_to_str);
44
45 const char *phy_duplex_to_str(unsigned int duplex)
46 {
47 if (duplex == DUPLEX_HALF)
48 return "Half";
49 if (duplex == DUPLEX_FULL)
50 return "Full";
51 if (duplex == DUPLEX_UNKNOWN)
52 return "Unknown";
53 return "Unsupported (update phy-core.c)";
54 }
55 EXPORT_SYMBOL_GPL(phy_duplex_to_str);
56
57 /* A mapping of all SUPPORTED settings to speed/duplex. This table
58 * must be grouped by speed and sorted in descending match priority
59 * - iow, descending speed. */
60 static const struct phy_setting settings[] = {
61 /* 100G */
62 {
63 .speed = SPEED_100000,
64 .duplex = DUPLEX_FULL,
65 .bit = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
66 },
67 {
68 .speed = SPEED_100000,
69 .duplex = DUPLEX_FULL,
70 .bit = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
71 },
72 {
73 .speed = SPEED_100000,
74 .duplex = DUPLEX_FULL,
75 .bit = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
76 },
77 {
78 .speed = SPEED_100000,
79 .duplex = DUPLEX_FULL,
80 .bit = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
81 },
82 /* 56G */
83 {
84 .speed = SPEED_56000,
85 .duplex = DUPLEX_FULL,
86 .bit = ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT,
87 },
88 {
89 .speed = SPEED_56000,
90 .duplex = DUPLEX_FULL,
91 .bit = ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT,
92 },
93 {
94 .speed = SPEED_56000,
95 .duplex = DUPLEX_FULL,
96 .bit = ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT,
97 },
98 {
99 .speed = SPEED_56000,
100 .duplex = DUPLEX_FULL,
101 .bit = ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT,
102 },
103 /* 50G */
104 {
105 .speed = SPEED_50000,
106 .duplex = DUPLEX_FULL,
107 .bit = ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
108 },
109 {
110 .speed = SPEED_50000,
111 .duplex = DUPLEX_FULL,
112 .bit = ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
113 },
114 {
115 .speed = SPEED_50000,
116 .duplex = DUPLEX_FULL,
117 .bit = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
118 },
119 /* 40G */
120 {
121 .speed = SPEED_40000,
122 .duplex = DUPLEX_FULL,
123 .bit = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
124 },
125 {
126 .speed = SPEED_40000,
127 .duplex = DUPLEX_FULL,
128 .bit = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
129 },
130 {
131 .speed = SPEED_40000,
132 .duplex = DUPLEX_FULL,
133 .bit = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
134 },
135 {
136 .speed = SPEED_40000,
137 .duplex = DUPLEX_FULL,
138 .bit = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
139 },
140 /* 25G */
141 {
142 .speed = SPEED_25000,
143 .duplex = DUPLEX_FULL,
144 .bit = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
145 },
146 {
147 .speed = SPEED_25000,
148 .duplex = DUPLEX_FULL,
149 .bit = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
150 },
151 {
152 .speed = SPEED_25000,
153 .duplex = DUPLEX_FULL,
154 .bit = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
155 },
156
157 /* 20G */
158 {
159 .speed = SPEED_20000,
160 .duplex = DUPLEX_FULL,
161 .bit = ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
162 },
163 {
164 .speed = SPEED_20000,
165 .duplex = DUPLEX_FULL,
166 .bit = ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT,
167 },
168 /* 10G */
169 {
170 .speed = SPEED_10000,
171 .duplex = DUPLEX_FULL,
172 .bit = ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
173 },
174 {
175 .speed = SPEED_10000,
176 .duplex = DUPLEX_FULL,
177 .bit = ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
178 },
179 {
180 .speed = SPEED_10000,
181 .duplex = DUPLEX_FULL,
182 .bit = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
183 },
184 {
185 .speed = SPEED_10000,
186 .duplex = DUPLEX_FULL,
187 .bit = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
188 },
189 {
190 .speed = SPEED_10000,
191 .duplex = DUPLEX_FULL,
192 .bit = ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
193 },
194 {
195 .speed = SPEED_10000,
196 .duplex = DUPLEX_FULL,
197 .bit = ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
198 },
199 {
200 .speed = SPEED_10000,
201 .duplex = DUPLEX_FULL,
202 .bit = ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
203 },
204 {
205 .speed = SPEED_10000,
206 .duplex = DUPLEX_FULL,
207 .bit = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
208 },
209 {
210 .speed = SPEED_10000,
211 .duplex = DUPLEX_FULL,
212 .bit = ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
213 },
214 /* 5G */
215 {
216 .speed = SPEED_5000,
217 .duplex = DUPLEX_FULL,
218 .bit = ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
219 },
220
221 /* 2.5G */
222 {
223 .speed = SPEED_2500,
224 .duplex = DUPLEX_FULL,
225 .bit = ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
226 },
227 {
228 .speed = SPEED_2500,
229 .duplex = DUPLEX_FULL,
230 .bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
231 },
232 /* 1G */
233 {
234 .speed = SPEED_1000,
235 .duplex = DUPLEX_FULL,
236 .bit = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
237 },
238 {
239 .speed = SPEED_1000,
240 .duplex = DUPLEX_FULL,
241 .bit = ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
242 },
243 {
244 .speed = SPEED_1000,
245 .duplex = DUPLEX_HALF,
246 .bit = ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
247 },
248 {
249 .speed = SPEED_1000,
250 .duplex = DUPLEX_FULL,
251 .bit = ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
252 },
253 /* 100M */
254 {
255 .speed = SPEED_100,
256 .duplex = DUPLEX_FULL,
257 .bit = ETHTOOL_LINK_MODE_100baseT_Full_BIT,
258 },
259 {
260 .speed = SPEED_100,
261 .duplex = DUPLEX_HALF,
262 .bit = ETHTOOL_LINK_MODE_100baseT_Half_BIT,
263 },
264 /* 10M */
265 {
266 .speed = SPEED_10,
267 .duplex = DUPLEX_FULL,
268 .bit = ETHTOOL_LINK_MODE_10baseT_Full_BIT,
269 },
270 {
271 .speed = SPEED_10,
272 .duplex = DUPLEX_HALF,
273 .bit = ETHTOOL_LINK_MODE_10baseT_Half_BIT,
274 },
275 };
276
277 /**
278 * phy_lookup_setting - lookup a PHY setting
279 * @speed: speed to match
280 * @duplex: duplex to match
281 * @mask: allowed link modes
282 * @exact: an exact match is required
283 *
284 * Search the settings array for a setting that matches the speed and
285 * duplex, and which is supported.
286 *
287 * If @exact is unset, either an exact match or %NULL for no match will
288 * be returned.
289 *
290 * If @exact is set, an exact match, the fastest supported setting at
291 * or below the specified speed, the slowest supported setting, or if
292 * they all fail, %NULL will be returned.
293 */
294 const struct phy_setting *
295 phy_lookup_setting(int speed, int duplex, const unsigned long *mask, bool exact)
296 {
297 const struct phy_setting *p, *match = NULL, *last = NULL;
298 int i;
299
300 for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
301 if (p->bit < __ETHTOOL_LINK_MODE_MASK_NBITS &&
302 test_bit(p->bit, mask)) {
303 last = p;
304 if (p->speed == speed && p->duplex == duplex) {
305 /* Exact match for speed and duplex */
306 match = p;
307 break;
308 } else if (!exact) {
309 if (!match && p->speed <= speed)
310 /* Candidate */
311 match = p;
312
313 if (p->speed < speed)
314 break;
315 }
316 }
317 }
318
319 if (!match && !exact)
320 match = last;
321
322 return match;
323 }
324 EXPORT_SYMBOL_GPL(phy_lookup_setting);
325
326 size_t phy_speeds(unsigned int *speeds, size_t size,
327 unsigned long *mask)
328 {
329 size_t count;
330 int i;
331
332 for (i = 0, count = 0; i < ARRAY_SIZE(settings) && count < size; i++)
333 if (settings[i].bit < __ETHTOOL_LINK_MODE_MASK_NBITS &&
334 test_bit(settings[i].bit, mask) &&
335 (count == 0 || speeds[count - 1] != settings[i].speed))
336 speeds[count++] = settings[i].speed;
337
338 return count;
339 }
340
341 /**
342 * phy_resolve_aneg_linkmode - resolve the advertisements into phy settings
343 * @phydev: The phy_device struct
344 *
345 * Resolve our and the link partner advertisements into their corresponding
346 * speed and duplex. If full duplex was negotiated, extract the pause mode
347 * from the link partner mask.
348 */
349 void phy_resolve_aneg_linkmode(struct phy_device *phydev)
350 {
351 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
352
353 linkmode_and(common, phydev->lp_advertising, phydev->advertising);
354
355 if (linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, common)) {
356 phydev->speed = SPEED_10000;
357 phydev->duplex = DUPLEX_FULL;
358 } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
359 common)) {
360 phydev->speed = SPEED_5000;
361 phydev->duplex = DUPLEX_FULL;
362 } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
363 common)) {
364 phydev->speed = SPEED_2500;
365 phydev->duplex = DUPLEX_FULL;
366 } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
367 common)) {
368 phydev->speed = SPEED_1000;
369 phydev->duplex = DUPLEX_FULL;
370 } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
371 common)) {
372 phydev->speed = SPEED_1000;
373 phydev->duplex = DUPLEX_HALF;
374 } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
375 common)) {
376 phydev->speed = SPEED_100;
377 phydev->duplex = DUPLEX_FULL;
378 } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
379 common)) {
380 phydev->speed = SPEED_100;
381 phydev->duplex = DUPLEX_HALF;
382 } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
383 common)) {
384 phydev->speed = SPEED_10;
385 phydev->duplex = DUPLEX_FULL;
386 } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
387 common)) {
388 phydev->speed = SPEED_10;
389 phydev->duplex = DUPLEX_HALF;
390 }
391
392 if (phydev->duplex == DUPLEX_FULL) {
393 phydev->pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
394 phydev->lp_advertising);
395 phydev->asym_pause = linkmode_test_bit(
396 ETHTOOL_LINK_MODE_Asym_Pause_BIT,
397 phydev->lp_advertising);
398 }
399 }
400 EXPORT_SYMBOL_GPL(phy_resolve_aneg_linkmode);
401
402 static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
403 u16 regnum)
404 {
405 /* Write the desired MMD Devad */
406 __mdiobus_write(bus, phy_addr, MII_MMD_CTRL, devad);
407
408 /* Write the desired MMD register address */
409 __mdiobus_write(bus, phy_addr, MII_MMD_DATA, regnum);
410
411 /* Select the Function : DATA with no post increment */
412 __mdiobus_write(bus, phy_addr, MII_MMD_CTRL,
413 devad | MII_MMD_CTRL_NOINCR);
414 }
415
416 /**
417 * __phy_read_mmd - Convenience function for reading a register
418 * from an MMD on a given PHY.
419 * @phydev: The phy_device struct
420 * @devad: The MMD to read from (0..31)
421 * @regnum: The register on the MMD to read (0..65535)
422 *
423 * Same rules as for __phy_read();
424 */
425 int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
426 {
427 int val;
428
429 if (regnum > (u16)~0 || devad > 32)
430 return -EINVAL;
431
432 if (phydev->drv->read_mmd) {
433 val = phydev->drv->read_mmd(phydev, devad, regnum);
434 } else if (phydev->is_c45) {
435 u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
436
437 val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
438 } else {
439 struct mii_bus *bus = phydev->mdio.bus;
440 int phy_addr = phydev->mdio.addr;
441
442 mmd_phy_indirect(bus, phy_addr, devad, regnum);
443
444 /* Read the content of the MMD's selected register */
445 val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
446 }
447 return val;
448 }
449 EXPORT_SYMBOL(__phy_read_mmd);
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
456 * @regnum: The register on the MMD to read
457 *
458 * Same rules as for phy_read();
459 */
460 int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
461 {
462 int ret;
463
464 mutex_lock(&phydev->mdio.bus->mdio_lock);
465 ret = __phy_read_mmd(phydev, devad, regnum);
466 mutex_unlock(&phydev->mdio.bus->mdio_lock);
467
468 return ret;
469 }
470 EXPORT_SYMBOL(phy_read_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 */
482 int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
483 {
484 int ret;
485
486 if (regnum > (u16)~0 || devad > 32)
487 return -EINVAL;
488
489 if (phydev->drv->write_mmd) {
490 ret = phydev->drv->write_mmd(phydev, devad, regnum, val);
491 } else if (phydev->is_c45) {
492 u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
493
494 ret = __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
495 addr, val);
496 } else {
497 struct mii_bus *bus = phydev->mdio.bus;
498 int phy_addr = phydev->mdio.addr;
499
500 mmd_phy_indirect(bus, phy_addr, devad, regnum);
501
502 /* Write the data into MMD's selected register */
503 __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);
504
505 ret = 0;
506 }
507 return ret;
508 }
509 EXPORT_SYMBOL(__phy_write_mmd);
510
511 /**
512 * phy_write_mmd - Convenience function for writing a register
513 * on an MMD on a given PHY.
514 * @phydev: The phy_device struct
515 * @devad: The MMD to read from
516 * @regnum: The register on the MMD to read
517 * @val: value to write to @regnum
518 *
519 * Same rules as for phy_write();
520 */
521 int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
522 {
523 int ret;
524
525 mutex_lock(&phydev->mdio.bus->mdio_lock);
526 ret = __phy_write_mmd(phydev, devad, regnum, val);
527 mutex_unlock(&phydev->mdio.bus->mdio_lock);
528
529 return ret;
530 }
531 EXPORT_SYMBOL(phy_write_mmd);
532
533 /**
534 * __phy_modify_changed() - Convenience function for modifying a PHY register
535 * @phydev: a pointer to a &struct phy_device
536 * @regnum: register number
537 * @mask: bit mask of bits to clear
538 * @set: bit mask of bits to set
539 *
540 * Unlocked helper function which allows a PHY register to be modified as
541 * new register value = (old register value & ~mask) | set
542 *
543 * Returns negative errno, 0 if there was no change, and 1 in case of change
544 */
545 int __phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
546 u16 set)
547 {
548 int new, ret;
549
550 ret = __phy_read(phydev, regnum);
551 if (ret < 0)
552 return ret;
553
554 new = (ret & ~mask) | set;
555 if (new == ret)
556 return 0;
557
558 ret = __phy_write(phydev, regnum, new);
559
560 return ret < 0 ? ret : 1;
561 }
562 EXPORT_SYMBOL_GPL(__phy_modify_changed);
563
564 /**
565 * phy_modify_changed - 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 *
575 * Returns negative errno, 0 if there was no change, and 1 in case of change
576 */
577 int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
578 {
579 int ret;
580
581 mutex_lock(&phydev->mdio.bus->mdio_lock);
582 ret = __phy_modify_changed(phydev, regnum, mask, set);
583 mutex_unlock(&phydev->mdio.bus->mdio_lock);
584
585 return ret;
586 }
587 EXPORT_SYMBOL_GPL(phy_modify_changed);
588
589 /**
590 * __phy_modify - Convenience function for modifying a PHY register
591 * @phydev: the phy_device struct
592 * @regnum: register number to modify
593 * @mask: bit mask of bits to clear
594 * @set: new value of bits set in mask to write to @regnum
595 *
596 * NOTE: MUST NOT be called from interrupt context,
597 * because the bus read/write functions may wait for an interrupt
598 * to conclude the operation.
599 */
600 int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
601 {
602 int ret;
603
604 ret = __phy_modify_changed(phydev, regnum, mask, set);
605
606 return ret < 0 ? ret : 0;
607 }
608 EXPORT_SYMBOL_GPL(__phy_modify);
609
610 /**
611 * phy_modify - Convenience function for modifying a given PHY register
612 * @phydev: the phy_device struct
613 * @regnum: register number to write
614 * @mask: bit mask of bits to clear
615 * @set: new value of bits set in mask to write to @regnum
616 *
617 * NOTE: MUST NOT be called from interrupt context,
618 * because the bus read/write functions may wait for an interrupt
619 * to conclude the operation.
620 */
621 int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
622 {
623 int ret;
624
625 mutex_lock(&phydev->mdio.bus->mdio_lock);
626 ret = __phy_modify(phydev, regnum, mask, set);
627 mutex_unlock(&phydev->mdio.bus->mdio_lock);
628
629 return ret;
630 }
631 EXPORT_SYMBOL_GPL(phy_modify);
632
633 /**
634 * __phy_modify_mmd_changed - Function for modifying a register on MMD
635 * @phydev: the phy_device struct
636 * @devad: the MMD containing register to modify
637 * @regnum: register number to modify
638 * @mask: bit mask of bits to clear
639 * @set: new value of bits set in mask to write to @regnum
640 *
641 * Unlocked helper function which allows a MMD register to be modified as
642 * new register value = (old register value & ~mask) | set
643 *
644 * Returns negative errno, 0 if there was no change, and 1 in case of change
645 */
646 int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
647 u16 mask, u16 set)
648 {
649 int new, ret;
650
651 ret = __phy_read_mmd(phydev, devad, regnum);
652 if (ret < 0)
653 return ret;
654
655 new = (ret & ~mask) | set;
656 if (new == ret)
657 return 0;
658
659 ret = __phy_write_mmd(phydev, devad, regnum, new);
660
661 return ret < 0 ? ret : 1;
662 }
663 EXPORT_SYMBOL_GPL(__phy_modify_mmd_changed);
664
665 /**
666 * phy_modify_mmd_changed - Function for modifying a register on MMD
667 * @phydev: the phy_device struct
668 * @devad: the MMD containing register to modify
669 * @regnum: register number to modify
670 * @mask: bit mask of bits to clear
671 * @set: new value of bits set in mask to write to @regnum
672 *
673 * NOTE: MUST NOT be called from interrupt context,
674 * because the bus read/write functions may wait for an interrupt
675 * to conclude the operation.
676 *
677 * Returns negative errno, 0 if there was no change, and 1 in case of change
678 */
679 int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
680 u16 mask, u16 set)
681 {
682 int ret;
683
684 mutex_lock(&phydev->mdio.bus->mdio_lock);
685 ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
686 mutex_unlock(&phydev->mdio.bus->mdio_lock);
687
688 return ret;
689 }
690 EXPORT_SYMBOL_GPL(phy_modify_mmd_changed);
691
692 /**
693 * __phy_modify_mmd - Convenience function for modifying a register on MMD
694 * @phydev: the phy_device struct
695 * @devad: the MMD containing register to modify
696 * @regnum: register number to modify
697 * @mask: bit mask of bits to clear
698 * @set: new value of bits set in mask to write to @regnum
699 *
700 * NOTE: MUST NOT be called from interrupt context,
701 * because the bus read/write functions may wait for an interrupt
702 * to conclude the operation.
703 */
704 int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
705 u16 mask, u16 set)
706 {
707 int ret;
708
709 ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
710
711 return ret < 0 ? ret : 0;
712 }
713 EXPORT_SYMBOL_GPL(__phy_modify_mmd);
714
715 /**
716 * phy_modify_mmd - Convenience function for modifying a register on MMD
717 * @phydev: the phy_device struct
718 * @devad: the MMD containing register to modify
719 * @regnum: register number to modify
720 * @mask: bit mask of bits to clear
721 * @set: new value of bits set in mask to write to @regnum
722 *
723 * NOTE: MUST NOT be called from interrupt context,
724 * because the bus read/write functions may wait for an interrupt
725 * to conclude the operation.
726 */
727 int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
728 u16 mask, u16 set)
729 {
730 int ret;
731
732 mutex_lock(&phydev->mdio.bus->mdio_lock);
733 ret = __phy_modify_mmd(phydev, devad, regnum, mask, set);
734 mutex_unlock(&phydev->mdio.bus->mdio_lock);
735
736 return ret;
737 }
738 EXPORT_SYMBOL_GPL(phy_modify_mmd);
739
740 static int __phy_read_page(struct phy_device *phydev)
741 {
742 return phydev->drv->read_page(phydev);
743 }
744
745 static int __phy_write_page(struct phy_device *phydev, int page)
746 {
747 return phydev->drv->write_page(phydev, page);
748 }
749
750 /**
751 * phy_save_page() - take the bus lock and save the current page
752 * @phydev: a pointer to a &struct phy_device
753 *
754 * Take the MDIO bus lock, and return the current page number. On error,
755 * returns a negative errno. phy_restore_page() must always be called
756 * after this, irrespective of success or failure of this call.
757 */
758 int phy_save_page(struct phy_device *phydev)
759 {
760 mutex_lock(&phydev->mdio.bus->mdio_lock);
761 return __phy_read_page(phydev);
762 }
763 EXPORT_SYMBOL_GPL(phy_save_page);
764
765 /**
766 * phy_select_page() - take the bus lock, save the current page, and set a page
767 * @phydev: a pointer to a &struct phy_device
768 * @page: desired page
769 *
770 * Take the MDIO bus lock to protect against concurrent access, save the
771 * current PHY page, and set the current page. On error, returns a
772 * negative errno, otherwise returns the previous page number.
773 * phy_restore_page() must always be called after this, irrespective
774 * of success or failure of this call.
775 */
776 int phy_select_page(struct phy_device *phydev, int page)
777 {
778 int ret, oldpage;
779
780 oldpage = ret = phy_save_page(phydev);
781 if (ret < 0)
782 return ret;
783
784 if (oldpage != page) {
785 ret = __phy_write_page(phydev, page);
786 if (ret < 0)
787 return ret;
788 }
789
790 return oldpage;
791 }
792 EXPORT_SYMBOL_GPL(phy_select_page);
793
794 /**
795 * phy_restore_page() - restore the page register and release the bus lock
796 * @phydev: a pointer to a &struct phy_device
797 * @oldpage: the old page, return value from phy_save_page() or phy_select_page()
798 * @ret: operation's return code
799 *
800 * Release the MDIO bus lock, restoring @oldpage if it is a valid page.
801 * This function propagates the earliest error code from the group of
802 * operations.
803 *
804 * Returns:
805 * @oldpage if it was a negative value, otherwise
806 * @ret if it was a negative errno value, otherwise
807 * phy_write_page()'s negative value if it were in error, otherwise
808 * @ret.
809 */
810 int phy_restore_page(struct phy_device *phydev, int oldpage, int ret)
811 {
812 int r;
813
814 if (oldpage >= 0) {
815 r = __phy_write_page(phydev, oldpage);
816
817 /* Propagate the operation return code if the page write
818 * was successful.
819 */
820 if (ret >= 0 && r < 0)
821 ret = r;
822 } else {
823 /* Propagate the phy page selection error code */
824 ret = oldpage;
825 }
826
827 mutex_unlock(&phydev->mdio.bus->mdio_lock);
828
829 return ret;
830 }
831 EXPORT_SYMBOL_GPL(phy_restore_page);
832
833 /**
834 * phy_read_paged() - Convenience function for reading a paged register
835 * @phydev: a pointer to a &struct phy_device
836 * @page: the page for the phy
837 * @regnum: register number
838 *
839 * Same rules as for phy_read().
840 */
841 int phy_read_paged(struct phy_device *phydev, int page, u32 regnum)
842 {
843 int ret = 0, oldpage;
844
845 oldpage = phy_select_page(phydev, page);
846 if (oldpage >= 0)
847 ret = __phy_read(phydev, regnum);
848
849 return phy_restore_page(phydev, oldpage, ret);
850 }
851 EXPORT_SYMBOL(phy_read_paged);
852
853 /**
854 * phy_write_paged() - Convenience function for writing a paged register
855 * @phydev: a pointer to a &struct phy_device
856 * @page: the page for the phy
857 * @regnum: register number
858 * @val: value to write
859 *
860 * Same rules as for phy_write().
861 */
862 int phy_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val)
863 {
864 int ret = 0, oldpage;
865
866 oldpage = phy_select_page(phydev, page);
867 if (oldpage >= 0)
868 ret = __phy_write(phydev, regnum, val);
869
870 return phy_restore_page(phydev, oldpage, ret);
871 }
872 EXPORT_SYMBOL(phy_write_paged);
873
874 /**
875 * phy_modify_paged() - Convenience function for modifying a paged register
876 * @phydev: a pointer to a &struct phy_device
877 * @page: the page for the phy
878 * @regnum: register number
879 * @mask: bit mask of bits to clear
880 * @set: bit mask of bits to set
881 *
882 * Same rules as for phy_read() and phy_write().
883 */
884 int phy_modify_paged(struct phy_device *phydev, int page, u32 regnum,
885 u16 mask, u16 set)
886 {
887 int ret = 0, oldpage;
888
889 oldpage = phy_select_page(phydev, page);
890 if (oldpage >= 0)
891 ret = __phy_modify(phydev, regnum, mask, set);
892
893 return phy_restore_page(phydev, oldpage, ret);
894 }
895 EXPORT_SYMBOL(phy_modify_paged);