diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2006-12-15 04:39:45 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-26 15:51:30 -0500 |
commit | 018ea44ef1eade417296c4a57afe3cd963268433 (patch) | |
tree | 1be60d1e3f76f49c7675da5c314576ff601db644 /drivers/net/e1000 | |
parent | d89b6c6750e7d7527603b573ec60ba787f5c04a6 (diff) |
[PATCH] e1000: Fix PBA allocation calculations
Assign the PBA to be large enough to contain at least 2 jumbo frames on
all adapters. This dramatically increases performance on several adapters
and fixes TX performance degradation issues where the PBA was misallocated
in the old algorithm.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/e1000')
-rw-r--r-- | drivers/net/e1000/e1000_hw.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 99 |
2 files changed, 86 insertions, 14 deletions
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index f4d01e169c48..15b8625c40c1 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h | |||
@@ -2422,6 +2422,7 @@ struct e1000_host_command_info { | |||
2422 | #define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */ | 2422 | #define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */ |
2423 | #define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */ | 2423 | #define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */ |
2424 | #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ | 2424 | #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ |
2425 | #define E1000_PBA_20K 0x0014 | ||
2425 | #define E1000_PBA_22K 0x0016 | 2426 | #define E1000_PBA_22K 0x0016 |
2426 | #define E1000_PBA_24K 0x0018 | 2427 | #define E1000_PBA_24K 0x0018 |
2427 | #define E1000_PBA_30K 0x001E | 2428 | #define E1000_PBA_30K 0x001E |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index e04f1ba847fd..6c3618d55d15 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -661,16 +661,34 @@ e1000_reinit_locked(struct e1000_adapter *adapter) | |||
661 | void | 661 | void |
662 | e1000_reset(struct e1000_adapter *adapter) | 662 | e1000_reset(struct e1000_adapter *adapter) |
663 | { | 663 | { |
664 | uint32_t pba; | 664 | uint32_t pba = 0, tx_space, min_tx_space, min_rx_space; |
665 | uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF; | 665 | uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF; |
666 | boolean_t legacy_pba_adjust = FALSE; | ||
666 | 667 | ||
667 | /* Repartition Pba for greater than 9k mtu | 668 | /* Repartition Pba for greater than 9k mtu |
668 | * To take effect CTRL.RST is required. | 669 | * To take effect CTRL.RST is required. |
669 | */ | 670 | */ |
670 | 671 | ||
671 | switch (adapter->hw.mac_type) { | 672 | switch (adapter->hw.mac_type) { |
673 | case e1000_82542_rev2_0: | ||
674 | case e1000_82542_rev2_1: | ||
675 | case e1000_82543: | ||
676 | case e1000_82544: | ||
677 | case e1000_82540: | ||
678 | case e1000_82541: | ||
679 | case e1000_82541_rev_2: | ||
680 | legacy_pba_adjust = TRUE; | ||
681 | pba = E1000_PBA_48K; | ||
682 | break; | ||
683 | case e1000_82545: | ||
684 | case e1000_82545_rev_3: | ||
685 | case e1000_82546: | ||
686 | case e1000_82546_rev_3: | ||
687 | pba = E1000_PBA_48K; | ||
688 | break; | ||
672 | case e1000_82547: | 689 | case e1000_82547: |
673 | case e1000_82547_rev_2: | 690 | case e1000_82547_rev_2: |
691 | legacy_pba_adjust = TRUE; | ||
674 | pba = E1000_PBA_30K; | 692 | pba = E1000_PBA_30K; |
675 | break; | 693 | break; |
676 | case e1000_82571: | 694 | case e1000_82571: |
@@ -679,27 +697,80 @@ e1000_reset(struct e1000_adapter *adapter) | |||
679 | pba = E1000_PBA_38K; | 697 | pba = E1000_PBA_38K; |
680 | break; | 698 | break; |
681 | case e1000_82573: | 699 | case e1000_82573: |
682 | pba = E1000_PBA_12K; | 700 | pba = E1000_PBA_20K; |
683 | break; | 701 | break; |
684 | case e1000_ich8lan: | 702 | case e1000_ich8lan: |
685 | pba = E1000_PBA_8K; | 703 | pba = E1000_PBA_8K; |
686 | break; | 704 | case e1000_undefined: |
687 | default: | 705 | case e1000_num_macs: |
688 | pba = E1000_PBA_48K; | ||
689 | break; | 706 | break; |
690 | } | 707 | } |
691 | 708 | ||
692 | if ((adapter->hw.mac_type != e1000_82573) && | 709 | if (legacy_pba_adjust == TRUE) { |
693 | (adapter->netdev->mtu > E1000_RXBUFFER_8192)) | 710 | if (adapter->netdev->mtu > E1000_RXBUFFER_8192) |
694 | pba -= 8; /* allocate more FIFO for Tx */ | 711 | pba -= 8; /* allocate more FIFO for Tx */ |
695 | 712 | ||
713 | if (adapter->hw.mac_type == e1000_82547) { | ||
714 | adapter->tx_fifo_head = 0; | ||
715 | adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; | ||
716 | adapter->tx_fifo_size = | ||
717 | (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; | ||
718 | atomic_set(&adapter->tx_fifo_stall, 0); | ||
719 | } | ||
720 | } else if (adapter->hw.max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) { | ||
721 | /* adjust PBA for jumbo frames */ | ||
722 | E1000_WRITE_REG(&adapter->hw, PBA, pba); | ||
723 | |||
724 | /* To maintain wire speed transmits, the Tx FIFO should be | ||
725 | * large enough to accomodate two full transmit packets, | ||
726 | * rounded up to the next 1KB and expressed in KB. Likewise, | ||
727 | * the Rx FIFO should be large enough to accomodate at least | ||
728 | * one full receive packet and is similarly rounded up and | ||
729 | * expressed in KB. */ | ||
730 | pba = E1000_READ_REG(&adapter->hw, PBA); | ||
731 | /* upper 16 bits has Tx packet buffer allocation size in KB */ | ||
732 | tx_space = pba >> 16; | ||
733 | /* lower 16 bits has Rx packet buffer allocation size in KB */ | ||
734 | pba &= 0xffff; | ||
735 | /* don't include ethernet FCS because hardware appends/strips */ | ||
736 | min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE + | ||
737 | VLAN_TAG_SIZE; | ||
738 | min_tx_space = min_rx_space; | ||
739 | min_tx_space *= 2; | ||
740 | E1000_ROUNDUP(min_tx_space, 1024); | ||
741 | min_tx_space >>= 10; | ||
742 | E1000_ROUNDUP(min_rx_space, 1024); | ||
743 | min_rx_space >>= 10; | ||
744 | |||
745 | /* If current Tx allocation is less than the min Tx FIFO size, | ||
746 | * and the min Tx FIFO size is less than the current Rx FIFO | ||
747 | * allocation, take space away from current Rx allocation */ | ||
748 | if (tx_space < min_tx_space && | ||
749 | ((min_tx_space - tx_space) < pba)) { | ||
750 | pba = pba - (min_tx_space - tx_space); | ||
751 | |||
752 | /* PCI/PCIx hardware has PBA alignment constraints */ | ||
753 | switch (adapter->hw.mac_type) { | ||
754 | case e1000_82545 ... e1000_82546_rev_3: | ||
755 | pba &= ~(E1000_PBA_8K - 1); | ||
756 | break; | ||
757 | default: | ||
758 | break; | ||
759 | } | ||
696 | 760 | ||
697 | if (adapter->hw.mac_type == e1000_82547) { | 761 | /* if short on rx space, rx wins and must trump tx |
698 | adapter->tx_fifo_head = 0; | 762 | * adjustment or use Early Receive if available */ |
699 | adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; | 763 | if (pba < min_rx_space) { |
700 | adapter->tx_fifo_size = | 764 | switch (adapter->hw.mac_type) { |
701 | (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; | 765 | case e1000_82573: |
702 | atomic_set(&adapter->tx_fifo_stall, 0); | 766 | /* ERT enabled in e1000_configure_rx */ |
767 | break; | ||
768 | default: | ||
769 | pba = min_rx_space; | ||
770 | break; | ||
771 | } | ||
772 | } | ||
773 | } | ||
703 | } | 774 | } |
704 | 775 | ||
705 | E1000_WRITE_REG(&adapter->hw, PBA, pba); | 776 | E1000_WRITE_REG(&adapter->hw, PBA, pba); |