diff options
author | Tom Herbert <therbert@google.com> | 2011-02-16 10:27:02 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-17 12:49:45 -0800 |
commit | ab532cf32b4055028ad095d3c1fee9eec28ed25e (patch) | |
tree | 03c537583ce9d9dfa87d96e83ec4f467695ed3e4 /drivers/net/bnx2x/bnx2x_ethtool.c | |
parent | f878b995b0f746f5726af9e66940f3bf373dae91 (diff) |
bnx2x: Support for managing RX indirection table
Support fetching and retrieving RX indirection table via ethtool.
Signed-off-by: Tom Herbert <therbert@google.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_ethtool.c')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_ethtool.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 816fef6d384..8d19d127f79 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -2134,6 +2134,59 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data) return 0; } +static int bnx2x_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, + void *rules __always_unused) +{ + struct bnx2x *bp = netdev_priv(dev); + + switch (info->cmd) { + case ETHTOOL_GRXRINGS: + info->data = BNX2X_NUM_ETH_QUEUES(bp); + return 0; + + default: + return -EOPNOTSUPP; + } +} + +static int bnx2x_get_rxfh_indir(struct net_device *dev, + struct ethtool_rxfh_indir *indir) +{ + struct bnx2x *bp = netdev_priv(dev); + size_t copy_size = + min_t(size_t, indir->size, TSTORM_INDIRECTION_TABLE_SIZE); + + if (bp->multi_mode == ETH_RSS_MODE_DISABLED) + return -EOPNOTSUPP; + + indir->size = TSTORM_INDIRECTION_TABLE_SIZE; + memcpy(indir->ring_index, bp->rx_indir_table, + copy_size * sizeof(bp->rx_indir_table[0])); + return 0; +} + +static int bnx2x_set_rxfh_indir(struct net_device *dev, + const struct ethtool_rxfh_indir *indir) +{ + struct bnx2x *bp = netdev_priv(dev); + size_t i; + + if (bp->multi_mode == ETH_RSS_MODE_DISABLED) + return -EOPNOTSUPP; + + /* Validate size and indices */ + if (indir->size != TSTORM_INDIRECTION_TABLE_SIZE) + return -EINVAL; + for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) + if (indir->ring_index[i] >= BNX2X_NUM_ETH_QUEUES(bp)) + return -EINVAL; + + memcpy(bp->rx_indir_table, indir->ring_index, + indir->size * sizeof(bp->rx_indir_table[0])); + bnx2x_push_indir_table(bp); + return 0; +} + static const struct ethtool_ops bnx2x_ethtool_ops = { .get_settings = bnx2x_get_settings, .set_settings = bnx2x_set_settings, @@ -2170,6 +2223,9 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { .get_strings = bnx2x_get_strings, .phys_id = bnx2x_phys_id, .get_ethtool_stats = bnx2x_get_ethtool_stats, + .get_rxnfc = bnx2x_get_rxnfc, + .get_rxfh_indir = bnx2x_get_rxfh_indir, + .set_rxfh_indir = bnx2x_set_rxfh_indir, }; void bnx2x_set_ethtool_ops(struct net_device *netdev) |