--- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -2064,7 +2064,7 @@ static int gfar_start_xmit(struct sk_buf int i, rq = 0, do_tstamp = 0; u32 bufaddr; unsigned long flags; - unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN; + unsigned int nr_frags, nr_txbds, bytes_sent, fcb_length = GMAC_FCB_LEN; /* TOE=1 frames larger than 2500 bytes may see excess delays * before start of transmission. @@ -2130,7 +2130,10 @@ static int gfar_start_xmit(struct sk_buf } /* Update transmit stats */ - tx_queue->stats.tx_bytes += skb->len; + bytes_sent = skb->len; + tx_queue->stats.tx_bytes += bytes_sent; + /* keep Tx bytes on wire for BQL accounting */ + GFAR_CB(skb)->bytes_sent = bytes_sent; tx_queue->stats.tx_packets++; txbdp = txbdp_start = tx_queue->cur_tx; @@ -2150,12 +2153,13 @@ static int gfar_start_xmit(struct sk_buf } else { /* Place the fragment addresses and lengths into the TxBDs */ for (i = 0; i < nr_frags; i++) { + unsigned int frag_len; /* Point at the next BD, wrapping as needed */ txbdp = next_txbd(txbdp, base, tx_queue->tx_ring_size); - length = skb_shinfo(skb)->frags[i].size; + frag_len = skb_shinfo(skb)->frags[i].size; - lstatus = txbdp->lstatus | length | + lstatus = txbdp->lstatus | frag_len | BD_LFLAG(TXBD_READY); /* Handle the last BD specially */ @@ -2165,7 +2169,7 @@ static int gfar_start_xmit(struct sk_buf bufaddr = skb_frag_dma_map(priv->dev, &skb_shinfo(skb)->frags[i], 0, - length, + frag_len, DMA_TO_DEVICE); /* set the TxBD length and buffer pointer */ @@ -2231,7 +2235,7 @@ static int gfar_start_xmit(struct sk_buf lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); } - netdev_tx_sent_queue(txq, skb->len); + netdev_tx_sent_queue(txq, bytes_sent); /* We can work in parallel with gfar_clean_tx_ring(), except * when modifying num_txbdfree. Note that we didn't grab the lock @@ -2551,7 +2555,7 @@ static void gfar_clean_tx_ring(struct gf bdp = next_txbd(bdp, base, tx_ring_size); } - bytes_sent += skb->len; + bytes_sent += GFAR_CB(skb)->bytes_sent; dev_kfree_skb_any(skb); --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -571,7 +571,7 @@ struct rxfcb { }; struct gianfar_skb_cb { - int alignamount; + unsigned int bytes_sent; /* bytes-on-wire (i.e. no FCB) */ }; #define GFAR_CB(skb) ((struct gianfar_skb_cb *)((skb)->cb))