Signed-off-by: Roman Yeryomin <ro...@advem.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