lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20171015162353.1050-1-roman@advem.lv>
Date:   Sun, 15 Oct 2017 19:23:53 +0300
From:   Roman Yeryomin <roman@...em.lv>
To:     netdev <netdev@...r.kernel.org>
Subject: [PATCH net-next 07/10] net: korina: move tx to napi context

Signed-off-by: Roman Yeryomin <roman@...em.lv>
---
 drivers/net/ethernet/korina.c | 79 +++++++++++--------------------------------
 1 file changed, 20 insertions(+), 59 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index a076b0c49e6e..f606f1e01af1 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -185,10 +185,6 @@ static inline void korina_abort_dma(struct net_device *dev,
 {
 	if (readl(&ch->dmac) & DMA_CHAN_RUN_BIT) {
 		writel(0x10, &ch->dmac);
-
-		while (!(readl(&ch->dmas) & DMA_STAT_HALT))
-			netif_trans_update(dev);
-
 		writel(0, &ch->dmas);
 	}
 
@@ -260,12 +256,9 @@ static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
 	struct korina_private *lp = netdev_priv(dev);
-	unsigned long flags;
 	u32 chain_prev, chain_next, dmandptr;
 	struct dma_desc *td;
 
-	spin_lock_irqsave(&lp->lock, flags);
-
 	td = &lp->td_ring[lp->tx_chain_tail];
 
 	/* stop queue when full, drop pkts if queue already full */
@@ -276,7 +269,6 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 		if (lp->tx_count > (KORINA_NUM_TDS - 2)) {
 			dev->stats.tx_dropped++;
 			dev_kfree_skb_any(skb);
-			spin_unlock_irqrestore(&lp->lock, flags);
 
 			return NETDEV_TX_BUSY;
 		}
@@ -319,9 +311,6 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 	dma_cache_wback((u32) td, sizeof(*td));
 
-	netif_trans_update(dev);
-	spin_unlock_irqrestore(&lp->lock, flags);
-
 	return NETDEV_TX_OK;
 }
 
@@ -332,8 +321,6 @@ static void korina_tx(struct net_device *dev)
 	u32 devcs;
 	u32 dmas;
 
-	spin_lock(&lp->lock);
-
 	/* Process all desc that are done */
 	while (IS_DMA_FINISHED(td->control)) {
 		if (lp->tx_full == 1) {
@@ -389,10 +376,6 @@ static void korina_tx(struct net_device *dev)
 	/* Clear the DMA status register */
 	dmas = readl(&lp->tx_dma_regs->dmas);
 	writel(~dmas, &lp->tx_dma_regs->dmas);
-
-	korina_int_enable_tx(lp);
-
-	spin_unlock(&lp->lock);
 }
 
 static int korina_rx(struct net_device *dev, int limit)
@@ -513,67 +496,47 @@ static int korina_poll(struct napi_struct *napi, int budget)
 	struct net_device *dev = lp->dev;
 	int work_done;
 
+	korina_tx(dev);
+
 	work_done = korina_rx(dev, budget);
 	if (work_done < budget) {
 		napi_complete_done(napi, work_done);
+		spin_lock_bh(&lp->lock);
+		korina_int_enable_tx(lp);
 		korina_int_enable_rx(lp);
+		spin_unlock_bh(&lp->lock);
 	}
 	return work_done;
 }
 
-static irqreturn_t
-korina_tx_dma_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct korina_private *lp = netdev_priv(dev);
-	u32 dmas;
-
-	dmas = readl(&lp->tx_dma_regs->dmas);
-
-	if (likely(dmas & KORINA_INT_TX)) {
-		korina_int_disable_tx(lp);
-
-		korina_tx(dev);
-
-		if (lp->tx_chain_status == desc_filled &&
-			(readl(&(lp->tx_dma_regs->dmandptr)) == 0)) {
-			writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]),
-				&(lp->tx_dma_regs->dmandptr));
-			lp->tx_chain_status = desc_empty;
-			lp->tx_chain_head = lp->tx_chain_tail;
-			netif_trans_update(dev);
-		}
-
-		if (unlikely(dmas & DMA_STAT_ERR))
-			lp->dma_halt_cnt++;
-
-		return IRQ_HANDLED;
-	}
-
-	return IRQ_NONE;
-}
-
 /* Ethernet Rx DMA interrupt */
-static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id)
+static irqreturn_t korina_dma_interrupt(int irq, void *dev_id)
 {
 	struct net_device *dev = dev_id;
 	struct korina_private *lp = netdev_priv(dev);
 	u32 dmas;
+	unsigned long flags;
+	irqreturn_t ret = IRQ_NONE;
 
-	dmas = readl(&lp->rx_dma_regs->dmas);
+	spin_lock_irqsave(&lp->lock, flags);
 
-	if (likely(dmas & KORINA_INT_RX)) {
+	dmas = readl(&lp->tx_dma_regs->dmas);
+	dmas |= readl(&lp->rx_dma_regs->dmas);
+
+	if (likely(dmas & KORINA_INT_TXRX)) {
 		korina_int_disable_rx(lp);
+		korina_int_disable_tx(lp);
 
 		napi_schedule(&lp->napi);
 
 		if (unlikely(dmas & DMA_STAT_ERR))
 			lp->dma_halt_cnt++;
 
-		return IRQ_HANDLED;
+		ret = IRQ_HANDLED;
 	}
 
-	return IRQ_NONE;
+	spin_unlock_irqrestore(&lp->lock, flags);
+	return ret;
 }
 
 /*
@@ -792,8 +755,6 @@ static int korina_init(struct net_device *dev)
 
 	/* reset ethernet logic */
 	writel(0, &lp->eth_regs->ethintfc);
-	while ((readl(&lp->eth_regs->ethintfc) & ETH_INT_FC_RIP))
-		netif_trans_update(dev);
 
 	/* Enable Ethernet Interface */
 	writel(ETH_INT_FC_EN, &lp->eth_regs->ethintfc);
@@ -897,7 +858,7 @@ static void korina_tx_timeout(struct net_device *dev)
 static void korina_poll_controller(struct net_device *dev)
 {
 	disable_irq(dev->irq);
-	korina_tx_dma_interrupt(dev->irq, dev);
+	korina_dma_interrupt(dev->irq, dev);
 	enable_irq(dev->irq);
 }
 #endif
@@ -916,14 +877,14 @@ static int korina_open(struct net_device *dev)
 
 	/* Install the interrupt handler
 	 * that handles the Done Finished */
-	ret = request_irq(lp->rx_irq, korina_rx_dma_interrupt,
+	ret = request_irq(lp->rx_irq, korina_dma_interrupt,
 			0, "Korina ethernet Rx", dev);
 	if (ret < 0) {
 		printk(KERN_ERR "%s: unable to get Rx DMA IRQ %d\n",
 			dev->name, lp->rx_irq);
 		goto err_release;
 	}
-	ret = request_irq(lp->tx_irq, korina_tx_dma_interrupt,
+	ret = request_irq(lp->tx_irq, korina_dma_interrupt,
 			0, "Korina ethernet Tx", dev);
 	if (ret < 0) {
 		printk(KERN_ERR "%s: unable to get Tx DMA IRQ %d\n",
-- 
2.11.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