net/octeontx2: fix PTP performance
[dpdk.git] / drivers / net / octeontx2 / otx2_ethdev.c
index 7d1fce5..595c800 100644 (file)
@@ -277,6 +277,8 @@ nix_cq_rq_init(struct rte_eth_dev *eth_dev, struct otx2_eth_dev *dev,
 
        /* Many to one reduction */
        aq->cq.qint_idx = qid % dev->qints;
+       /* Map CQ0 [RQ0] to CINT0 and so on till max 64 irqs */
+       aq->cq.cint_idx = qid;
 
        if (otx2_ethdev_fixup_is_limit_cq_full(dev)) {
                uint16_t min_rx_drop;
@@ -584,6 +586,24 @@ nix_tx_offload_flags(struct rte_eth_dev *eth_dev)
        RTE_BUILD_BUG_ON(PKT_TX_TCP_CKSUM != (1ULL << 52));
        RTE_BUILD_BUG_ON(PKT_TX_SCTP_CKSUM != (2ULL << 52));
        RTE_BUILD_BUG_ON(PKT_TX_UDP_CKSUM != (3ULL << 52));
+       RTE_BUILD_BUG_ON(PKT_TX_IP_CKSUM != (1ULL << 54));
+       RTE_BUILD_BUG_ON(PKT_TX_IPV4 != (1ULL << 55));
+       RTE_BUILD_BUG_ON(PKT_TX_OUTER_IP_CKSUM != (1ULL << 58));
+       RTE_BUILD_BUG_ON(PKT_TX_OUTER_IPV4 != (1ULL << 59));
+       RTE_BUILD_BUG_ON(PKT_TX_OUTER_IPV6 != (1ULL << 60));
+       RTE_BUILD_BUG_ON(PKT_TX_OUTER_UDP_CKSUM != (1ULL << 41));
+       RTE_BUILD_BUG_ON(RTE_MBUF_L2_LEN_BITS != 7);
+       RTE_BUILD_BUG_ON(RTE_MBUF_L3_LEN_BITS != 9);
+       RTE_BUILD_BUG_ON(RTE_MBUF_OUTL2_LEN_BITS != 7);
+       RTE_BUILD_BUG_ON(RTE_MBUF_OUTL3_LEN_BITS != 9);
+       RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) !=
+                        offsetof(struct rte_mbuf, buf_iova) + 8);
+       RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
+                        offsetof(struct rte_mbuf, buf_iova) + 16);
+       RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
+                        offsetof(struct rte_mbuf, ol_flags) + 12);
+       RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, tx_offload) !=
+                        offsetof(struct rte_mbuf, pool) + 2 * sizeof(void *));
 
        if (conf & DEV_TX_OFFLOAD_VLAN_INSERT ||
            conf & DEV_TX_OFFLOAD_QINQ_INSERT)
@@ -605,6 +625,9 @@ nix_tx_offload_flags(struct rte_eth_dev *eth_dev)
        if (conf & DEV_TX_OFFLOAD_MULTI_SEGS)
                flags |= NIX_TX_MULTI_SEG_F;
 
+       if ((dev->rx_offloads & DEV_RX_OFFLOAD_TIMESTAMP))
+               flags |= NIX_TX_OFFLOAD_TSTAMP_F;
+
        return flags;
 }
 
@@ -851,8 +874,6 @@ otx2_nix_form_default_desc(struct otx2_eth_txq *txq)
                        send_mem = (struct nix_send_mem_s *)(txq->cmd +
                                                (send_hdr->w0.sizem1 << 1));
                        send_mem->subdc = NIX_SUBDC_MEM;
-                       send_mem->dsz = 0x0;
-                       send_mem->wmem = 0x1;
                        send_mem->alg = NIX_SENDMEMALG_SETTSTMP;
                        send_mem->addr = txq->dev->tstamp.tx_tstamp_iova;
                }
@@ -1183,38 +1204,41 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev)
        /* Sanity checks */
        if (rte_eal_has_hugepages() == 0) {
                otx2_err("Huge page is not configured");
-               goto fail;
-       }
-
-       if (rte_eal_iova_mode() != RTE_IOVA_VA) {
-               otx2_err("iova mode should be va");
-               goto fail;
+               goto fail_configure;
        }
 
        if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
                otx2_err("Setting link speed/duplex not supported");
