From f5a9ec20b3b2adf03a0b01902cda913b05abd382 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Tue, 5 Apr 2016 13:59:59 -0700 Subject: [PATCH 1/3] net: bcmgenet: cleanup for bcmgenet_xmit() 1. Readability: Move nr_frags assignment a few lines down in order to bundle index -> ring -> txq calculations together. 2. Readability: Add parentheses around nr_frags + 1. 3. Minor fix: Stop the Tx queue and throw the error message only if the Tx queue hasn't already been stopped. Signed-off-by: Petri Gynther Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index cf6445d148ca..7f85a8494eee 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1447,15 +1447,19 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) else index -= 1; - nr_frags = skb_shinfo(skb)->nr_frags; ring = &priv->tx_rings[index]; txq = netdev_get_tx_queue(dev, ring->queue); + nr_frags = skb_shinfo(skb)->nr_frags; + spin_lock_irqsave(&ring->lock, flags); - if (ring->free_bds <= nr_frags + 1) { - netif_tx_stop_queue(txq); - netdev_err(dev, "%s: tx ring %d full when queue %d awake\n", - __func__, index, ring->queue); + if (ring->free_bds <= (nr_frags + 1)) { + if (!netif_tx_queue_stopped(txq)) { + netif_tx_stop_queue(txq); + netdev_err(dev, + "%s: tx ring %d full when queue %d awake\n", + __func__, index, ring->queue); + } ret = NETDEV_TX_BUSY; goto out; } From 824ba603573d910e32df75fe6a5e7d7ec2a0a6a7 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Tue, 5 Apr 2016 14:00:00 -0700 Subject: [PATCH 2/3] net: bcmgenet: cleanup for bcmgenet_xmit_frag() Add frag_size = skb_frag_size(frag) and use it when needed. Signed-off-by: Petri Gynther Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 7f85a8494eee..d77cd6dee092 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1331,6 +1331,7 @@ static int bcmgenet_xmit_frag(struct net_device *dev, struct bcmgenet_priv *priv = netdev_priv(dev); struct device *kdev = &priv->pdev->dev; struct enet_cb *tx_cb_ptr; + unsigned int frag_size; dma_addr_t mapping; int ret; @@ -1338,10 +1339,12 @@ static int bcmgenet_xmit_frag(struct net_device *dev, if (unlikely(!tx_cb_ptr)) BUG(); + tx_cb_ptr->skb = NULL; - mapping = skb_frag_dma_map(kdev, frag, 0, - skb_frag_size(frag), DMA_TO_DEVICE); + frag_size = skb_frag_size(frag); + + mapping = skb_frag_dma_map(kdev, frag, 0, frag_size, DMA_TO_DEVICE); ret = dma_mapping_error(kdev, mapping); if (ret) { priv->mib.tx_dma_failed++; @@ -1351,10 +1354,10 @@ static int bcmgenet_xmit_frag(struct net_device *dev, } dma_unmap_addr_set(tx_cb_ptr, dma_addr, mapping); - dma_unmap_len_set(tx_cb_ptr, dma_len, frag->size); + dma_unmap_len_set(tx_cb_ptr, dma_len, frag_size); dmadesc_set(priv, tx_cb_ptr->bd_addr, mapping, - (frag->size << DMA_BUFLENGTH_SHIFT) | dma_desc_flags | + (frag_size << DMA_BUFLENGTH_SHIFT) | dma_desc_flags | (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT)); return 0; From 7ee4062562bae8f248f0aa72dfb3023ddea65942 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Tue, 5 Apr 2016 14:00:01 -0700 Subject: [PATCH 3/3] net: bcmgenet: cleanup for dmadesc_set() dmadesc_set() is used for setting the Tx buffer DMA address, length, and status bits on a Tx ring descriptor when a frame is being Tx'ed. Always set the Tx buffer DMA address first, before updating the length and status bits, i.e. giving the Tx descriptor to the hardware. The reason this is a cleanup rather than a fix is that the hardware won't transmit anything from a Tx ring until the TDMA producer index has been incremented. As long as the dmadesc_set() writes complete before the TDMA producer index write, life is good. Signed-off-by: Petri Gynther Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index d77cd6dee092..f7b42b9fc979 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -104,8 +104,8 @@ static inline void dmadesc_set_addr(struct bcmgenet_priv *priv, static inline void dmadesc_set(struct bcmgenet_priv *priv, void __iomem *d, dma_addr_t addr, u32 val) { - dmadesc_set_length_status(priv, d, val); dmadesc_set_addr(priv, d, addr); + dmadesc_set_length_status(priv, d, val); } static inline dma_addr_t dmadesc_get_addr(struct bcmgenet_priv *priv,