diff options
Diffstat (limited to 'drivers/net/igb/igb_ethtool.c')
-rw-r--r-- | drivers/net/igb/igb_ethtool.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index d004c359244c..b243ed3b0c36 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/if_ether.h> | 35 | #include <linux/if_ether.h> |
36 | #include <linux/ethtool.h> | 36 | #include <linux/ethtool.h> |
37 | #include <linux/sched.h> | ||
37 | 38 | ||
38 | #include "igb.h" | 39 | #include "igb.h" |
39 | 40 | ||
@@ -731,7 +732,7 @@ static int igb_set_ringparam(struct net_device *netdev, | |||
731 | { | 732 | { |
732 | struct igb_adapter *adapter = netdev_priv(netdev); | 733 | struct igb_adapter *adapter = netdev_priv(netdev); |
733 | struct igb_ring *temp_ring; | 734 | struct igb_ring *temp_ring; |
734 | int i, err; | 735 | int i, err = 0; |
735 | u32 new_rx_count, new_tx_count; | 736 | u32 new_rx_count, new_tx_count; |
736 | 737 | ||
737 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 738 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
@@ -751,18 +752,30 @@ static int igb_set_ringparam(struct net_device *netdev, | |||
751 | return 0; | 752 | return 0; |
752 | } | 753 | } |
753 | 754 | ||
755 | while (test_and_set_bit(__IGB_RESETTING, &adapter->state)) | ||
756 | msleep(1); | ||
757 | |||
758 | if (!netif_running(adapter->netdev)) { | ||
759 | for (i = 0; i < adapter->num_tx_queues; i++) | ||
760 | adapter->tx_ring[i].count = new_tx_count; | ||
761 | for (i = 0; i < adapter->num_rx_queues; i++) | ||
762 | adapter->rx_ring[i].count = new_rx_count; | ||
763 | adapter->tx_ring_count = new_tx_count; | ||
764 | adapter->rx_ring_count = new_rx_count; | ||
765 | goto clear_reset; | ||
766 | } | ||
767 | |||
754 | if (adapter->num_tx_queues > adapter->num_rx_queues) | 768 | if (adapter->num_tx_queues > adapter->num_rx_queues) |
755 | temp_ring = vmalloc(adapter->num_tx_queues * sizeof(struct igb_ring)); | 769 | temp_ring = vmalloc(adapter->num_tx_queues * sizeof(struct igb_ring)); |
756 | else | 770 | else |
757 | temp_ring = vmalloc(adapter->num_rx_queues * sizeof(struct igb_ring)); | 771 | temp_ring = vmalloc(adapter->num_rx_queues * sizeof(struct igb_ring)); |
758 | if (!temp_ring) | ||
759 | return -ENOMEM; | ||
760 | 772 | ||
761 | while (test_and_set_bit(__IGB_RESETTING, &adapter->state)) | 773 | if (!temp_ring) { |
762 | msleep(1); | 774 | err = -ENOMEM; |
775 | goto clear_reset; | ||
776 | } | ||
763 | 777 | ||
764 | if (netif_running(adapter->netdev)) | 778 | igb_down(adapter); |
765 | igb_down(adapter); | ||
766 | 779 | ||
767 | /* | 780 | /* |
768 | * We can't just free everything and then setup again, | 781 | * We can't just free everything and then setup again, |
@@ -819,14 +832,11 @@ static int igb_set_ringparam(struct net_device *netdev, | |||
819 | 832 | ||
820 | adapter->rx_ring_count = new_rx_count; | 833 | adapter->rx_ring_count = new_rx_count; |
821 | } | 834 | } |
822 | |||
823 | err = 0; | ||
824 | err_setup: | 835 | err_setup: |
825 | if (netif_running(adapter->netdev)) | 836 | igb_up(adapter); |
826 | igb_up(adapter); | ||
827 | |||
828 | clear_bit(__IGB_RESETTING, &adapter->state); | ||
829 | vfree(temp_ring); | 837 | vfree(temp_ring); |
838 | clear_reset: | ||
839 | clear_bit(__IGB_RESETTING, &adapter->state); | ||
830 | return err; | 840 | return err; |
831 | } | 841 | } |
832 | 842 | ||