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 { ...@@ -2422,6 +2422,7 @@ struct e1000_host_command_info {
#define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */ #define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */
#define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */ #define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */
#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
#define E1000_PBA_20K 0x0014
#define E1000_PBA_22K 0x0016 #define E1000_PBA_22K 0x0016
#define E1000_PBA_24K 0x0018 #define E1000_PBA_24K 0x0018
#define E1000_PBA_30K 0x001E #define E1000_PBA_30K 0x001E
......
...@@ -661,16 +661,34 @@ e1000_reinit_locked(struct e1000_adapter *adapter) ...@@ -661,16 +661,34 @@ e1000_reinit_locked(struct e1000_adapter *adapter)
void void
e1000_reset(struct e1000_adapter *adapter) 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; uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
boolean_t legacy_pba_adjust = FALSE;
/* Repartition Pba for greater than 9k mtu /* Repartition Pba for greater than 9k mtu
* To take effect CTRL.RST is required. * To take effect CTRL.RST is required.
*/ */
switch (adapter->hw.mac_type) { 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:
case e1000_82547_rev_2: case e1000_82547_rev_2:
legacy_pba_adjust = TRUE;
pba = E1000_PBA_30K; pba = E1000_PBA_30K;
break; break;
case e1000_82571: case e1000_82571:
...@@ -679,21 +697,19 @@ e1000_reset(struct e1000_adapter *adapter) ...@@ -679,21 +697,19 @@ e1000_reset(struct e1000_adapter *adapter)
pba = E1000_PBA_38K; pba = E1000_PBA_38K;
break; break;
case e1000_82573: case e1000_82573:
pba = E1000_PBA_12K; pba = E1000_PBA_20K;
break; break;
case e1000_ich8lan: case e1000_ich8lan:
pba = E1000_PBA_8K; pba = E1000_PBA_8K;
break; case e1000_undefined:
default: case e1000_num_macs:
pba = E1000_PBA_48K;
break; break;
} }
if ((adapter->hw.mac_type != e1000_82573) && if (legacy_pba_adjust == TRUE) {
(adapter->netdev->mtu > E1000_RXBUFFER_8192)) if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
pba -= 8; /* allocate more FIFO for Tx */ pba -= 8; /* allocate more FIFO for Tx */
if (adapter->hw.mac_type == e1000_82547) { if (adapter->hw.mac_type == e1000_82547) {
adapter->tx_fifo_head = 0; adapter->tx_fifo_head = 0;
adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
...@@ -701,6 +717,61 @@ e1000_reset(struct e1000_adapter *adapter) ...@@ -701,6 +717,61 @@ e1000_reset(struct e1000_adapter *adapter)
(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
atomic_set(&adapter->tx_fifo_stall, 0); 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 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); 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