summaryrefslogtreecommitdiff
path: root/include/linux/phy.h
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2020-05-10 21:12:30 +0200
committerJakub Kicinski <kuba@kernel.org>2020-05-10 12:27:31 -0700
commita68a813836e12b15715d9101309899123c250302 (patch)
treefab31149fd53722c3c1f3157e115513b08d5d146 /include/linux/phy.h
parentb9f96423bba6155cdf54f96f0b1e43fa6d0b0b74 (diff)
net: phy: Add cable test support to state machine
Running a cable test is desruptive to normal operation of the PHY and can take a 5 to 10 seconds to complete. The RTNL lock cannot be held for this amount of time, and add a new state to the state machine for running a cable test. The driver is expected to implement two functions. The first is used to start a cable test. Once the test has started, it should return. The second function is called once per second, or on interrupt to check if the cable test is complete, and to allow the PHY to report the status. v2: Rename phy_cable_test_abort to phy_abort_cable_test Return different extack when already running test Use phy_init_hw() to reset the PHY Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include/linux/phy.h')
-rw-r--r--include/linux/phy.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/include/linux/phy.h b/include/linux/phy.h
index a2b91b5f9d0a..632403fc34f4 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -15,6 +15,7 @@
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/linkmode.h>
+#include <linux/netlink.h>
#include <linux/mdio.h>
#include <linux/mii.h>
#include <linux/mii_timestamper.h>
@@ -372,6 +373,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
* - irq or timer will set NOLINK if link goes down
* - phy_stop moves to HALTED
*
+ * CABLETEST: PHY is performing a cable test. Packet reception/sending
+ * is not expected to work, carrier will be indicated as down. PHY will be
+ * poll once per second, or on interrupt for it current state.
+ * Once complete, move to UP to restart the PHY.
+ * - phy_stop aborts the running test and moves to HALTED
+ *
* HALTED: PHY is up, but no polling or interrupts are done. Or
* PHY is in an error state.
* - phy_start moves to UP
@@ -383,6 +390,7 @@ enum phy_state {
PHY_UP,
PHY_RUNNING,
PHY_NOLINK,
+ PHY_CABLETEST,
};
/**
@@ -689,6 +697,13 @@ struct phy_driver {
int (*module_eeprom)(struct phy_device *dev,
struct ethtool_eeprom *ee, u8 *data);
+ /* Start a cable test */
+ int (*cable_test_start)(struct phy_device *dev);
+ /* Once per second, or on interrupt, request the status of the
+ * test.
+ */
+ int (*cable_test_get_status)(struct phy_device *dev, bool *finished);
+
/* Get statistics from the phy using ethtool */
int (*get_sset_count)(struct phy_device *dev);
void (*get_strings)(struct phy_device *dev, u8 *data);
@@ -1227,6 +1242,19 @@ int phy_speed_up(struct phy_device *phydev);
int phy_restart_aneg(struct phy_device *phydev);
int phy_reset_after_clk_enable(struct phy_device *phydev);
+#if IS_ENABLED(CONFIG_PHYLIB)
+int phy_start_cable_test(struct phy_device *phydev,
+ struct netlink_ext_ack *extack);
+#else
+static inline
+int phy_start_cable_test(struct phy_device *phydev,
+ struct netlink_ext_ack *extack)
+{
+ NL_SET_ERR_MSG(extack, "Kernel not compiled with PHYLIB support");
+ return -EOPNOTSUPP;
+}
+#endif
+
static inline void phy_device_reset(struct phy_device *phydev, int value)
{
mdio_device_reset(&phydev->mdio, value);