diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_ethtool.c')
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 95 |
1 files changed, 47 insertions, 48 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index f18e3daaf4f5..928b97cc1700 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
| @@ -654,12 +654,9 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
| 654 | struct ethtool_ringparam *ring) | 654 | struct ethtool_ringparam *ring) |
| 655 | { | 655 | { |
| 656 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 656 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
| 657 | struct ixgbe_tx_buffer *old_buf; | 657 | struct ixgbe_ring *temp_ring; |
| 658 | struct ixgbe_rx_buffer *old_rx_buf; | ||
| 659 | void *old_desc; | ||
| 660 | int i, err; | 658 | int i, err; |
| 661 | u32 new_rx_count, new_tx_count, old_size; | 659 | u32 new_rx_count, new_tx_count; |
| 662 | dma_addr_t old_dma; | ||
| 663 | 660 | ||
| 664 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 661 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
| 665 | return -EINVAL; | 662 | return -EINVAL; |
| @@ -678,6 +675,15 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
| 678 | return 0; | 675 | return 0; |
| 679 | } | 676 | } |
| 680 | 677 | ||
| 678 | if (adapter->num_tx_queues > adapter->num_rx_queues) | ||
| 679 | temp_ring = vmalloc(adapter->num_tx_queues * | ||
| 680 | sizeof(struct ixgbe_ring)); | ||
| 681 | else | ||
| 682 | temp_ring = vmalloc(adapter->num_rx_queues * | ||
| 683 | sizeof(struct ixgbe_ring)); | ||
| 684 | if (!temp_ring) | ||
| 685 | return -ENOMEM; | ||
| 686 | |||
| 681 | while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) | 687 | while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) |
| 682 | msleep(1); | 688 | msleep(1); |
| 683 | 689 | ||
| @@ -690,66 +696,59 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
| 690 | * to the tx and rx ring structs. | 696 | * to the tx and rx ring structs. |
| 691 | */ | 697 | */ |
| 692 | if (new_tx_count != adapter->tx_ring->count) { | 698 | if (new_tx_count != adapter->tx_ring->count) { |
| 699 | memcpy(temp_ring, adapter->tx_ring, | ||
| 700 | adapter->num_tx_queues * sizeof(struct ixgbe_ring)); | ||
| 701 | |||
| 693 | for (i = 0; i < adapter->num_tx_queues; i++) { | 702 | for (i = 0; i < adapter->num_tx_queues; i++) { |
| 694 | /* Save existing descriptor ring */ | 703 | temp_ring[i].count = new_tx_count; |
| 695 | old_buf = adapter->tx_ring[i].tx_buffer_info; | 704 | err = ixgbe_setup_tx_resources(adapter, &temp_ring[i]); |
| 696 | old_desc = adapter->tx_ring[i].desc; | ||
| 697 | old_size = adapter->tx_ring[i].size; | ||
| 698 | old_dma = adapter->tx_ring[i].dma; | ||
| 699 | /* Try to allocate a new one */ | ||
| 700 | adapter->tx_ring[i].tx_buffer_info = NULL; | ||
| 701 | adapter->tx_ring[i].desc = NULL; | ||
| 702 | adapter->tx_ring[i].count = new_tx_count; | ||
| 703 | err = ixgbe_setup_tx_resources(adapter, | ||
| 704 | &adapter->tx_ring[i]); | ||
| 705 | if (err) { | 705 | if (err) { |
| 706 | /* Restore the old one so at least | 706 | while (i) { |
| 707 | the adapter still works, even if | 707 | i--; |
| 708 | we failed the request */ | 708 | ixgbe_free_tx_resources(adapter, &temp_ring[i]); |
| 709 | adapter->tx_ring[i].tx_buffer_info = old_buf; | 709 | } |
| 710 | adapter->tx_ring[i].desc = old_desc; | ||
| 711 | adapter->tx_ring[i].size = old_size; | ||
| 712 | adapter->tx_ring[i].dma = old_dma; | ||
| 713 | goto err_setup; | 710 | goto err_setup; |
| 714 | } | 711 | } |
| 715 | /* Free the old buffer manually */ | ||
| 716 | vfree(old_buf); | ||
| 717 | pci_free_consistent(adapter->pdev, old_size, | ||
| 718 | old_desc, old_dma); | ||
| 719 | } | 712 | } |
| 713 | |||
| 714 | for (i = 0; i < adapter->num_tx_queues; i++) | ||
| 715 | ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]); | ||
| 716 | |||
| 717 | memcpy(adapter->tx_ring, temp_ring, | ||
| 718 | adapter->num_tx_queues * sizeof(struct ixgbe_ring)); | ||
| 719 | |||
| 720 | adapter->tx_ring_count = new_tx_count; | ||
| 720 | } | 721 | } |
| 721 | 722 | ||
| 722 | if (new_rx_count != adapter->rx_ring->count) { | 723 | if (new_rx_count != adapter->rx_ring->count) { |
| 723 | for (i = 0; i < adapter->num_rx_queues; i++) { | 724 | memcpy(temp_ring, adapter->rx_ring, |
| 725 | adapter->num_rx_queues * sizeof(struct ixgbe_ring)); | ||
| 724 | 726 | ||
| 725 | old_rx_buf = adapter->rx_ring[i].rx_buffer_info; | 727 | for (i = 0; i < adapter->num_rx_queues; i++) { |
| 726 | old_desc = adapter->rx_ring[i].desc; | 728 | temp_ring[i].count = new_rx_count; |
| 727 | old_size = adapter->rx_ring[i].size; | 729 | err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]); |
| 728 | old_dma = adapter->rx_ring[i].dma; | ||
| 729 | |||
| 730 | adapter->rx_ring[i].rx_buffer_info = NULL; | ||
| 731 | adapter->rx_ring[i].desc = NULL; | ||
| 732 | adapter->rx_ring[i].dma = 0; | ||
| 733 | adapter->rx_ring[i].count = new_rx_count; | ||
| 734 | err = ixgbe_setup_rx_resources(adapter, | ||
| 735 | &adapter->rx_ring[i]); | ||
| 736 | if (err) { | 730 | if (err) { |
| 737 | adapter->rx_ring[i].rx_buffer_info = old_rx_buf; | 731 | while (i) { |
| 738 | adapter->rx_ring[i].desc = old_desc; | 732 | i--; |
| 739 | adapter->rx_ring[i].size = old_size; | 733 | ixgbe_free_rx_resources(adapter, &temp_ring[i]); |
| 740 | adapter->rx_ring[i].dma = old_dma; | 734 | } |
| 741 | goto err_setup; | 735 | goto err_setup; |
| 742 | } | 736 | } |
| 743 | |||
| 744 | vfree(old_rx_buf); | ||
| 745 | pci_free_consistent(adapter->pdev, old_size, old_desc, | ||
| 746 | old_dma); | ||
| 747 | } | 737 | } |
| 738 | |||
| 739 | for (i = 0; i < adapter->num_rx_queues; i++) | ||
| 740 | ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]); | ||
| 741 | |||
| 742 | memcpy(adapter->rx_ring, temp_ring, | ||
| 743 | adapter->num_rx_queues * sizeof(struct ixgbe_ring)); | ||
| 744 | |||
| 745 | adapter->rx_ring_count = new_rx_count; | ||
| 748 | } | 746 | } |
| 749 | 747 | ||
| 748 | /* success! */ | ||
| 750 | err = 0; | 749 | err = 0; |
| 751 | err_setup: | 750 | err_setup: |
| 752 | if (netif_running(adapter->netdev)) | 751 | if (netif_running(netdev)) |
| 753 | ixgbe_up(adapter); | 752 | ixgbe_up(adapter); |
| 754 | 753 | ||
| 755 | clear_bit(__IXGBE_RESETTING, &adapter->state); | 754 | clear_bit(__IXGBE_RESETTING, &adapter->state); |
