Commit 018ea44e authored by Bruce Allan's avatar Bruce Allan Committed by Jeff Garzik

[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: default avatarBruce Allan <bruce.w.allan@intel.com>
Signed-off-by: default avatarAuke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: default avatarArjan van de Ven <arjan@linux.intel.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent d89b6c67
......@@ -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);
/* 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 (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);
/* 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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment