aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/igb')
-rw-r--r--drivers/net/igb/igb.h4
-rw-r--r--drivers/net/igb/igb_ethtool.c102
-rw-r--r--drivers/net/igb/igb_main.c10
3 files changed, 59 insertions, 57 deletions
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 4ff6f0567f3..acf2569b98f 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -294,6 +294,8 @@ struct igb_adapter {
294 unsigned int lro_flushed; 294 unsigned int lro_flushed;
295 unsigned int lro_no_desc; 295 unsigned int lro_no_desc;
296#endif 296#endif
297 unsigned int tx_ring_count;
298 unsigned int rx_ring_count;
297}; 299};
298 300
299#define IGB_FLAG_HAS_MSI (1 << 0) 301#define IGB_FLAG_HAS_MSI (1 << 0)
@@ -325,6 +327,8 @@ extern void igb_reset(struct igb_adapter *);
325extern int igb_set_spd_dplx(struct igb_adapter *, u16); 327extern int igb_set_spd_dplx(struct igb_adapter *, u16);
326extern int igb_setup_tx_resources(struct igb_adapter *, struct igb_ring *); 328extern int igb_setup_tx_resources(struct igb_adapter *, struct igb_ring *);
327extern int igb_setup_rx_resources(struct igb_adapter *, struct igb_ring *); 329extern int igb_setup_rx_resources(struct igb_adapter *, struct igb_ring *);
330extern void igb_free_tx_resources(struct igb_ring *);
331extern void igb_free_rx_resources(struct igb_ring *);
328extern void igb_update_stats(struct igb_adapter *); 332extern void igb_update_stats(struct igb_adapter *);
329extern void igb_set_ethtool_ops(struct net_device *); 333extern void igb_set_ethtool_ops(struct net_device *);
330 334
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 9b9066c5b0e..a661159a097 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -714,15 +714,13 @@ static void igb_get_ringparam(struct net_device *netdev,
714 struct ethtool_ringparam *ring) 714 struct ethtool_ringparam *ring)
715{ 715{
716 struct igb_adapter *adapter = netdev_priv(netdev); 716 struct igb_adapter *adapter = netdev_priv(netdev);
717 struct igb_ring *tx_ring = adapter->tx_ring;
718 struct igb_ring *rx_ring = adapter->rx_ring;
719 717
720 ring->rx_max_pending = IGB_MAX_RXD; 718 ring->rx_max_pending = IGB_MAX_RXD;
721 ring->tx_max_pending = IGB_MAX_TXD; 719 ring->tx_max_pending = IGB_MAX_TXD;
722 ring->rx_mini_max_pending = 0; 720 ring->rx_mini_max_pending = 0;
723 ring->rx_jumbo_max_pending = 0; 721 ring->rx_jumbo_max_pending = 0;
724 ring->rx_pending = rx_ring->count; 722 ring->rx_pending = adapter->rx_ring_count;
725 ring->tx_pending = tx_ring->count; 723 ring->tx_pending = adapter->tx_ring_count;
726 ring->rx_mini_pending = 0; 724 ring->rx_mini_pending = 0;
727 ring->rx_jumbo_pending = 0; 725 ring->rx_jumbo_pending = 0;
728} 726}
@@ -731,12 +729,9 @@ static int igb_set_ringparam(struct net_device *netdev,
731 struct ethtool_ringparam *ring) 729 struct ethtool_ringparam *ring)
732{ 730{
733 struct igb_adapter *adapter = netdev_priv(netdev); 731 struct igb_adapter *adapter = netdev_priv(netdev);
734 struct igb_buffer *old_buf; 732 struct igb_ring *temp_ring;
735 struct igb_buffer *old_rx_buf;
736 void *old_desc;
737 int i, err; 733 int i, err;
738 u32 new_rx_count, new_tx_count, old_size; 734 u32 new_rx_count, new_tx_count;
739 dma_addr_t old_dma;
740 735
741 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 736 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
742 return -EINVAL; 737 return -EINVAL;
@@ -749,12 +744,19 @@ static int igb_set_ringparam(struct net_device *netdev,
749 new_tx_count = min(new_tx_count, (u32)IGB_MAX_TXD); 744 new_tx_count = min(new_tx_count, (u32)IGB_MAX_TXD);
750 new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE); 745 new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
751 746
752 if ((new_tx_count == adapter->tx_ring->count) && 747 if ((new_tx_count == adapter->tx_ring_count) &&
753 (new_rx_count == adapter->rx_ring->count)) { 748 (new_rx_count == adapter->rx_ring_count)) {
754 /* nothing to do */ 749 /* nothing to do */
755 return 0; 750 return 0;
756 } 751 }
757 752
753 if (adapter->num_tx_queues > adapter->num_rx_queues)
754 temp_ring = vmalloc(adapter->num_tx_queues * sizeof(struct igb_ring));
755 else
756 temp_ring = vmalloc(adapter->num_rx_queues * sizeof(struct igb_ring));
757 if (!temp_ring)
758 return -ENOMEM;
759
758 while (test_and_set_bit(__IGB_RESETTING, &adapter->state)) 760 while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
759 msleep(1); 761 msleep(1);
760 762
@@ -766,62 +768,55 @@ static int igb_set_ringparam(struct net_device *netdev,
766 * because the ISRs in MSI-X mode get passed pointers 768 * because the ISRs in MSI-X mode get passed pointers
767 * to the tx and rx ring structs. 769 * to the tx and rx ring structs.
768 */ 770 */
769 if (new_tx_count != adapter->tx_ring->count) { 771 if (new_tx_count != adapter->tx_ring_count) {
772 memcpy(temp_ring, adapter->tx_ring,
773 adapter->num_tx_queues * sizeof(struct igb_ring));
774
770 for (i = 0; i < adapter->num_tx_queues; i++) { 775 for (i = 0; i < adapter->num_tx_queues; i++) {
771 /* Save existing descriptor ring */ 776 temp_ring[i].count = new_tx_count;
772 old_buf = adapter->tx_ring[i].buffer_info; 777 err = igb_setup_tx_resources(adapter, &temp_ring[i]);
773 old_desc = adapter->tx_ring[i].desc;
774 old_size = adapter->tx_ring[i].size;
775 old_dma = adapter->tx_ring[i].dma;
776 /* Try to allocate a new one */
777 adapter->tx_ring[i].buffer_info = NULL;
778 adapter->tx_ring[i].desc = NULL;
779 adapter->tx_ring[i].count = new_tx_count;
780 err = igb_setup_tx_resources(adapter,
781 &adapter->tx_ring[i]);
782 if (err) { 778 if (err) {
783 /* Restore the old one so at least 779 while (i) {
784 the adapter still works, even if 780 i--;
785 we failed the request */ 781 igb_free_tx_resources(&temp_ring[i]);
786 adapter->tx_ring[i].buffer_info = old_buf; 782 }
787 adapter->tx_ring[i].desc = old_desc;
788 adapter->tx_ring[i].size = old_size;
789 adapter->tx_ring[i].dma = old_dma;
790 goto err_setup; 783 goto err_setup;
791 } 784 }
792 /* Free the old buffer manually */
793 vfree(old_buf);
794 pci_free_consistent(adapter->pdev, old_size,
795 old_desc, old_dma);
796 } 785 }
786
787 for (i = 0; i < adapter->num_tx_queues; i++)
788 igb_free_tx_resources(&adapter->tx_ring[i]);
789
790 memcpy(adapter->tx_ring, temp_ring,
791 adapter->num_tx_queues * sizeof(struct igb_ring));
792
793 adapter->tx_ring_count = new_tx_count;
797 } 794 }
798 795
799 if (new_rx_count != adapter->rx_ring->count) { 796 if (new_rx_count != adapter->rx_ring->count) {
800 for (i = 0; i < adapter->num_rx_queues; i++) { 797 memcpy(temp_ring, adapter->rx_ring,
798 adapter->num_rx_queues * sizeof(struct igb_ring));
801 799
802 old_rx_buf = adapter->rx_ring[i].buffer_info; 800 for (i = 0; i < adapter->num_rx_queues; i++) {
803 old_desc = adapter->rx_ring[i].desc; 801 temp_ring[i].count = new_rx_count;
804 old_size = adapter->rx_ring[i].size; 802 err = igb_setup_rx_resources(adapter, &temp_ring[i]);
805 old_dma = adapter->rx_ring[i].dma;
806
807 adapter->rx_ring[i].buffer_info = NULL;
808 adapter->rx_ring[i].desc = NULL;
809 adapter->rx_ring[i].dma = 0;
810 adapter->rx_ring[i].count = new_rx_count;
811 err = igb_setup_rx_resources(adapter,
812 &adapter->rx_ring[i]);
813 if (err) { 803 if (err) {
814 adapter->rx_ring[i].buffer_info = old_rx_buf; 804 while (i) {
815 adapter->rx_ring[i].desc = old_desc; 805 i--;
816 adapter->rx_ring[i].size = old_size; 806 igb_free_rx_resources(&temp_ring[i]);
817 adapter->rx_ring[i].dma = old_dma; 807 }
818 goto err_setup; 808 goto err_setup;
819 } 809 }
820 810
821 vfree(old_rx_buf);
822 pci_free_consistent(adapter->pdev, old_size, old_desc,
823 old_dma);
824 } 811 }
812
813 for (i = 0; i < adapter->num_rx_queues; i++)
814 igb_free_rx_resources(&adapter->rx_ring[i]);
815
816 memcpy(adapter->rx_ring, temp_ring,
817 adapter->num_rx_queues * sizeof(struct igb_ring));
818
819 adapter->rx_ring_count = new_rx_count;
825 } 820 }
826 821
827 err = 0; 822 err = 0;
@@ -830,6 +825,7 @@ err_setup:
830 igb_up(adapter); 825 igb_up(adapter);
831 826
832 clear_bit(__IGB_RESETTING, &adapter->state); 827 clear_bit(__IGB_RESETTING, &adapter->state);
828 vfree(temp_ring);
833 return err; 829 return err;
834} 830}
835 831
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 0d33378edc6..ceb0a045879 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -76,8 +76,6 @@ static int igb_setup_all_tx_resources(struct igb_adapter *);
76static int igb_setup_all_rx_resources(struct igb_adapter *); 76static int igb_setup_all_rx_resources(struct igb_adapter *);
77static void igb_free_all_tx_resources(struct igb_adapter *); 77static void igb_free_all_tx_resources(struct igb_adapter *);
78static void igb_free_all_rx_resources(struct igb_adapter *); 78static void igb_free_all_rx_resources(struct igb_adapter *);
79static void igb_free_tx_resources(struct igb_ring *);
80static void igb_free_rx_resources(struct igb_ring *);
81void igb_update_stats(struct igb_adapter *); 79void igb_update_stats(struct igb_adapter *);
82static int igb_probe(struct pci_dev *, const struct pci_device_id *); 80static int igb_probe(struct pci_dev *, const struct pci_device_id *);
83static void __devexit igb_remove(struct pci_dev *pdev); 81static void __devexit igb_remove(struct pci_dev *pdev);
@@ -259,11 +257,13 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
259 257
260 for (i = 0; i < adapter->num_tx_queues; i++) { 258 for (i = 0; i < adapter->num_tx_queues; i++) {
261 struct igb_ring *ring = &(adapter->tx_ring[i]); 259 struct igb_ring *ring = &(adapter->tx_ring[i]);
260 ring->count = adapter->tx_ring_count;
262 ring->adapter = adapter; 261 ring->adapter = adapter;
263 ring->queue_index = i; 262 ring->queue_index = i;
264 } 263 }
265 for (i = 0; i < adapter->num_rx_queues; i++) { 264 for (i = 0; i < adapter->num_rx_queues; i++) {
266 struct igb_ring *ring = &(adapter->rx_ring[i]); 265 struct igb_ring *ring = &(adapter->rx_ring[i]);
266 ring->count = adapter->rx_ring_count;
267 ring->adapter = adapter; 267 ring->adapter = adapter;
268 ring->queue_index = i; 268 ring->queue_index = i;
269 ring->itr_register = E1000_ITR; 269 ring->itr_register = E1000_ITR;
@@ -1400,6 +1400,8 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
1400 1400
1401 pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word); 1401 pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);
1402 1402
1403 adapter->tx_ring_count = IGB_DEFAULT_TXD;
1404 adapter->rx_ring_count = IGB_DEFAULT_RXD;
1403 adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; 1405 adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
1404 adapter->rx_ps_hdr_size = 0; /* disable packet split */ 1406 adapter->rx_ps_hdr_size = 0; /* disable packet split */
1405 adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; 1407 adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
@@ -1988,7 +1990,7 @@ static void igb_configure_rx(struct igb_adapter *adapter)
1988 * 1990 *
1989 * Free all transmit software resources 1991 * Free all transmit software resources
1990 **/ 1992 **/
1991static void igb_free_tx_resources(struct igb_ring *tx_ring) 1993void igb_free_tx_resources(struct igb_ring *tx_ring)
1992{ 1994{
1993 struct pci_dev *pdev = tx_ring->adapter->pdev; 1995 struct pci_dev *pdev = tx_ring->adapter->pdev;
1994 1996
@@ -2088,7 +2090,7 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter)
2088 * 2090 *
2089 * Free all receive software resources 2091 * Free all receive software resources
2090 **/ 2092 **/
2091static void igb_free_rx_resources(struct igb_ring *rx_ring) 2093void igb_free_rx_resources(struct igb_ring *rx_ring)
2092{ 2094{
2093 struct pci_dev *pdev = rx_ring->adapter->pdev; 2095 struct pci_dev *pdev = rx_ring->adapter->pdev;
2094 2096