[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
|
@ -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)
|
||||||
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,27 +697,80 @@ 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) {
|
||||||
|
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) {
|
/* To maintain wire speed transmits, the Tx FIFO should be
|
||||||
adapter->tx_fifo_head = 0;
|
* large enough to accomodate two full transmit packets,
|
||||||
adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
|
* rounded up to the next 1KB and expressed in KB. Likewise,
|
||||||
adapter->tx_fifo_size =
|
* the Rx FIFO should be large enough to accomodate at least
|
||||||
(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
|
* one full receive packet and is similarly rounded up and
|
||||||
atomic_set(&adapter->tx_fifo_stall, 0);
|
* 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);
|
||||||
|
|
Loading…
Reference in New Issue