summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2023-08-21 13:04:32 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-02-27 15:35:50 +0000
commit1d44310fa01aed5a9fd97026dacb6c7abbcc2138 (patch)
tree25e6a9b955348ca37b8ae11e8adb23c58799fa6a
parent7601110207dde9b2b8837b6e548a055e1e6a455a (diff)
net: phy: add phy_query_inband()
Add a method to query the PHY's in-band capabilities for a PHY interface mode. This can be used to determine for the specified interface mode whether in-band signalling is supported, and whether the PHY requires in-band signalling. When not implemented, or the PHY driver doesn't report any modes for the interface, LINK_INBAND_VALID will not be set. When set, the remainder of the flags can be interpreted. LINK_INBAND_POSSIBLE means that the device can be configured to use or not use in-band signalling. Later patches may add support to configure this at the PHY. LINK_INBAND_REQUIRED means that the device uses in-band signalling which can not be disabled. When only LINK_INBAND_VALID has been set, this means that the device does not support any in-band signalling, and can't be configured to do so. "Bypass" mode (where the device may be configured for in-band, but may still bring the link up if there is no in-band received from the link partner) is not considered in this patch. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-rw-r--r--drivers/net/phy/phy.c21
-rw-r--r--include/linux/phy.h28
2 files changed, 49 insertions, 0 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 70631914934d..ea280b0d843c 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -973,6 +973,27 @@ static int phy_check_link_status(struct phy_device *phydev)
}
/**
+ * phy_query_inband - 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
+ * for this interface mode.
+ */
+unsigned int phy_query_inband(struct phy_device *phydev,
+ phy_interface_t interface)
+{
+ if (phydev->drv && phydev->drv->query_inband)
+ return phydev->drv->query_inband(phydev, interface);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(phy_query_inband);
+
+/**
* _phy_start_aneg - start auto-negotiation for this PHY device
* @phydev: the phy_device struct
*
diff --git a/include/linux/phy.h b/include/linux/phy.h
index bae7be7b44a1..12957e239916 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -795,6 +795,24 @@ struct phy_tdr_config {
#define PHY_PAIR_ALL -1
/**
+ * enum link_inband_signalling - inband signalling modes that are supported
+ *
+ * @LINK_INBAND_VALID: inband signalling report is valid
+ * @LINK_INBAND_POSSIBLE: inband signalling can be used
+ * @LINK_INBAND_REQUIRED: inband signalling is required
+ *
+ * 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_VALID = BIT(0),
+ LINK_INBAND_POSSIBLE = BIT(1),
+ LINK_INBAND_REQUIRED = BIT(2),
+};
+
+/**
* struct phy_plca_cfg - Configuration of the PLCA (Physical Layer Collision
* Avoidance) Reconciliation Sublayer.
*
@@ -924,6 +942,14 @@ struct phy_driver {
int (*get_features)(struct phy_device *phydev);
/**
+ * @query_inband: query whether inband is supported for the given PHY
+ * interface mode. Returns a bitmask of bits defined by enum
+ * link_inband_signalling.
+ */
+ unsigned int (*query_inband)(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
* whether to advertise lower-speed modes for that interface. It is
@@ -1741,6 +1767,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_query_inband(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);