|
@@ -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;
|
|
|
|
- default:
|
|
|
|
- pba = E1000_PBA_48K;
|
|
|
|
|
|
+ case e1000_undefined:
|
|
|
|
+ case e1000_num_macs:
|
|
break;
|
|
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);
|
|
E1000_WRITE_REG(&adapter->hw, PBA, pba);
|