{
        struct xgene_enet_pdata *pdata = netdev_priv(ndev);
        struct device *dev = ndev_to_dev(ndev);
+       struct xgene_enet_desc_ring *ring;
        int ret;
 
-       ret = devm_request_irq(dev, pdata->rx_ring->irq, xgene_enet_rx_irq,
-                              IRQF_SHARED, ndev->name, pdata->rx_ring);
-       if (ret) {
-               netdev_err(ndev, "rx%d interrupt request failed\n",
-                          pdata->rx_ring->irq);
+       ring = pdata->rx_ring;
+       ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
+                              IRQF_SHARED, ring->irq_name, ring);
+       if (ret)
+               netdev_err(ndev, "Failed to request irq %s\n", ring->irq_name);
+
+       if (pdata->cq_cnt) {
+               ring = pdata->tx_ring->cp_ring;
+               ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
+                                      IRQF_SHARED, ring->irq_name, ring);
+               if (ret) {
+                       netdev_err(ndev, "Failed to request irq %s\n",
+                                  ring->irq_name);
+               }
        }
 
        return ret;
        pdata = netdev_priv(ndev);
        dev = ndev_to_dev(ndev);
        devm_free_irq(dev, pdata->rx_ring->irq, pdata->rx_ring);
+
+       if (pdata->cq_cnt) {
+               devm_free_irq(dev, pdata->tx_ring->cp_ring->irq,
+                             pdata->tx_ring->cp_ring);
+       }
+}
+
+static void xgene_enet_napi_enable(struct xgene_enet_pdata *pdata)
+{
+       struct napi_struct *napi;
+
+       napi = &pdata->rx_ring->napi;
+       napi_enable(napi);
+
+       if (pdata->cq_cnt) {
+               napi = &pdata->tx_ring->cp_ring->napi;
+               napi_enable(napi);
+       }
+}
+
+static void xgene_enet_napi_disable(struct xgene_enet_pdata *pdata)
+{
+       struct napi_struct *napi;
+
+       napi = &pdata->rx_ring->napi;
+       napi_disable(napi);
+
+       if (pdata->cq_cnt) {
+               napi = &pdata->tx_ring->cp_ring->napi;
+               napi_disable(napi);
+       }
 }
 
 static int xgene_enet_open(struct net_device *ndev)
        ret = xgene_enet_register_irq(ndev);
        if (ret)
                return ret;
-       napi_enable(&pdata->rx_ring->napi);
+       xgene_enet_napi_enable(pdata);
 
        if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
                phy_start(pdata->phy_dev);
        else
                cancel_delayed_work_sync(&pdata->link_work);
 
-       napi_disable(&pdata->rx_ring->napi);
+       xgene_enet_napi_disable(pdata);
        xgene_enet_free_irq(ndev);
        xgene_enet_process_ring(pdata->rx_ring, -1);
 
        if (ring) {
                if (ring->cp_ring && ring->cp_ring->cp_skb)
                        devm_kfree(dev, ring->cp_ring->cp_skb);
+               if (ring->cp_ring && pdata->cq_cnt)
+                       xgene_enet_free_desc_ring(ring->cp_ring);
                xgene_enet_free_desc_ring(ring);
        }
 
        rx_ring->nbufpool = NUM_BUFPOOL;
        rx_ring->buf_pool = buf_pool;
        rx_ring->irq = pdata->rx_irq;
+       if (!pdata->cq_cnt) {
+               snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx-txc",
+                        ndev->name);
+       } else {
+               snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx", ndev->name);
+       }
        buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots,
                                        sizeof(struct sk_buff *), GFP_KERNEL);
        if (!buf_pool->rx_skb) {
        }
        pdata->tx_ring = tx_ring;
 
