Commit b4c7698d authored by Russell King (Oracle)'s avatar Russell King (Oracle) Committed by Jakub Kicinski
Browse files

net: phy: add phy_inband_caps()



Add a method to query the PHY's in-band capabilities for a PHY
interface mode.

Where the interface mode does not have in-band capability, or the PHY
driver has not been updated to return this information, then
phy_inband_caps() should return zero. Otherwise, PHY drivers will
return a value consisting of the following flags:

LINK_INBAND_DISABLE indicates that the hardware does not support
in-band signalling, or can have in-band signalling configured via
software to be disabled.

LINK_INBAND_ENABLE indicates that the hardware will use in-band
signalling, or can have in-band signalling configured via software
to be enabled.

LINK_INBAND_BYPASS indicates that the hardware has the ability to
bypass in-band signalling when enabled after a timeout if the link
partner does not respond to its in-band signalling.

This reports the PHY capabilities for the particular interface mode,
not the current configuration.

Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://patch.msgid.link/E1tIUre-006ITz-KF@rmk-PC.armlinux.org.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 4e7d0002
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -1005,6 +1005,27 @@ static int phy_check_link_status(struct phy_device *phydev)
	return 0;
}

/**
 * phy_inband_caps - query which in-band signalling modes are supported
 * @phydev: a pointer to a &struct phy_device
 * @interface: the interface mode for the PHY
 *
 * Returns zero if it is unknown what in-band signalling is supported by the
 * PHY (e.g. because the PHY driver doesn't implement the method.) Otherwise,
 * returns a bit mask of the LINK_INBAND_* values from
 * &enum link_inband_signalling to describe which inband modes are supported
 * by the PHY for this interface mode.
 */
unsigned int phy_inband_caps(struct phy_device *phydev,
			     phy_interface_t interface)
{
	if (phydev->drv && phydev->drv->inband_caps)
		return phydev->drv->inband_caps(phydev, interface);

	return 0;
}
EXPORT_SYMBOL_GPL(phy_inband_caps);

/**
 * _phy_start_aneg - start auto-negotiation for this PHY device
 * @phydev: the phy_device struct
+28 −0
Original line number Diff line number Diff line
@@ -817,6 +817,24 @@ struct phy_tdr_config {
};
#define PHY_PAIR_ALL -1

/**
 * enum link_inband_signalling - in-band signalling modes that are supported
 *
 * @LINK_INBAND_DISABLE: in-band signalling can be disabled
 * @LINK_INBAND_ENABLE: in-band signalling can be enabled without bypass
 * @LINK_INBAND_BYPASS: in-band signalling can be enabled with bypass
 *
 * The possible and required bits can only be used if the valid bit is set.
 * If possible is clear, that means inband signalling can not be used.
 * Required is only valid when possible is set, and means that inband
 * signalling must be used.
 */
enum link_inband_signalling {
	LINK_INBAND_DISABLE		= BIT(0),
	LINK_INBAND_ENABLE		= BIT(1),
	LINK_INBAND_BYPASS		= BIT(2),
};

/**
 * struct phy_plca_cfg - Configuration of the PLCA (Physical Layer Collision
 * Avoidance) Reconciliation Sublayer.
@@ -956,6 +974,14 @@ struct phy_driver {
	 */
	int (*get_features)(struct phy_device *phydev);

	/**
	 * @inband_caps: query whether in-band is supported for the given PHY
	 * interface mode. Returns a bitmask of bits defined by enum
	 * link_inband_signalling.
	 */
	unsigned int (*inband_caps)(struct phy_device *phydev,
				    phy_interface_t interface);

	/**
	 * @get_rate_matching: Get the supported type of rate matching for a
	 * particular phy interface. This is used by phy consumers to determine
@@ -1818,6 +1844,8 @@ int phy_config_aneg(struct phy_device *phydev);
int _phy_start_aneg(struct phy_device *phydev);
int phy_start_aneg(struct phy_device *phydev);
int phy_aneg_done(struct phy_device *phydev);
unsigned int phy_inband_caps(struct phy_device *phydev,
			     phy_interface_t interface);
int phy_speed_down(struct phy_device *phydev, bool sync);
int phy_speed_up(struct phy_device *phydev);
bool phy_check_valid(int speed, int duplex, unsigned long *features);