netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch 1/2] myri10ge - Always do a dummy RDMA after loading the firmware
       [not found] <44C12D14.7050509@myri.com>
@ 2006-07-21 19:49 ` Brice Goglin
  2006-07-21 19:49 ` [patch 2/2] myri10ge - Write the firmware in 256-bytes chunks Brice Goglin
  1 sibling, 0 replies; 4+ messages in thread
From: Brice Goglin @ 2006-07-21 19:49 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

Always do a dummy RDMA after loading the firmware to work around
buggy PCIe chipsets which do not implement resending properly.
This is so cheap as to be almost free, and should never have been
conditional on the tx boundary != 4096.

Signed-off-by: Brice Goglin <brice@myri.com>
---
 drivers/net/myri10ge/myri10ge.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-mm/drivers/net/myri10ge/myri10ge.c
===================================================================
--- linux-mm.orig/drivers/net/myri10ge/myri10ge.c	2006-07-18 15:15:13.000000000 -0400
+++ linux-mm/drivers/net/myri10ge/myri10ge.c	2006-07-18 15:15:57.000000000 -0400
@@ -620,7 +620,7 @@
 		return -ENXIO;
 	}
 	dev_info(&mgp->pdev->dev, "handoff confirmed\n");
-	myri10ge_dummy_rdma(mgp, mgp->tx.boundary != 4096);
+	myri10ge_dummy_rdma(mgp, 1);
 
 	return 0;
 }



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [patch 2/2] myri10ge - Write the firmware in 256-bytes chunks
       [not found] <44C12D14.7050509@myri.com>
  2006-07-21 19:49 ` [patch 1/2] myri10ge - Always do a dummy RDMA after loading the firmware Brice Goglin
@ 2006-07-21 19:49 ` Brice Goglin
  2006-07-21 20:11   ` Michael Buesch
  1 sibling, 1 reply; 4+ messages in thread
From: Brice Goglin @ 2006-07-21 19:49 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

When writing the firmware to the NIC, the FIFO is 256-bytes long,
so we use 256-bytes chunks and a read to wait until the previous
write is done.

Signed-off-by: Brice Goglin <brice@myri.com>
---
 drivers/net/myri10ge/myri10ge.c |   20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

Index: linux-mm/drivers/net/myri10ge/myri10ge.c
===================================================================
--- linux-mm.orig/drivers/net/myri10ge/myri10ge.c	2006-07-18 15:17:55.000000000 -0400
+++ linux-mm/drivers/net/myri10ge/myri10ge.c	2006-07-18 15:19:44.000000000 -0400
@@ -448,6 +448,7 @@
 	struct mcp_gen_header *hdr;
 	size_t hdr_offset;
 	int status;
+	unsigned i;
 
 	if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) {
 		dev_err(dev, "Unable to load %s firmware image via hotplug\n",
@@ -479,18 +480,13 @@
 		goto abort_with_fw;
 
 	crc = crc32(~0, fw->data, fw->size);
-	if (mgp->tx.boundary == 2048) {
-		/* Avoid PCI burst on chipset with unaligned completions. */
-		int i;
-		__iomem u32 *ptr = (__iomem u32 *) (mgp->sram +
-						    MYRI10GE_FW_OFFSET);
-		for (i = 0; i < fw->size / 4; i++) {
-			__raw_writel(((u32 *) fw->data)[i], ptr + i);
-			wmb();
-		}
-	} else {
-		myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET, fw->data,
-				  fw->size);
+	for (i = 0; i < fw->size; i += 256) {
+		myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET + i,
+				  fw->data + i,
+				  min(256U, (unsigned)(fw->size - i)));
+		mb();
+		readb(mgp->sram);
+		mb();
 	}
 	/* corruption checking is good for parity recovery and buggy chipset */
 	memcpy_fromio(fw->data, mgp->sram + MYRI10GE_FW_OFFSET, fw->size);



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch 2/2] myri10ge - Write the firmware in 256-bytes chunks
  2006-07-21 19:49 ` [patch 2/2] myri10ge - Write the firmware in 256-bytes chunks Brice Goglin
@ 2006-07-21 20:11   ` Michael Buesch
  2006-07-22  2:42     ` Brice Goglin
  0 siblings, 1 reply; 4+ messages in thread
From: Michael Buesch @ 2006-07-21 20:11 UTC (permalink / raw)
  To: Brice Goglin; +Cc: Jeff Garzik, netdev

On Friday 21 July 2006 21:49, Brice Goglin wrote:
> When writing the firmware to the NIC, the FIFO is 256-bytes long,
> so we use 256-bytes chunks and a read to wait until the previous
> write is done.
> 
> Signed-off-by: Brice Goglin <brice@myri.com>
> ---
>  drivers/net/myri10ge/myri10ge.c |   20 ++++++++------------
>  1 file changed, 8 insertions(+), 12 deletions(-)
> 
> Index: linux-mm/drivers/net/myri10ge/myri10ge.c
> ===================================================================
> --- linux-mm.orig/drivers/net/myri10ge/myri10ge.c	2006-07-18 15:17:55.000000000 -0400
> +++ linux-mm/drivers/net/myri10ge/myri10ge.c	2006-07-18 15:19:44.000000000 -0400
> @@ -448,6 +448,7 @@
>  	struct mcp_gen_header *hdr;
>  	size_t hdr_offset;
>  	int status;
> +	unsigned i;
>  
>  	if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) {
>  		dev_err(dev, "Unable to load %s firmware image via hotplug\n",
> @@ -479,18 +480,13 @@
>  		goto abort_with_fw;
>  
>  	crc = crc32(~0, fw->data, fw->size);
> -	if (mgp->tx.boundary == 2048) {
> -		/* Avoid PCI burst on chipset with unaligned completions. */
> -		int i;
> -		__iomem u32 *ptr = (__iomem u32 *) (mgp->sram +
> -						    MYRI10GE_FW_OFFSET);
> -		for (i = 0; i < fw->size / 4; i++) {
> -			__raw_writel(((u32 *) fw->data)[i], ptr + i);
> -			wmb();
> -		}
> -	} else {
> -		myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET, fw->data,
> -				  fw->size);
> +	for (i = 0; i < fw->size; i += 256) {
> +		myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET + i,
> +				  fw->data + i,
> +				  min(256U, (unsigned)(fw->size - i)));
> +		mb();
> +		readb(mgp->sram);
> +		mb();

Why two mb() here?
I would say actually none is needed.
The readb fully synchronizes the previous writes on bus level
(and so on CPU level, too).

-- 
Greetings Michael.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch 2/2] myri10ge - Write the firmware in 256-bytes chunks
  2006-07-21 20:11   ` Michael Buesch
@ 2006-07-22  2:42     ` Brice Goglin
  0 siblings, 0 replies; 4+ messages in thread
From: Brice Goglin @ 2006-07-22  2:42 UTC (permalink / raw)
  To: Michael Buesch; +Cc: Jeff Garzik, netdev

Michael Buesch wrote:
> On Friday 21 July 2006 21:49, Brice Goglin wrote:
>   
>> +		myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET + i,
>> +				  fw->data + i,
>> +				  min(256U, (unsigned)(fw->size - i)));
>> +		mb();
>> +		readb(mgp->sram);
>> +		mb();
>>     
>
> Why two mb() here?
> I would say actually none is needed.
> The readb fully synchronizes the previous writes on bus level
> (and so on CPU level, too)

At least on i386 and x86-64, readb does not pass an explicit memory
barrier to the processor. We use a "weak-ordering" write-combining
mapping, so the previous PIO-write accesses and the readb are not
automatically serialized. So in absence of the first mb(), and because
"WC" read can definitely pass "WC" write, the readb (whose purpose is to
guarantee the previous write is finished) could actually be complete
long before those have even started (especially because WC buffers can
stay in the processor a long time before being flushed in absence of
synchronization instructions).

The second mb() is indeed probably superfluous and could be removed. The
WC semantics are not weak enough to allow WC writes to pass WC read
(given it was only one instruction in init code, we did the lazy thing).

Brice




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-07-22  2:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <44C12D14.7050509@myri.com>
2006-07-21 19:49 ` [patch 1/2] myri10ge - Always do a dummy RDMA after loading the firmware Brice Goglin
2006-07-21 19:49 ` [patch 2/2] myri10ge - Write the firmware in 256-bytes chunks Brice Goglin
2006-07-21 20:11   ` Michael Buesch
2006-07-22  2:42     ` Brice Goglin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).