aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2008-06-27 14:00:29 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-07-04 08:47:00 -0400
commit662d7205b3db0bf9ebcae31f30ed72a1bceb47af (patch)
tree85f217f793ba893a346d042c2af54aa6be7f30f2 /drivers/net/igb
parent652fff321490fc3fcc8e8d302826a9c2379f03d2 (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.c73
-rw-r--r--drivers/net/igb/e1000_82575.h2
-rw-r--r--drivers/net/igb/e1000_defines.h1
-rw-r--r--drivers/net/igb/igb_main.c3
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 **/
1239void 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
1230static struct e1000_mac_operations e1000_mac_ops_82575 = { 1303static 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
31extern 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 */