Re: [PATCH 10/21] e1000: force register write flushes to circumvent broken platforms

2006-06-27 Thread Auke Kok

Jeff Garzik wrote:

Kok, Auke wrote:

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 [EMAIL PROTECTED]
Signed-off-by: Auke Kok [EMAIL PROTECTED]
---

 drivers/net/e1000/e1000_hw.c   |   24 ++--
 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 3959039..749d621 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)
 /* Zero out the Multicast HASH table */
 DEBUGOUT(Zeroing the MTA\n);
 mta_size = E1000_MC_TBL_SIZE;
-for(i = 0; i  mta_size; i++)
+for(i = 0; i  mta_size; i++) {
 E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
+/* use write flush to prevent Memory Write Block (MWB) from
+ * occuring when accessing our register space */
+E1000_WRITE_FLUSH(hw);
+}


NAK.  We can't crap up every driver just for one weird piece of hardware.

If this problem falls outside the grounds of mmiowb() [see 
Documentation/memory-barriers.txt], then other solutions need to be 
looked into... ioremap_nocache() ?  Tweaking the MTRR for this region? 
Chipset quirk?  ...


If there is an in-kernel fix for this that would make these flushes obsolete I 
would certainly prefer it too, unfortunately we can't fix already released 
kernels and our driver still needs to work there too, so that's why I queued 
it. It can be dropped from this series if that's preferred.


Cheers,

Auke
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 10/21] e1000: force register write flushes to circumvent broken platforms

2006-06-27 Thread Jeff Garzik

Auke Kok wrote:
If there is an in-kernel fix for this that would make these flushes 
obsolete I would certainly prefer it too, unfortunately we can't fix 
already released kernels and our driver still needs to work there too, 
so that's why I queued it. It can be dropped from this series if that's 
preferred.


Yes, definitely drop it from the series...

Jeff


-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 10/21] e1000: force register write flushes to circumvent broken platforms

2006-06-27 Thread Auke Kok

Auke Kok wrote:

Jeff Garzik wrote:

Kok, Auke wrote:

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 [EMAIL PROTECTED]
Signed-off-by: Auke Kok [EMAIL PROTECTED]
---

 drivers/net/e1000/e1000_hw.c   |   24 ++--
 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 3959039..749d621 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)
 /* Zero out the Multicast HASH table */
 DEBUGOUT(Zeroing the MTA\n);
 mta_size = E1000_MC_TBL_SIZE;
-for(i = 0; i  mta_size; i++)
+for(i = 0; i  mta_size; i++) {
 E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
+/* use write flush to prevent Memory Write Block (MWB) from
+ * occuring when accessing our register space */
+E1000_WRITE_FLUSH(hw);
+}


NAK.  We can't crap up every driver just for one weird piece of hardware.

If this problem falls outside the grounds of mmiowb() [see 
Documentation/memory-barriers.txt], then other solutions need to be 
looked into... ioremap_nocache() ?  Tweaking the MTRR for this region? 
Chipset quirk?  ...


If there is an in-kernel fix for this that would make these flushes 
obsolete I would certainly prefer it too, unfortunately we can't fix 
already released kernels and our driver still needs to work there too, 
so that's why I queued it. It can be dropped from this series if that's 
preferred.


I have to get back on that - it's not as simple as the platform is broken. 
e1000's don't support write-combining in hardware but the problem only shows 
itself during initialization. This patch makes it work on AMD platforms with 
write-combining enabled, the platform itself isn't broken - technically the 
NIC is (ixgb doesn't have this problem for instance).


The added write flushes are at initialization only, and fix the problem for 
any other case. I don't see much harm in that.


Auke
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 10/21] e1000: force register write flushes to circumvent broken platforms

2006-06-26 Thread Jeff Garzik

Kok, Auke wrote:

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 [EMAIL PROTECTED]
Signed-off-by: Auke Kok [EMAIL PROTECTED]
---

 drivers/net/e1000/e1000_hw.c   |   24 ++--
 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 3959039..749d621 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)
 /* Zero out the Multicast HASH table */
 DEBUGOUT(Zeroing the MTA\n);
 mta_size = E1000_MC_TBL_SIZE;
-for(i = 0; i  mta_size; i++)
+for(i = 0; i  mta_size; i++) {
 E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
+/* use write flush to prevent Memory Write Block (MWB) from
+ * occuring when accessing our register space */
+E1000_WRITE_FLUSH(hw);
+}


NAK.  We can't crap up every driver just for one weird piece of hardware.

If this problem falls outside the grounds of mmiowb() [see 
Documentation/memory-barriers.txt], then other solutions need to be 
looked into... ioremap_nocache() ?  Tweaking the MTRR for this region? 
Chipset quirk?  ...


Jeff



-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/21] e1000: force register write flushes to circumvent broken platforms

