dev_kfree_skb_any(new_skb);
 }
 
-static irqreturn_t cpsw_interrupt(int irq, void *dev_id)
+static irqreturn_t cpsw_tx_interrupt(int irq, void *dev_id)
 {
        struct cpsw_priv *priv = dev_id;
-       int value = irq - priv->irqs_table[0];
 
-       /* NOTICE: Ending IRQ here. The trick with the 'value' variable above
-        * is to make sure we will always write the correct value to the EOI
-        * register. Namely 0 for RX_THRESH Interrupt, 1 for RX Interrupt, 2
-        * for TX Interrupt and 3 for MISC Interrupt.
-        */
-       cpdma_ctlr_eoi(priv->dma, value);
+       cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
+       cpdma_chan_process(priv->txch, 128);
+
+       priv = cpsw_get_slave_priv(priv, 1);
+       if (priv)
+               cpdma_chan_process(priv->txch, 128);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id)
+{
+       struct cpsw_priv *priv = dev_id;
+
+       cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
 
        cpsw_intr_disable(priv);
        if (priv->irq_enabled == true) {
 
        cpsw_intr_disable(priv);
        cpdma_ctlr_int_ctrl(priv->dma, false);
-       cpsw_interrupt(ndev->irq, priv);
+       cpsw_rx_interrupt(priv->irq[0], priv);
+       cpsw_tx_interrupt(priv->irq[1], priv);
        cpdma_ctlr_int_ctrl(priv->dma, true);
        cpsw_intr_enable(priv);
 }
                goto clean_dma_ret;
        }
 
-       ndev->irq = platform_get_irq(pdev, 0);
+       ndev->irq = platform_get_irq(pdev, 1);
        if (ndev->irq < 0) {
                dev_err(priv->dev, "error getting irq resource\n");
                ret = -ENOENT;
                goto clean_ale_ret;
        }
 
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0)
-               goto clean_ale_ret;
-
-       priv->irqs_table[0] = irq;
-       ret = devm_request_irq(&pdev->dev, irq, cpsw_interrupt,
-                              0, dev_name(&pdev->dev), priv);
-       if (ret < 0) {
-               dev_err(priv->dev, "error attaching irq (%d)\n", ret);
-               goto clean_ale_ret;
-       }
+       /* Grab RX and TX IRQs. Note that we also have RX_THRESHOLD and
+        * MISC IRQs which are always kept disabled with this driver so
+        * we will not request them.
+        *
+        * If anyone wants to implement support for those, make sure to
+        * first request and append them to irqs_table array.
+        */
 
+       /* RX IRQ */
        irq = platform_get_irq(pdev, 1);
        if (irq < 0)
                goto clean_ale_ret;
 
-       priv->irqs_table[1] = irq;
-       ret = devm_request_irq(&pdev->dev, irq, cpsw_interrupt,
+       priv->irqs_table[0] = irq;
+       ret = devm_request_irq(&pdev->dev, irq, cpsw_rx_interrupt,
                               0, dev_name(&pdev->dev), priv);
        if (ret < 0) {
                dev_err(priv->dev, "error attaching irq (%d)\n", ret);
                goto clean_ale_ret;
        }
 
+       /* TX IRQ */
        irq = platform_get_irq(pdev, 2);
        if (irq < 0)
                goto clean_ale_ret;
 
-       priv->irqs_table[2] = irq;
-       ret = devm_request_irq(&pdev->dev, irq, cpsw_interrupt,
-                              0, dev_name(&pdev->dev), priv);
-       if (ret < 0) {
-               dev_err(priv->dev, "error attaching irq (%d)\n", ret);
-               goto clean_ale_ret;
-       }
-
-       irq = platform_get_irq(pdev, 3);
-       if (irq < 0)
-               goto clean_ale_ret;
-
-       priv->irqs_table[3] = irq;
-       ret = devm_request_irq(&pdev->dev, irq, cpsw_interrupt,
+       priv->irqs_table[1] = irq;
+       ret = devm_request_irq(&pdev->dev, irq, cpsw_tx_interrupt,
                               0, dev_name(&pdev->dev), priv);
        if (ret < 0) {
                dev_err(priv->dev, "error attaching irq (%d)\n", ret);
                goto clean_ale_ret;
        }
-
-       priv->num_irqs = 4;
+       priv->num_irqs = 2;
 
        ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;