-       cp_ring = pdata->rx_ring;
+       if (!pdata->cq_cnt) {
+               cp_ring = pdata->rx_ring;
+       } else {
+               /* allocate tx completion descriptor ring */
+               ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU, cpu_bufnum++);
+               cp_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
+                                                     RING_CFGSIZE_16KB,
+                                                     ring_id);
+               if (!cp_ring) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+               cp_ring->irq = pdata->txc_irq;
+               snprintf(cp_ring->irq_name, IRQ_ID_SIZE, "%s-txc", ndev->name);
+       }
+
        cp_ring->cp_skb = devm_kcalloc(dev, tx_ring->slots,
                                       sizeof(struct sk_buff *), GFP_KERNEL);
        if (!cp_ring->cp_skb) {
                return -ENOMEM;
        }
 
-       ret = platform_get_irq(pdev, 0);
-       if (ret <= 0) {
-               dev_err(dev, "Unable to get ENET Rx IRQ\n");
-               ret = ret ? : -ENXIO;
-               return ret;
-       }
-       pdata->rx_irq = ret;
-
        ret = xgene_get_port_id(dev, pdata);
        if (ret)
                return ret;
                return -ENODEV;
        }
 
+       ret = platform_get_irq(pdev, 0);
+       if (ret <= 0) {
+               dev_err(dev, "Unable to get ENET Rx IRQ\n");
+               ret = ret ? : -ENXIO;
+               return ret;
+       }
+       pdata->rx_irq = ret;
+
+       if (pdata->phy_mode != PHY_INTERFACE_MODE_RGMII) {
+               ret = platform_get_irq(pdev, 1);
+               if (ret <= 0) {
+                       dev_err(dev, "Unable to get ENET Tx completion IRQ\n");
+                       ret = ret ? : -ENXIO;
+                       return ret;
+               }
+               pdata->txc_irq = ret;
+       }
+
        pdata->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(pdata->clk)) {
                /* Firmware may have set up the clock already. */
                pdata->mac_ops = &xgene_sgmac_ops;
                pdata->port_ops = &xgene_sgport_ops;
                pdata->rm = RM1;
+               pdata->cq_cnt = XGENE_MAX_TXC_RINGS;
                break;
        default:
                pdata->mac_ops = &xgene_xgmac_ops;
                pdata->port_ops = &xgene_xgport_ops;
                pdata->rm = RM0;
+               pdata->cq_cnt = XGENE_MAX_TXC_RINGS;
                break;
        }
 
 
 }
 
+static void xgene_enet_napi_add(struct xgene_enet_pdata *pdata)
+{
+       struct napi_struct *napi;
+
+       napi = &pdata->rx_ring->napi;
+       netif_napi_add(pdata->ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
+
+       if (pdata->cq_cnt) {
+               napi = &pdata->tx_ring->cp_ring->napi;
+               netif_napi_add(pdata->ndev, napi, xgene_enet_napi,
+                              NAPI_POLL_WEIGHT);
+       }
+}
+
+static void xgene_enet_napi_del(struct xgene_enet_pdata *pdata)
+{
+       struct napi_struct *napi;
+
+       napi = &pdata->rx_ring->napi;
+       netif_napi_del(napi);
+
+       if (pdata->cq_cnt) {
+               napi = &pdata->tx_ring->cp_ring->napi;
+               netif_napi_del(napi);
+       }
+}
+
 static int xgene_enet_probe(struct platform_device *pdev)
 {
        struct net_device *ndev;
        struct xgene_enet_pdata *pdata;
        struct device *dev = &pdev->dev;
-       struct napi_struct *napi;
        struct xgene_mac_ops *mac_ops;
        int ret;
 
        if (ret)
                goto err;
 
-       napi = &pdata->rx_ring->napi;
-       netif_napi_add(ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
+       xgene_enet_napi_add(pdata);
        mac_ops = pdata->mac_ops;
        if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
                ret = xgene_enet_mdio_config(pdata);
        mac_ops->rx_disable(pdata);
        mac_ops->tx_disable(pdata);
 
-       netif_napi_del(&pdata->rx_ring->napi);
+       xgene_enet_napi_del(pdata);
        xgene_enet_mdio_remove(pdata);
        xgene_enet_delete_desc_rings(pdata);
        unregister_netdev(ndev);