--- /dev/null
+From 58f4c4cfce5c4715b79621f0a635925c55f855d5 Mon Sep 17 00:00:00 2001
+From: Eilon Greenstein <eilong@broadcom.com>
+Date: Wed, 14 Jan 2009 21:23:36 -0800
+Subject: bnx2x: Missing memory barriers
+Acked-by: Karsten Keil <kkeil@novell.com>
+Reference: bnc#472500
+
+While working on IA64, it became clear that the following memory
+barriers are missing
+
+Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/bnx2x_main.c | 28 ++++++++++++++++++++++++++--
+ 1 files changed, 26 insertions(+), 2 deletions(-)
+
+Index: linux-2.6.27-bnx2x_2/drivers/net/bnx2x_main.c
+===================================================================
+--- linux-2.6.27-bnx2x_2.orig/drivers/net/bnx2x_main.c
++++ linux-2.6.27-bnx2x_2/drivers/net/bnx2x_main.c
+@@ -1358,11 +1358,23 @@ static inline void bnx2x_update_rx_prod(
+ rx_prods.cqe_prod = rx_comp_prod;
+ rx_prods.sge_prod = rx_sge_prod;
+
++ /*
++ * Make sure that the BD and SGE data is updated before updating the
++ * producers since FW might read the BD/SGE right after the producer
++ * is updated.
++ * This is only applicable for weak-ordered memory model archs such
++ * as IA-64. The following barrier is also mandatory since FW will
++ * assumes BDs must have buffers.
++ */
++ wmb();
++
+ for (i = 0; i < sizeof(struct tstorm_eth_rx_producers)/4; i++)
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_RX_PRODS_OFFSET(BP_PORT(bp), FP_CL_ID(fp)) + i*4,
+ ((u32 *)&rx_prods)[i]);
+
++ mmiowb(); /* keep prod updates ordered */
++
+ DP(NETIF_MSG_RX_STATUS,
+ "Wrote: bd_prod %u cqe_prod %u sge_prod %u\n",
+ bd_prod, rx_comp_prod, rx_sge_prod);
+@@ -1584,7 +1596,6 @@ next_cqe:
+ /* Update producers */
+ bnx2x_update_rx_prod(bp, fp, bd_prod_fw, sw_comp_prod,
+ fp->rx_sge_prod);
+- mmiowb(); /* keep prod updates ordered */
+
+ fp->rx_pkt += rx_pkt;
+ fp->rx_calls++;
+@@ -8732,6 +8743,8 @@ static int bnx2x_run_loopback(struct bnx
+ tx_bd->general_data = ((UNICAST_ADDRESS <<
+ ETH_TX_BD_ETH_ADDR_TYPE_SHIFT) | 1);
+
++ wmb();
++
+ fp->hw_tx_prods->bds_prod =
+ cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + 1);
+ mb(); /* FW restriction: must not reorder writing nbd and packets */
+@@ -8784,7 +8797,6 @@ test_loopback_rx_exit:
+ /* Update producers */
+ bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
+ fp->rx_sge_prod);
+- mmiowb(); /* keep prod updates ordered */
+
+ test_loopback_exit:
+ bp->link_params.loopback_mode = LOOPBACK_NONE;
+@@ -9711,6 +9723,15 @@ static int bnx2x_start_xmit(struct sk_bu
+
+ DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod);
+
++ /*
++ * Make sure that the BD data is updated before updating the producer
++ * since FW might read the BD right after the producer is updated.
++ * This is only applicable for weak-ordered memory model archs such
++ * as IA-64. The following barrier is also mandatory since FW will
++ * assumes packets must have BDs.
++ */
++ wmb();
++
+ fp->hw_tx_prods->bds_prod =
+ cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd);
+ mb(); /* FW restriction: must not reorder writing nbd and packets */
+@@ -9724,6 +9745,9 @@ static int bnx2x_start_xmit(struct sk_bu
+ dev->trans_start = jiffies;
+
+ if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
++ /* We want bnx2x_tx_int to "see" the updated tx_bd_prod
++ if we put Tx into XOFF state. */
++ smp_mb();
+ netif_stop_queue(dev);
+ bp->eth_stats.driver_xoff++;
+ if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)