diff options
author | Petri Gynther <pgynther@google.com> | 2016-03-24 14:27:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-03-24 15:11:39 -0400 |
commit | 55868120a3e5420bf5aa26a816c07d691579c9e6 (patch) | |
tree | 8e1e3d1af8f42b8bec8e7a1c63afff98119cf104 | |
parent | 3e347660488818070bff7533f8561928e09e1d65 (diff) |
net: bcmgenet: fix dev->stats.tx_bytes accounting
1. Add bytes_compl local variable to __bcmgenet_tx_reclaim() to collect
transmitted bytes. dev->stats updates can then be moved outside the
while-loop. bytes_compl is also needed for future BQL support.
2. When bcmgenet device uses Tx checksum offload, each transmitted skb
gets an extra 64-byte header prepended to it. Before this header is
prepended to the skb, we need to save the skb "wire" length in
GENET_CB(skb)->bytes_sent, so that proper Tx bytes accounting can
be done in __bcmgenet_tx_reclaim().
3. skb->len covers the entire length of skb, whether it is linear or
fragmented. Thus, when we clean the fragments, do not increase
transmitted bytes.
Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file")
Signed-off-by: Petri Gynther <pgynther@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmgenet.c | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmgenet.h | 6 |
2 files changed, 16 insertions, 4 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 6746fd03cb3a..c1c7c0e6fb7c 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c | |||
@@ -1171,6 +1171,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, | |||
1171 | struct enet_cb *tx_cb_ptr; | 1171 | struct enet_cb *tx_cb_ptr; |
1172 | struct netdev_queue *txq; | 1172 | struct netdev_queue *txq; |
1173 | unsigned int pkts_compl = 0; | 1173 | unsigned int pkts_compl = 0; |
1174 | unsigned int bytes_compl = 0; | ||
1174 | unsigned int c_index; | 1175 | unsigned int c_index; |
1175 | unsigned int txbds_ready; | 1176 | unsigned int txbds_ready; |
1176 | unsigned int txbds_processed = 0; | 1177 | unsigned int txbds_processed = 0; |
@@ -1193,16 +1194,13 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, | |||
1193 | tx_cb_ptr = &priv->tx_cbs[ring->clean_ptr]; | 1194 | tx_cb_ptr = &priv->tx_cbs[ring->clean_ptr]; |
1194 | if (tx_cb_ptr->skb) { | 1195 | if (tx_cb_ptr->skb) { |
1195 | pkts_compl++; | 1196 | pkts_compl++; |
1196 | dev->stats.tx_packets++; | 1197 | bytes_compl += GENET_CB(tx_cb_ptr->skb)->bytes_sent; |
1197 | dev->stats.tx_bytes += tx_cb_ptr->skb->len; | ||
1198 | dma_unmap_single(&dev->dev, | 1198 | dma_unmap_single(&dev->dev, |
1199 | dma_unmap_addr(tx_cb_ptr, dma_addr), | 1199 | dma_unmap_addr(tx_cb_ptr, dma_addr), |
1200 | dma_unmap_len(tx_cb_ptr, dma_len), | 1200 | dma_unmap_len(tx_cb_ptr, dma_len), |
1201 | DMA_TO_DEVICE); | 1201 | DMA_TO_DEVICE); |
1202 | bcmgenet_free_cb(tx_cb_ptr); | 1202 | bcmgenet_free_cb(tx_cb_ptr); |
1203 | } else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) { | 1203 | } else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) { |
1204 | dev->stats.tx_bytes += | ||
1205 | dma_unmap_len(tx_cb_ptr, dma_len); | ||
1206 | dma_unmap_page(&dev->dev, | 1204 | dma_unmap_page(&dev->dev, |
1207 | dma_unmap_addr(tx_cb_ptr, dma_addr), | 1205 | dma_unmap_addr(tx_cb_ptr, dma_addr), |
1208 | dma_unmap_len(tx_cb_ptr, dma_len), | 1206 | dma_unmap_len(tx_cb_ptr, dma_len), |
@@ -1220,6 +1218,9 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, | |||
1220 | ring->free_bds += txbds_processed; | 1218 | ring->free_bds += txbds_processed; |
1221 | ring->c_index = (ring->c_index + txbds_processed) & DMA_C_INDEX_MASK; | 1219 | ring->c_index = (ring->c_index + txbds_processed) & DMA_C_INDEX_MASK; |
1222 | 1220 | ||
1221 | dev->stats.tx_packets += pkts_compl; | ||
1222 | dev->stats.tx_bytes += bytes_compl; | ||
1223 | |||
1223 | if (ring->free_bds > (MAX_SKB_FRAGS + 1)) { | 1224 | if (ring->free_bds > (MAX_SKB_FRAGS + 1)) { |
1224 | txq = netdev_get_tx_queue(dev, ring->queue); | 1225 | txq = netdev_get_tx_queue(dev, ring->queue); |
1225 | if (netif_tx_queue_stopped(txq)) | 1226 | if (netif_tx_queue_stopped(txq)) |
@@ -1464,6 +1465,11 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1464 | goto out; | 1465 | goto out; |
1465 | } | 1466 | } |
1466 | 1467 | ||
1468 | /* Retain how many bytes will be sent on the wire, without TSB inserted | ||
1469 | * by transmit checksum offload | ||
1470 | */ | ||
1471 | GENET_CB(skb)->bytes_sent = skb->len; | ||
1472 | |||
1467 | /* set the SKB transmit checksum */ | 1473 | /* set the SKB transmit checksum */ |
1468 | if (priv->desc_64b_en) { | 1474 | if (priv->desc_64b_en) { |
1469 | skb = bcmgenet_put_tx_csum(dev, skb); | 1475 | skb = bcmgenet_put_tx_csum(dev, skb); |
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 967367557309..1e2dc34d331a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h | |||
@@ -531,6 +531,12 @@ struct bcmgenet_hw_params { | |||
531 | u32 flags; | 531 | u32 flags; |
532 | }; | 532 | }; |
533 | 533 | ||
534 | struct bcmgenet_skb_cb { | ||
535 | unsigned int bytes_sent; /* bytes on the wire (no TSB) */ | ||
536 | }; | ||
537 | |||
538 | #define GENET_CB(skb) ((struct bcmgenet_skb_cb *)((skb)->cb)) | ||
539 | |||
534 | struct bcmgenet_tx_ring { | 540 | struct bcmgenet_tx_ring { |
535 | spinlock_t lock; /* ring lock */ | 541 | spinlock_t lock; /* ring lock */ |
536 | struct napi_struct napi; /* NAPI per tx queue */ | 542 | struct napi_struct napi; /* NAPI per tx queue */ |