be2net: memory barrier fixes on IBM p7 platform
authorSathya Perla <sathyap@serverengines.com>
Tue, 29 Jun 2010 00:11:17 +0000 (00:11 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 30 Jun 2010 20:26:42 +0000 (13:26 -0700)
The ibm p7 architecure seems to reorder memory accesses more
aggressively than previous ppc64 architectures. This requires memory
barriers to ensure that rx/tx doorbells are pressed only after
memory to be DMAed is written.

Signed-off-by: Sathya Perla <sathyap@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/benet/be_cmds.c
drivers/net/benet/be_main.c

index ee1ad9693c8f064b89a133b6d6f0eb252a80a0dd..65e3260d0f080b40c3096c7294352d9911fa2418 100644 (file)
@@ -25,6 +25,8 @@ static void be_mcc_notify(struct be_adapter *adapter)
 
        val |= mccq->id & DB_MCCQ_RING_ID_MASK;
        val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
+
+       wmb();
        iowrite32(val, adapter->db + DB_MCCQ_OFFSET);
 }
 
index 01eb447f98b6224ed0ed62b253b4172bf0b8ad03..b63687956f2be87b7a214d3b4d3494144c542176 100644 (file)
@@ -89,6 +89,8 @@ static void be_rxq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
        u32 val = 0;
        val |= qid & DB_RQ_RING_ID_MASK;
        val |= posted << DB_RQ_NUM_POSTED_SHIFT;
+
+       wmb();
        iowrite32(val, adapter->db + DB_RQ_OFFSET);
 }
 
@@ -97,6 +99,8 @@ static void be_txq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
        u32 val = 0;
        val |= qid & DB_TXULP_RING_ID_MASK;
        val |= (posted & DB_TXULP_NUM_POSTED_MASK) << DB_TXULP_NUM_POSTED_SHIFT;
+
+       wmb();
        iowrite32(val, adapter->db + DB_TXULP1_OFFSET);
 }
 
@@ -973,6 +977,7 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
        if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0)
                return NULL;
 
+       rmb();
        be_dws_le_to_cpu(rxcp, sizeof(*rxcp));
 
        queue_tail_inc(&adapter->rx_obj.cq);
@@ -1066,6 +1071,7 @@ static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
        if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0)
                return NULL;
 
+       rmb();
        be_dws_le_to_cpu(txcp, sizeof(*txcp));
 
        txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0;
@@ -1113,6 +1119,7 @@ static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
        if (!eqe->evt)
                return NULL;
 
+       rmb();
        eqe->evt = le32_to_cpu(eqe->evt);
        queue_tail_inc(&eq_obj->q);
        return eqe;