aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/genet
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2014-09-22 14:54:42 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-22 18:38:40 -0400
commit478a010c9235ca92e66cc5058b42e30e33275ad4 (patch)
tree450e9ba46516bb9f215e210502785f0c6c3bf5bd /drivers/net/ethernet/broadcom/genet
parenta35165ca101695aa2cc5a6300ef69ae60be39a49 (diff)
net: bcmgenet: fix TX reclaim accounting for fragments
The GENET driver supports SKB fragments, and succeeds in transmitting them properly, but when reclaiming these transmitted fragments, we will only update the count of free buffer descriptors by 1, even for SKBs with fragments. This leads to the networking stack thinking it has more room than the hardware has when pushing new SKBs, and backing off consequently because we return NETDEV_TX_BUSY. Fix this by accounting for the SKB nr_frags plus one (itself) and update ring->free_bds accordingly with that value for each iteration loop in __bcmgenet_tx_reclaim(). Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file") Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/genet')
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index cdef86a03862..11a96437862d 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -875,6 +875,7 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
875 int last_tx_cn, last_c_index, num_tx_bds; 875 int last_tx_cn, last_c_index, num_tx_bds;
876 struct enet_cb *tx_cb_ptr; 876 struct enet_cb *tx_cb_ptr;
877 struct netdev_queue *txq; 877 struct netdev_queue *txq;
878 unsigned int bds_compl;
878 unsigned int c_index; 879 unsigned int c_index;
879 880
880 /* Compute how many buffers are transmitted since last xmit call */ 881 /* Compute how many buffers are transmitted since last xmit call */
@@ -899,7 +900,9 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
899 /* Reclaim transmitted buffers */ 900 /* Reclaim transmitted buffers */
900 while (last_tx_cn-- > 0) { 901 while (last_tx_cn-- > 0) {
901 tx_cb_ptr = ring->cbs + last_c_index; 902 tx_cb_ptr = ring->cbs + last_c_index;
903 bds_compl = 0;
902 if (tx_cb_ptr->skb) { 904 if (tx_cb_ptr->skb) {
905 bds_compl = skb_shinfo(tx_cb_ptr->skb)->nr_frags + 1;
903 dev->stats.tx_bytes += tx_cb_ptr->skb->len; 906 dev->stats.tx_bytes += tx_cb_ptr->skb->len;
904 dma_unmap_single(&dev->dev, 907 dma_unmap_single(&dev->dev,
905 dma_unmap_addr(tx_cb_ptr, dma_addr), 908 dma_unmap_addr(tx_cb_ptr, dma_addr),
@@ -916,7 +919,7 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
916 dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0); 919 dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0);
917 } 920 }
918 dev->stats.tx_packets++; 921 dev->stats.tx_packets++;
919 ring->free_bds += 1; 922 ring->free_bds += bds_compl;
920 923
921 last_c_index++; 924 last_c_index++;
922 last_c_index &= (num_tx_bds - 1); 925 last_c_index &= (num_tx_bds - 1);