diff options
author | Tom Lendacky <thomas.lendacky@amd.com> | 2018-05-23 11:38:56 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-05-23 16:33:00 -0400 |
commit | bab748de986d786cbbef31d550bea3bc616304cb (patch) | |
tree | 85dd0089469f437be29289794f2306a7651101ea /drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c | |
parent | 53a1024abf3e4cb3310a54b08c48323649158c13 (diff) |
amd-xgbe: Add ethtool show/set ring parameter support
Add ethtool support to show and set the number of the Rx and Tx ring
descriptors. Changing the ring configuration will result in a device
restart.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c')
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c index 57394b77b2d3..d12f982d73b4 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c @@ -642,6 +642,69 @@ static int xgbe_get_module_eeprom(struct net_device *netdev, return pdata->phy_if.module_eeprom(pdata, eeprom, data); } +static void xgbe_get_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ringparam) +{ + struct xgbe_prv_data *pdata = netdev_priv(netdev); + + ringparam->rx_max_pending = XGBE_RX_DESC_CNT_MAX; + ringparam->tx_max_pending = XGBE_TX_DESC_CNT_MAX; + ringparam->rx_pending = pdata->rx_desc_count; + ringparam->tx_pending = pdata->tx_desc_count; +} + +static int xgbe_set_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ringparam) +{ + struct xgbe_prv_data *pdata = netdev_priv(netdev); + unsigned int rx, tx; + + if (ringparam->rx_mini_pending || ringparam->rx_jumbo_pending) { + netdev_err(netdev, "unsupported ring parameter\n"); + return -EINVAL; + } + + if ((ringparam->rx_pending < XGBE_RX_DESC_CNT_MIN) || + (ringparam->rx_pending > XGBE_RX_DESC_CNT_MAX)) { + netdev_err(netdev, + "rx ring parameter must be between %u and %u\n", + XGBE_RX_DESC_CNT_MIN, XGBE_RX_DESC_CNT_MAX); + return -EINVAL; + } + + if ((ringparam->tx_pending < XGBE_TX_DESC_CNT_MIN) || + (ringparam->tx_pending > XGBE_TX_DESC_CNT_MAX)) { + netdev_err(netdev, + "tx ring parameter must be between %u and %u\n", + XGBE_TX_DESC_CNT_MIN, XGBE_TX_DESC_CNT_MAX); + return -EINVAL; + } + + rx = __rounddown_pow_of_two(ringparam->rx_pending); + if (rx != ringparam->rx_pending) + netdev_notice(netdev, + "rx ring parameter rounded to power of two: %u\n", + rx); + + tx = __rounddown_pow_of_two(ringparam->tx_pending); + if (tx != ringparam->tx_pending) + netdev_notice(netdev, + "tx ring parameter rounded to power of two: %u\n", + tx); + + if ((rx == pdata->rx_desc_count) && + (tx == pdata->tx_desc_count)) + goto out; + + pdata->rx_desc_count = rx; + pdata->tx_desc_count = tx; + + xgbe_restart_dev(pdata); + +out: + return 0; +} + static const struct ethtool_ops xgbe_ethtool_ops = { .get_drvinfo = xgbe_get_drvinfo, .get_msglevel = xgbe_get_msglevel, @@ -664,6 +727,8 @@ static const struct ethtool_ops xgbe_ethtool_ops = { .set_link_ksettings = xgbe_set_link_ksettings, .get_module_info = xgbe_get_module_info, .get_module_eeprom = xgbe_get_module_eeprom, + .get_ringparam = xgbe_get_ringparam, + .set_ringparam = xgbe_set_ringparam, }; const struct ethtool_ops *xgbe_get_ethtool_ops(void) |