Implement NIC stop and close function for NFDK firmware.

Signed-off-by: Jin Liu <jin....@corigine.com>
Signed-off-by: Diana Wang <na.w...@corigine.com>
Signed-off-by: Peng Zhang <peng.zh...@corigine.com>
Signed-off-by: Chaoyong He <chaoyong...@corigine.com>
Signed-off-by: Niklas Söderlund <niklas.soderl...@corigine.com>
---
 drivers/net/nfp/nfp_ethdev.c    | 92 ++++++++++++++++++++++++++++++++-
 drivers/net/nfp/nfp_ethdev_vf.c | 64 +++++++++++++++++++++--
 2 files changed, 151 insertions(+), 5 deletions(-)

diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index 0a5c703190..4e3a6a964d 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -309,6 +309,94 @@ nfp_net_nfd3_close(struct rte_eth_dev *dev)
        return 0;
 }
 
+static int
+nfp_net_nfdk_stop(struct rte_eth_dev *dev)
+{
+       struct nfp_net_hw *hw;
+
+       PMD_INIT_LOG(DEBUG, "Stop");
+
+       hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+       nfp_net_disable_queues(dev);
+
+       /* Clear queues */
+       nfp_net_nfdk_stop_tx_queue(dev);
+
+       nfp_net_stop_rx_queue(dev);
+
+       if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+               /* Configure the physical port down */
+               nfp_eth_set_configured(hw->cpp, hw->nfp_idx, 0);
+       else
+               nfp_eth_set_configured(dev->process_private, hw->nfp_idx, 0);
+
+       return 0;
+}
+
+static int
+nfp_net_nfdk_close(struct rte_eth_dev *dev)
+{
+       int i;
+       struct nfp_net_hw *hw;
+       struct rte_pci_device *pci_dev;
+       struct nfp_pf_dev *pf_dev;
+
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
+       PMD_INIT_LOG(DEBUG, "Close");
+
+       pf_dev = NFP_NET_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+
+       /*
+        * We assume that the DPDK application is stopping all the
+        * threads/queues before calling the device close function.
+        */
+
+       nfp_net_disable_queues(dev);
+
+       /* Clear queues */
+       nfp_net_nfdk_close_tx_queue(dev);
+
+       nfp_net_close_rx_queue(dev);
+
+       /* Cancel possible impending LSC work here before releasing the port*/
+       rte_eal_alarm_cancel(nfp_net_dev_interrupt_delayed_handler, (void 
*)dev);
+
+       /* Only free PF resources after all physical ports have been closed */
+       /* Mark this port as unused and free device priv resources*/
+       nn_cfg_writeb(hw, NFP_NET_CFG_LSC, 0xff);
+       pf_dev->ports[hw->idx] = NULL;
+       rte_eth_dev_release_port(dev);
+
+       for (i = 0; i < pf_dev->total_phyports; i++) {
+               /* Check to see if ports are still in use */
+               if (pf_dev->ports[i])
+                       return 0;
+       }
+
+       /* Now it is safe to free all PF resources */
+       PMD_INIT_LOG(INFO, "Freeing PF resources");
+       nfp_cpp_area_free(pf_dev->ctrl_area);
+       nfp_cpp_area_free(pf_dev->hwqueues_area);
+       free(pf_dev->hwinfo);
+       free(pf_dev->sym_tbl);
+       nfp_cpp_free(pf_dev->cpp);
+       rte_free(pf_dev);
+
+       rte_intr_disable(pci_dev->intr_handle);
+
+       /* unregister callback func from eal lib */
+       rte_intr_callback_unregister(pci_dev->intr_handle,
+                               nfp_net_dev_interrupt_handler,
+                               (void *)dev);
+
+       return 0;
+}
+
 /* Initialise and register driver with DPDK Application */
 static const struct eth_dev_ops nfp_net_nfd3_eth_dev_ops = {
        .dev_configure          = nfp_net_configure,
@@ -342,10 +430,10 @@ static const struct eth_dev_ops nfp_net_nfd3_eth_dev_ops 
= {
 static const struct eth_dev_ops nfp_net_nfdk_eth_dev_ops = {
        .dev_configure          = nfp_net_configure,
        .dev_start              = nfp_net_start,
-       .dev_stop               = nfp_net_nfd3_stop,
+       .dev_stop               = nfp_net_nfdk_stop,
        .dev_set_link_up        = nfp_net_set_link_up,
        .dev_set_link_down      = nfp_net_set_link_down,
-       .dev_close              = nfp_net_nfd3_close,
+       .dev_close              = nfp_net_nfdk_close,
        .promiscuous_enable     = nfp_net_promisc_enable,
        .promiscuous_disable    = nfp_net_promisc_disable,
        .link_update            = nfp_net_link_update,
diff --git a/drivers/net/nfp/nfp_ethdev_vf.c b/drivers/net/nfp/nfp_ethdev_vf.c
index d347c98134..a5c6aceb32 100644
--- a/drivers/net/nfp/nfp_ethdev_vf.c
+++ b/drivers/net/nfp/nfp_ethdev_vf.c
@@ -214,6 +214,58 @@ nfp_netvf_nfd3_close(struct rte_eth_dev *dev)
        return 0;
 }
 
+static int
+nfp_netvf_nfdk_stop(struct rte_eth_dev *dev)
+{
+       PMD_INIT_LOG(DEBUG, "Stop");
+
+       nfp_net_disable_queues(dev);
+
+       /* Clear queues */
+       nfp_net_nfdk_stop_tx_queue(dev);
+
+       nfp_net_stop_rx_queue(dev);
+
+       return 0;
+}
+
+static int
+nfp_netvf_nfdk_close(struct rte_eth_dev *dev)
+{
+       struct rte_pci_device *pci_dev;
+
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
+       PMD_INIT_LOG(DEBUG, "Close");
+
+       pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+
+       /*
+        * We assume that the DPDK application is stopping all the
+        * threads/queues before calling the device close function.
+        */
+
+       nfp_net_disable_queues(dev);
+
+       /* Clear queues */
+       nfp_net_nfdk_close_tx_queue(dev);
+
+       nfp_net_close_rx_queue(dev);
+
+       rte_intr_disable(pci_dev->intr_handle);
+
+       /* unregister callback func from eal lib */
+       rte_intr_callback_unregister(pci_dev->intr_handle,
+                               nfp_net_dev_interrupt_handler,
+                               (void *)dev);
+
+       /* Cancel possible impending LSC work here before releasing the port*/
+       rte_eal_alarm_cancel(nfp_net_dev_interrupt_delayed_handler, (void 
*)dev);
+
+       return 0;
+}
+
 /* Initialise and register VF driver with DPDK Application */
 static const struct eth_dev_ops nfp_netvf_nfd3_eth_dev_ops = {
        .dev_configure          = nfp_net_configure,
@@ -247,10 +299,10 @@ static const struct eth_dev_ops 
nfp_netvf_nfd3_eth_dev_ops = {
 static const struct eth_dev_ops nfp_netvf_nfdk_eth_dev_ops = {
        .dev_configure          = nfp_net_configure,
        .dev_start              = nfp_netvf_start,
-       .dev_stop               = nfp_netvf_nfd3_stop,
+       .dev_stop               = nfp_netvf_nfdk_stop,
        .dev_set_link_up        = nfp_netvf_set_link_up,
        .dev_set_link_down      = nfp_netvf_set_link_down,
-       .dev_close              = nfp_netvf_nfd3_close,
+       .dev_close              = nfp_netvf_nfdk_close,
        .promiscuous_enable     = nfp_net_promisc_enable,
        .promiscuous_disable    = nfp_net_promisc_disable,
        .link_update            = nfp_net_link_update,
@@ -498,7 +550,13 @@ static const struct rte_pci_id pci_id_nfp_vf_net_map[] = {
 static int nfp_vf_pci_uninit(struct rte_eth_dev *eth_dev)
 {
        /* VF cleanup, just free private port data */
-       return nfp_netvf_nfd3_close(eth_dev);
+       struct nfp_net_hw *hw;
+
+       hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+       if (NFD_CFG_CLASS_VER_of(hw->ver) == NFP_NET_CFG_VERSION_DP_NFD3)
+               return nfp_netvf_nfd3_close(eth_dev);
+       else
+               return nfp_netvf_nfdk_close(eth_dev);
 }
 
 static int eth_nfp_vf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
-- 
2.27.0

Reply via email to