diff options
author | Vladislav Zolotarov <vladz@broadcom.com> | 2009-01-26 15:36:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-26 15:36:42 -0500 |
commit | e8b5fc514d1c7637cb4b8f77e7d8ac33ef66130c (patch) | |
tree | 486a72b31cdadfe976b7baf181e90e0767b4dee5 /drivers/net/bnx2x_main.c | |
parent | 32ec803348b4d5f1353e1d7feae30880b8b3e342 (diff) |
bnx2x: tx_has_work should not wait for FW
The current tx_has_work waited until all packets sent by the driver
are marked as completed by the FW. This is too greedy and it causes
the bnx2x_poll to spin in vain. The driver should only check that all
packets FW already completed are freed - only in unload flow the
driver should make sure that transmit queue is empty
Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 4b84f6ce5ed2..d3e7775a9ccf 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -57,8 +57,8 @@ | |||
57 | #include "bnx2x.h" | 57 | #include "bnx2x.h" |
58 | #include "bnx2x_init.h" | 58 | #include "bnx2x_init.h" |
59 | 59 | ||
60 | #define DRV_MODULE_VERSION "1.45.25" | 60 | #define DRV_MODULE_VERSION "1.45.26" |
61 | #define DRV_MODULE_RELDATE "2009/01/22" | 61 | #define DRV_MODULE_RELDATE "2009/01/26" |
62 | #define BNX2X_BC_VER 0x040200 | 62 | #define BNX2X_BC_VER 0x040200 |
63 | 63 | ||
64 | /* Time in jiffies before concluding the transmitter is hung */ | 64 | /* Time in jiffies before concluding the transmitter is hung */ |
@@ -740,8 +740,15 @@ static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp) | |||
740 | /* Tell compiler that status block fields can change */ | 740 | /* Tell compiler that status block fields can change */ |
741 | barrier(); | 741 | barrier(); |
742 | tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb); | 742 | tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb); |
743 | return ((fp->tx_pkt_prod != tx_cons_sb) || | 743 | return (fp->tx_pkt_cons != tx_cons_sb); |
744 | (fp->tx_pkt_prod != fp->tx_pkt_cons)); | 744 | } |
745 | |||
746 | static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp) | ||
747 | { | ||
748 | /* Tell compiler that consumer and producer can change */ | ||
749 | barrier(); | ||
750 | return (fp->tx_pkt_prod != fp->tx_pkt_cons); | ||
751 | |||
745 | } | 752 | } |
746 | 753 | ||
747 | /* free skb in the packet ring at pos idx | 754 | /* free skb in the packet ring at pos idx |
@@ -6729,7 +6736,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) | |||
6729 | 6736 | ||
6730 | cnt = 1000; | 6737 | cnt = 1000; |
6731 | smp_rmb(); | 6738 | smp_rmb(); |
6732 | while (bnx2x_has_tx_work(fp)) { | 6739 | while (bnx2x_has_tx_work_unload(fp)) { |
6733 | 6740 | ||
6734 | bnx2x_tx_int(fp, 1000); | 6741 | bnx2x_tx_int(fp, 1000); |
6735 | if (!cnt) { | 6742 | if (!cnt) { |