igb: fix init on 82575 with MNG enabled
This patch resolves an issue seen on 82575 adapters with managability pass-thru enabled, which could cause the system to panic. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
parent
652fff3214
commit
662d7205b3
4 changed files with 79 additions and 0 deletions
|
@ -1227,6 +1227,79 @@ static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw)
|
|||
temp = rd32(E1000_SCVPC);
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_rx_fifo_flush_82575 - Clean rx fifo after RX enable
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* After rx enable if managability is enabled then there is likely some
|
||||
* bad data at the start of the fifo and possibly in the DMA fifo. This
|
||||
* function clears the fifos and flushes any packets that came in as rx was
|
||||
* being enabled.
|
||||
**/
|
||||
void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
|
||||
{
|
||||
u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
|
||||
int i, ms_wait;
|
||||
|
||||
if (hw->mac.type != e1000_82575 ||
|
||||
!(rd32(E1000_MANC) & E1000_MANC_RCV_TCO_EN))
|
||||
return;
|
||||
|
||||
/* Disable all RX queues */
|
||||
for (i = 0; i < 4; i++) {
|
||||
rxdctl[i] = rd32(E1000_RXDCTL(i));
|
||||
wr32(E1000_RXDCTL(i),
|
||||
rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
|
||||
}
|
||||
/* Poll all queues to verify they have shut down */
|
||||
for (ms_wait = 0; ms_wait < 10; ms_wait++) {
|
||||
msleep(1);
|
||||
rx_enabled = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
rx_enabled |= rd32(E1000_RXDCTL(i));
|
||||
if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ms_wait == 10)
|
||||
hw_dbg("Queue disable timed out after 10ms\n");
|
||||
|
||||
/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
|
||||
* incoming packets are rejected. Set enable and wait 2ms so that
|
||||
* any packet that was coming in as RCTL.EN was set is flushed
|
||||
*/
|
||||
rfctl = rd32(E1000_RFCTL);
|
||||
wr32(E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
|
||||
|
||||
rlpml = rd32(E1000_RLPML);
|
||||
wr32(E1000_RLPML, 0);
|
||||
|
||||
rctl = rd32(E1000_RCTL);
|
||||
temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
|
||||
temp_rctl |= E1000_RCTL_LPE;
|
||||
|
||||
wr32(E1000_RCTL, temp_rctl);
|
||||
wr32(E1000_RCTL, temp_rctl | E1000_RCTL_EN);
|
||||
wrfl();
|
||||
msleep(2);
|
||||
|
||||
/* Enable RX queues that were previously enabled and restore our
|
||||
* previous state
|
||||
*/
|
||||
for (i = 0; i < 4; i++)
|
||||
wr32(E1000_RXDCTL(i), rxdctl[i]);
|
||||
wr32(E1000_RCTL, rctl);
|
||||
wrfl();
|
||||
|
||||
wr32(E1000_RLPML, rlpml);
|
||||
wr32(E1000_RFCTL, rfctl);
|
||||
|
||||
/* Flush receive errors generated by workaround */
|
||||
rd32(E1000_ROC);
|
||||
rd32(E1000_RNBC);
|
||||
rd32(E1000_MPC);
|
||||
}
|
||||
|
||||
static struct e1000_mac_operations e1000_mac_ops_82575 = {
|
||||
.reset_hw = igb_reset_hw_82575,
|
||||
.init_hw = igb_init_hw_82575,
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#ifndef _E1000_82575_H_
|
||||
#define _E1000_82575_H_
|
||||
|
||||
extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
|
||||
|
||||
#define E1000_RAR_ENTRIES_82575 16
|
||||
|
||||
/* SRRCTL bit definitions */
|
||||
|
|
|
@ -340,6 +340,7 @@
|
|||
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
|
||||
|
||||
/* Header split receive */
|
||||
#define E1000_RFCTL_LEF 0x00040000
|
||||
|
||||
/* Collision related configuration parameters */
|
||||
#define E1000_COLLISION_THRESHOLD 15
|
||||
|
|
|
@ -630,6 +630,9 @@ static void igb_configure(struct igb_adapter *adapter)
|
|||
igb_configure_tx(adapter);
|
||||
igb_setup_rctl(adapter);
|
||||
igb_configure_rx(adapter);
|
||||
|
||||
igb_rx_fifo_flush_82575(&adapter->hw);
|
||||
|
||||
/* call IGB_DESC_UNUSED which always leaves
|
||||
* at least 1 descriptor unused to make sure
|
||||
* next_to_use != next_to_clean */
|
||||
|
|
Loading…
Reference in a new issue