kni: use netdev_alloc_skb
[dpdk.git] / drivers / net / octeontx2 / otx2_ethdev.c
index 113d382..fcb1869 100644 (file)
@@ -184,6 +184,19 @@ cgx_intlbk_enable(struct otx2_eth_dev *dev, bool en)
        return otx2_mbox_process(mbox);
 }
 
+static int
+nix_cgx_stop_link_event(struct otx2_eth_dev *dev)
+{
+       struct otx2_mbox *mbox = dev->mbox;
+
+       if (otx2_dev_is_vf(dev))
+               return 0;
+
+       otx2_mbox_alloc_msg_cgx_stop_linkevents(mbox);
+
+       return otx2_mbox_process(mbox);
+}
+
 static inline void
 nix_rx_queue_reset(struct otx2_eth_rxq *rxq)
 {
@@ -264,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;
@@ -1208,7 +1223,10 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev)
        if (dev->configured == 1) {
                otx2_nix_rxchan_bpid_cfg(eth_dev, false);
                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)
@@ -1217,7 +1235,7 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev)
                nix_lf_free(dev);
        }
 
-       if (otx2_dev_is_A0(dev) &&
+       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))) {
@@ -1269,6 +1287,27 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev)
                goto free_nix_lf;
        }
 
+       /* 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 free_nix_lf;
+               }
+               /* 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 free_nix_lf;
+               }
+       }
+
        /* Configure loop back mode */
        rc = cgx_intlbk_enable(dev, eth_dev->data->dev_conf.lpbk_mode);
        if (rc) {
@@ -1425,12 +1464,49 @@ done:
        return rc;
 }
 
+static void
+otx2_nix_dev_stop(struct rte_eth_dev *eth_dev)
+{
+       struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
+       struct rte_mbuf *rx_pkts[32];
+       struct otx2_eth_rxq *rxq;
+       int count, i, j, rc;
+
+       nix_cgx_stop_link_event(dev);
+       npc_rx_disable(dev);
+
+       /* Stop rx queues and free up pkts pending */
+       for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+               rc = otx2_nix_rx_queue_stop(eth_dev, i);
+               if (rc)
+                       continue;
+
+               rxq = eth_dev->data->rx_queues[i];
+               count = dev->rx_pkt_burst_no_offload(rxq, rx_pkts, 32);
+               while (count) {
+                       for (j = 0; j < count; j++)
+                               rte_pktmbuf_free(rx_pkts[j]);
+                       count = dev->rx_pkt_burst_no_offload(rxq, rx_pkts, 32);
+               }
+       }
+
+       /* Stop tx queues  */
+       for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
+               otx2_nix_tx_queue_stop(eth_dev, i);
+}
+
 static int
 otx2_nix_dev_start(struct rte_eth_dev *eth_dev)
 {
        struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
        int rc, i;
 
+       if (eth_dev->data->nb_rx_queues != 0) {
+               rc = otx2_nix_recalc_mtu(eth_dev);
+               if (rc)
+                       return rc;
+       }
+
        /* Start rx queues */
        for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
                rc = otx2_nix_rx_queue_start(eth_dev, i);
@@ -1477,6 +1553,8 @@ rx_disable:
        return rc;
 }
 
+static int otx2_nix_dev_reset(struct rte_eth_dev *eth_dev);
+static void otx2_nix_dev_close(struct rte_eth_dev *eth_dev);
 
 /* Initialize and register driver with DPDK Application */
 static const struct eth_dev_ops otx2_eth_dev_ops = {
@@ -1488,14 +1566,20 @@ static const struct eth_dev_ops otx2_eth_dev_ops = {
        .rx_queue_setup           = otx2_nix_rx_queue_setup,
        .rx_queue_release         = otx2_nix_rx_queue_release,
        .dev_start                = otx2_nix_dev_start,
+       .dev_stop                 = otx2_nix_dev_stop,
+       .dev_close                = otx2_nix_dev_close,
        .tx_queue_start           = otx2_nix_tx_queue_start,
        .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,
        .stats_reset              = otx2_nix_dev_stats_reset,
        .get_reg                  = otx2_nix_dev_get_reg,
+       .mtu_set                  = otx2_nix_mtu_set,
        .mac_addr_add             = otx2_nix_mac_addr_add,
        .mac_addr_remove          = otx2_nix_mac_addr_del,
        .mac_addr_set             = otx2_nix_mac_addr_set,
@@ -1538,6 +1622,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
@@ -1701,7 +1787,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;
        }
@@ -1744,9 +1830,14 @@ otx2_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close)
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return 0;
 
+       /* Clear the flag since we are closing down */
+       dev->configured = 0;
+
        /* Disable nix bpid config */
        otx2_nix_rxchan_bpid_cfg(eth_dev, false);
 
+       npc_rx_disable(dev);
+
        /* Disable vlan offloads */
        otx2_nix_vlan_fini(eth_dev);
 
@@ -1757,6 +1848,8 @@ otx2_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close)
        if (otx2_ethdev_is_ptp_en(dev))
                otx2_nix_timesync_disable(eth_dev);
 
+       nix_cgx_stop_link_event(dev);
+
        /* Free up SQs */
        for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
                otx2_nix_tx_queue_release(eth_dev->data->tx_queues[i]);
@@ -1779,6 +1872,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);
@@ -1812,6 +1909,24 @@ otx2_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close)
        return 0;
 }
 
+static void
+otx2_nix_dev_close(struct rte_eth_dev *eth_dev)
+{
+       otx2_eth_dev_uninit(eth_dev, true);
+}
+
+static int
+otx2_nix_dev_reset(struct rte_eth_dev *eth_dev)
+{
+       int rc;
+
+       rc = otx2_eth_dev_uninit(eth_dev, false);
+       if (rc)
+               return rc;
+
+       return otx2_eth_dev_init(eth_dev);
+}
+
 static int
 nix_remove(struct rte_pci_device *pci_dev)
 {