enic: Add support for 'ethtool -g/-G'
authorParvi Kaustubhi <pkaustub@cisco.com>
Wed, 1 Nov 2017 15:44:47 +0000 (08:44 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 2 Nov 2017 05:17:11 +0000 (14:17 +0900)
Add support for displaying and modifying rx and tx ring sizes using
ethtool.

Also, increasing version to  2.3.0.45

Signed-off-by: Parvi Kaustubhi <pkaustub@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/cisco/enic/enic.h
drivers/net/ethernet/cisco/enic/enic_ethtool.c

index ba032ac9ae86cf71fd45ceddb1bc9b66c9308152..6a9527004cb17bbdf77de12fdad162acb487e1b5 100644 (file)
@@ -33,7 +33,7 @@
 
 #define DRV_NAME               "enic"
 #define DRV_DESCRIPTION                "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION            "2.3.0.42"
+#define DRV_VERSION            "2.3.0.45"
 #define DRV_COPYRIGHT          "Copyright 2008-2013 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX          6
index fd3980cc1e345110c030bc3c8cd71dba924a538f..462d0ce512403a673562d28a5f70c9866080950c 100644 (file)
@@ -176,6 +176,81 @@ static void enic_get_strings(struct net_device *netdev, u32 stringset,
        }
 }
 
+static void enic_get_ringparam(struct net_device *netdev,
+                              struct ethtool_ringparam *ring)
+{
+       struct enic *enic = netdev_priv(netdev);
+       struct vnic_enet_config *c = &enic->config;
+
+       ring->rx_max_pending = ENIC_MAX_RQ_DESCS;
+       ring->rx_pending = c->rq_desc_count;
+       ring->tx_max_pending = ENIC_MAX_WQ_DESCS;
+       ring->tx_pending = c->wq_desc_count;
+}
+
+static int enic_set_ringparam(struct net_device *netdev,
+                             struct ethtool_ringparam *ring)
+{
+       struct enic *enic = netdev_priv(netdev);
+       struct vnic_enet_config *c = &enic->config;
+       int running = netif_running(netdev);
+       unsigned int rx_pending;
+       unsigned int tx_pending;
+       int err = 0;
+
+       if (ring->rx_mini_max_pending || ring->rx_mini_pending) {
+               netdev_info(netdev,
+                           "modifying mini ring params is not supported");
+               return -EINVAL;
+       }
+       if (ring->rx_jumbo_max_pending || ring->rx_jumbo_pending) {
+               netdev_info(netdev,
+                           "modifying jumbo ring params is not supported");
+               return -EINVAL;
+       }
+       rx_pending = c->rq_desc_count;
+       tx_pending = c->wq_desc_count;
+       if (ring->rx_pending > ENIC_MAX_RQ_DESCS ||
+           ring->rx_pending < ENIC_MIN_RQ_DESCS) {
+               netdev_info(netdev, "rx pending (%u) not in range [%u,%u]",
+                           ring->rx_pending, ENIC_MIN_RQ_DESCS,
+                           ENIC_MAX_RQ_DESCS);
+               return -EINVAL;
+       }
+       if (ring->tx_pending > ENIC_MAX_WQ_DESCS ||
+           ring->tx_pending < ENIC_MIN_WQ_DESCS) {
+               netdev_info(netdev, "tx pending (%u) not in range [%u,%u]",
+                           ring->tx_pending, ENIC_MIN_WQ_DESCS,
+                           ENIC_MAX_WQ_DESCS);
+               return -EINVAL;
+       }
+       if (running)
+               dev_close(netdev);
+       c->rq_desc_count =
+               ring->rx_pending & 0xffffffe0; /* must be aligned to groups of 32 */
+       c->wq_desc_count =
+               ring->tx_pending & 0xffffffe0; /* must be aligned to groups of 32 */
+       enic_free_vnic_resources(enic);
+       err = enic_alloc_vnic_resources(enic);
+       if (err) {
+               netdev_err(netdev,
+                          "Failed to alloc vNIC resources, aborting\n");
+               enic_free_vnic_resources(enic);
+               goto err_out;
+       }
+       enic_init_vnic_resources(enic);
+       if (running) {
+               err = dev_open(netdev);
+               if (err)
+                       goto err_out;
+       }
+       return 0;
+err_out:
+       c->rq_desc_count = rx_pending;
+       c->wq_desc_count = tx_pending;
+       return err;
+}
+
 static int enic_get_sset_count(struct net_device *netdev, int sset)
 {
        switch (sset) {
@@ -509,6 +584,8 @@ static const struct ethtool_ops enic_ethtool_ops = {
        .set_msglevel = enic_set_msglevel,
        .get_link = ethtool_op_get_link,
        .get_strings = enic_get_strings,
+       .get_ringparam = enic_get_ringparam,
+       .set_ringparam = enic_set_ringparam,
        .get_sset_count = enic_get_sset_count,
        .get_ethtool_stats = enic_get_ethtool_stats,
        .get_coalesce = enic_get_coalesce,