[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>
This commit is contained in:
parent
d89b6c6750
commit
018ea44ef1
2 changed files with 86 additions and 14 deletions
|
@ -2422,6 +2422,7 @@ struct e1000_host_command_info {
|
|||
#define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */
|
||||
#define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */
|
||||
#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
|
||||
#define E1000_PBA_20K 0x0014
|
||||
#define E1000_PBA_22K 0x0016
|
||||
#define E1000_PBA_24K 0x0018
|
||||
#define E1000_PBA_30K 0x001E
|
||||
|
|
|
@ -661,16 +661,34 @@ e1000_reinit_locked(struct e1000_adapter *adapter)
|
|||
void
|
||||
e1000_reset(struct e1000_adapter *adapter)
|
||||
{
|
||||
uint32_t pba;
|
||||
uint32_t pba = 0, tx_space, min_tx_space, min_rx_space;
|
||||
uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
|
||||
boolean_t legacy_pba_adjust = FALSE;
|
||||
|
||||
/* Repartition Pba for greater than 9k mtu
|
||||
* To take effect CTRL.RST is required.
|
||||
*/
|
||||
|
||||
switch (adapter->hw.mac_type) {
|
||||
case e1000_82542_rev2_0:
|
||||
case e1000_82542_rev2_1:
|
||||
case e1000_82543:
|
||||
case e1000_82544:
|
||||
case e1000_82540:
|
||||
case e1000_82541:
|
||||
case e1000_82541_rev_2:
|
||||
legacy_pba_adjust = TRUE;
|
||||
pba = E1000_PBA_48K;
|
||||
break;
|
||||
case e1000_82545:
|
||||
case e1000_82545_rev_3:
|
||||
case e1000_82546:
|
||||
case e1000_82546_rev_3:
|
||||
pba = E1000_PBA_48K;
|
||||
break;
|
||||
case e1000_82547:
|
||||
case e1000_82547_rev_2:
|
||||
legacy_pba_adjust = TRUE;
|
||||
pba = E1000_PBA_30K;
|
||||
break;
|
||||
case e1000_82571:
|
||||
|
@ -679,27 +697,80 @@ e1000_reset(struct e1000_adapter *adapter)
|
|||
pba = E1000_PBA_38K;
|
||||
break;
|
||||
case e1000_82573:
|
||||
pba = E1000_PBA_12K;
|
||||
pba = E1000_PBA_20K;
|
||||
break;
|
||||
case e1000_ich8lan:
|
||||
pba = E1000_PBA_8K;
|
||||
break;
|
||||
default:
|
||||
pba = E1000_PBA_48K;
|
||||
case e1000_undefined:
|
||||
case e1000_num_macs:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((adapter->hw.mac_type != e1000_82573) &&
|
||||
(adapter->netdev->mtu > E1000_RXBUFFER_8192))
|
||||
pba -= 8; /* allocate more FIFO for Tx */
|
||||
if (legacy_pba_adjust == TRUE) {
|
||||
if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
|
||||
pba -= 8; /* allocate more FIFO for Tx */
|
||||
|
||||
if (adapter->hw.mac_type == e1000_82547) {
|
||||
adapter->tx_fifo_head = 0;
|
||||
adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
|
||||
adapter->tx_fifo_size =
|
||||
(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
|
||||
atomic_set(&adapter->tx_fifo_stall, 0);
|
||||
}
|
||||
} else if (adapter->hw.max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
|
||||
/* adjust PBA for jumbo frames */
|
||||
E1000_WRITE_REG(&adapter->hw, PBA, pba);
|
||||
|
||||
if (adapter->hw.mac_type == e1000_82547) {
|
||||
adapter->tx_fifo_head = 0;
|
||||
adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
|
||||
adapter->tx_fifo_size =
|
||||
(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
|
||||
atomic_set(&adapter->tx_fifo_stall, 0);
|
||||
/* To maintain wire speed transmits, the Tx FIFO should be
|
||||
* large enough to accomodate two full transmit packets,
|
||||
* rounded up to the next 1KB and expressed in KB. Likewise,
|
||||
* the Rx FIFO should be large enough to accomodate at least
|
||||
* one full receive packet and is similarly rounded up and
|
||||
* expressed in KB. */
|
||||
pba = E1000_READ_REG(&adapter->hw, PBA);
|
||||
/* upper 16 bits has Tx packet buffer allocation size in KB */
|
||||
tx_space = pba >> 16;
|
||||
/* lower 16 bits has Rx packet buffer allocation size in KB */
|
||||
pba &= 0xffff;
|
||||
/* don't include ethernet FCS because hardware appends/strips */
|
||||
min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE +
|
||||
VLAN_TAG_SIZE;
|
||||
min_tx_space = min_rx_space;
|
||||
min_tx_space *= 2;
|
||||
E1000_ROUNDUP(min_tx_space, 1024);
|
||||
min_tx_space >>= 10;
|
||||
E1000_ROUNDUP(min_rx_space, 1024);
|
||||
min_rx_space >>= 10;
|
||||
|
||||
/* If current Tx allocation is less than the min Tx FIFO size,
|
||||
* and the min Tx FIFO size is less than the current Rx FIFO
|
||||
* allocation, take space away from current Rx allocation */
|
||||
if (tx_space < min_tx_space &&
|
||||
((min_tx_space - tx_space) < pba)) {
|
||||
pba = pba - (min_tx_space - tx_space);
|
||||
|
||||
/* PCI/PCIx hardware has PBA alignment constraints */
|
||||
switch (adapter->hw.mac_type) {
|
||||
case e1000_82545 ... e1000_82546_rev_3:
|
||||
pba &= ~(E1000_PBA_8K - 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* if short on rx space, rx wins and must trump tx
|
||||
* adjustment or use Early Receive if available */
|
||||
if (pba < min_rx_space) {
|
||||
switch (adapter->hw.mac_type) {
|
||||
case e1000_82573:
|
||||
/* ERT enabled in e1000_configure_rx */
|
||||
break;
|
||||
default:
|
||||
pba = min_rx_space;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
E1000_WRITE_REG(&adapter->hw, PBA, pba);
|
||||
|
|
Loading…
Reference in a new issue