bnxt_en: Modify ethtool -l|-L to support combined or rx/tx rings.
authorMichael Chan <mchan@broadcom.com>
Sun, 3 Jan 2016 04:45:04 +0000 (23:45 -0500)
committerDavid S. Miller <davem@davemloft.net>
Mon, 4 Jan 2016 20:54:40 +0000 (15:54 -0500)
The driver can support either all combined or all rx/tx rings.  The
default is combined, but the user can now select rx/tx rings.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

index 8ad1b6c..4f62c9f 100644 (file)
@@ -212,6 +212,9 @@ static void bnxt_get_channels(struct net_device *dev,
        int max_rx_rings, max_tx_rings, tcs;
 
        bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, true);
+       channel->max_combined = max_rx_rings;
+
+       bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, false);
        tcs = netdev_get_num_tc(dev);
        if (tcs > 1)
                max_tx_rings /= tcs;
@@ -219,9 +222,12 @@ static void bnxt_get_channels(struct net_device *dev,
        channel->max_rx = max_rx_rings;
        channel->max_tx = max_tx_rings;
        channel->max_other = 0;
-       channel->max_combined = 0;
-       channel->rx_count = bp->rx_nr_rings;
-       channel->tx_count = bp->tx_nr_rings_per_tc;
+       if (bp->flags & BNXT_FLAG_SHARED_RINGS) {
+               channel->combined_count = bp->rx_nr_rings;
+       } else {
+               channel->rx_count = bp->rx_nr_rings;
+               channel->tx_count = bp->tx_nr_rings_per_tc;
+       }
 }
 
 static int bnxt_set_channels(struct net_device *dev,
@@ -230,19 +236,35 @@ static int bnxt_set_channels(struct net_device *dev,
        struct bnxt *bp = netdev_priv(dev);
        int max_rx_rings, max_tx_rings, tcs;
        u32 rc = 0;
+       bool sh = false;
 
-       if (channel->other_count || channel->combined_count ||
-           !channel->rx_count || !channel->tx_count)
+       if (channel->other_count)
                return -EINVAL;
 
-       bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, true);
+       if (!channel->combined_count &&
+           (!channel->rx_count || !channel->tx_count))
+               return -EINVAL;
+
+       if (channel->combined_count &&
+           (channel->rx_count || channel->tx_count))
+               return -EINVAL;
+
+       if (channel->combined_count)
+               sh = true;
+
+       bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, sh);
+
        tcs = netdev_get_num_tc(dev);
        if (tcs > 1)
                max_tx_rings /= tcs;
 
-       if (channel->rx_count > max_rx_rings ||
-           channel->tx_count > max_tx_rings)
-               return -EINVAL;
+       if (sh && (channel->combined_count > max_rx_rings ||
+                  channel->combined_count > max_tx_rings))
+               return -ENOMEM;
+
+       if (!sh && (channel->rx_count > max_rx_rings ||
+                   channel->tx_count > max_tx_rings))
+               return -ENOMEM;
 
        if (netif_running(dev)) {
                if (BNXT_PF(bp)) {
@@ -258,12 +280,23 @@ static int bnxt_set_channels(struct net_device *dev,
                }
        }
 
-       bp->rx_nr_rings = channel->rx_count;
-       bp->tx_nr_rings_per_tc = channel->tx_count;
+       if (sh) {
+               bp->flags |= BNXT_FLAG_SHARED_RINGS;
+               bp->rx_nr_rings = channel->combined_count;
+               bp->tx_nr_rings_per_tc = channel->combined_count;
+       } else {
+               bp->flags &= ~BNXT_FLAG_SHARED_RINGS;
+               bp->rx_nr_rings = channel->rx_count;
+               bp->tx_nr_rings_per_tc = channel->tx_count;
+       }
+
        bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
        if (tcs > 1)
                bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tcs;
-       bp->cp_nr_rings = max_t(int, bp->tx_nr_rings, bp->rx_nr_rings);
+
+       bp->cp_nr_rings = sh ? max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) :
+                              bp->tx_nr_rings + bp->rx_nr_rings;
+
        bp->num_stat_ctxs = bp->cp_nr_rings;
 
        /* After changing number of rx channels, update NTUPLE feature. */