]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
net: macb: Add ethtool get_ringparam and set_ringparam functionality
authorZach Brown <zach.brown@ni.com>
Thu, 8 Mar 2018 12:45:51 +0000 (18:15 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Fri, 9 Mar 2018 08:09:56 +0000 (09:09 +0100)
Some applications want to tune the size of the macb rx/tx ring buffers.
The ethtool set_ringparam function is the standard way of doing it.

Signed-off-by: Zach Brown <zach.brown@ni.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/net/ethernet/cadence/macb_main.c

index 1044702f48f9b34bbb0743f01c629ce8d2f67663..20b0604c9d1181d77bc6df972297f5db3af3abc2 100644 (file)
@@ -2679,6 +2679,56 @@ static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
 }
 
 
+static void macb_get_ringparam(struct net_device *netdev,
+                              struct ethtool_ringparam *ring)
+{
+       struct macb *bp = netdev_priv(netdev);
+
+       ring->rx_max_pending = MAX_RX_RING_SIZE;
+       ring->tx_max_pending = MAX_TX_RING_SIZE;
+
+       ring->rx_pending = bp->rx_ring_size;
+       ring->tx_pending = bp->tx_ring_size;
+}
+
+static int macb_set_ringparam(struct net_device *netdev,
+                             struct ethtool_ringparam *ring)
+{
+       struct macb *bp = netdev_priv(netdev);
+       u32 new_rx_size, new_tx_size;
+       unsigned int reset = 0;
+
+       if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+               return -EINVAL;
+
+       new_rx_size = clamp_t(u32, ring->rx_pending,
+                             MIN_RX_RING_SIZE, MAX_RX_RING_SIZE);
+       new_rx_size = roundup_pow_of_two(new_rx_size);
+
+       new_tx_size = clamp_t(u32, ring->tx_pending,
+                             MIN_TX_RING_SIZE, MAX_TX_RING_SIZE);
+       new_tx_size = roundup_pow_of_two(new_tx_size);
+
+       if ((new_tx_size == bp->tx_ring_size) &&
+           (new_rx_size == bp->rx_ring_size)) {
+               /* nothing to do */
+               return 0;
+       }
+
+       if (netif_running(bp->dev)) {
+               reset = 1;
+               macb_close(bp->dev);
+       }
+
+       bp->rx_ring_size = new_rx_size;
+       bp->tx_ring_size = new_tx_size;
+
+       if (reset)
+               macb_open(bp->dev);
+
+       return 0;
+}
+
 #ifdef CONFIG_MACB_USE_HWSTAMP
 static unsigned int gem_get_tsu_rate(struct macb *bp)
 {
@@ -2761,6 +2811,8 @@ static const struct ethtool_ops macb_ethtool_ops = {
        .get_ts_info            = ethtool_op_get_ts_info,
        .get_link_ksettings     = phy_ethtool_get_link_ksettings,
        .set_link_ksettings     = phy_ethtool_set_link_ksettings,
+       .get_ringparam          = macb_get_ringparam,
+       .set_ringparam          = macb_set_ringparam,
 };
 
 static const struct ethtool_ops gem_ethtool_ops = {
@@ -2773,6 +2825,8 @@ static const struct ethtool_ops gem_ethtool_ops = {
        .get_sset_count         = gem_get_sset_count,
        .get_link_ksettings     = phy_ethtool_get_link_ksettings,
        .set_link_ksettings     = phy_ethtool_set_link_ksettings,
+       .get_ringparam          = macb_get_ringparam,
+       .set_ringparam          = macb_set_ringparam,
 };
 
 static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)