[PATCH RFC 20/26] net: mvneta: add flow control support via phylink
From: Russell King <hidden>
Date: 2015-12-07 17:38:56
Subsystem:
marvell mvneta ethernet driver, networking drivers, the rest · Maintainers:
Marcin Wojtas, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Add flow control support to mvneta, including the ethtool hooks. This uses the phylink code to calculate the result of autonegotiation where a phy is attached, and to handle the ethtool settings. Signed-off-by: Russell King <redacted> --- drivers/net/ethernet/marvell/mvneta.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 82aa2b59a249..00cfb120e324 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c@@ -2701,9 +2701,13 @@ static void mvneta_mac_config(struct net_device *ndev, unsigned int mode, if (state->advertising & ADVERTISED_Pause) new_an |= MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL; + if (state->pause & MLO_PAUSE_AN && state->an_enabled) + new_an |= MVNETA_GMAC_AN_FLOW_CTRL_EN; + else if (state->pause & MLO_PAUSE_TXRX_MASK) + new_an |= MVNETA_GMAC_CONFIG_FLOW_CTRL; + if (state->an_enabled) - new_an |= MVNETA_GMAC_AN_FLOW_CTRL_EN | - MVNETA_GMAC_AN_DUPLEX_EN; + new_an |= MVNETA_GMAC_AN_DUPLEX_EN; else if (state->duplex) new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; break;
@@ -2717,6 +2721,9 @@ static void mvneta_mac_config(struct net_device *ndev, unsigned int mode, new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED; else if (state->speed == SPEED_100) new_an |= MVNETA_GMAC_CONFIG_MII_SPEED; + + if (state->pause & MLO_PAUSE_TXRX_MASK) + new_an |= MVNETA_GMAC_CONFIG_FLOW_CTRL; break; }
@@ -3116,6 +3123,22 @@ static int mvneta_ethtool_set_ringparam(struct net_device *dev, return 0; } +static void mvneta_ethtool_get_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *pause) +{ + struct mvneta_port *pp = netdev_priv(dev); + + phylink_ethtool_get_pauseparam(pp->phylink, pause); +} + +static int mvneta_ethtool_set_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *pause) +{ + struct mvneta_port *pp = netdev_priv(dev); + + return phylink_ethtool_set_pauseparam(pp->phylink, pause); +} + static void mvneta_ethtool_get_strings(struct net_device *netdev, u32 sset, u8 *data) {
@@ -3197,6 +3220,8 @@ const struct ethtool_ops mvneta_eth_tool_ops = { .get_drvinfo = mvneta_ethtool_get_drvinfo, .get_ringparam = mvneta_ethtool_get_ringparam, .set_ringparam = mvneta_ethtool_set_ringparam, + .get_pauseparam = mvneta_ethtool_get_pauseparam, + .set_pauseparam = mvneta_ethtool_set_pauseparam, .get_strings = mvneta_ethtool_get_strings, .get_ethtool_stats = mvneta_ethtool_get_stats, .get_sset_count = mvneta_ethtool_get_sset_count,
--
2.1.0