Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1422822Ab2JLPQd (ORCPT ); Fri, 12 Oct 2012 11:16:33 -0400 Received: from mail-ob0-f174.google.com ([209.85.214.174]:42004 "EHLO mail-ob0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1422771Ab2JLPPt (ORCPT ); Fri, 12 Oct 2012 11:15:49 -0400 From: Rob Herring To: linux-kernel@vger.kernel.org, netdev@vger.kernel.org Cc: jonathan@jonmasters.org, eric.dumazet@gmail.com, Mark Langsdorf , Rob Herring Subject: [PATCH 5/6] net: calxedaxgmac: rework transmit ring handling Date: Fri, 12 Oct 2012 10:15:07 -0500 Message-Id: <1350054908-30646-6-git-send-email-robherring2@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1350054908-30646-1-git-send-email-robherring2@gmail.com> References: <1350054908-30646-1-git-send-email-robherring2@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3212 Lines: 94 From: Rob Herring Only generate tx interrupts on every ring size / 4 descriptors. Move the netif_stop_queue call to the end of the xmit function rather than checking at the beginning. Signed-off-by: Rob Herring --- drivers/net/ethernet/calxeda/xgmac.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index 4a1a06a..5cb10b6 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -374,6 +374,7 @@ struct xgmac_priv { struct sk_buff **tx_skbuff; unsigned int tx_head; unsigned int tx_tail; + int tx_irq_cnt; void __iomem *base; unsigned int dma_buf_sz; @@ -886,7 +887,7 @@ static void xgmac_tx_complete(struct xgmac_priv *priv) } if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) > - TX_THRESH) + MAX_SKB_FRAGS) netif_wake_queue(priv->dev); } @@ -1057,19 +1058,15 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) struct xgmac_priv *priv = netdev_priv(dev); unsigned int entry; int i; + u32 irq_flag; int nfrags = skb_shinfo(skb)->nr_frags; struct xgmac_dma_desc *desc, *first; unsigned int desc_flags; unsigned int len; dma_addr_t paddr; - if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) < - (nfrags + 1)) { - writel(DMA_INTR_DEFAULT_MASK | DMA_INTR_ENA_TIE, - priv->base + XGMAC_DMA_INTR_ENA); - netif_stop_queue(dev); - return NETDEV_TX_BUSY; - } + priv->tx_irq_cnt = (priv->tx_irq_cnt + 1) & (DMA_TX_RING_SZ/4 - 1); + irq_flag = priv->tx_irq_cnt ? 0 : TXDESC_INTERRUPT; desc_flags = (skb->ip_summed == CHECKSUM_PARTIAL) ? TXDESC_CSUM_ALL : 0; @@ -1110,9 +1107,9 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) /* Interrupt on completition only for the latest segment */ if (desc != first) desc_set_tx_owner(desc, desc_flags | - TXDESC_LAST_SEG | TXDESC_INTERRUPT); + TXDESC_LAST_SEG | irq_flag); else - desc_flags |= TXDESC_LAST_SEG | TXDESC_INTERRUPT; + desc_flags |= TXDESC_LAST_SEG | irq_flag; /* Set owner on first desc last to avoid race condition */ wmb(); @@ -1121,6 +1118,9 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ); writel(1, priv->base + XGMAC_DMA_TX_POLL); + if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) < + MAX_SKB_FRAGS) + netif_stop_queue(dev); return NETDEV_TX_OK; } @@ -1397,7 +1397,7 @@ static irqreturn_t xgmac_interrupt(int irq, void *dev_id) } /* TX/RX NORMAL interrupts */ - if (intr_status & (DMA_STATUS_RI | DMA_STATUS_TU)) { + if (intr_status & (DMA_STATUS_RI | DMA_STATUS_TU | DMA_STATUS_TI)) { writel_relaxed(DMA_INTR_ABNORMAL, priv->base + XGMAC_DMA_INTR_ENA); napi_schedule(&priv->napi); } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/