-               goto fail;
+               goto fail_configure;
        }
 
        if (conf->dcb_capability_en == 1) {
                otx2_err("dcb enable is not supported");
-               goto fail;
+               goto fail_configure;
        }
 
        if (conf->fdir_conf.mode != RTE_FDIR_MODE_NONE) {
                otx2_err("Flow director is not supported");
-               goto fail;
+               goto fail_configure;
        }
 
        if (rxmode->mq_mode != ETH_MQ_RX_NONE &&
            rxmode->mq_mode != ETH_MQ_RX_RSS) {
                otx2_err("Unsupported mq rx mode %d", rxmode->mq_mode);
-               goto fail;
+               goto fail_configure;
        }
 
        if (txmode->mq_mode != ETH_MQ_TX_NONE) {
                otx2_err("Unsupported mq tx mode %d", txmode->mq_mode);
-               goto fail;
+               goto fail_configure;
+       }
+
+       if (otx2_dev_is_Ax(dev) &&
+           (txmode->offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) &&
+           ((txmode->offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) ||
+           (txmode->offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM))) {
+               otx2_err("Outer IP and SCTP checksum unsupported");
+               goto fail_configure;
        }
 
        /* Free the resources allocated from the previous configure */
@@ -1223,23 +1247,16 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev)
                otx2_nix_vlan_fini(eth_dev);
                otx2_flow_free_all_resources(dev);
                oxt2_nix_unregister_queue_irqs(eth_dev);
+               if (eth_dev->data->dev_conf.intr_conf.rxq)
+                       oxt2_nix_unregister_cq_irqs(eth_dev);
                nix_set_nop_rxtx_function(eth_dev);
                rc = nix_store_queue_cfg_and_then_release(eth_dev);
                if (rc)
-                       goto fail;
+                       goto fail_configure;
                otx2_nix_tm_fini(eth_dev);
                nix_lf_free(dev);
        }
 
-       if (otx2_dev_is_A0(dev) &&
-           (txmode->offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) &&
-           ((txmode->offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) ||
-           (txmode->offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM))) {
-               otx2_err("Outer IP and SCTP checksum unsupported");
-               rc = -EINVAL;
-               goto fail;
-       }
-
        dev->rx_offloads = rxmode->offloads;
        dev->tx_offloads = txmode->offloads;
        dev->rx_offload_flags |= nix_rx_offload_flags(eth_dev);
@@ -1253,7 +1270,7 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev)
        rc = nix_lf_alloc(dev, nb_rxq, nb_txq);
        if (rc) {
                otx2_err("Failed to init nix_lf rc=%d", rc);
-               goto fail;
+               goto fail_offloads;
        }
 
        /* Configure RSS */
@@ -1273,39 +1290,50 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev)
        rc = otx2_nix_vlan_offload_init(eth_dev);
        if (rc) {
                otx2_err("Failed to init vlan offload rc=%d", rc);
-               goto free_nix_lf;
+               goto tm_fini;
        }
 
        /* Register queue IRQs */
        rc = oxt2_nix_register_queue_irqs(eth_dev);
        if (rc) {
                otx2_err("Failed to register queue interrupts rc=%d", rc);
-               goto free_nix_lf;
+               goto vlan_fini;
+       }
+
+       /* Register cq IRQs */
+       if (eth_dev->data->dev_conf.intr_conf.rxq) {
+               if (eth_dev->data->nb_rx_queues > dev->cints) {
+                       otx2_err("Rx interrupt cannot be enabled, rxq > %d",
+                                dev->cints);
+                       goto q_irq_fini;
+               }
+               /* Rx interrupt feature cannot work with vector mode because,
+                * vector mode doesn't process packets unless min 4 pkts are
+                * received, while cq interrupts are generated even for 1 pkt
+                * in the CQ.
+                */
+               dev->scalar_ena = true;
+
+               rc = oxt2_nix_register_cq_irqs(eth_dev);
+               if (rc) {
+                       otx2_err("Failed to register CQ interrupts rc=%d", rc);
+                       goto q_irq_fini;
+               }
        }
 
        /* Configure loop back mode */
        rc = cgx_intlbk_enable(dev, eth_dev->data->dev_conf.lpbk_mode);
        if (rc) {
                otx2_err("Failed to configure cgx loop back mode rc=%d", rc);
-               goto free_nix_lf;
+               goto q_irq_fini;
        }
 
        rc = otx2_nix_rxchan_bpid_cfg(eth_dev, true);
        if (rc) {
                otx2_err("Failed to configure nix rx chan bpid cfg rc=%d", rc);
-               goto free_nix_lf;
+               goto q_irq_fini;
        }
 
-       /* Enable PTP if it was requested by the app or if it is already
-        * enabled in PF owning this VF
-        */
-       memset(&dev->tstamp, 0, sizeof(struct otx2_timesync_info));
-       if ((dev->rx_offloads & DEV_RX_OFFLOAD_TIMESTAMP) ||
-           otx2_ethdev_is_ptp_en(dev))
-               otx2_nix_timesync_enable(eth_dev);
-       else
-               otx2_nix_timesync_disable(eth_dev);
-
        /*
         * Restore queue config when reconfigure followed by
         * reconfigure and no queue configure invoked from application case.
@@ -1313,7 +1341,7 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev)
        if (dev->configured == 1) {
                rc = nix_restore_queue_cfg(eth_dev);
                if (rc)
-                       goto free_nix_lf;
+                       goto cq_fini;
        }
 
        /* Update the mac address */
