diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2010-09-10 02:42:33 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-10 15:27:34 -0400 |
commit | 4642610c77b345130d6b5a08c75d23ad98601fd5 (patch) | |
tree | bf6345d84e6dbd3a3d44ff4e050dc862f01a01fc /drivers/net/sfc/ethtool.c | |
parent | ecc910f520ba8f22848982ee816ad75c449b805d (diff) |
sfc: Allow changing the DMA ring sizes dynamically via ethtool
This requires some reorganisation of channel setup and teardown to
ensure that we can always roll-back a failed change.
Based on work by Steve Hodgson <shodgson@solarflare.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/ethtool.c')
-rw-r--r-- | drivers/net/sfc/ethtool.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index b9291db023bb..7f735d804801 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
@@ -742,6 +742,42 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, | |||
742 | return 0; | 742 | return 0; |
743 | } | 743 | } |
744 | 744 | ||
745 | static void efx_ethtool_get_ringparam(struct net_device *net_dev, | ||
746 | struct ethtool_ringparam *ring) | ||
747 | { | ||
748 | struct efx_nic *efx = netdev_priv(net_dev); | ||
749 | |||
750 | ring->rx_max_pending = EFX_MAX_DMAQ_SIZE; | ||
751 | ring->tx_max_pending = EFX_MAX_DMAQ_SIZE; | ||
752 | ring->rx_mini_max_pending = 0; | ||
753 | ring->rx_jumbo_max_pending = 0; | ||
754 | ring->rx_pending = efx->rxq_entries; | ||
755 | ring->tx_pending = efx->txq_entries; | ||
756 | ring->rx_mini_pending = 0; | ||
757 | ring->rx_jumbo_pending = 0; | ||
758 | } | ||
759 | |||
760 | static int efx_ethtool_set_ringparam(struct net_device *net_dev, | ||
761 | struct ethtool_ringparam *ring) | ||
762 | { | ||
763 | struct efx_nic *efx = netdev_priv(net_dev); | ||
764 | |||
765 | if (ring->rx_mini_pending || ring->rx_jumbo_pending || | ||
766 | ring->rx_pending > EFX_MAX_DMAQ_SIZE || | ||
767 | ring->tx_pending > EFX_MAX_DMAQ_SIZE) | ||
768 | return -EINVAL; | ||
769 | |||
770 | if (ring->rx_pending < EFX_MIN_RING_SIZE || | ||
771 | ring->tx_pending < EFX_MIN_RING_SIZE) { | ||
772 | netif_err(efx, drv, efx->net_dev, | ||
773 | "TX and RX queues cannot be smaller than %ld\n", | ||
774 | EFX_MIN_RING_SIZE); | ||
775 | return -EINVAL; | ||
776 | } | ||
777 | |||
778 | return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending); | ||
779 | } | ||
780 | |||
745 | static int efx_ethtool_set_pauseparam(struct net_device *net_dev, | 781 | static int efx_ethtool_set_pauseparam(struct net_device *net_dev, |
746 | struct ethtool_pauseparam *pause) | 782 | struct ethtool_pauseparam *pause) |
747 | { | 783 | { |
@@ -972,6 +1008,8 @@ const struct ethtool_ops efx_ethtool_ops = { | |||
972 | .set_eeprom = efx_ethtool_set_eeprom, | 1008 | .set_eeprom = efx_ethtool_set_eeprom, |
973 | .get_coalesce = efx_ethtool_get_coalesce, | 1009 | .get_coalesce = efx_ethtool_get_coalesce, |
974 | .set_coalesce = efx_ethtool_set_coalesce, | 1010 | .set_coalesce = efx_ethtool_set_coalesce, |
1011 | .get_ringparam = efx_ethtool_get_ringparam, | ||
1012 | .set_ringparam = efx_ethtool_set_ringparam, | ||
975 | .get_pauseparam = efx_ethtool_get_pauseparam, | 1013 | .get_pauseparam = efx_ethtool_get_pauseparam, |
976 | .set_pauseparam = efx_ethtool_set_pauseparam, | 1014 | .set_pauseparam = efx_ethtool_set_pauseparam, |
977 | .get_rx_csum = efx_ethtool_get_rx_csum, | 1015 | .get_rx_csum = efx_ethtool_get_rx_csum, |