diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2014-09-20 19:49:03 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-09-23 03:59:17 -0700 |
commit | e27ef599abc559dfc9b40910071cb6f27277e243 (patch) | |
tree | a0e79b6c785206668300f9c89db6ff83f330c344 /drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | |
parent | fm10k: Add interrupt support (diff) | |
download | linux-dev-e27ef599abc559dfc9b40910071cb6f27277e243.tar.xz linux-dev-e27ef599abc559dfc9b40910071cb6f27277e243.zip |
fm10k: add support for Tx/Rx rings
This change adds the defines and structures necessary to support both Tx
and Rx descriptor rings.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/fm10k/fm10k_netdev.c')
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c index 487efcbb309e..b987bb6a5e1c 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c @@ -67,10 +67,19 @@ int fm10k_open(struct net_device *netdev) /* setup GLORT assignment for this port */ fm10k_request_glort_range(interface); + /* Notify the stack of the actual queue counts */ + + err = netif_set_real_num_rx_queues(netdev, + interface->num_rx_queues); + if (err) + goto err_set_queues; + fm10k_up(interface); return 0; +err_set_queues: + fm10k_qv_free_irq(interface); err_req_irq: return err; } @@ -474,6 +483,64 @@ void fm10k_reset_rx_state(struct fm10k_intfc *interface) __dev_mc_unsync(netdev, NULL); } +/** + * fm10k_get_stats64 - Get System Network Statistics + * @netdev: network interface device structure + * @stats: storage space for 64bit statistics + * + * Returns 64bit statistics, for use in the ndo_get_stats64 callback. This + * function replaces fm10k_get_stats for kernels which support it. + */ +static struct rtnl_link_stats64 *fm10k_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) +{ + struct fm10k_intfc *interface = netdev_priv(netdev); + struct fm10k_ring *ring; + unsigned int start, i; + u64 bytes, packets; + + rcu_read_lock(); + + for (i = 0; i < interface->num_rx_queues; i++) { + ring = ACCESS_ONCE(interface->rx_ring[i]); + + if (!ring) + continue; + + do { + start = u64_stats_fetch_begin_irq(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; + } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); + + stats->rx_packets += packets; + stats->rx_bytes += bytes; + } + + for (i = 0; i < interface->num_tx_queues; i++) { + ring = ACCESS_ONCE(interface->rx_ring[i]); + + if (!ring) + continue; + + do { + start = u64_stats_fetch_begin_irq(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; + } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); + + stats->tx_packets += packets; + stats->tx_bytes += bytes; + } + + rcu_read_unlock(); + + /* following stats updated by fm10k_service_task() */ + stats->rx_missed_errors = netdev->stats.rx_missed_errors; + + return stats; +} + static const struct net_device_ops fm10k_netdev_ops = { .ndo_open = fm10k_open, .ndo_stop = fm10k_close, @@ -484,6 +551,7 @@ static const struct net_device_ops fm10k_netdev_ops = { .ndo_vlan_rx_add_vid = fm10k_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = fm10k_vlan_rx_kill_vid, .ndo_set_rx_mode = fm10k_set_rx_mode, + .ndo_get_stats64 = fm10k_get_stats64, }; #define DEFAULT_DEBUG_LEVEL_SHIFT 3 @@ -493,7 +561,7 @@ struct net_device *fm10k_alloc_netdev(void) struct fm10k_intfc *interface; struct net_device *dev; - dev = alloc_etherdev(sizeof(struct fm10k_intfc)); + dev = alloc_etherdev_mq(sizeof(struct fm10k_intfc), MAX_QUEUES); if (!dev) return NULL; |