From ae67bf0188cbb9d1786bdfcca9e1976cb36ee327 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 13 Mar 2015 12:11:06 -0700 Subject: [PATCH 1/2] net: bcmgenet: update ring producer index and buffer count in xmit There is no need to have both bcmgenet_xmit_single() and bcmgenet_xmit_frag() perform a free_bds decrement and a prod_index increment by one. In case one of these functions fails to map a SKB or fragment for transmit, we will return and exit bcmgenet_xmit() with an error. We can therefore safely use our local copy of nr_frags to know by how much we should decrement the number of free buffers available, and by how much the producer count must be incremented and do this in the tail of bcmgenet_xmit(). Signed-off-by: Florian Fainelli Acked-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 875967e8d719..53c916ea06a2 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1130,11 +1130,6 @@ static int bcmgenet_xmit_single(struct net_device *dev, dmadesc_set(priv, tx_cb_ptr->bd_addr, mapping, length_status); - /* Decrement total BD count and advance our write pointer */ - ring->free_bds -= 1; - ring->prod_index += 1; - ring->prod_index &= DMA_P_INDEX_MASK; - return 0; } @@ -1173,11 +1168,6 @@ static int bcmgenet_xmit_frag(struct net_device *dev, (frag->size << DMA_BUFLENGTH_SHIFT) | dma_desc_flags | (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT)); - - ring->free_bds -= 1; - ring->prod_index += 1; - ring->prod_index &= DMA_P_INDEX_MASK; - return 0; } @@ -1321,9 +1311,11 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) skb_tx_timestamp(skb); - /* we kept a software copy of how much we should advance the TDMA - * producer index, now write it down to the hardware - */ + /* Decrement total BD count and advance our write pointer */ + ring->free_bds -= nr_frags + 1; + ring->prod_index += nr_frags + 1; + ring->prod_index &= DMA_P_INDEX_MASK; + bcmgenet_tdma_ring_writel(priv, ring->index, ring->prod_index, TDMA_PROD_INDEX); From ddd0ca5d60b350bbfbfb60b25885a9779ce6d6c7 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 13 Mar 2015 12:11:07 -0700 Subject: [PATCH 2/2] net: bcmgenet: add support for xmit_more Delay the update of the TDMA producer index unless this is the last SKB in a batch, or the queue is already stopped. Move the check for whether the queue should be stopped before the xmit_more check to avoid locking the transmit queue in case there was a SKB submitted which has xmit_more set. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 53c916ea06a2..e74ae628bbb9 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1316,12 +1316,13 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) ring->prod_index += nr_frags + 1; ring->prod_index &= DMA_P_INDEX_MASK; - bcmgenet_tdma_ring_writel(priv, ring->index, - ring->prod_index, TDMA_PROD_INDEX); - if (ring->free_bds <= (MAX_SKB_FRAGS + 1)) netif_tx_stop_queue(txq); + if (!skb->xmit_more || netif_xmit_stopped(txq)) + /* Packets are ready, update producer index */ + bcmgenet_tdma_ring_writel(priv, ring->index, + ring->prod_index, TDMA_PROD_INDEX); out: spin_unlock_irqrestore(&ring->lock, flags);