diff options
| -rw-r--r-- | drivers/net/bnx2x_main.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 5adf2a05246f..ed785a30e98b 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
| @@ -57,8 +57,8 @@ | |||
| 57 | #include "bnx2x_init_ops.h" | 57 | #include "bnx2x_init_ops.h" |
| 58 | #include "bnx2x_dump.h" | 58 | #include "bnx2x_dump.h" |
| 59 | 59 | ||
| 60 | #define DRV_MODULE_VERSION "1.52.1-6" | 60 | #define DRV_MODULE_VERSION "1.52.1-7" |
| 61 | #define DRV_MODULE_RELDATE "2010/02/16" | 61 | #define DRV_MODULE_RELDATE "2010/02/28" |
| 62 | #define BNX2X_BC_VER 0x040200 | 62 | #define BNX2X_BC_VER 0x040200 |
| 63 | 63 | ||
| 64 | #include <linux/firmware.h> | 64 | #include <linux/firmware.h> |
| @@ -957,21 +957,34 @@ static int bnx2x_tx_int(struct bnx2x_fastpath *fp) | |||
| 957 | fp->tx_pkt_cons = sw_cons; | 957 | fp->tx_pkt_cons = sw_cons; |
| 958 | fp->tx_bd_cons = bd_cons; | 958 | fp->tx_bd_cons = bd_cons; |
| 959 | 959 | ||
| 960 | /* Need to make the tx_bd_cons update visible to start_xmit() | ||
| 961 | * before checking for netif_tx_queue_stopped(). Without the | ||
| 962 | * memory barrier, there is a small possibility that | ||
| 963 | * start_xmit() will miss it and cause the queue to be stopped | ||
| 964 | * forever. | ||
| 965 | */ | ||
| 966 | smp_wmb(); | ||
| 967 | |||
| 960 | /* TBD need a thresh? */ | 968 | /* TBD need a thresh? */ |
| 961 | if (unlikely(netif_tx_queue_stopped(txq))) { | 969 | if (unlikely(netif_tx_queue_stopped(txq))) { |
| 962 | 970 | /* Taking tx_lock() is needed to prevent reenabling the queue | |
| 963 | /* Need to make the tx_bd_cons update visible to start_xmit() | 971 | * while it's empty. This could have happen if rx_action() gets |
| 964 | * before checking for netif_tx_queue_stopped(). Without the | 972 | * suspended in bnx2x_tx_int() after the condition before |
| 965 | * memory barrier, there is a small possibility that | 973 | * netif_tx_wake_queue(), while tx_action (bnx2x_start_xmit()): |
| 966 | * start_xmit() will miss it and cause the queue to be stopped | 974 | * |
| 967 | * forever. | 975 | * stops the queue->sees fresh tx_bd_cons->releases the queue-> |
| 976 | * sends some packets consuming the whole queue again-> | ||
| 977 | * stops the queue | ||
| 968 | */ | 978 | */ |
| 969 | smp_mb(); | 979 | |
| 980 | __netif_tx_lock(txq, smp_processor_id()); | ||
| 970 | 981 | ||
| 971 | if ((netif_tx_queue_stopped(txq)) && | 982 | if ((netif_tx_queue_stopped(txq)) && |
| 972 | (bp->state == BNX2X_STATE_OPEN) && | 983 | (bp->state == BNX2X_STATE_OPEN) && |
| 973 | (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)) | 984 | (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)) |
| 974 | netif_tx_wake_queue(txq); | 985 | netif_tx_wake_queue(txq); |
| 986 | |||
| 987 | __netif_tx_unlock(txq); | ||
| 975 | } | 988 | } |
| 976 | return 0; | 989 | return 0; |
| 977 | } | 990 | } |
