[Top] [All Lists]

Patch: ATI Xilleon port 2/11 net/e100 Memory barriers and write flushing

Subject: Patch: ATI Xilleon port 2/11 net/e100 Memory barriers and write flushing
From: David Daney <>
Date: Wed, 19 Oct 2005 22:54:32 -0700
Original-recipient: rfc822;
This is the second part of my Xilleon port.

I am sending the full set of patches to
which is archived at:

Only the patches that touch generic parts of the kernel are coming

The Xilleon (32bit MIPS SOC) has a write back buffer that seems to
operate on the pci bus and does not get flushed before a read.  The
result is that a memory barrier must be done before a read intended to
flush PCI writes.

The second problem is that writes need to be flushed in e100_exec_cmd.

I am not sure exactly what was going wrong, but without this patch
packets in the send queue were not being sent until... Well I don't
know exactly when, but reception of packets and interrupts by other devices on
the PCI bus seemed to get them to be kicked out.

The result was that when pinging from an external host, the round trip
time was usually the same as the ping interval (i.e. one second).
This lead to very poor NFS performance.

With the patch applied the ethernet seems to work flawlessly

Patch against 2.6.14-rc2 from

Signed-off-by: David Daney <>

Memory barriers and write flushing added for use with xilleon port.

commit 8817d129d5d5fc662858925aa39ddda0cb3b73a0
tree bfc8ec97ad24b9477919f861cc29fc396258dc5f
parent 7c598df35a43f53dd6704bb2490f82fcd1e28a9a
author David Daney <> Tue, 04 Oct 2005 13:11:51 -0700
committer David Daney <> Tue, 04 Oct 2005 13:11:51 -0700

 drivers/net/e100.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/net/e100.c b/drivers/net/e100.c
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -584,6 +584,7 @@ static inline void e100_write_flush(stru
        /* Flush previous PCI writes through intermediate bridges
         * by doing a benign read */
+       wmb();
@@ -807,9 +808,13 @@ static inline int e100_exec_cmd(struct n
                goto err_unlock;
-       if(unlikely(cmd != cuc_resume))
+       wmb();
+       if(unlikely(cmd != cuc_resume)) {
                writel(dma_addr, &nic->csr->scb.gen_ptr);
+               e100_write_flush(nic);
+       }
        writeb(cmd, &nic->csr->scb.cmd_lo);
+       e100_write_flush(nic);
        spin_unlock_irqrestore(&nic->cmd_lock, flags);

<Prev in Thread] Current Thread [Next in Thread>