File Index
Files and directories
Sign in
FILE

phy-core.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/phy/phy-core.c 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#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);
~/ Read-only file preview.