diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2008-06-27 14:00:29 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-07-04 08:47:00 -0400 |
commit | 662d7205b3db0bf9ebcae31f30ed72a1bceb47af (patch) | |
tree | 85f217f793ba893a346d042c2af54aa6be7f30f2 /drivers/net/igb | |
parent | 652fff321490fc3fcc8e8d302826a9c2379f03d2 (diff) |
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>
Diffstat (limited to 'drivers/net/igb')
-rw-r--r-- | drivers/net/igb/e1000_82575.c | 73 | ||||
-rw-r--r-- | drivers/net/igb/e1000_82575.h | 2 | ||||
-rw-r--r-- | drivers/net/igb/e1000_defines.h | 1 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 3 |
4 files changed, 79 insertions, 0 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 84ef695ccaca..2c8b91060d98 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
@@ -1227,6 +1227,79 @@ static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw) | |||
1227 | temp = rd32(E1000_SCVPC); | 1227 | temp = rd32(E1000_SCVPC); |
1228 | } | 1228 | } |
1229 | 1229 | ||
1230 | /** | ||
1231 | * igb_rx_fifo_flush_82575 - Clean rx fifo after RX enable | ||
1232 | * @hw: pointer to the HW structure | ||
1233 | * | ||
1234 | * After rx enable if managability is enabled then there is likely some | ||
1235 | * bad data at the start of the fifo and possibly in the DMA fifo. This | ||
1236 | * function clears the fifos and flushes any packets that came in as rx was | ||
1237 | * being enabled. | ||
1238 | **/ | ||
1239 | void igb_rx_fifo_flush_82575(struct e1000_hw *hw) | ||
1240 | { | ||
1241 | u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled; | ||
1242 | int i, ms_wait; | ||
1243 | |||
1244 | if (hw->mac.type != e1000_82575 || | ||
1245 | !(rd32(E1000_MANC) & E1000_MANC_RCV_TCO_EN)) | ||
1246 | return; | ||
1247 | |||
1248 | /* Disable all RX queues */ | ||
1249 | for (i = 0; i < 4; i++) { | ||
1250 | rxdctl[i] = rd32(E1000_RXDCTL(i)); | ||
1251 | wr32(E1000_RXDCTL(i), | ||
1252 | rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE); | ||
1253 | } | ||
1254 | /* Poll all queues to verify they have shut down */ | ||
1255 | for (ms_wait = 0; ms_wait < 10; ms_wait++) { | ||
1256 | msleep(1); | ||
1257 | rx_enabled = 0; | ||
1258 | for (i = 0; i < 4; i++) | ||
1259 | rx_enabled |= rd32(E1000_RXDCTL(i)); | ||
1260 | if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE)) | ||
1261 | break; | ||
1262 | } | ||
1263 | |||
1264 | if (ms_wait == 10) | ||
1265 | hw_dbg("Queue disable timed out after 10ms\n"); | ||
1266 | |||
1267 | /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all | ||
1268 | * incoming packets are rejected. Set enable and wait 2ms so that | ||
1269 | * any packet that was coming in as RCTL.EN was set is flushed | ||
1270 | */ | ||
1271 | rfctl = rd32(E1000_RFCTL); | ||
1272 | wr32(E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF); | ||
1273 | |||
1274 | rlpml = rd32(E1000_RLPML); | ||
1275 | wr32(E1000_RLPML, 0); | ||
1276 | |||
1277 | rctl = rd32(E1000_RCTL); | ||
1278 | temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP); | ||
1279 | temp_rctl |= E1000_RCTL_LPE; | ||
1280 | |||
1281 | wr32(E1000_RCTL, temp_rctl); | ||
1282 | wr32(E1000_RCTL, temp_rctl | E1000_RCTL_EN); | ||
1283 | wrfl(); | ||
1284 | msleep(2); | ||
1285 | |||
1286 | /* Enable RX queues that were previously enabled and restore our | ||
1287 | * previous state | ||
1288 | */ | ||
1289 | for (i = 0; i < 4; i++) | ||
1290 | wr32(E1000_RXDCTL(i), rxdctl[i]); | ||
1291 | wr32(E1000_RCTL, rctl); | ||
1292 | wrfl(); | ||
1293 | |||
1294 | wr32(E1000_RLPML, rlpml); | ||
1295 | wr32(E1000_RFCTL, rfctl); | ||
1296 | |||
1297 | /* Flush receive errors generated by workaround */ | ||
1298 | rd32(E1000_ROC); | ||
1299 | rd32(E1000_RNBC); | ||
1300 | rd32(E1000_MPC); | ||
1301 | } | ||
1302 | |||
1230 | static struct e1000_mac_operations e1000_mac_ops_82575 = { | 1303 | static struct e1000_mac_operations e1000_mac_ops_82575 = { |
1231 | .reset_hw = igb_reset_hw_82575, | 1304 | .reset_hw = igb_reset_hw_82575, |
1232 | .init_hw = igb_init_hw_82575, | 1305 | .init_hw = igb_init_hw_82575, |
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index 5fb79dd0e940..d78ad33d32bf 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h | |||
@@ -28,6 +28,8 @@ | |||
28 | #ifndef _E1000_82575_H_ | 28 | #ifndef _E1000_82575_H_ |
29 | #define _E1000_82575_H_ | 29 | #define _E1000_82575_H_ |
30 | 30 | ||
31 | extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw); | ||
32 | |||
31 | #define E1000_RAR_ENTRIES_82575 16 | 33 | #define E1000_RAR_ENTRIES_82575 16 |
32 | 34 | ||
33 | /* SRRCTL bit definitions */ | 35 | /* SRRCTL bit definitions */ |
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 1006d53fd688..ed748dcfb7a4 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h | |||
@@ -340,6 +340,7 @@ | |||
340 | #define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ | 340 | #define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ |
341 | 341 | ||
342 | /* Header split receive */ | 342 | /* Header split receive */ |
343 | #define E1000_RFCTL_LEF 0x00040000 | ||
343 | 344 | ||
344 | /* Collision related configuration parameters */ | 345 | /* Collision related configuration parameters */ |
345 | #define E1000_COLLISION_THRESHOLD 15 | 346 | #define E1000_COLLISION_THRESHOLD 15 |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index d8bee212d61f..e5dff61f162e 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -630,6 +630,9 @@ static void igb_configure(struct igb_adapter *adapter) | |||
630 | igb_configure_tx(adapter); | 630 | igb_configure_tx(adapter); |
631 | igb_setup_rctl(adapter); | 631 | igb_setup_rctl(adapter); |
632 | igb_configure_rx(adapter); | 632 | igb_configure_rx(adapter); |
633 | |||
634 | igb_rx_fifo_flush_82575(&adapter->hw); | ||
635 | |||
633 | /* call IGB_DESC_UNUSED which always leaves | 636 | /* call IGB_DESC_UNUSED which always leaves |
634 | * at least 1 descriptor unused to make sure | 637 | * at least 1 descriptor unused to make sure |
635 | * next_to_use != next_to_clean */ | 638 | * next_to_use != next_to_clean */ |