aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJulien Ducourthial <jducourt@free.fr>2012-05-08 18:00:06 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-08 19:34:10 -0400
commit477206a018f902895bfcd069dd820bfe94c187b1 (patch)
tree00327b9b57c77652b6629c9d540c497db886338f /drivers/net
parentc5baa80ac879a3b38314f434c0a7255a2c2e4c86 (diff)
r8169: fix unsigned int wraparound with TSO
The r8169 may get stuck or show bad behaviour after activating TSO : the net_device is not stopped when it has no more TX descriptors. This problem comes from TX_BUFS_AVAIL which may reach -1 when all transmit descriptors are in use. The patch simply tries to keep positive values. Tested with 8111d(onboard) on a D510MO, and with 8111e(onboard) on a Zotac 890GXITX. Signed-off-by: Julien Ducourthial <jducourt@free.fr> Acked-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/realtek/r8169.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index f54509377efa..ce6b44d1f252 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -61,8 +61,12 @@
61#define R8169_MSG_DEFAULT \ 61#define R8169_MSG_DEFAULT \
62 (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN) 62 (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN)
63 63
64#define TX_BUFFS_AVAIL(tp) \ 64#define TX_SLOTS_AVAIL(tp) \
65 (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1) 65 (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx)
66
67/* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */
68#define TX_FRAGS_READY_FOR(tp,nr_frags) \
69 (TX_SLOTS_AVAIL(tp) >= (nr_frags + 1))
66 70
67/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). 71/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
68 The RTL chips use a 64 element hash table based on the Ethernet CRC. */ 72 The RTL chips use a 64 element hash table based on the Ethernet CRC. */
@@ -5115,7 +5119,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
5115 u32 opts[2]; 5119 u32 opts[2];
5116 int frags; 5120 int frags;
5117 5121
5118 if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { 5122 if (unlikely(!TX_FRAGS_READY_FOR(tp, skb_shinfo(skb)->nr_frags))) {
5119 netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n"); 5123 netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n");
5120 goto err_stop_0; 5124 goto err_stop_0;
5121 } 5125 }
@@ -5169,7 +5173,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
5169 5173
5170 mmiowb(); 5174 mmiowb();
5171 5175
5172 if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { 5176 if (!TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) {
5173 /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must 5177 /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
5174 * not miss a ring update when it notices a stopped queue. 5178 * not miss a ring update when it notices a stopped queue.
5175 */ 5179 */
@@ -5183,7 +5187,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
5183 * can't. 5187 * can't.
5184 */ 5188 */
5185 smp_mb(); 5189 smp_mb();
5186 if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) 5190 if (TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS))
5187 netif_wake_queue(dev); 5191 netif_wake_queue(dev);
5188 } 5192 }
5189 5193
@@ -5306,7 +5310,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
5306 */ 5310 */
5307 smp_mb(); 5311 smp_mb();
5308 if (netif_queue_stopped(dev) && 5312 if (netif_queue_stopped(dev) &&
5309 (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { 5313 TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) {
5310 netif_wake_queue(dev); 5314 netif_wake_queue(dev);
5311 } 5315 }
5312 /* 5316 /*