@@ -1337,9 +1365,21 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev)
        dev->configured_nb_tx_qs = data->nb_tx_queues;
        return 0;
 
+cq_fini:
+       oxt2_nix_unregister_cq_irqs(eth_dev);
+q_irq_fini:
+       oxt2_nix_unregister_queue_irqs(eth_dev);
+vlan_fini:
+       otx2_nix_vlan_fini(eth_dev);
+tm_fini:
+       otx2_nix_tm_fini(eth_dev);
 free_nix_lf:
-       rc = nix_lf_free(dev);
-fail:
+       nix_lf_free(dev);
+fail_offloads:
+       dev->rx_offload_flags &= ~nix_rx_offload_flags(eth_dev);
+       dev->tx_offload_flags &= ~nix_tx_offload_flags(eth_dev);
+fail_configure:
+       dev->configured = 0;
        return rc;
 }
 
@@ -1502,6 +1542,16 @@ otx2_nix_dev_start(struct rte_eth_dev *eth_dev)
                return rc;
        }
 
+       /* Enable PTP if it was requested by the app or if it is already
+        * enabled in PF owning this VF
+        */
+       memset(&dev->tstamp, 0, sizeof(struct otx2_timesync_info));
+       if ((dev->rx_offloads & DEV_RX_OFFLOAD_TIMESTAMP) ||
+           otx2_ethdev_is_ptp_en(dev))
+               otx2_nix_timesync_enable(eth_dev);
+       else
+               otx2_nix_timesync_disable(eth_dev);
+
        rc = npc_rx_enable(dev);
        if (rc) {
                otx2_err("Failed to enable NPC rx %d", rc);
@@ -1547,6 +1597,8 @@ static const struct eth_dev_ops otx2_eth_dev_ops = {
        .tx_queue_stop            = otx2_nix_tx_queue_stop,
        .rx_queue_start           = otx2_nix_rx_queue_start,
        .rx_queue_stop            = otx2_nix_rx_queue_stop,
+       .dev_set_link_up          = otx2_nix_dev_set_link_up,
+       .dev_set_link_down        = otx2_nix_dev_set_link_down,
        .dev_supported_ptypes_get = otx2_nix_supported_ptypes_get,
        .dev_reset                = otx2_nix_dev_reset,
        .stats_get                = otx2_nix_dev_stats_get,
@@ -1595,6 +1647,8 @@ static const struct eth_dev_ops otx2_eth_dev_ops = {
        .vlan_strip_queue_set     = otx2_nix_vlan_strip_queue_set,
        .vlan_tpid_set            = otx2_nix_vlan_tpid_set,
        .vlan_pvid_set            = otx2_nix_vlan_pvid_set,
+       .rx_queue_intr_enable     = otx2_nix_rx_queue_intr_enable,
+       .rx_queue_intr_disable    = otx2_nix_rx_queue_intr_disable,
 };
 
 static inline int
@@ -1758,7 +1812,7 @@ otx2_eth_dev_init(struct rte_eth_dev *eth_dev)
        dev->tx_offload_capa = nix_get_tx_offload_capa(dev);
        dev->rx_offload_capa = nix_get_rx_offload_capa(dev);
 
-       if (otx2_dev_is_A0(dev)) {
+       if (otx2_dev_is_Ax(dev)) {
                dev->hwcap |= OTX2_FIXUP_F_MIN_4K_Q;
                dev->hwcap |= OTX2_FIXUP_F_LIMIT_CQ_FULL;
        }
@@ -1843,6 +1897,10 @@ otx2_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close)
        /* Unregister queue irqs */
        oxt2_nix_unregister_queue_irqs(eth_dev);
 
+       /* Unregister cq irqs */
+       if (eth_dev->data->dev_conf.intr_conf.rxq)
+               oxt2_nix_unregister_cq_irqs(eth_dev);
+
        rc = nix_lf_free(dev);
        if (rc)
                otx2_err("Failed to free nix lf, rc=%d", rc);
@@ -1973,7 +2031,7 @@ static const struct rte_pci_id pci_nix_map[] = {
 
 static struct rte_pci_driver pci_nix = {
        .id_table = pci_nix_map,
-       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA |
+       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA |
                        RTE_PCI_DRV_INTR_LSC,
        .probe = nix_probe,
        .remove = nix_remove,