2006-06-21 Thread Kok, Auke

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 [EMAIL PROTECTED]
Signed-off-by: Auke Kok [EMAIL PROTECTED]
---

 drivers/net/e1000/e1000_hw.c   |   24 ++--
 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 3959039..749d621 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)
 /* Zero out the Multicast HASH table */
 DEBUGOUT(Zeroing the MTA\n);
 mta_size = E1000_MC_TBL_SIZE;
-for(i = 0; i  mta_size; i++)
+for(i = 0; i  mta_size; i++) {
 E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
+/* use write flush to prevent Memory Write Block (MWB) from
+ * occuring when accessing our register space */
+E1000_WRITE_FLUSH(hw);
+}
 
 /* Set the PCI priority bit correctly in the CTRL register.  This
  * determines if the adapter gives priority to receives, or if it
@@ -5106,7 +5110,9 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
 DEBUGOUT(Clearing RAR[1-15]\n);
 for(i = 1; i  rar_num; i++) {
 E1000_WRITE_REG_ARRAY(hw, RA, (i  1), 0);
+E1000_WRITE_FLUSH(hw);
 E1000_WRITE_REG_ARRAY(hw, RA, ((i  1) + 1), 0);
+E1000_WRITE_FLUSH(hw);
 }
 }
 
@@ -5153,7 +5159,9 @@ e1000_mc_addr_list_update(struct e1000_h
 
 for(i = rar_used_count; i  num_rar_entry; i++) {
 E1000_WRITE_REG_ARRAY(hw, RA, (i  1), 0);
+E1000_WRITE_FLUSH(hw);
 E1000_WRITE_REG_ARRAY(hw, RA, ((i  1) + 1), 0);
+E1000_WRITE_FLUSH(hw);
 }
 
 /* Clear the MTA */
@@ -5161,6 +5169,7 @@ e1000_mc_addr_list_update(struct e1000_h
 num_mta_entry = E1000_NUM_MTA_REGISTERS;
 for(i = 0; i  num_mta_entry; i++) {
 E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
+E1000_WRITE_FLUSH(hw);
 }
 
 /* Add the new addresses */
@@ -5275,9 +5284,12 @@ e1000_mta_set(struct e1000_hw *hw,
 if((hw-mac_type == e1000_82544)  ((hash_reg  0x1) == 1)) {
 temp = E1000_READ_REG_ARRAY(hw, MTA, (hash_reg - 1));
 E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
+E1000_WRITE_FLUSH(hw);
 E1000_WRITE_REG_ARRAY(hw, MTA, (hash_reg - 1), temp);
+E1000_WRITE_FLUSH(hw);
 } else {
 E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
+E1000_WRITE_FLUSH(hw);
 }
 }
 
@@ -5334,7 +5346,9 @@ e1000_rar_set(struct e1000_hw *hw,
 }
 
 E1000_WRITE_REG_ARRAY(hw, RA, (index  1), rar_low);
+E1000_WRITE_FLUSH(hw);
 E1000_WRITE_REG_ARRAY(hw, RA, ((index  1) + 1), rar_high);
+E1000_WRITE_FLUSH(hw);
 }
 
 /**
@@ -5354,9 +5368,12 @@ e1000_write_vfta(struct e1000_hw *hw,
 if((hw-mac_type == e1000_82544)  ((offset  0x1) == 1)) {
 temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
 E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
+E1000_WRITE_FLUSH(hw);
 E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
+E1000_WRITE_FLUSH(hw);
 } else {
 E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
+E1000_WRITE_FLUSH(hw);
 }
 }
 
@@ -5392,6 +5409,7 @@ e1000_clear_vfta(struct e1000_hw *hw)
  * manageability unit */
 vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
 E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
+E1000_WRITE_FLUSH(hw);
 }
 }
 
@@ -6928,8 +6946,10 @@ e1000_mng_write_cmd_header(struct e1000_
 
 length = 2;
 /* The device driver writes the relevant command block into the ram area. 
*/
-for (i = 0; i  length; i++)
+for (i = 0; i  length; i++) {
 E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((uint32_t *) hdr + i));
+E1000_WRITE_FLUSH(hw);
+}
 
 return E1000_SUCCESS;
 }
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index c58fafd..c44ed6f 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 
tdba = adapter-tx_ring[0].dma;
tdlen = adapter-tx_ring[0].count *
sizeof(struct e1000_tx_desc);
-   E1000_WRITE_REG(hw, TDBAL, (tdba  0xULL));
-   E1000_WRITE_REG(hw, TDBAH, (tdba  32));
E1000_WRITE_REG(hw, TDLEN, tdlen);
-   E1000_WRITE_REG(hw, TDH, 0);
+   E1000_WRITE_REG(hw, TDBAH, (tdba  32));
+   E1000_WRITE_REG(hw, TDBAL, (tdba  0xULL));
E1000_WRITE_REG(hw, TDT, 0);
+   E1000_WRITE_REG(hw, TDH, 0);
adapter-tx_ring[0].tdh = E1000_TDH;
adapter-tx_ring[0].tdt =