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 | |
| 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>
| -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) { |
