From: Parvi Kaustubhi <pkaustub@cisco.com>
Date: Wed, 1 Nov 2017 08:44:47 -0700
Subject: enic: Add support for 'ethtool -g/-G'
Patch-mainline: v4.15-rc1
Git-commit: ed519b7488a42ce549ef7eae8dd13e043dde10a4
References: bsc#1037697
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>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
drivers/net/ethernet/cisco/enic/enic.h | 2
drivers/net/ethernet/cisco/enic/enic_ethtool.c | 77 +++++++++++++++++++++++++
2 files changed, 78 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -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
--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
+++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
@@ -176,6 +176,81 @@ static void enic_get_strings(struct net_
}
}
+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_eth
.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,