diff options
| author | Auke Kok <auke-jan.h.kok@intel.com> | 2006-06-27 12:07:08 -0400 |
|---|---|---|
| committer | Auke Kok <juke-jan.h.kok@intel.com> | 2006-06-27 12:07:08 -0400 |
| commit | 4ca213a6957318219822c024c8e4c61b3e42a7dc (patch) | |
| tree | 9bef34eab2afb685c9e61d0a34bab6ff5c0811f3 /drivers | |
| parent | 17231712ab89fa085bc235ef19c1e6e0c163e4fc (diff) | |
e1000: force register write flushes to circumvent broken platforms
A certain AMD64 bridge (8132) has an option to turn on write combining
which breaks our adapter. To circumvent this we need to flush every write.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/e1000/e1000_hw.c | 24 | ||||
| -rw-r--r-- | drivers/net/e1000/e1000_main.c | 18 |
2 files changed, 33 insertions, 9 deletions
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 3959039b16ec..749d621a07da 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c | |||
| @@ -705,8 +705,12 @@ e1000_init_hw(struct e1000_hw *hw) | |||
| 705 | /* Zero out the Multicast HASH table */ | 705 | /* Zero out the Multicast HASH table */ |
| 706 | DEBUGOUT("Zeroing the MTA\n"); | 706 | DEBUGOUT("Zeroing the MTA\n"); |
| 707 | mta_size = E1000_MC_TBL_SIZE; | 707 | mta_size = E1000_MC_TBL_SIZE; |
| 708 | for(i = 0; i < mta_size; i++) | 708 | for(i = 0; i < mta_size; i++) { |
| 709 | E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); | 709 | E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); |
| 710 | /* use write flush to prevent Memory Write Block (MWB) from | ||
| 711 | * occuring when accessing our register space */ | ||
| 712 | E1000_WRITE_FLUSH(hw); | ||
| 713 | } | ||
| 710 | 714 | ||
| 711 | /* Set the PCI priority bit correctly in the CTRL register. This | 715 | /* Set the PCI priority bit correctly in the CTRL register. This |
| 712 | * determines if the adapter gives priority to receives, or if it | 716 | * determines if the adapter gives priority to receives, or if it |
| @@ -5106,7 +5110,9 @@ e1000_init_rx_addrs(struct e1000_hw *hw) | |||
| 5106 | DEBUGOUT("Clearing RAR[1-15]\n"); | 5110 | DEBUGOUT("Clearing RAR[1-15]\n"); |
| 5107 | for(i = 1; i < rar_num; i++) { | 5111 | for(i = 1; i < rar_num; i++) { |
| 5108 | E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); | 5112 | E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); |
| 5113 | E1000_WRITE_FLUSH(hw); | ||
| 5109 | E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); | 5114 | E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); |
| 5115 | E1000_WRITE_FLUSH(hw); | ||
| 5110 | } | 5116 | } |
| 5111 | } | 5117 | } |
| 5112 | 5118 | ||
| @@ -5153,7 +5159,9 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, | |||
| 5153 | 5159 | ||
| 5154 | for(i = rar_used_count; i < num_rar_entry; i++) { | 5160 | for(i = rar_used_count; i < num_rar_entry; i++) { |
| 5155 | E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); | 5161 | E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); |
| 5162 | E1000_WRITE_FLUSH(hw); | ||
| 5156 | E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); | 5163 | E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); |
| 5164 | E1000_WRITE_FLUSH(hw); | ||
| 5157 | } | 5165 | } |
| 5158 | 5166 | ||
| 5159 | /* Clear the MTA */ | 5167 | /* Clear the MTA */ |
| @@ -5161,6 +5169,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, | |||
| 5161 | num_mta_entry = E1000_NUM_MTA_REGISTERS; | 5169 | num_mta_entry = E1000_NUM_MTA_REGISTERS; |
| 5162 | for(i = 0; i < num_mta_entry; i++) { | 5170 | for(i = 0; i < num_mta_entry; i++) { |
| 5163 | E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); | 5171 | E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); |
| 5172 | E1000_WRITE_FLUSH(hw); | ||
| 5164 | } | 5173 | } |
| 5165 | 5174 | ||
| 5166 | /* Add the new addresses */ | 5175 | /* Add the new addresses */ |
| @@ -5275,9 +5284,12 @@ e1000_mta_set(struct e1000_hw *hw, | |||
| 5275 | if((hw->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) { | 5284 | if((hw->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) { |
| 5276 | temp = E1000_READ_REG_ARRAY(hw, MTA, (hash_reg - 1)); | 5285 | temp = E1000_READ_REG_ARRAY(hw, MTA, (hash_reg - 1)); |
| 5277 | E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta); | 5286 | E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta); |
| 5287 | E1000_WRITE_FLUSH(hw); | ||
| 5278 | E1000_WRITE_REG_ARRAY(hw, MTA, (hash_reg - 1), temp); | 5288 | E1000_WRITE_REG_ARRAY(hw, MTA, (hash_reg - 1), temp); |
| 5289 | E1000_WRITE_FLUSH(hw); | ||
| 5279 | } else { | 5290 | } else { |
| 5280 | E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta); | 5291 | E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta); |
| 5292 | E1000_WRITE_FLUSH(hw); | ||
| 5281 | } | 5293 | } |
| 5282 | } | 5294 | } |
| 5283 | 5295 | ||
| @@ -5334,7 +5346,9 @@ e1000_rar_set(struct e1000_hw *hw, | |||
| 5334 | } | 5346 | } |
| 5335 | 5347 | ||
| 5336 | E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low); | 5348 | E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low); |
| 5349 | E1000_WRITE_FLUSH(hw); | ||
| 5337 | E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high); | 5350 | E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high); |
| 5351 | E1000_WRITE_FLUSH(hw); | ||
| 5338 | } | 5352 | } |
| 5339 | 5353 | ||
| 5340 | /****************************************************************************** | 5354 | /****************************************************************************** |
| @@ -5354,9 +5368,12 @@ e1000_write_vfta(struct e1000_hw *hw, | |||
| 5354 | if((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) { | 5368 | if((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) { |
| 5355 | temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1)); | 5369 | temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1)); |
| 5356 | E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value); | 5370 | E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value); |
| 5371 | E1000_WRITE_FLUSH(hw); | ||
| 5357 | E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp); | 5372 | E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp); |
| 5373 | E1000_WRITE_FLUSH(hw); | ||
| 5358 | } else { | 5374 | } else { |
| 5359 | E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value); | 5375 | E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value); |
| 5376 | E1000_WRITE_FLUSH(hw); | ||
| 5360 | } | 5377 | } |
| 5361 | } | 5378 | } |
| 5362 | 5379 | ||
| @@ -5392,6 +5409,7 @@ e1000_clear_vfta(struct e1000_hw *hw) | |||
| 5392 | * manageability unit */ | 5409 | * manageability unit */ |
| 5393 | vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0; | 5410 | vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0; |
| 5394 | E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value); | 5411 | E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value); |
| 5412 | E1000_WRITE_FLUSH(hw); | ||
| 5395 | } | 5413 | } |
| 5396 | } | 5414 | } |
| 5397 | 5415 | ||
| @@ -6928,8 +6946,10 @@ e1000_mng_write_cmd_header(struct e1000_hw * hw, | |||
| 6928 | 6946 | ||
| 6929 | length >>= 2; | 6947 | length >>= 2; |
| 6930 | /* The device driver writes the relevant command block into the ram area. */ | 6948 | /* The device driver writes the relevant command block into the ram area. */ |
| 6931 | for (i = 0; i < length; i++) | 6949 | for (i = 0; i < length; i++) { |
| 6932 | E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((uint32_t *) hdr + i)); | 6950 | E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((uint32_t *) hdr + i)); |
| 6951 | E1000_WRITE_FLUSH(hw); | ||
| 6952 | } | ||
| 6933 | 6953 | ||
| 6934 | return E1000_SUCCESS; | 6954 | return E1000_SUCCESS; |
| 6935 | } | 6955 | } |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index c58fafd1c4be..c44ed6f4ba78 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
| @@ -1370,11 +1370,11 @@ e1000_configure_tx(struct e1000_adapter *adapter) | |||
| 1370 | tdba = adapter->tx_ring[0].dma; | 1370 | tdba = adapter->tx_ring[0].dma; |
| 1371 | tdlen = adapter->tx_ring[0].count * | 1371 | tdlen = adapter->tx_ring[0].count * |
| 1372 | sizeof(struct e1000_tx_desc); | 1372 | sizeof(struct e1000_tx_desc); |
| 1373 | E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL)); | ||
| 1374 | E1000_WRITE_REG(hw, TDBAH, (tdba >> 32)); | ||
| 1375 | E1000_WRITE_REG(hw, TDLEN, tdlen); | 1373 | E1000_WRITE_REG(hw, TDLEN, tdlen); |
| 1376 | E1000_WRITE_REG(hw, TDH, 0); | 1374 | E1000_WRITE_REG(hw, TDBAH, (tdba >> 32)); |
| 1375 | E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL)); | ||
| 1377 | E1000_WRITE_REG(hw, TDT, 0); | 1376 | E1000_WRITE_REG(hw, TDT, 0); |
| 1377 | E1000_WRITE_REG(hw, TDH, 0); | ||
| 1378 | adapter->tx_ring[0].tdh = E1000_TDH; | 1378 | adapter->tx_ring[0].tdh = E1000_TDH; |
| 1379 | adapter->tx_ring[0].tdt = E1000_TDT; | 1379 | adapter->tx_ring[0].tdt = E1000_TDT; |
| 1380 | break; | 1380 | break; |
| @@ -1780,11 +1780,11 @@ e1000_configure_rx(struct e1000_adapter *adapter) | |||
| 1780 | case 1: | 1780 | case 1: |
| 1781 | default: | 1781 | default: |
| 1782 | rdba = adapter->rx_ring[0].dma; | 1782 | rdba = adapter->rx_ring[0].dma; |
| 1783 | E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL)); | ||
| 1784 | E1000_WRITE_REG(hw, RDBAH, (rdba >> 32)); | ||
| 1785 | E1000_WRITE_REG(hw, RDLEN, rdlen); | 1783 | E1000_WRITE_REG(hw, RDLEN, rdlen); |
| 1786 | E1000_WRITE_REG(hw, RDH, 0); | 1784 | E1000_WRITE_REG(hw, RDBAH, (rdba >> 32)); |
| 1785 | E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL)); | ||
| 1787 | E1000_WRITE_REG(hw, RDT, 0); | 1786 | E1000_WRITE_REG(hw, RDT, 0); |
| 1787 | E1000_WRITE_REG(hw, RDH, 0); | ||
| 1788 | adapter->rx_ring[0].rdh = E1000_RDH; | 1788 | adapter->rx_ring[0].rdh = E1000_RDH; |
| 1789 | adapter->rx_ring[0].rdt = E1000_RDT; | 1789 | adapter->rx_ring[0].rdt = E1000_RDT; |
| 1790 | break; | 1790 | break; |
| @@ -2189,14 +2189,18 @@ e1000_set_multi(struct net_device *netdev) | |||
| 2189 | mc_ptr = mc_ptr->next; | 2189 | mc_ptr = mc_ptr->next; |
| 2190 | } else { | 2190 | } else { |
| 2191 | E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0); | 2191 | E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0); |
| 2192 | E1000_WRITE_FLUSH(hw); | ||
| 2192 | E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0); | 2193 | E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0); |
| 2194 | E1000_WRITE_FLUSH(hw); | ||
| 2193 | } | 2195 | } |
| 2194 | } | 2196 | } |
| 2195 | 2197 | ||
| 2196 | /* clear the old settings from the multicast hash table */ | 2198 | /* clear the old settings from the multicast hash table */ |
| 2197 | 2199 | ||
| 2198 | for (i = 0; i < E1000_NUM_MTA_REGISTERS; i++) | 2200 | for (i = 0; i < E1000_NUM_MTA_REGISTERS; i++) { |
| 2199 | E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); | 2201 | E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); |
| 2202 | E1000_WRITE_FLUSH(hw); | ||
| 2203 | } | ||
| 2200 | 2204 | ||
| 2201 | /* load any remaining addresses into the hash table */ | 2205 | /* load any remaining addresses into the hash table */ |
| 2202 | 2206 | ||
