diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2011-02-02 05:19:50 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-02-17 04:11:21 -0500 |
commit | 713b3c9e4c1a6da6b45da6474ed554ed0a48de69 (patch) | |
tree | 9c578651c91b70da176e3a65a5537aad53814e15 | |
parent | 615b32af9730def64330e4c0c95c973e90bd9c6d (diff) |
e1000e: flush all writebacks before unload
The driver was not flushing all writebacks before unloading, possibly
causing memory to be written by the hardware after the driver had
reinitialized the rings.
This adds missing functionality to flush any pending writebacks and is
called in all spots where descriptors should be completed before the driver
begins processing.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Reviewed-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/e1000e/netdev.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 174633c93325..3fa110ddb041 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -3344,6 +3344,21 @@ int e1000e_up(struct e1000_adapter *adapter) | |||
3344 | return 0; | 3344 | return 0; |
3345 | } | 3345 | } |
3346 | 3346 | ||
3347 | static void e1000e_flush_descriptors(struct e1000_adapter *adapter) | ||
3348 | { | ||
3349 | struct e1000_hw *hw = &adapter->hw; | ||
3350 | |||
3351 | if (!(adapter->flags2 & FLAG2_DMA_BURST)) | ||
3352 | return; | ||
3353 | |||
3354 | /* flush pending descriptor writebacks to memory */ | ||
3355 | ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); | ||
3356 | ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); | ||
3357 | |||
3358 | /* execute the writes immediately */ | ||
3359 | e1e_flush(); | ||
3360 | } | ||
3361 | |||
3347 | void e1000e_down(struct e1000_adapter *adapter) | 3362 | void e1000e_down(struct e1000_adapter *adapter) |
3348 | { | 3363 | { |
3349 | struct net_device *netdev = adapter->netdev; | 3364 | struct net_device *netdev = adapter->netdev; |
@@ -3383,6 +3398,9 @@ void e1000e_down(struct e1000_adapter *adapter) | |||
3383 | 3398 | ||
3384 | if (!pci_channel_offline(adapter->pdev)) | 3399 | if (!pci_channel_offline(adapter->pdev)) |
3385 | e1000e_reset(adapter); | 3400 | e1000e_reset(adapter); |
3401 | |||
3402 | e1000e_flush_descriptors(adapter); | ||
3403 | |||
3386 | e1000_clean_tx_ring(adapter); | 3404 | e1000_clean_tx_ring(adapter); |
3387 | e1000_clean_rx_ring(adapter); | 3405 | e1000_clean_rx_ring(adapter); |
3388 | 3406 | ||
@@ -4354,19 +4372,12 @@ link_up: | |||
4354 | else | 4372 | else |
4355 | ew32(ICS, E1000_ICS_RXDMT0); | 4373 | ew32(ICS, E1000_ICS_RXDMT0); |
4356 | 4374 | ||
4375 | /* flush pending descriptors to memory before detecting Tx hang */ | ||
4376 | e1000e_flush_descriptors(adapter); | ||
4377 | |||
4357 | /* Force detection of hung controller every watchdog period */ | 4378 | /* Force detection of hung controller every watchdog period */ |
4358 | adapter->detect_tx_hung = 1; | 4379 | adapter->detect_tx_hung = 1; |
4359 | 4380 | ||
4360 | /* flush partial descriptors to memory before detecting Tx hang */ | ||
4361 | if (adapter->flags2 & FLAG2_DMA_BURST) { | ||
4362 | ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); | ||
4363 | ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); | ||
4364 | /* | ||
4365 | * no need to flush the writes because the timeout code does | ||
4366 | * an er32 first thing | ||
4367 | */ | ||
4368 | } | ||
4369 | |||
4370 | /* | 4381 | /* |
4371 | * With 82571 controllers, LAA may be overwritten due to controller | 4382 | * With 82571 controllers, LAA may be overwritten due to controller |
4372 | * reset from the other port. Set the appropriate LAA in RAR[0] | 4383 | * reset from the other port. Set the appropriate LAA in RAR[0] |