summaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/phy_device.c
diff options
context:
space:
mode:
authorAndrew Lunn2018-09-12 01:53:17 +0200
committerDavid S. Miller2018-09-13 05:24:21 +0200
commit70814e819c1139e5e7faacb3700eab5eac559272 (patch)
treeace5dc192ed3e22e719f148d531c6d01345a7858 /drivers/net/phy/phy_device.c
parentnet: ethernet: Add helper for MACs which support pause (diff)
downloadkernel-qcow2-linux-70814e819c1139e5e7faacb3700eab5eac559272.tar.gz
kernel-qcow2-linux-70814e819c1139e5e7faacb3700eab5eac559272.tar.xz
kernel-qcow2-linux-70814e819c1139e5e7faacb3700eab5eac559272.zip
net: ethernet: Add helper for set_pauseparam for Asym Pause
ethtool can be used to enable/disable pause. Add a helper to configure the PHY when asym pause is supported. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/phy_device.c')
-rw-r--r--drivers/net/phy/phy_device.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index e657d5ae2ab8..5732d89c8e37 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1810,6 +1810,36 @@ void phy_support_asym_pause(struct phy_device *phydev)
}
EXPORT_SYMBOL(phy_support_asym_pause);
+/**
+ * phy_set_asym_pause - Configure Pause and Asym Pause
+ * @phydev: target phy_device struct
+ * @rx: Receiver Pause is supported
+ * @tx: Transmit Pause is supported
+ *
+ * Description: Configure advertised Pause support depending on if
+ * transmit and receiver pause is supported. If there has been a
+ * change in adverting, trigger a new autoneg. Generally called from
+ * the set_pauseparam .ndo.
+ */
+void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx)
+{
+ u16 oldadv = phydev->advertising;
+ u16 newadv = oldadv &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause);
+
+ if (rx)
+ newadv |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+ if (tx)
+ newadv ^= SUPPORTED_Asym_Pause;
+
+ if (oldadv != newadv) {
+ phydev->advertising = newadv;
+
+ if (phydev->autoneg)
+ phy_start_aneg(phydev);
+ }
+}
+EXPORT_SYMBOL(phy_set_asym_pause);
+
static void of_set_phy_supported(struct phy_device *phydev)
{
struct device_node *node = phydev->mdio.dev.of_node;