diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 11:47:02 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 11:47:02 -0700 |
commit | 5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0 (patch) | |
tree | 7851ef1c93aa1aba7ef327ca4b75fd35e6d10f29 /drivers/net/ixgbevf/ethtool.c | |
parent | 02f36038c568111ad4fc433f6fa760ff5e38fab4 (diff) | |
parent | ec37a48d1d16c30b655ac5280209edf52a6775d4 (diff) | |
download | op-kernel-dev-5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0.zip op-kernel-dev-5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0.tar.gz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1699 commits)
bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL.
vlan: Calling vlan_hwaccel_do_receive() is always valid.
tproxy: use the interface primary IP address as a default value for --on-ip
tproxy: added IPv6 support to the socket match
cxgb3: function namespace cleanup
tproxy: added IPv6 support to the TPROXY target
tproxy: added IPv6 socket lookup function to nf_tproxy_core
be2net: Changes to use only priority codes allowed by f/w
tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
tproxy: added tproxy sockopt interface in the IPV6 layer
tproxy: added udp6_lib_lookup function
tproxy: added const specifiers to udp lookup functions
tproxy: split off ipv6 defragmentation to a separate module
l2tp: small cleanup
nf_nat: restrict ICMP translation for embedded header
can: mcp251x: fix generation of error frames
can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set
can-raw: add msg_flags to distinguish local traffic
9p: client code cleanup
rds: make local functions/variables static
...
Fix up conflicts in net/core/dev.c, drivers/net/pcmcia/smc91c92_cs.c and
drivers/net/wireless/ath/ath9k/debug.c as per David
Diffstat (limited to 'drivers/net/ixgbevf/ethtool.c')
-rw-r--r-- | drivers/net/ixgbevf/ethtool.c | 153 |
1 files changed, 79 insertions, 74 deletions
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c index 4680b06..4cc817a 100644 --- a/drivers/net/ixgbevf/ethtool.c +++ b/drivers/net/ixgbevf/ethtool.c @@ -330,10 +330,8 @@ static int ixgbevf_set_ringparam(struct net_device *netdev, { struct ixgbevf_adapter *adapter = netdev_priv(netdev); struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL; - int i, err; + int i, err = 0; u32 new_rx_count, new_tx_count; - bool need_tx_update = false; - bool need_rx_update = false; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; @@ -355,89 +353,96 @@ static int ixgbevf_set_ringparam(struct net_device *netdev, while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state)) msleep(1); - if (new_tx_count != adapter->tx_ring_count) { - tx_ring = kcalloc(adapter->num_tx_queues, - sizeof(struct ixgbevf_ring), GFP_KERNEL); - if (!tx_ring) { - err = -ENOMEM; - goto err_setup; - } - memcpy(tx_ring, adapter->tx_ring, - adapter->num_tx_queues * sizeof(struct ixgbevf_ring)); - for (i = 0; i < adapter->num_tx_queues; i++) { - tx_ring[i].count = new_tx_count; - err = ixgbevf_setup_tx_resources(adapter, - &tx_ring[i]); - if (err) { - while (i) { - i--; - ixgbevf_free_tx_resources(adapter, - &tx_ring[i]); - } - kfree(tx_ring); - goto err_setup; - } - tx_ring[i].v_idx = adapter->tx_ring[i].v_idx; - } - need_tx_update = true; + /* + * If the adapter isn't up and running then just set the + * new parameters and scurry for the exits. + */ + if (!netif_running(adapter->netdev)) { + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i].count = new_tx_count; + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i].count = new_rx_count; + adapter->tx_ring_count = new_tx_count; + adapter->rx_ring_count = new_rx_count; + goto clear_reset; } - if (new_rx_count != adapter->rx_ring_count) { - rx_ring = kcalloc(adapter->num_rx_queues, - sizeof(struct ixgbevf_ring), GFP_KERNEL); - if ((!rx_ring) && (need_tx_update)) { - err = -ENOMEM; - goto err_rx_setup; - } - memcpy(rx_ring, adapter->rx_ring, - adapter->num_rx_queues * sizeof(struct ixgbevf_ring)); - for (i = 0; i < adapter->num_rx_queues; i++) { - rx_ring[i].count = new_rx_count; - err = ixgbevf_setup_rx_resources(adapter, - &rx_ring[i]); - if (err) { - while (i) { - i--; - ixgbevf_free_rx_resources(adapter, - &rx_ring[i]); - } - kfree(rx_ring); - goto err_rx_setup; - } - rx_ring[i].v_idx = adapter->rx_ring[i].v_idx; - } - need_rx_update = true; + tx_ring = kcalloc(adapter->num_tx_queues, + sizeof(struct ixgbevf_ring), GFP_KERNEL); + if (!tx_ring) { + err = -ENOMEM; + goto clear_reset; } -err_rx_setup: - /* if rings need to be updated, here's the place to do it in one shot */ - if (need_tx_update || need_rx_update) { - if (netif_running(netdev)) - ixgbevf_down(adapter); + rx_ring = kcalloc(adapter->num_rx_queues, + sizeof(struct ixgbevf_ring), GFP_KERNEL); + if (!rx_ring) { + err = -ENOMEM; + goto err_rx_setup; } - /* tx */ - if (need_tx_update) { - kfree(adapter->tx_ring); - adapter->tx_ring = tx_ring; - tx_ring = NULL; - adapter->tx_ring_count = new_tx_count; + ixgbevf_down(adapter); + + memcpy(tx_ring, adapter->tx_ring, + adapter->num_tx_queues * sizeof(struct ixgbevf_ring)); + for (i = 0; i < adapter->num_tx_queues; i++) { + tx_ring[i].count = new_tx_count; + err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]); + if (err) { + while (i) { + i--; + ixgbevf_free_tx_resources(adapter, + &tx_ring[i]); + } + goto err_tx_ring_setup; + } + tx_ring[i].v_idx = adapter->tx_ring[i].v_idx; } - /* rx */ - if (need_rx_update) { - kfree(adapter->rx_ring); - adapter->rx_ring = rx_ring; - rx_ring = NULL; - adapter->rx_ring_count = new_rx_count; + memcpy(rx_ring, adapter->rx_ring, + adapter->num_rx_queues * sizeof(struct ixgbevf_ring)); + for (i = 0; i < adapter->num_rx_queues; i++) { + rx_ring[i].count = new_rx_count; + err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]); + if (err) { + while (i) { + i--; + ixgbevf_free_rx_resources(adapter, + &rx_ring[i]); + } + goto err_rx_ring_setup; + } + rx_ring[i].v_idx = adapter->rx_ring[i].v_idx; } + /* + * Only switch to new rings if all the prior allocations + * and ring setups have succeeded. + */ + kfree(adapter->tx_ring); + adapter->tx_ring = tx_ring; + adapter->tx_ring_count = new_tx_count; + + kfree(adapter->rx_ring); + adapter->rx_ring = rx_ring; + adapter->rx_ring_count = new_rx_count; + /* success! */ - err = 0; - if (netif_running(netdev)) - ixgbevf_up(adapter); + ixgbevf_up(adapter); + + goto clear_reset; + +err_rx_ring_setup: + for(i = 0; i < adapter->num_tx_queues; i++) + ixgbevf_free_tx_resources(adapter, &tx_ring[i]); + +err_tx_ring_setup: + kfree(rx_ring); + +err_rx_setup: + kfree(tx_ring); -err_setup: +clear_reset: clear_bit(__IXGBEVF_RESETTING, &adapter->state); return err; } |