diff options
author | Himanshu Madhani <himanshu.madhani@qlogic.com> | 2013-08-21 11:24:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-21 12:17:18 -0700 |
commit | aa4a1f7df7cbb98797c9f4edfde3c726e2b3841f (patch) | |
tree | 0281089c4d1e9650bc5f558e8fd1dfb496ce6e2e /drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | |
parent | 012ec81223aa45d2b80aeafb77392fd1a19c7b10 (diff) | |
download | linux-stable-aa4a1f7df7cbb98797c9f4edfde3c726e2b3841f.tar.gz linux-stable-aa4a1f7df7cbb98797c9f4edfde3c726e2b3841f.tar.bz2 linux-stable-aa4a1f7df7cbb98797c9f4edfde3c726e2b3841f.zip |
qlcnic: Enable Tx queue changes using ethtool for 82xx Series adapter.
o using ethtool {set|get}_channel option, user can change number
of Tx queues for 82xx Series adapter.
o updated ethtool -S <ethX> option to display stats from each Tx queue.
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 79a5855f926c..583dc2b29a84 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -125,6 +125,14 @@ static const char qlcnic_83xx_mac_stats_strings[][ETH_GSTRING_LEN] = { }; #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) + +static const char qlcnic_tx_ring_stats_strings[][ETH_GSTRING_LEN] = { + "xmit_on", + "xmit_off", + "xmit_called", + "xmit_finished", +}; + static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = { "ctx_rx_bytes", "ctx_rx_pkts", @@ -630,15 +638,15 @@ qlcnic_set_ringparam(struct net_device *dev, static void qlcnic_get_channels(struct net_device *dev, struct ethtool_channels *channel) { - int min; struct qlcnic_adapter *adapter = netdev_priv(dev); + int min; min = min_t(int, adapter->ahw->max_rx_ques, num_online_cpus()); channel->max_rx = rounddown_pow_of_two(min); - channel->max_tx = adapter->ahw->max_tx_ques; + channel->max_tx = min_t(int, QLCNIC_MAX_TX_RINGS, num_online_cpus()); channel->rx_count = adapter->max_sds_rings; - channel->tx_count = adapter->ahw->max_tx_ques; + channel->tx_count = adapter->max_drv_tx_rings; } static int qlcnic_set_channels(struct net_device *dev, @@ -646,18 +654,27 @@ static int qlcnic_set_channels(struct net_device *dev, { struct qlcnic_adapter *adapter = netdev_priv(dev); int err; + int txq = 0; - if (channel->other_count || channel->combined_count || - channel->tx_count != channel->max_tx) + if (channel->other_count || channel->combined_count) return -EINVAL; - err = qlcnic_validate_max_rss(adapter, channel->rx_count); - if (err) - return err; + if (channel->rx_count) { + err = qlcnic_validate_max_rss(adapter, channel->rx_count); + if (err) + return err; + } + + if (channel->tx_count) { + err = qlcnic_validate_max_tx_rings(adapter, channel->tx_count); + if (err) + return err; + txq = channel->tx_count; + } - err = qlcnic_set_max_rss(adapter, channel->rx_count, 0); - netdev_info(dev, "allocated 0x%x sds rings\n", - adapter->max_sds_rings); + err = qlcnic_set_max_rss(adapter, channel->rx_count, txq); + netdev_info(dev, "allocated 0x%x sds rings and 0x%x tx rings\n", + adapter->max_sds_rings, adapter->max_drv_tx_rings); return err; } @@ -893,6 +910,7 @@ free_diag_res: clear_diag_irq: adapter->max_sds_rings = max_sds_rings; clear_bit(__QLCNIC_RESETTING, &adapter->state); + return ret; } @@ -1077,11 +1095,21 @@ qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data) QLCNIC_TEST_LEN * ETH_GSTRING_LEN); break; case ETH_SS_STATS: + num_stats = ARRAY_SIZE(qlcnic_tx_ring_stats_strings); + for (i = 0; i < adapter->max_drv_tx_rings; i++) { + for (index = 0; index < num_stats; index++) { + sprintf(data, "tx_ring_%d %s", i, + qlcnic_tx_ring_stats_strings[index]); + data += ETH_GSTRING_LEN; + } + } + for (index = 0; index < QLCNIC_STATS_LEN; index++) { memcpy(data + index * ETH_GSTRING_LEN, qlcnic_gstrings_stats[index].stat_string, ETH_GSTRING_LEN); } + if (qlcnic_83xx_check(adapter)) { num_stats = ARRAY_SIZE(qlcnic_83xx_tx_stats_strings); for (i = 0; i < num_stats; i++, index++) @@ -1173,11 +1201,22 @@ static void qlcnic_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data) { struct qlcnic_adapter *adapter = netdev_priv(dev); + struct qlcnic_host_tx_ring *tx_ring; struct qlcnic_esw_statistics port_stats; struct qlcnic_mac_statistics mac_stats; - int index, ret, length, size; + int index, ret, length, size, ring; char *p; + memset(data, 0, adapter->max_drv_tx_rings * 4 * sizeof(u64)); + for (ring = 0, index = 0; ring < adapter->max_drv_tx_rings; ring++) { + if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { + tx_ring = &adapter->tx_ring[ring]; + *data++ = tx_ring->xmit_on; + *data++ = tx_ring->xmit_off; + *data++ = tx_ring->xmit_called; + *data++ = tx_ring->xmit_finished; + } + } memset(data, 0, stats->n_stats * sizeof(u64)); length = QLCNIC_STATS_LEN; for (index = 0; index < length; index++) { |