Skip to content

Commit 50ad076

Browse files
claudiu-mdavem330
authored andcommitted
gianfar: Fix reported number of sent bytes to BQL
Fix the amount of sent bytes reported to BQL by reporting the number of bytes on wire in the xmit routine, and recording that value for each skb in order to be correctly confirmed on Tx confirmation cleanup. Reporting skb->len to BQL just before exiting xmit is not correct due to possible insertions of TOE block and alignment bytes in the skb->data, which are being stripped off by the controller before transmission on wire. This led to mismatch of (incorrectly) reported bytes to BQL b/w xmit and Tx confirmation, resulting in Tx timeout firing, for the h/w tx timestamping acceleration case. There's no easy way to obtain the number of bytes on wire in the Tx confirmation routine, so skb->cb is used to convey that information from xmit to Tx confirmation, for now (as proposed by Eric). Revived the currently unused GFAR_CB() construct for that purpose. Signed-off-by: Claudiu Manoil <[email protected]> Cc: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7a163bf commit 50ad076

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

drivers/net/ethernet/freescale/gianfar.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,7 +2092,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
20922092
int do_tstamp, do_csum, do_vlan;
20932093
u32 bufaddr;
20942094
unsigned long flags;
2095-
unsigned int nr_frags, nr_txbds, length, fcb_len = 0;
2095+
unsigned int nr_frags, nr_txbds, bytes_sent, fcb_len = 0;
20962096

20972097
rq = skb->queue_mapping;
20982098
tx_queue = priv->tx_queue[rq];
@@ -2147,7 +2147,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
21472147
}
21482148

21492149
/* Update transmit stats */
2150-
tx_queue->stats.tx_bytes += skb->len;
2150+
bytes_sent = skb->len;
2151+
tx_queue->stats.tx_bytes += bytes_sent;
2152+
/* keep Tx bytes on wire for BQL accounting */
2153+
GFAR_CB(skb)->bytes_sent = bytes_sent;
21512154
tx_queue->stats.tx_packets++;
21522155

21532156
txbdp = txbdp_start = tx_queue->cur_tx;
@@ -2167,12 +2170,13 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
21672170
} else {
21682171
/* Place the fragment addresses and lengths into the TxBDs */
21692172
for (i = 0; i < nr_frags; i++) {
2173+
unsigned int frag_len;
21702174
/* Point at the next BD, wrapping as needed */
21712175
txbdp = next_txbd(txbdp, base, tx_queue->tx_ring_size);
21722176

2173-
length = skb_shinfo(skb)->frags[i].size;
2177+
frag_len = skb_shinfo(skb)->frags[i].size;
21742178

2175-
lstatus = txbdp->lstatus | length |
2179+
lstatus = txbdp->lstatus | frag_len |
21762180
BD_LFLAG(TXBD_READY);
21772181

21782182
/* Handle the last BD specially */
@@ -2182,7 +2186,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
21822186
bufaddr = skb_frag_dma_map(priv->dev,
21832187
&skb_shinfo(skb)->frags[i],
21842188
0,
2185-
length,
2189+
frag_len,
21862190
DMA_TO_DEVICE);
21872191

21882192
/* set the TxBD length and buffer pointer */
@@ -2250,7 +2254,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
22502254
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
22512255
}
22522256

2253-
netdev_tx_sent_queue(txq, skb->len);
2257+
netdev_tx_sent_queue(txq, bytes_sent);
22542258

22552259
/* We can work in parallel with gfar_clean_tx_ring(), except
22562260
* when modifying num_txbdfree. Note that we didn't grab the lock
@@ -2570,7 +2574,7 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
25702574
bdp = next_txbd(bdp, base, tx_ring_size);
25712575
}
25722576

2573-
bytes_sent += skb->len;
2577+
bytes_sent += GFAR_CB(skb)->bytes_sent;
25742578

25752579
dev_kfree_skb_any(skb);
25762580

drivers/net/ethernet/freescale/gianfar.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ struct rxfcb {
575575
};
576576

577577
struct gianfar_skb_cb {
578-
int alignamount;
578+
unsigned int bytes_sent; /* bytes-on-wire (i.e. no FCB) */
579579
};
580580

581581
#define GFAR_CB(skb) ((struct gianfar_skb_cb *)((skb)->cb))

0 commit comments

Comments
 (0)