]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.drivers/bnx2x-Barriers-for-the-compiler.patch
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / bnx2x-Barriers-for-the-compiler.patch
diff --git a/src/patches/suse-2.6.27.31/patches.drivers/bnx2x-Barriers-for-the-compiler.patch b/src/patches/suse-2.6.27.31/patches.drivers/bnx2x-Barriers-for-the-compiler.patch
new file mode 100644 (file)
index 0000000..f0bc6a6
--- /dev/null
@@ -0,0 +1,117 @@
+From 237907c1ded8a1a447cea7c4f97ab853e8b46052 Mon Sep 17 00:00:00 2001
+From: Eilon Greenstein <eilong@broadcom.com>
+Date: Wed, 14 Jan 2009 06:42:44 +0000
+Subject: bnx2x: Barriers for the compiler
+Acked-by: Karsten Keil <kkeil@novell.com>
+Reference: bnc#472500
+
+To make sure no swapping are made by the compiler, changed HAS_WORK to inline
+functions and added all the necessary barriers
+
+Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/bnx2x.h      |    9 +--------
+ drivers/net/bnx2x_main.c |   37 ++++++++++++++++++++++++++-----------
+ 2 files changed, 27 insertions(+), 19 deletions(-)
+
+Index: linux-2.6.27-bnx2x_2/drivers/net/bnx2x.h
+===================================================================
+--- linux-2.6.27-bnx2x_2.orig/drivers/net/bnx2x.h
++++ linux-2.6.27-bnx2x_2/drivers/net/bnx2x.h
+@@ -271,14 +271,7 @@ struct bnx2x_fastpath {
+ #define bnx2x_fp(bp, nr, var)         (bp->fp[nr].var)
+-#define BNX2X_HAS_TX_WORK(fp) \
+-                      ((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) || \
+-                       (fp->tx_pkt_prod != fp->tx_pkt_cons))
+-
+-#define BNX2X_HAS_RX_WORK(fp) \
+-                      (fp->rx_comp_cons != rx_cons_sb)
+-
+-#define BNX2X_HAS_WORK(fp)    (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp))
++#define BNX2X_HAS_WORK(fp)    (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))
+ /* MC hsi */
+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
+@@ -733,6 +733,17 @@ static u16 bnx2x_ack_int(struct bnx2x *b
+  * fast path service functions
+  */
++static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp)
++{
++      u16 tx_cons_sb;
++
++      /* Tell compiler that status block fields can change */
++      barrier();
++      tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb);
++      return ((fp->tx_pkt_prod != tx_cons_sb) ||
++              (fp->tx_pkt_prod != fp->tx_pkt_cons));
++}
++
+ /* free skb in the packet ring at pos idx
+  * return idx of last bd freed
+  */
+@@ -6696,7 +6707,7 @@ static int bnx2x_nic_unload(struct bnx2x
+               cnt = 1000;
+               smp_rmb();
+-              while (BNX2X_HAS_TX_WORK(fp)) {
++              while (bnx2x_has_tx_work(fp)) {
+                       bnx2x_tx_int(fp, 1000);
+                       if (!cnt) {
+@@ -9285,6 +9296,18 @@ static int bnx2x_set_power_state(struct 
+       return 0;
+ }
++static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
++{
++      u16 rx_cons_sb;
++
++      /* Tell compiler that status block fields can change */
++      barrier();
++      rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
++      if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
++              rx_cons_sb++;
++      return (fp->rx_comp_cons != rx_cons_sb);
++}
++
+ /*
+  * net_device service functions
+  */
+@@ -9295,7 +9318,6 @@ static int bnx2x_poll(struct napi_struct
+                                                napi);
+       struct bnx2x *bp = fp->bp;
+       int work_done = 0;
+-      u16 rx_cons_sb;
+ #ifdef BNX2X_STOP_ON_ERROR
+       if (unlikely(bp->panic))
+@@ -9308,19 +9330,12 @@ static int bnx2x_poll(struct napi_struct
+       bnx2x_update_fpsb_idx(fp);
+-      if (BNX2X_HAS_TX_WORK(fp))
++      if (bnx2x_has_tx_work(fp))
+               bnx2x_tx_int(fp, budget);
+-      rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
+-      if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+-              rx_cons_sb++;
+-      if (BNX2X_HAS_RX_WORK(fp))
++      if (bnx2x_has_rx_work(fp))
+               work_done = bnx2x_rx_int(fp, budget);
+-
+       rmb(); /* BNX2X_HAS_WORK() reads the status block */
+-      rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
+-      if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+-              rx_cons_sb++;
+       /* must not complete if we consumed full budget */
+       if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {