]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.drivers/bnx2x-Missing-memory-barriers.patch
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / bnx2x-Missing-memory-barriers.patch
diff --git a/src/patches/suse-2.6.27.31/patches.drivers/bnx2x-Missing-memory-barriers.patch b/src/patches/suse-2.6.27.31/patches.drivers/bnx2x-Missing-memory-barriers.patch
new file mode 100644 (file)
index 0000000..ea5f70e
--- /dev/null
@@ -0,0 +1,95 @@
+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)