diff options
| author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2011-07-19 20:56:21 -0400 |
|---|---|---|
| committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-08-04 07:59:07 -0400 |
| commit | 945a51517cc0bd9e461f2018624dfc1faef9ddee (patch) | |
| tree | 5782ffe27f3fb8f5b4cbc19ffe7b74bff36c6a05 /drivers/net/igb | |
| parent | d3e614577198757d5854caa912e88f2d4296479b (diff) | |
intel drivers: repair missing flush operations
after review of all intel drivers, found several instances where
drivers had the incorrect pattern of:
memory mapped write();
delay();
which should always be:
memory mapped write();
write flush(); /* aka memory mapped read */
delay();
explanation:
The reason for including the flush is that writes can be held
(posted) in PCI/PCIe bridges, but the read always has to complete
synchronously and therefore has to flush all pending writes to a
device. If a write is held and followed by a delay, the delay
means nothing because the write may not have reached hardware
(maybe even not until the next read)
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/igb')
| -rw-r--r-- | drivers/net/igb/e1000_nvm.c | 1 | ||||
| -rw-r--r-- | drivers/net/igb/igb_ethtool.c | 5 | ||||
| -rw-r--r-- | drivers/net/igb/igb_main.c | 2 |
3 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c index 7dcd65cede56..40407124e722 100644 --- a/drivers/net/igb/e1000_nvm.c +++ b/drivers/net/igb/e1000_nvm.c | |||
| @@ -285,6 +285,7 @@ static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw) | |||
| 285 | /* Clear SK and CS */ | 285 | /* Clear SK and CS */ |
| 286 | eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); | 286 | eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); |
| 287 | wr32(E1000_EECD, eecd); | 287 | wr32(E1000_EECD, eecd); |
| 288 | wrfl(); | ||
| 288 | udelay(1); | 289 | udelay(1); |
| 289 | timeout = NVM_MAX_RETRY_SPI; | 290 | timeout = NVM_MAX_RETRY_SPI; |
| 290 | 291 | ||
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index ff244ce803ce..414b0225be89 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c | |||
| @@ -1225,6 +1225,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) | |||
| 1225 | 1225 | ||
| 1226 | /* Disable all the interrupts */ | 1226 | /* Disable all the interrupts */ |
| 1227 | wr32(E1000_IMC, ~0); | 1227 | wr32(E1000_IMC, ~0); |
| 1228 | wrfl(); | ||
| 1228 | msleep(10); | 1229 | msleep(10); |
| 1229 | 1230 | ||
| 1230 | /* Define all writable bits for ICS */ | 1231 | /* Define all writable bits for ICS */ |
| @@ -1268,6 +1269,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) | |||
| 1268 | 1269 | ||
| 1269 | wr32(E1000_IMC, mask); | 1270 | wr32(E1000_IMC, mask); |
| 1270 | wr32(E1000_ICS, mask); | 1271 | wr32(E1000_ICS, mask); |
| 1272 | wrfl(); | ||
| 1271 | msleep(10); | 1273 | msleep(10); |
| 1272 | 1274 | ||
| 1273 | if (adapter->test_icr & mask) { | 1275 | if (adapter->test_icr & mask) { |
| @@ -1289,6 +1291,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) | |||
| 1289 | 1291 | ||
| 1290 | wr32(E1000_IMS, mask); | 1292 | wr32(E1000_IMS, mask); |
| 1291 | wr32(E1000_ICS, mask); | 1293 | wr32(E1000_ICS, mask); |
| 1294 | wrfl(); | ||
| 1292 | msleep(10); | 1295 | msleep(10); |
| 1293 | 1296 | ||
| 1294 | if (!(adapter->test_icr & mask)) { | 1297 | if (!(adapter->test_icr & mask)) { |
| @@ -1310,6 +1313,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) | |||
| 1310 | 1313 | ||
| 1311 | wr32(E1000_IMC, ~mask); | 1314 | wr32(E1000_IMC, ~mask); |
| 1312 | wr32(E1000_ICS, ~mask); | 1315 | wr32(E1000_ICS, ~mask); |
| 1316 | wrfl(); | ||
| 1313 | msleep(10); | 1317 | msleep(10); |
| 1314 | 1318 | ||
| 1315 | if (adapter->test_icr & mask) { | 1319 | if (adapter->test_icr & mask) { |
| @@ -1321,6 +1325,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) | |||
| 1321 | 1325 | ||
| 1322 | /* Disable all the interrupts */ | 1326 | /* Disable all the interrupts */ |
| 1323 | wr32(E1000_IMC, ~0); | 1327 | wr32(E1000_IMC, ~0); |
| 1328 | wrfl(); | ||
| 1324 | msleep(10); | 1329 | msleep(10); |
| 1325 | 1330 | ||
| 1326 | /* Unhook test interrupt handler */ | 1331 | /* Unhook test interrupt handler */ |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index dc599059512a..ae3937e8cdef 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
| @@ -1052,6 +1052,7 @@ msi_only: | |||
| 1052 | kfree(adapter->vf_data); | 1052 | kfree(adapter->vf_data); |
| 1053 | adapter->vf_data = NULL; | 1053 | adapter->vf_data = NULL; |
| 1054 | wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); | 1054 | wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); |
| 1055 | wrfl(); | ||
| 1055 | msleep(100); | 1056 | msleep(100); |
| 1056 | dev_info(&adapter->pdev->dev, "IOV Disabled\n"); | 1057 | dev_info(&adapter->pdev->dev, "IOV Disabled\n"); |
| 1057 | } | 1058 | } |
| @@ -2198,6 +2199,7 @@ static void __devexit igb_remove(struct pci_dev *pdev) | |||
| 2198 | kfree(adapter->vf_data); | 2199 | kfree(adapter->vf_data); |
| 2199 | adapter->vf_data = NULL; | 2200 | adapter->vf_data = NULL; |
| 2200 | wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); | 2201 | wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); |
| 2202 | wrfl(); | ||
| 2201 | msleep(100); | 2203 | msleep(100); |
| 2202 | dev_info(&pdev->dev, "IOV Disabled\n"); | 2204 | dev_info(&pdev->dev, "IOV Disabled\n"); |
| 2203 | } | 2205 | } |
