get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/95964/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 95964,
    "url": "http://patchwork.dpdk.org/api/patches/95964/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20210716083545.34444-7-heinrich.kuhn@netronome.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20210716083545.34444-7-heinrich.kuhn@netronome.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210716083545.34444-7-heinrich.kuhn@netronome.com",
    "date": "2021-07-16T08:35:45",
    "name": "[v2,6/7] net/nfp: move PF functions into new file",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "106e9d0a009c3ad04af6838b65cca92fc7a45fde",
    "submitter": {
        "id": 1523,
        "url": "http://patchwork.dpdk.org/api/people/1523/?format=api",
        "name": "Heinrich Kuhn",
        "email": "heinrich.kuhn@netronome.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20210716083545.34444-7-heinrich.kuhn@netronome.com/mbox/",
    "series": [
        {
            "id": 17856,
            "url": "http://patchwork.dpdk.org/api/series/17856/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=17856",
            "date": "2021-07-16T08:35:38",
            "name": "Refactor the NFP PMD",
            "version": 2,
            "mbox": "http://patchwork.dpdk.org/series/17856/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/95964/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/95964/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id B37F7A0C50;\n\tFri, 16 Jul 2021 10:37:39 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 1101C41361;\n\tFri, 16 Jul 2021 10:37:17 +0200 (CEST)",
            "from mail-ej1-f46.google.com (mail-ej1-f46.google.com\n [209.85.218.46]) by mails.dpdk.org (Postfix) with ESMTP id 896CE41357\n for <dev@dpdk.org>; Fri, 16 Jul 2021 10:37:16 +0200 (CEST)",
            "by mail-ej1-f46.google.com with SMTP id c17so13930423ejk.13\n for <dev@dpdk.org>; Fri, 16 Jul 2021 01:37:16 -0700 (PDT)",
            "from localhost.localdomain ([155.93.216.150])\n by smtp.gmail.com with ESMTPSA id e6sm3371650edk.63.2021.07.16.01.37.14\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Fri, 16 Jul 2021 01:37:15 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=netronome-com.20150623.gappssmtp.com; s=20150623;\n h=from:to:cc:subject:date:message-id:in-reply-to:references\n :mime-version:content-transfer-encoding;\n bh=qiN+NfDY4iiG+2b4CfNflzqEf0JnaS3DyFOZXrfYFDc=;\n b=MNmEB0ughr3wziXhOQq6vh0/rJ2D0DStwmJsFiXyme0Yt8yhKdk1YQ/+BfG3ps8d8E\n /HkeLEvcD0p1PWMY+UylxgtDTMRpAIcjFEi8yMR5WdJk5qPxUUPy43Gnla1Y6SG/VEXl\n s/ehAR5PsHAiIAAxQ0TyQRMVSxwhVccMj5wQtSeFT5YRO/Bldym/WNrBnrjsgezXyEac\n UjoEj2Pt14NeWlnxK3oXLOzp79vVQz0p9+qjQOfAwecMjmEBCHAtGc+R6SZAvzl/5o7u\n h7ANaFiLeqpx5Qv6EnQ7jKhjNRraAaXi9A8+cspmypF9AUdtUwhiWNmF9SyrTazxhu78\n iHjA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20161025;\n h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n :references:mime-version:content-transfer-encoding;\n bh=qiN+NfDY4iiG+2b4CfNflzqEf0JnaS3DyFOZXrfYFDc=;\n b=a54zr8Vfp++xoB/4JnBRcYFQyyAN+7ejsXKMJBGoWKeVN70jPEhTsNhZlorD95YuUn\n AHKnt2E32UaloCOrg/hpg5RJK6eT+Vu6dSjiKnUusjzQnH8T7TxZuhnrbDe0Ho9bvcby\n ZNxeAj9I4+1hJ0SOWyGLPHRuUBhBmFmMjWRaOuenwO/QvrfxYm/fE9HnjjMaZHDz4urC\n fSQoG4IyT9adnmfn/+MjabTixsVB1gyRYwBdDXJr2dfvWxMly3qccsaBPGOcnb8O04V5\n nOAKQiybAxBfP1yDPJpwPqNLEZ8B8WHqHfEoMT04nU4SP7TM1TE3Xhnmfdy92Ku/sGdf\n mF/A==",
        "X-Gm-Message-State": "AOAM5332MeDOKWWwnzXzN1kKUW8yxY4KQBdwdR+QajlOOD34JXgcWMcZ\n 9SNL9EQiQpE6yc4OarUUg3vWCr/VcWD7vSGYyn+aSzNYm9v7UFZGdNRfKX9XCPvaCoJR/SvyONY\n aUljoTz21bpvLfL8utIcu7JWW5MvNNgbRlQ0Qx4EpEJ3qQpQKj+1c7970Mg9WY/ET",
        "X-Google-Smtp-Source": "\n ABdhPJwG4VOckxXsN5MAbrrFflUZLq20QEpGCeRcxe0MS2sjGS9Zh0cXJAWDSABs8TFp5S2juOSRdw==",
        "X-Received": "by 2002:a17:907:a05c:: with SMTP id\n gz28mr10851719ejc.56.1626424635657;\n Fri, 16 Jul 2021 01:37:15 -0700 (PDT)",
        "From": "Heinrich Kuhn <heinrich.kuhn@netronome.com>",
        "To": "dev@dpdk.org",
        "Cc": "Heinrich Kuhn <heinrich.kuhn@netronome.com>,\n Simon Horman <simon.horman@corigine.com>",
        "Date": "Fri, 16 Jul 2021 10:35:45 +0200",
        "Message-Id": "<20210716083545.34444-7-heinrich.kuhn@netronome.com>",
        "X-Mailer": "git-send-email 2.30.1 (Apple Git-130)",
        "In-Reply-To": "<20210716083545.34444-1-heinrich.kuhn@netronome.com>",
        "References": "<20210716082314.33865-1-heinrich.kuhn@netronome.com>\n <20210716083545.34444-1-heinrich.kuhn@netronome.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v2 6/7] net/nfp: move PF functions into new file",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Similar to the last commit, this changeset moves all the PF specific\nfunctions to a new file called nfp_ethdev.c.\n\nSigned-off-by: Heinrich Kuhn <heinrich.kuhn@netronome.com>\nSigned-off-by: Simon Horman <simon.horman@corigine.com>\n---\n drivers/net/nfp/meson.build  |    1 +\n drivers/net/nfp/nfp_ethdev.c | 1099 ++++++++++++++++++++++++++++++++++\n drivers/net/nfp/nfp_net.c    | 1088 +--------------------------------\n 3 files changed, 1103 insertions(+), 1085 deletions(-)\n create mode 100644 drivers/net/nfp/nfp_ethdev.c",
    "diff": "diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build\nindex 34f4054b3c..ab64d0cac3 100644\n--- a/drivers/net/nfp/meson.build\n+++ b/drivers/net/nfp/meson.build\n@@ -22,4 +22,5 @@ sources = files(\n         'nfp_rxtx.c',\n         'nfp_cpp_bridge.c',\n         'nfp_ethdev_vf.c',\n+        'nfp_ethdev.c',\n )\ndiff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c\nnew file mode 100644\nindex 0000000000..ab08906704\n--- /dev/null\n+++ b/drivers/net/nfp/nfp_ethdev.c\n@@ -0,0 +1,1099 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2014-2021 Netronome Systems, Inc.\n+ * All rights reserved.\n+ *\n+ * Small portions derived from code Copyright(c) 2010-2015 Intel Corporation.\n+ */\n+\n+/*\n+ * vim:shiftwidth=8:noexpandtab\n+ *\n+ * @file dpdk/pmd/nfp_ethdev.c\n+ *\n+ * Netronome vNIC DPDK Poll-Mode Driver: Main entry point\n+ */\n+\n+#include <rte_common.h>\n+#include <ethdev_driver.h>\n+#include <ethdev_pci.h>\n+#include <rte_dev.h>\n+#include <rte_ether.h>\n+#include <rte_malloc.h>\n+#include <rte_memzone.h>\n+#include <rte_mempool.h>\n+#include <rte_service_component.h>\n+\n+#include \"nfpcore/nfp_cpp.h\"\n+#include \"nfpcore/nfp_nffw.h\"\n+#include \"nfpcore/nfp_hwinfo.h\"\n+#include \"nfpcore/nfp_mip.h\"\n+#include \"nfpcore/nfp_rtsym.h\"\n+#include \"nfpcore/nfp_nsp.h\"\n+\n+#include \"nfp_net_pmd.h\"\n+#include \"nfp_rxtx.h\"\n+#include \"nfp_net_logs.h\"\n+#include \"nfp_net_ctrl.h\"\n+#include \"nfp_cpp_bridge.h\"\n+\n+\n+static int nfp_net_pf_read_mac(struct nfp_pf_dev *pf_dev, int port);\n+static int nfp_net_start(struct rte_eth_dev *dev);\n+static int nfp_net_stop(struct rte_eth_dev *dev);\n+static int nfp_net_set_link_up(struct rte_eth_dev *dev);\n+static int nfp_net_set_link_down(struct rte_eth_dev *dev);\n+static int nfp_net_close(struct rte_eth_dev *dev);\n+static int nfp_net_init(struct rte_eth_dev *eth_dev);\n+static int nfp_fw_upload(struct rte_pci_device *dev,\n+\t\t\t struct nfp_nsp *nsp, char *card);\n+static int nfp_fw_setup(struct rte_pci_device *dev,\n+\t\t\tstruct nfp_cpp *cpp,\n+\t\t\tstruct nfp_eth_table *nfp_eth_table,\n+\t\t\tstruct nfp_hwinfo *hwinfo);\n+static int nfp_init_phyports(struct nfp_pf_dev *pf_dev);\n+static int nfp_pf_init(struct rte_pci_device *pci_dev);\n+static int nfp_pf_secondary_init(struct rte_pci_device *pci_dev);\n+static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n+\t\t\t    struct rte_pci_device *dev);\n+static int nfp_pci_uninit(struct rte_eth_dev *eth_dev);\n+static int eth_nfp_pci_remove(struct rte_pci_device *pci_dev);\n+\n+static int\n+nfp_net_pf_read_mac(struct nfp_pf_dev *pf_dev, int port)\n+{\n+\tstruct nfp_eth_table *nfp_eth_table;\n+\tstruct nfp_net_hw *hw = NULL;\n+\n+\t/* Grab a pointer to the correct physical port */\n+\thw = pf_dev->ports[port];\n+\n+\tnfp_eth_table = nfp_eth_read_ports(pf_dev->cpp);\n+\n+\tnfp_eth_copy_mac((uint8_t *)&hw->mac_addr,\n+\t\t\t (uint8_t *)&nfp_eth_table->ports[port].mac_addr);\n+\n+\tfree(nfp_eth_table);\n+\treturn 0;\n+}\n+\n+static int\n+nfp_net_start(struct rte_eth_dev *dev)\n+{\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tstruct rte_intr_handle *intr_handle = &pci_dev->intr_handle;\n+\tuint32_t new_ctrl, update = 0;\n+\tstruct nfp_net_hw *hw;\n+\tstruct nfp_pf_dev *pf_dev;\n+\tstruct rte_eth_conf *dev_conf;\n+\tstruct rte_eth_rxmode *rxmode;\n+\tuint32_t intr_vector;\n+\tint ret;\n+\n+\thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tpf_dev = NFP_NET_DEV_PRIVATE_TO_PF(dev->data->dev_private);\n+\n+\tPMD_INIT_LOG(DEBUG, \"Start\");\n+\n+\t/* Disabling queues just in case... */\n+\tnfp_net_disable_queues(dev);\n+\n+\t/* Enabling the required queues in the device */\n+\tnfp_net_enable_queues(dev);\n+\n+\t/* check and configure queue intr-vector mapping */\n+\tif (dev->data->dev_conf.intr_conf.rxq != 0) {\n+\t\tif (pf_dev->multiport) {\n+\t\t\tPMD_INIT_LOG(ERR, \"PMD rx interrupt is not supported \"\n+\t\t\t\t\t  \"with NFP multiport PF\");\n+\t\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tif (intr_handle->type == RTE_INTR_HANDLE_UIO) {\n+\t\t\t/*\n+\t\t\t * Better not to share LSC with RX interrupts.\n+\t\t\t * Unregistering LSC interrupt handler\n+\t\t\t */\n+\t\t\trte_intr_callback_unregister(&pci_dev->intr_handle,\n+\t\t\t\tnfp_net_dev_interrupt_handler, (void *)dev);\n+\n+\t\t\tif (dev->data->nb_rx_queues > 1) {\n+\t\t\t\tPMD_INIT_LOG(ERR, \"PMD rx interrupt only \"\n+\t\t\t\t\t     \"supports 1 queue with UIO\");\n+\t\t\t\treturn -EIO;\n+\t\t\t}\n+\t\t}\n+\t\tintr_vector = dev->data->nb_rx_queues;\n+\t\tif (rte_intr_efd_enable(intr_handle, intr_vector))\n+\t\t\treturn -1;\n+\n+\t\tnfp_configure_rx_interrupt(dev, intr_handle);\n+\t\tupdate = NFP_NET_CFG_UPDATE_MSIX;\n+\t}\n+\n+\trte_intr_enable(intr_handle);\n+\n+\tnew_ctrl = nfp_check_offloads(dev);\n+\n+\t/* Writing configuration parameters in the device */\n+\tnfp_net_params_setup(hw);\n+\n+\tdev_conf = &dev->data->dev_conf;\n+\trxmode = &dev_conf->rxmode;\n+\n+\tif (rxmode->mq_mode & ETH_MQ_RX_RSS) {\n+\t\tnfp_net_rss_config_default(dev);\n+\t\tupdate |= NFP_NET_CFG_UPDATE_RSS;\n+\t\tnew_ctrl |= NFP_NET_CFG_CTRL_RSS;\n+\t}\n+\n+\t/* Enable device */\n+\tnew_ctrl |= NFP_NET_CFG_CTRL_ENABLE;\n+\n+\tupdate |= NFP_NET_CFG_UPDATE_GEN | NFP_NET_CFG_UPDATE_RING;\n+\n+\tif (hw->cap & NFP_NET_CFG_CTRL_RINGCFG)\n+\t\tnew_ctrl |= NFP_NET_CFG_CTRL_RINGCFG;\n+\n+\tnn_cfg_writel(hw, NFP_NET_CFG_CTRL, new_ctrl);\n+\tif (nfp_net_reconfig(hw, new_ctrl, update) < 0)\n+\t\treturn -EIO;\n+\n+\t/*\n+\t * Allocating rte mbufs for configured rx queues.\n+\t * This requires queues being enabled before\n+\t */\n+\tif (nfp_net_rx_freelist_setup(dev) < 0) {\n+\t\tret = -ENOMEM;\n+\t\tgoto error;\n+\t}\n+\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n+\t\t/* Configure the physical port up */\n+\t\tnfp_eth_set_configured(hw->cpp, hw->nfp_idx, 1);\n+\telse\n+\t\tnfp_eth_set_configured(dev->process_private,\n+\t\t\t\t       hw->nfp_idx, 1);\n+\n+\thw->ctrl = new_ctrl;\n+\n+\treturn 0;\n+\n+error:\n+\t/*\n+\t * An error returned by this function should mean the app\n+\t * exiting and then the system releasing all the memory\n+\t * allocated even memory coming from hugepages.\n+\t *\n+\t * The device could be enabled at this point with some queues\n+\t * ready for getting packets. This is true if the call to\n+\t * nfp_net_rx_freelist_setup() succeeds for some queues but\n+\t * fails for subsequent queues.\n+\t *\n+\t * This should make the app exiting but better if we tell the\n+\t * device first.\n+\t */\n+\tnfp_net_disable_queues(dev);\n+\n+\treturn ret;\n+}\n+\n+/* Stop device: disable rx and tx functions to allow for reconfiguring. */\n+static int\n+nfp_net_stop(struct rte_eth_dev *dev)\n+{\n+\tint i;\n+\tstruct nfp_net_hw *hw;\n+\tstruct nfp_net_txq *this_tx_q;\n+\tstruct nfp_net_rxq *this_rx_q;\n+\n+\tPMD_INIT_LOG(DEBUG, \"Stop\");\n+\n+\thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\n+\tnfp_net_disable_queues(dev);\n+\n+\t/* Clear queues */\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\tthis_tx_q = (struct nfp_net_txq *)dev->data->tx_queues[i];\n+\t\tnfp_net_reset_tx_queue(this_tx_q);\n+\t}\n+\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\tthis_rx_q = (struct nfp_net_rxq *)dev->data->rx_queues[i];\n+\t\tnfp_net_reset_rx_queue(this_rx_q);\n+\t}\n+\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n+\t\t/* Configure the physical port down */\n+\t\tnfp_eth_set_configured(hw->cpp, hw->nfp_idx, 0);\n+\telse\n+\t\tnfp_eth_set_configured(dev->process_private,\n+\t\t\t\t       hw->nfp_idx, 0);\n+\n+\treturn 0;\n+}\n+\n+/* Set the link up. */\n+static int\n+nfp_net_set_link_up(struct rte_eth_dev *dev)\n+{\n+\tstruct nfp_net_hw *hw;\n+\n+\tPMD_DRV_LOG(DEBUG, \"Set link up\");\n+\n+\thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n+\t\t/* Configure the physical port down */\n+\t\treturn nfp_eth_set_configured(hw->cpp, hw->nfp_idx, 1);\n+\telse\n+\t\treturn nfp_eth_set_configured(dev->process_private,\n+\t\t\t\t\t      hw->nfp_idx, 1);\n+}\n+\n+/* Set the link down. */\n+static int\n+nfp_net_set_link_down(struct rte_eth_dev *dev)\n+{\n+\tstruct nfp_net_hw *hw;\n+\n+\tPMD_DRV_LOG(DEBUG, \"Set link down\");\n+\n+\thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n+\t\t/* Configure the physical port down */\n+\t\treturn nfp_eth_set_configured(hw->cpp, hw->nfp_idx, 0);\n+\telse\n+\t\treturn nfp_eth_set_configured(dev->process_private,\n+\t\t\t\t\t      hw->nfp_idx, 0);\n+}\n+\n+/* Reset and stop device. The device can not be restarted. */\n+static int\n+nfp_net_close(struct rte_eth_dev *dev)\n+{\n+\tstruct nfp_net_hw *hw;\n+\tstruct rte_pci_device *pci_dev;\n+\tstruct nfp_pf_dev *pf_dev;\n+\tstruct nfp_net_txq *this_tx_q;\n+\tstruct nfp_net_rxq *this_rx_q;\n+\tint i;\n+\n+\tif (rte_eal_process_type() != RTE_PROC_PRIMARY)\n+\t\treturn 0;\n+\n+\tPMD_INIT_LOG(DEBUG, \"Close\");\n+\n+\tpf_dev = NFP_NET_DEV_PRIVATE_TO_PF(dev->data->dev_private);\n+\thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tpci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\n+\t/*\n+\t * We assume that the DPDK application is stopping all the\n+\t * threads/queues before calling the device close function.\n+\t */\n+\n+\tnfp_net_disable_queues(dev);\n+\n+\t/* Clear queues */\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\tthis_tx_q = (struct nfp_net_txq *)dev->data->tx_queues[i];\n+\t\tnfp_net_reset_tx_queue(this_tx_q);\n+\t}\n+\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\tthis_rx_q = (struct nfp_net_rxq *)dev->data->rx_queues[i];\n+\t\tnfp_net_reset_rx_queue(this_rx_q);\n+\t}\n+\n+\t/* Only free PF resources after all physical ports have been closed */\n+\t/* Mark this port as unused and free device priv resources*/\n+\tnn_cfg_writeb(hw, NFP_NET_CFG_LSC, 0xff);\n+\tpf_dev->ports[hw->idx] = NULL;\n+\trte_eth_dev_release_port(dev);\n+\n+\tfor (i = 0; i < pf_dev->total_phyports; i++) {\n+\t\t/* Check to see if ports are still in use */\n+\t\tif (pf_dev->ports[i])\n+\t\t\treturn 0;\n+\t}\n+\n+\t/* Now it is safe to free all PF resources */\n+\tPMD_INIT_LOG(INFO, \"Freeing PF resources\");\n+\tnfp_cpp_area_free(pf_dev->ctrl_area);\n+\tnfp_cpp_area_free(pf_dev->hwqueues_area);\n+\tfree(pf_dev->hwinfo);\n+\tfree(pf_dev->sym_tbl);\n+\tnfp_cpp_free(pf_dev->cpp);\n+\trte_free(pf_dev);\n+\n+\trte_intr_disable(&pci_dev->intr_handle);\n+\n+\t/* unregister callback func from eal lib */\n+\trte_intr_callback_unregister(&pci_dev->intr_handle,\n+\t\t\t\t     nfp_net_dev_interrupt_handler,\n+\t\t\t\t     (void *)dev);\n+\n+\t/*\n+\t * The ixgbe PMD driver disables the pcie master on the\n+\t * device. The i40e does not...\n+\t */\n+\n+\treturn 0;\n+}\n+\n+/* Initialise and register driver with DPDK Application */\n+static const struct eth_dev_ops nfp_net_eth_dev_ops = {\n+\t.dev_configure\t\t= nfp_net_configure,\n+\t.dev_start\t\t= nfp_net_start,\n+\t.dev_stop\t\t= nfp_net_stop,\n+\t.dev_set_link_up\t= nfp_net_set_link_up,\n+\t.dev_set_link_down\t= nfp_net_set_link_down,\n+\t.dev_close\t\t= nfp_net_close,\n+\t.promiscuous_enable\t= nfp_net_promisc_enable,\n+\t.promiscuous_disable\t= nfp_net_promisc_disable,\n+\t.link_update\t\t= nfp_net_link_update,\n+\t.stats_get\t\t= nfp_net_stats_get,\n+\t.stats_reset\t\t= nfp_net_stats_reset,\n+\t.dev_infos_get\t\t= nfp_net_infos_get,\n+\t.dev_supported_ptypes_get = nfp_net_supported_ptypes_get,\n+\t.mtu_set\t\t= nfp_net_dev_mtu_set,\n+\t.mac_addr_set           = nfp_set_mac_addr,\n+\t.vlan_offload_set\t= nfp_net_vlan_offload_set,\n+\t.reta_update\t\t= nfp_net_reta_update,\n+\t.reta_query\t\t= nfp_net_reta_query,\n+\t.rss_hash_update\t= nfp_net_rss_hash_update,\n+\t.rss_hash_conf_get\t= nfp_net_rss_hash_conf_get,\n+\t.rx_queue_setup\t\t= nfp_net_rx_queue_setup,\n+\t.rx_queue_release\t= nfp_net_rx_queue_release,\n+\t.tx_queue_setup\t\t= nfp_net_tx_queue_setup,\n+\t.tx_queue_release\t= nfp_net_tx_queue_release,\n+\t.rx_queue_intr_enable   = nfp_rx_queue_intr_enable,\n+\t.rx_queue_intr_disable  = nfp_rx_queue_intr_disable,\n+};\n+\n+static int\n+nfp_net_init(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct rte_pci_device *pci_dev;\n+\tstruct nfp_pf_dev *pf_dev;\n+\tstruct nfp_net_hw *hw;\n+\tstruct rte_ether_addr *tmp_ether_addr;\n+\n+\tuint64_t tx_bar_off = 0, rx_bar_off = 0;\n+\tuint32_t start_q;\n+\tint stride = 4;\n+\tint port = 0;\n+\tint err;\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\tpci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n+\n+\t/* Use backpointer here to the PF of this eth_dev */\n+\tpf_dev = NFP_NET_DEV_PRIVATE_TO_PF(eth_dev->data->dev_private);\n+\n+\t/* NFP can not handle DMA addresses requiring more than 40 bits */\n+\tif (rte_mem_check_dma_mask(40)) {\n+\t\tRTE_LOG(ERR, PMD, \"device %s can not be used:\",\n+\t\t\t\t   pci_dev->device.name);\n+\t\tRTE_LOG(ERR, PMD, \"\\trestricted dma mask to 40 bits!\\n\");\n+\t\treturn -ENODEV;\n+\t};\n+\n+\tport = ((struct nfp_net_hw *)eth_dev->data->dev_private)->idx;\n+\tif (port < 0 || port > 7) {\n+\t\tPMD_DRV_LOG(ERR, \"Port value is wrong\");\n+\t\treturn -ENODEV;\n+\t}\n+\n+\t/* Use PF array of physical ports to get pointer to\n+\t * this specific port\n+\t */\n+\thw = pf_dev->ports[port];\n+\n+\tPMD_INIT_LOG(DEBUG, \"Working with physical port number: %d, \"\n+\t\t\t    \"NFP internal port number: %d\",\n+\t\t\t    port, hw->nfp_idx);\n+\n+\teth_dev->dev_ops = &nfp_net_eth_dev_ops;\n+\teth_dev->rx_queue_count = nfp_net_rx_queue_count;\n+\teth_dev->rx_pkt_burst = &nfp_net_recv_pkts;\n+\teth_dev->tx_pkt_burst = &nfp_net_xmit_pkts;\n+\n+\t/* For secondary processes, the primary has done all the work */\n+\tif (rte_eal_process_type() != RTE_PROC_PRIMARY)\n+\t\treturn 0;\n+\n+\trte_eth_copy_pci_info(eth_dev, pci_dev);\n+\n+\thw->device_id = pci_dev->id.device_id;\n+\thw->vendor_id = pci_dev->id.vendor_id;\n+\thw->subsystem_device_id = pci_dev->id.subsystem_device_id;\n+\thw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;\n+\n+\tPMD_INIT_LOG(DEBUG, \"nfp_net: device (%u:%u) %u:%u:%u:%u\",\n+\t\t     pci_dev->id.vendor_id, pci_dev->id.device_id,\n+\t\t     pci_dev->addr.domain, pci_dev->addr.bus,\n+\t\t     pci_dev->addr.devid, pci_dev->addr.function);\n+\n+\thw->ctrl_bar = (uint8_t *)pci_dev->mem_resource[0].addr;\n+\tif (hw->ctrl_bar == NULL) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"hw->ctrl_bar is NULL. BAR0 not configured\");\n+\t\treturn -ENODEV;\n+\t}\n+\n+\tif (port == 0) {\n+\t\thw->ctrl_bar = pf_dev->ctrl_bar;\n+\t} else {\n+\t\tif (!pf_dev->ctrl_bar)\n+\t\t\treturn -ENODEV;\n+\t\t/* Use port offset in pf ctrl_bar for this\n+\t\t * ports control bar\n+\t\t */\n+\t\thw->ctrl_bar = pf_dev->ctrl_bar +\n+\t\t\t       (port * NFP_PF_CSR_SLICE_SIZE);\n+\t}\n+\n+\tPMD_INIT_LOG(DEBUG, \"ctrl bar: %p\", hw->ctrl_bar);\n+\n+\thw->max_rx_queues = nn_cfg_readl(hw, NFP_NET_CFG_MAX_RXRINGS);\n+\thw->max_tx_queues = nn_cfg_readl(hw, NFP_NET_CFG_MAX_TXRINGS);\n+\n+\t/* Work out where in the BAR the queues start. */\n+\tswitch (pci_dev->id.device_id) {\n+\tcase PCI_DEVICE_ID_NFP4000_PF_NIC:\n+\tcase PCI_DEVICE_ID_NFP6000_PF_NIC:\n+\t\tstart_q = nn_cfg_readl(hw, NFP_NET_CFG_START_TXQ);\n+\t\ttx_bar_off = (uint64_t)start_q * NFP_QCP_QUEUE_ADDR_SZ;\n+\t\tstart_q = nn_cfg_readl(hw, NFP_NET_CFG_START_RXQ);\n+\t\trx_bar_off = (uint64_t)start_q * NFP_QCP_QUEUE_ADDR_SZ;\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"nfp_net: no device ID matching\");\n+\t\terr = -ENODEV;\n+\t\tgoto dev_err_ctrl_map;\n+\t}\n+\n+\tPMD_INIT_LOG(DEBUG, \"tx_bar_off: 0x%\" PRIx64 \"\", tx_bar_off);\n+\tPMD_INIT_LOG(DEBUG, \"rx_bar_off: 0x%\" PRIx64 \"\", rx_bar_off);\n+\n+\thw->tx_bar = pf_dev->hw_queues + tx_bar_off;\n+\thw->rx_bar = pf_dev->hw_queues + rx_bar_off;\n+\teth_dev->data->dev_private = hw;\n+\n+\tPMD_INIT_LOG(DEBUG, \"ctrl_bar: %p, tx_bar: %p, rx_bar: %p\",\n+\t\t     hw->ctrl_bar, hw->tx_bar, hw->rx_bar);\n+\n+\tnfp_net_cfg_queue_setup(hw);\n+\n+\t/* Get some of the read-only fields from the config BAR */\n+\thw->ver = nn_cfg_readl(hw, NFP_NET_CFG_VERSION);\n+\thw->cap = nn_cfg_readl(hw, NFP_NET_CFG_CAP);\n+\thw->max_mtu = nn_cfg_readl(hw, NFP_NET_CFG_MAX_MTU);\n+\thw->mtu = RTE_ETHER_MTU;\n+\n+\t/* VLAN insertion is incompatible with LSOv2 */\n+\tif (hw->cap & NFP_NET_CFG_CTRL_LSO2)\n+\t\thw->cap &= ~NFP_NET_CFG_CTRL_TXVLAN;\n+\n+\tif (NFD_CFG_MAJOR_VERSION_of(hw->ver) < 2)\n+\t\thw->rx_offset = NFP_NET_RX_OFFSET;\n+\telse\n+\t\thw->rx_offset = nn_cfg_readl(hw, NFP_NET_CFG_RX_OFFSET_ADDR);\n+\n+\tPMD_INIT_LOG(INFO, \"VER: %u.%u, Maximum supported MTU: %d\",\n+\t\t\t   NFD_CFG_MAJOR_VERSION_of(hw->ver),\n+\t\t\t   NFD_CFG_MINOR_VERSION_of(hw->ver), hw->max_mtu);\n+\n+\tPMD_INIT_LOG(INFO, \"CAP: %#x, %s%s%s%s%s%s%s%s%s%s%s%s%s%s\", hw->cap,\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_PROMISC ? \"PROMISC \" : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_L2BC    ? \"L2BCFILT \" : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_L2MC    ? \"L2MCFILT \" : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_RXCSUM  ? \"RXCSUM \"  : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_TXCSUM  ? \"TXCSUM \"  : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_RXVLAN  ? \"RXVLAN \"  : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_TXVLAN  ? \"TXVLAN \"  : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_SCATTER ? \"SCATTER \" : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_GATHER  ? \"GATHER \"  : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR ? \"LIVE_ADDR \"  : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_LSO     ? \"TSO \"     : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_LSO2     ? \"TSOv2 \"     : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_RSS     ? \"RSS \"     : \"\",\n+\t\t     hw->cap & NFP_NET_CFG_CTRL_RSS2     ? \"RSSv2 \"     : \"\");\n+\n+\thw->ctrl = 0;\n+\n+\thw->stride_rx = stride;\n+\thw->stride_tx = stride;\n+\n+\tPMD_INIT_LOG(INFO, \"max_rx_queues: %u, max_tx_queues: %u\",\n+\t\t     hw->max_rx_queues, hw->max_tx_queues);\n+\n+\t/* Initializing spinlock for reconfigs */\n+\trte_spinlock_init(&hw->reconfig_lock);\n+\n+\t/* Allocating memory for mac addr */\n+\teth_dev->data->mac_addrs = rte_zmalloc(\"mac_addr\",\n+\t\t\t\t\t       RTE_ETHER_ADDR_LEN, 0);\n+\tif (eth_dev->data->mac_addrs == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to space for MAC address\");\n+\t\terr = -ENOMEM;\n+\t\tgoto dev_err_queues_map;\n+\t}\n+\n+\tnfp_net_pf_read_mac(pf_dev, port);\n+\tnfp_net_write_mac(hw, (uint8_t *)&hw->mac_addr);\n+\n+\ttmp_ether_addr = (struct rte_ether_addr *)&hw->mac_addr;\n+\tif (!rte_is_valid_assigned_ether_addr(tmp_ether_addr)) {\n+\t\tPMD_INIT_LOG(INFO, \"Using random mac address for port %d\",\n+\t\t\t\t   port);\n+\t\t/* Using random mac addresses for VFs */\n+\t\trte_eth_random_addr(&hw->mac_addr[0]);\n+\t\tnfp_net_write_mac(hw, (uint8_t *)&hw->mac_addr);\n+\t}\n+\n+\t/* Copying mac address to DPDK eth_dev struct */\n+\trte_ether_addr_copy((struct rte_ether_addr *)hw->mac_addr,\n+\t\t\t&eth_dev->data->mac_addrs[0]);\n+\n+\tif (!(hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR))\n+\t\teth_dev->data->dev_flags |= RTE_ETH_DEV_NOLIVE_MAC_ADDR;\n+\n+\teth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;\n+\n+\tPMD_INIT_LOG(INFO, \"port %d VendorID=0x%x DeviceID=0x%x \"\n+\t\t     \"mac=%02x:%02x:%02x:%02x:%02x:%02x\",\n+\t\t     eth_dev->data->port_id, pci_dev->id.vendor_id,\n+\t\t     pci_dev->id.device_id,\n+\t\t     hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],\n+\t\t     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);\n+\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n+\t\t/* Registering LSC interrupt handler */\n+\t\trte_intr_callback_register(&pci_dev->intr_handle,\n+\t\t\t\t\t   nfp_net_dev_interrupt_handler,\n+\t\t\t\t\t   (void *)eth_dev);\n+\t\t/* Telling the firmware about the LSC interrupt entry */\n+\t\tnn_cfg_writeb(hw, NFP_NET_CFG_LSC, NFP_NET_IRQ_LSC_IDX);\n+\t\t/* Recording current stats counters values */\n+\t\tnfp_net_stats_reset(eth_dev);\n+\t}\n+\n+\treturn 0;\n+\n+dev_err_queues_map:\n+\t\tnfp_cpp_area_free(hw->hwqueues_area);\n+dev_err_ctrl_map:\n+\t\tnfp_cpp_area_free(hw->ctrl_area);\n+\n+\treturn err;\n+}\n+\n+#define DEFAULT_FW_PATH       \"/lib/firmware/netronome\"\n+\n+static int\n+nfp_fw_upload(struct rte_pci_device *dev, struct nfp_nsp *nsp, char *card)\n+{\n+\tstruct nfp_cpp *cpp = nsp->cpp;\n+\tint fw_f;\n+\tchar *fw_buf;\n+\tchar fw_name[125];\n+\tchar serial[40];\n+\tstruct stat file_stat;\n+\toff_t fsize, bytes;\n+\n+\t/* Looking for firmware file in order of priority */\n+\n+\t/* First try to find a firmware image specific for this device */\n+\tsnprintf(serial, sizeof(serial),\n+\t\t\t\"serial-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\",\n+\t\tcpp->serial[0], cpp->serial[1], cpp->serial[2], cpp->serial[3],\n+\t\tcpp->serial[4], cpp->serial[5], cpp->interface >> 8,\n+\t\tcpp->interface & 0xff);\n+\n+\tsnprintf(fw_name, sizeof(fw_name), \"%s/%s.nffw\", DEFAULT_FW_PATH,\n+\t\t\tserial);\n+\n+\tPMD_DRV_LOG(DEBUG, \"Trying with fw file: %s\", fw_name);\n+\tfw_f = open(fw_name, O_RDONLY);\n+\tif (fw_f >= 0)\n+\t\tgoto read_fw;\n+\n+\t/* Then try the PCI name */\n+\tsnprintf(fw_name, sizeof(fw_name), \"%s/pci-%s.nffw\", DEFAULT_FW_PATH,\n+\t\t\tdev->device.name);\n+\n+\tPMD_DRV_LOG(DEBUG, \"Trying with fw file: %s\", fw_name);\n+\tfw_f = open(fw_name, O_RDONLY);\n+\tif (fw_f >= 0)\n+\t\tgoto read_fw;\n+\n+\t/* Finally try the card type and media */\n+\tsnprintf(fw_name, sizeof(fw_name), \"%s/%s\", DEFAULT_FW_PATH, card);\n+\tPMD_DRV_LOG(DEBUG, \"Trying with fw file: %s\", fw_name);\n+\tfw_f = open(fw_name, O_RDONLY);\n+\tif (fw_f < 0) {\n+\t\tPMD_DRV_LOG(INFO, \"Firmware file %s not found.\", fw_name);\n+\t\treturn -ENOENT;\n+\t}\n+\n+read_fw:\n+\tif (fstat(fw_f, &file_stat) < 0) {\n+\t\tPMD_DRV_LOG(INFO, \"Firmware file %s size is unknown\", fw_name);\n+\t\tclose(fw_f);\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tfsize = file_stat.st_size;\n+\tPMD_DRV_LOG(INFO, \"Firmware file found at %s with size: %\" PRIu64 \"\",\n+\t\t\t    fw_name, (uint64_t)fsize);\n+\n+\tfw_buf = malloc((size_t)fsize);\n+\tif (!fw_buf) {\n+\t\tPMD_DRV_LOG(INFO, \"malloc failed for fw buffer\");\n+\t\tclose(fw_f);\n+\t\treturn -ENOMEM;\n+\t}\n+\tmemset(fw_buf, 0, fsize);\n+\n+\tbytes = read(fw_f, fw_buf, fsize);\n+\tif (bytes != fsize) {\n+\t\tPMD_DRV_LOG(INFO, \"Reading fw to buffer failed.\"\n+\t\t\t\t   \"Just %\" PRIu64 \" of %\" PRIu64 \" bytes read\",\n+\t\t\t\t   (uint64_t)bytes, (uint64_t)fsize);\n+\t\tfree(fw_buf);\n+\t\tclose(fw_f);\n+\t\treturn -EIO;\n+\t}\n+\n+\tPMD_DRV_LOG(INFO, \"Uploading the firmware ...\");\n+\tnfp_nsp_load_fw(nsp, fw_buf, bytes);\n+\tPMD_DRV_LOG(INFO, \"Done\");\n+\n+\tfree(fw_buf);\n+\tclose(fw_f);\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_fw_setup(struct rte_pci_device *dev, struct nfp_cpp *cpp,\n+\t     struct nfp_eth_table *nfp_eth_table, struct nfp_hwinfo *hwinfo)\n+{\n+\tstruct nfp_nsp *nsp;\n+\tconst char *nfp_fw_model;\n+\tchar card_desc[100];\n+\tint err = 0;\n+\n+\tnfp_fw_model = nfp_hwinfo_lookup(hwinfo, \"assembly.partno\");\n+\n+\tif (nfp_fw_model) {\n+\t\tPMD_DRV_LOG(INFO, \"firmware model found: %s\", nfp_fw_model);\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"firmware model NOT found\");\n+\t\treturn -EIO;\n+\t}\n+\n+\tif (nfp_eth_table->count == 0 || nfp_eth_table->count > 8) {\n+\t\tPMD_DRV_LOG(ERR, \"NFP ethernet table reports wrong ports: %u\",\n+\t\t       nfp_eth_table->count);\n+\t\treturn -EIO;\n+\t}\n+\n+\tPMD_DRV_LOG(INFO, \"NFP ethernet port table reports %u ports\",\n+\t\t\t   nfp_eth_table->count);\n+\n+\tPMD_DRV_LOG(INFO, \"Port speed: %u\", nfp_eth_table->ports[0].speed);\n+\n+\tsnprintf(card_desc, sizeof(card_desc), \"nic_%s_%dx%d.nffw\",\n+\t\t\tnfp_fw_model, nfp_eth_table->count,\n+\t\t\tnfp_eth_table->ports[0].speed / 1000);\n+\n+\tnsp = nfp_nsp_open(cpp);\n+\tif (!nsp) {\n+\t\tPMD_DRV_LOG(ERR, \"NFP error when obtaining NSP handle\");\n+\t\treturn -EIO;\n+\t}\n+\n+\tnfp_nsp_device_soft_reset(nsp);\n+\terr = nfp_fw_upload(dev, nsp, card_desc);\n+\n+\tnfp_nsp_close(nsp);\n+\treturn err;\n+}\n+\n+static int nfp_init_phyports(struct nfp_pf_dev *pf_dev)\n+{\n+\tstruct nfp_net_hw *hw;\n+\tstruct rte_eth_dev *eth_dev;\n+\tstruct nfp_eth_table *nfp_eth_table = NULL;\n+\tint ret = 0;\n+\tint i;\n+\n+\tnfp_eth_table = nfp_eth_read_ports(pf_dev->cpp);\n+\tif (!nfp_eth_table) {\n+\t\tPMD_INIT_LOG(ERR, \"Error reading NFP ethernet table\");\n+\t\tret = -EIO;\n+\t\tgoto error;\n+\t}\n+\n+\t/* Loop through all physical ports on PF */\n+\tfor (i = 0; i < pf_dev->total_phyports; i++) {\n+\t\tconst unsigned int numa_node = rte_socket_id();\n+\t\tchar port_name[RTE_ETH_NAME_MAX_LEN];\n+\n+\t\tsnprintf(port_name, sizeof(port_name), \"%s_port%d\",\n+\t\t\t pf_dev->pci_dev->device.name, i);\n+\n+\t\t/* Allocate a eth_dev for this phyport */\n+\t\teth_dev = rte_eth_dev_allocate(port_name);\n+\t\tif (!eth_dev) {\n+\t\t\tret = -ENODEV;\n+\t\t\tgoto port_cleanup;\n+\t\t}\n+\n+\t\t/* Allocate memory for this phyport */\n+\t\teth_dev->data->dev_private =\n+\t\t\trte_zmalloc_socket(port_name, sizeof(struct nfp_net_hw),\n+\t\t\t\t\t   RTE_CACHE_LINE_SIZE, numa_node);\n+\t\tif (!eth_dev->data->dev_private) {\n+\t\t\tret = -ENOMEM;\n+\t\t\trte_eth_dev_release_port(eth_dev);\n+\t\t\tgoto port_cleanup;\n+\t\t}\n+\n+\t\thw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);\n+\n+\t\t/* Add this device to the PF's array of physical ports */\n+\t\tpf_dev->ports[i] = hw;\n+\n+\t\thw->pf_dev = pf_dev;\n+\t\thw->cpp = pf_dev->cpp;\n+\t\thw->eth_dev = eth_dev;\n+\t\thw->idx = i;\n+\t\thw->nfp_idx = nfp_eth_table->ports[i].index;\n+\t\thw->is_phyport = true;\n+\n+\t\teth_dev->device = &pf_dev->pci_dev->device;\n+\n+\t\t/* ctrl/tx/rx BAR mappings and remaining init happens in\n+\t\t * nfp_net_init\n+\t\t */\n+\t\tret = nfp_net_init(eth_dev);\n+\n+\t\tif (ret) {\n+\t\t\tret = -ENODEV;\n+\t\t\tgoto port_cleanup;\n+\t\t}\n+\n+\t\trte_eth_dev_probing_finish(eth_dev);\n+\n+\t} /* End loop, all ports on this PF */\n+\tret = 0;\n+\tgoto eth_table_cleanup;\n+\n+port_cleanup:\n+\tfor (i = 0; i < pf_dev->total_phyports; i++) {\n+\t\tif (pf_dev->ports[i] && pf_dev->ports[i]->eth_dev) {\n+\t\t\tstruct rte_eth_dev *tmp_dev;\n+\t\t\ttmp_dev = pf_dev->ports[i]->eth_dev;\n+\t\t\trte_eth_dev_release_port(tmp_dev);\n+\t\t\tpf_dev->ports[i] = NULL;\n+\t\t}\n+\t}\n+eth_table_cleanup:\n+\tfree(nfp_eth_table);\n+error:\n+\treturn ret;\n+}\n+\n+static int nfp_pf_init(struct rte_pci_device *pci_dev)\n+{\n+\tstruct nfp_pf_dev *pf_dev = NULL;\n+\tstruct nfp_cpp *cpp;\n+\tstruct nfp_hwinfo *hwinfo;\n+\tstruct nfp_rtsym_table *sym_tbl;\n+\tstruct nfp_eth_table *nfp_eth_table = NULL;\n+\tchar name[RTE_ETH_NAME_MAX_LEN];\n+\tint total_ports;\n+\tint ret = -ENODEV;\n+\tint err;\n+\n+\tif (!pci_dev)\n+\t\treturn ret;\n+\n+\t/*\n+\t * When device bound to UIO, the device could be used, by mistake,\n+\t * by two DPDK apps, and the UIO driver does not avoid it. This\n+\t * could lead to a serious problem when configuring the NFP CPP\n+\t * interface. Here we avoid this telling to the CPP init code to\n+\t * use a lock file if UIO is being used.\n+\t */\n+\tif (pci_dev->kdrv == RTE_PCI_KDRV_VFIO)\n+\t\tcpp = nfp_cpp_from_device_name(pci_dev, 0);\n+\telse\n+\t\tcpp = nfp_cpp_from_device_name(pci_dev, 1);\n+\n+\tif (!cpp) {\n+\t\tPMD_INIT_LOG(ERR, \"A CPP handle can not be obtained\");\n+\t\tret = -EIO;\n+\t\tgoto error;\n+\t}\n+\n+\thwinfo = nfp_hwinfo_read(cpp);\n+\tif (!hwinfo) {\n+\t\tPMD_INIT_LOG(ERR, \"Error reading hwinfo table\");\n+\t\tret = -EIO;\n+\t\tgoto error;\n+\t}\n+\n+\tnfp_eth_table = nfp_eth_read_ports(cpp);\n+\tif (!nfp_eth_table) {\n+\t\tPMD_INIT_LOG(ERR, \"Error reading NFP ethernet table\");\n+\t\tret = -EIO;\n+\t\tgoto hwinfo_cleanup;\n+\t}\n+\n+\tif (nfp_fw_setup(pci_dev, cpp, nfp_eth_table, hwinfo)) {\n+\t\tPMD_INIT_LOG(ERR, \"Error when uploading firmware\");\n+\t\tret = -EIO;\n+\t\tgoto eth_table_cleanup;\n+\t}\n+\n+\t/* Now the symbol table should be there */\n+\tsym_tbl = nfp_rtsym_table_read(cpp);\n+\tif (!sym_tbl) {\n+\t\tPMD_INIT_LOG(ERR, \"Something is wrong with the firmware\"\n+\t\t\t\t\" symbol table\");\n+\t\tret = -EIO;\n+\t\tgoto eth_table_cleanup;\n+\t}\n+\n+\ttotal_ports = nfp_rtsym_read_le(sym_tbl, \"nfd_cfg_pf0_num_ports\", &err);\n+\tif (total_ports != (int)nfp_eth_table->count) {\n+\t\tPMD_DRV_LOG(ERR, \"Inconsistent number of ports\");\n+\t\tret = -EIO;\n+\t\tgoto sym_tbl_cleanup;\n+\t}\n+\n+\tPMD_INIT_LOG(INFO, \"Total physical ports: %d\", total_ports);\n+\n+\tif (total_ports <= 0 || total_ports > 8) {\n+\t\tPMD_INIT_LOG(ERR, \"nfd_cfg_pf0_num_ports symbol with wrong value\");\n+\t\tret = -ENODEV;\n+\t\tgoto sym_tbl_cleanup;\n+\t}\n+\t/* Allocate memory for the PF \"device\" */\n+\tsnprintf(name, sizeof(name), \"nfp_pf%d\", 0);\n+\tpf_dev = rte_zmalloc(name, sizeof(*pf_dev), 0);\n+\tif (!pf_dev) {\n+\t\tret = -ENOMEM;\n+\t\tgoto sym_tbl_cleanup;\n+\t}\n+\n+\t/* Populate the newly created PF device */\n+\tpf_dev->cpp = cpp;\n+\tpf_dev->hwinfo = hwinfo;\n+\tpf_dev->sym_tbl = sym_tbl;\n+\tpf_dev->total_phyports = total_ports;\n+\n+\tif (total_ports > 1)\n+\t\tpf_dev->multiport = true;\n+\n+\tpf_dev->pci_dev = pci_dev;\n+\n+\t/* Map the symbol table */\n+\tpf_dev->ctrl_bar = nfp_rtsym_map(pf_dev->sym_tbl, \"_pf0_net_bar0\",\n+\t\t\t\t     pf_dev->total_phyports * 32768,\n+\t\t\t\t     &pf_dev->ctrl_area);\n+\tif (!pf_dev->ctrl_bar) {\n+\t\tPMD_INIT_LOG(ERR, \"nfp_rtsym_map fails for _pf0_net_ctrl_bar\");\n+\t\tret = -EIO;\n+\t\tgoto pf_cleanup;\n+\t}\n+\n+\tPMD_INIT_LOG(DEBUG, \"ctrl bar: %p\", pf_dev->ctrl_bar);\n+\n+\t/* configure access to tx/rx vNIC BARs */\n+\tpf_dev->hw_queues = nfp_cpp_map_area(pf_dev->cpp, 0, 0,\n+\t\t\t\t\t      NFP_PCIE_QUEUE(0),\n+\t\t\t\t\t      NFP_QCP_QUEUE_AREA_SZ,\n+\t\t\t\t\t      &pf_dev->hwqueues_area);\n+\tif (!pf_dev->hw_queues) {\n+\t\tPMD_INIT_LOG(ERR, \"nfp_rtsym_map fails for net.qc\");\n+\t\tret = -EIO;\n+\t\tgoto ctrl_area_cleanup;\n+\t}\n+\n+\tPMD_INIT_LOG(DEBUG, \"tx/rx bar address: 0x%p\", pf_dev->hw_queues);\n+\n+\t/* Initialize and prep physical ports now\n+\t * This will loop through all physical ports\n+\t */\n+\tret = nfp_init_phyports(pf_dev);\n+\tif (ret) {\n+\t\tPMD_INIT_LOG(ERR, \"Could not create physical ports\");\n+\t\tgoto hwqueues_cleanup;\n+\t}\n+\n+\t/* register the CPP bridge service here for primary use */\n+\tnfp_register_cpp_service(pf_dev->cpp);\n+\n+\treturn 0;\n+\n+hwqueues_cleanup:\n+\tnfp_cpp_area_free(pf_dev->hwqueues_area);\n+ctrl_area_cleanup:\n+\tnfp_cpp_area_free(pf_dev->ctrl_area);\n+pf_cleanup:\n+\trte_free(pf_dev);\n+sym_tbl_cleanup:\n+\tfree(sym_tbl);\n+eth_table_cleanup:\n+\tfree(nfp_eth_table);\n+hwinfo_cleanup:\n+\tfree(hwinfo);\n+error:\n+\treturn ret;\n+}\n+\n+/*\n+ * When attaching to the NFP4000/6000 PF on a secondary process there\n+ * is no need to initilise the PF again. Only minimal work is required\n+ * here\n+ */\n+static int nfp_pf_secondary_init(struct rte_pci_device *pci_dev)\n+{\n+\tstruct nfp_cpp *cpp;\n+\tstruct nfp_rtsym_table *sym_tbl;\n+\tint total_ports;\n+\tint i;\n+\tint err;\n+\n+\tif (!pci_dev)\n+\t\treturn -ENODEV;\n+\n+\t/*\n+\t * When device bound to UIO, the device could be used, by mistake,\n+\t * by two DPDK apps, and the UIO driver does not avoid it. This\n+\t * could lead to a serious problem when configuring the NFP CPP\n+\t * interface. Here we avoid this telling to the CPP init code to\n+\t * use a lock file if UIO is being used.\n+\t */\n+\tif (pci_dev->kdrv == RTE_PCI_KDRV_VFIO)\n+\t\tcpp = nfp_cpp_from_device_name(pci_dev, 0);\n+\telse\n+\t\tcpp = nfp_cpp_from_device_name(pci_dev, 1);\n+\n+\tif (!cpp) {\n+\t\tPMD_INIT_LOG(ERR, \"A CPP handle can not be obtained\");\n+\t\treturn -EIO;\n+\t}\n+\n+\t/*\n+\t * We don't have access to the PF created in the primary process\n+\t * here so we have to read the number of ports from firmware\n+\t */\n+\tsym_tbl = nfp_rtsym_table_read(cpp);\n+\tif (!sym_tbl) {\n+\t\tPMD_INIT_LOG(ERR, \"Something is wrong with the firmware\"\n+\t\t\t\t\" symbol table\");\n+\t\treturn -EIO;\n+\t}\n+\n+\ttotal_ports = nfp_rtsym_read_le(sym_tbl, \"nfd_cfg_pf0_num_ports\", &err);\n+\n+\tfor (i = 0; i < total_ports; i++) {\n+\t\tstruct rte_eth_dev *eth_dev;\n+\t\tchar port_name[RTE_ETH_NAME_MAX_LEN];\n+\n+\t\tsnprintf(port_name, sizeof(port_name), \"%s_port%d\",\n+\t\t\t pci_dev->device.name, i);\n+\n+\t\tPMD_DRV_LOG(DEBUG, \"Secondary attaching to port %s\",\n+\t\t    port_name);\n+\t\teth_dev = rte_eth_dev_attach_secondary(port_name);\n+\t\tif (!eth_dev) {\n+\t\t\tRTE_LOG(ERR, EAL,\n+\t\t\t\"secondary process attach failed, \"\n+\t\t\t\"ethdev doesn't exist\");\n+\t\t\treturn -ENODEV;\n+\t\t}\n+\t\teth_dev->process_private = cpp;\n+\t\teth_dev->dev_ops = &nfp_net_eth_dev_ops;\n+\t\teth_dev->rx_queue_count = nfp_net_rx_queue_count;\n+\t\teth_dev->rx_pkt_burst = &nfp_net_recv_pkts;\n+\t\teth_dev->tx_pkt_burst = &nfp_net_xmit_pkts;\n+\t\trte_eth_dev_probing_finish(eth_dev);\n+\t}\n+\n+\t/* Register the CPP bridge service for the secondary too */\n+\tnfp_register_cpp_service(cpp);\n+\n+\treturn 0;\n+}\n+\n+static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n+\t\t\t    struct rte_pci_device *dev)\n+{\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n+\t\treturn nfp_pf_init(dev);\n+\telse\n+\t\treturn nfp_pf_secondary_init(dev);\n+}\n+\n+static const struct rte_pci_id pci_id_nfp_pf_net_map[] = {\n+\t{\n+\t\tRTE_PCI_DEVICE(PCI_VENDOR_ID_NETRONOME,\n+\t\t\t       PCI_DEVICE_ID_NFP4000_PF_NIC)\n+\t},\n+\t{\n+\t\tRTE_PCI_DEVICE(PCI_VENDOR_ID_NETRONOME,\n+\t\t\t       PCI_DEVICE_ID_NFP6000_PF_NIC)\n+\t},\n+\t{\n+\t\t.vendor_id = 0,\n+\t},\n+};\n+\n+static int nfp_pci_uninit(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct rte_pci_device *pci_dev;\n+\tuint16_t port_id;\n+\n+\tpci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n+\n+\t/* Free up all physical ports under PF */\n+\tRTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device)\n+\t\trte_eth_dev_close(port_id);\n+\t/*\n+\t * Ports can be closed and freed but hotplugging is not\n+\t * currently supported\n+\t */\n+\treturn -ENOTSUP;\n+}\n+\n+static int eth_nfp_pci_remove(struct rte_pci_device *pci_dev)\n+{\n+\treturn rte_eth_dev_pci_generic_remove(pci_dev, nfp_pci_uninit);\n+}\n+\n+static struct rte_pci_driver rte_nfp_net_pf_pmd = {\n+\t.id_table = pci_id_nfp_pf_net_map,\n+\t.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,\n+\t.probe = nfp_pf_pci_probe,\n+\t.remove = eth_nfp_pci_remove,\n+};\n+\n+RTE_PMD_REGISTER_PCI(net_nfp_pf, rte_nfp_net_pf_pmd);\n+RTE_PMD_REGISTER_PCI_TABLE(net_nfp_pf, pci_id_nfp_pf_net_map);\n+RTE_PMD_REGISTER_KMOD_DEP(net_nfp_pf, \"* igb_uio | uio_pci_generic | vfio\");\n+/*\n+ * Local variables:\n+ * c-file-style: \"Linux\"\n+ * indent-tabs-mode: t\n+ * End:\n+ */\ndiff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c\nindex a1722886ba..a6097eaab0 100644\n--- a/drivers/net/nfp/nfp_net.c\n+++ b/drivers/net/nfp/nfp_net.c\n@@ -37,10 +37,10 @@\n #include \"nfpcore/nfp_rtsym.h\"\n #include \"nfpcore/nfp_nsp.h\"\n \n-#include \"nfp_net_pmd.h\"\n+#include \"nfp_common.h\"\n #include \"nfp_rxtx.h\"\n-#include \"nfp_net_logs.h\"\n-#include \"nfp_net_ctrl.h\"\n+#include \"nfp_logs.h\"\n+#include \"nfp_ctrl.h\"\n #include \"nfp_cpp_bridge.h\"\n \n #include <sys/types.h>\n@@ -51,20 +51,6 @@\n #include <sys/ioctl.h>\n #include <errno.h>\n \n-/* Prototypes */\n-static int nfp_net_close(struct rte_eth_dev *dev);\n-static int nfp_net_init(struct rte_eth_dev *eth_dev);\n-static int nfp_pf_init(struct rte_pci_device *pci_dev);\n-static int nfp_pf_secondary_init(struct rte_pci_device *pci_dev);\n-static int nfp_net_pf_read_mac(struct nfp_pf_dev *pf_dev, int port);\n-static int nfp_pci_uninit(struct rte_eth_dev *eth_dev);\n-static int nfp_init_phyports(struct nfp_pf_dev *pf_dev);\n-static int nfp_net_stop(struct rte_eth_dev *dev);\n-static int nfp_fw_setup(struct rte_pci_device *dev,\n-\t\t\tstruct nfp_cpp *cpp,\n-\t\t\tstruct nfp_eth_table *nfp_eth_table,\n-\t\t\tstruct nfp_hwinfo *hwinfo);\n-\n static int\n __nfp_net_reconfig(struct nfp_net_hw *hw, uint32_t update)\n {\n@@ -266,24 +252,6 @@ nfp_eth_copy_mac(uint8_t *dst, const uint8_t *src)\n \t\tdst[i] = src[i];\n }\n \n-static int\n-nfp_net_pf_read_mac(struct nfp_pf_dev *pf_dev, int port)\n-{\n-\tstruct nfp_eth_table *nfp_eth_table;\n-\tstruct nfp_net_hw *hw = NULL;\n-\n-\t/* Grab a pointer to the correct physical port */\n-\thw = pf_dev->ports[port];\n-\n-\tnfp_eth_table = nfp_eth_read_ports(pf_dev->cpp);\n-\n-\tnfp_eth_copy_mac((uint8_t *)&hw->mac_addr,\n-\t\t\t (uint8_t *)&nfp_eth_table->ports[port].mac_addr);\n-\n-\tfree(nfp_eth_table);\n-\treturn 0;\n-}\n-\n void\n nfp_net_write_mac(struct nfp_net_hw *hw, uint8_t *mac)\n {\n@@ -436,282 +404,6 @@ nfp_check_offloads(struct rte_eth_dev *dev)\n \treturn ctrl;\n }\n \n-static int\n-nfp_net_start(struct rte_eth_dev *dev)\n-{\n-\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n-\tstruct rte_intr_handle *intr_handle = &pci_dev->intr_handle;\n-\tuint32_t new_ctrl, update = 0;\n-\tstruct nfp_net_hw *hw;\n-\tstruct nfp_pf_dev *pf_dev;\n-\tstruct rte_eth_conf *dev_conf;\n-\tstruct rte_eth_rxmode *rxmode;\n-\tuint32_t intr_vector;\n-\tint ret;\n-\n-\thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n-\tpf_dev = NFP_NET_DEV_PRIVATE_TO_PF(dev->data->dev_private);\n-\n-\tPMD_INIT_LOG(DEBUG, \"Start\");\n-\n-\t/* Disabling queues just in case... */\n-\tnfp_net_disable_queues(dev);\n-\n-\t/* Enabling the required queues in the device */\n-\tnfp_net_enable_queues(dev);\n-\n-\t/* check and configure queue intr-vector mapping */\n-\tif (dev->data->dev_conf.intr_conf.rxq != 0) {\n-\t\tif (pf_dev->multiport) {\n-\t\t\tPMD_INIT_LOG(ERR, \"PMD rx interrupt is not supported \"\n-\t\t\t\t\t  \"with NFP multiport PF\");\n-\t\t\t\treturn -EINVAL;\n-\t\t}\n-\t\tif (intr_handle->type == RTE_INTR_HANDLE_UIO) {\n-\t\t\t/*\n-\t\t\t * Better not to share LSC with RX interrupts.\n-\t\t\t * Unregistering LSC interrupt handler\n-\t\t\t */\n-\t\t\trte_intr_callback_unregister(&pci_dev->intr_handle,\n-\t\t\t\tnfp_net_dev_interrupt_handler, (void *)dev);\n-\n-\t\t\tif (dev->data->nb_rx_queues > 1) {\n-\t\t\t\tPMD_INIT_LOG(ERR, \"PMD rx interrupt only \"\n-\t\t\t\t\t     \"supports 1 queue with UIO\");\n-\t\t\t\treturn -EIO;\n-\t\t\t}\n-\t\t}\n-\t\tintr_vector = dev->data->nb_rx_queues;\n-\t\tif (rte_intr_efd_enable(intr_handle, intr_vector))\n-\t\t\treturn -1;\n-\n-\t\tnfp_configure_rx_interrupt(dev, intr_handle);\n-\t\tupdate = NFP_NET_CFG_UPDATE_MSIX;\n-\t}\n-\n-\trte_intr_enable(intr_handle);\n-\n-\tnew_ctrl = nfp_check_offloads(dev);\n-\n-\t/* Writing configuration parameters in the device */\n-\tnfp_net_params_setup(hw);\n-\n-\tdev_conf = &dev->data->dev_conf;\n-\trxmode = &dev_conf->rxmode;\n-\n-\tif (rxmode->mq_mode & ETH_MQ_RX_RSS) {\n-\t\tnfp_net_rss_config_default(dev);\n-\t\tupdate |= NFP_NET_CFG_UPDATE_RSS;\n-\t\tnew_ctrl |= NFP_NET_CFG_CTRL_RSS;\n-\t}\n-\n-\t/* Enable device */\n-\tnew_ctrl |= NFP_NET_CFG_CTRL_ENABLE;\n-\n-\tupdate |= NFP_NET_CFG_UPDATE_GEN | NFP_NET_CFG_UPDATE_RING;\n-\n-\tif (hw->cap & NFP_NET_CFG_CTRL_RINGCFG)\n-\t\tnew_ctrl |= NFP_NET_CFG_CTRL_RINGCFG;\n-\n-\tnn_cfg_writel(hw, NFP_NET_CFG_CTRL, new_ctrl);\n-\tif (nfp_net_reconfig(hw, new_ctrl, update) < 0)\n-\t\treturn -EIO;\n-\n-\t/*\n-\t * Allocating rte mbufs for configured rx queues.\n-\t * This requires queues being enabled before\n-\t */\n-\tif (nfp_net_rx_freelist_setup(dev) < 0) {\n-\t\tret = -ENOMEM;\n-\t\tgoto error;\n-\t}\n-\n-\tif (hw->is_phyport) {\n-\t\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n-\t\t\t/* Configure the physical port up */\n-\t\t\tnfp_eth_set_configured(hw->cpp, hw->nfp_idx, 1);\n-\t\telse\n-\t\t\tnfp_eth_set_configured(dev->process_private,\n-\t\t\t\t\t       hw->nfp_idx, 1);\n-\t}\n-\n-\thw->ctrl = new_ctrl;\n-\n-\treturn 0;\n-\n-error:\n-\t/*\n-\t * An error returned by this function should mean the app\n-\t * exiting and then the system releasing all the memory\n-\t * allocated even memory coming from hugepages.\n-\t *\n-\t * The device could be enabled at this point with some queues\n-\t * ready for getting packets. This is true if the call to\n-\t * nfp_net_rx_freelist_setup() succeeds for some queues but\n-\t * fails for subsequent queues.\n-\t *\n-\t * This should make the app exiting but better if we tell the\n-\t * device first.\n-\t */\n-\tnfp_net_disable_queues(dev);\n-\n-\treturn ret;\n-}\n-\n-/* Stop device: disable rx and tx functions to allow for reconfiguring. */\n-static int\n-nfp_net_stop(struct rte_eth_dev *dev)\n-{\n-\tint i;\n-\tstruct nfp_net_hw *hw;\n-\n-\tPMD_INIT_LOG(DEBUG, \"Stop\");\n-\n-\thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n-\n-\tnfp_net_disable_queues(dev);\n-\n-\t/* Clear queues */\n-\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n-\t\tnfp_net_reset_tx_queue(\n-\t\t\t(struct nfp_net_txq *)dev->data->tx_queues[i]);\n-\t}\n-\n-\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n-\t\tnfp_net_reset_rx_queue(\n-\t\t\t(struct nfp_net_rxq *)dev->data->rx_queues[i]);\n-\t}\n-\n-\tif (hw->is_phyport) {\n-\t\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n-\t\t\t/* Configure the physical port down */\n-\t\t\tnfp_eth_set_configured(hw->cpp, hw->nfp_idx, 0);\n-\t\telse\n-\t\t\tnfp_eth_set_configured(dev->process_private,\n-\t\t\t\t\t       hw->nfp_idx, 0);\n-\t}\n-\n-\treturn 0;\n-}\n-\n-/* Set the link up. */\n-static int\n-nfp_net_set_link_up(struct rte_eth_dev *dev)\n-{\n-\tstruct nfp_net_hw *hw;\n-\n-\tPMD_DRV_LOG(DEBUG, \"Set link up\");\n-\n-\thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n-\n-\tif (!hw->is_phyport)\n-\t\treturn -ENOTSUP;\n-\n-\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n-\t\t/* Configure the physical port down */\n-\t\treturn nfp_eth_set_configured(hw->cpp, hw->nfp_idx, 1);\n-\telse\n-\t\treturn nfp_eth_set_configured(dev->process_private,\n-\t\t\t\t\t      hw->nfp_idx, 1);\n-}\n-\n-/* Set the link down. */\n-static int\n-nfp_net_set_link_down(struct rte_eth_dev *dev)\n-{\n-\tstruct nfp_net_hw *hw;\n-\n-\tPMD_DRV_LOG(DEBUG, \"Set link down\");\n-\n-\thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n-\n-\tif (!hw->is_phyport)\n-\t\treturn -ENOTSUP;\n-\n-\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n-\t\t/* Configure the physical port down */\n-\t\treturn nfp_eth_set_configured(hw->cpp, hw->nfp_idx, 0);\n-\telse\n-\t\treturn nfp_eth_set_configured(dev->process_private,\n-\t\t\t\t\t      hw->nfp_idx, 0);\n-}\n-\n-/* Reset and stop device. The device can not be restarted. */\n-static int\n-nfp_net_close(struct rte_eth_dev *dev)\n-{\n-\tstruct nfp_net_hw *hw;\n-\tstruct rte_pci_device *pci_dev;\n-\tint i;\n-\n-\tif (rte_eal_process_type() != RTE_PROC_PRIMARY)\n-\t\treturn 0;\n-\n-\tPMD_INIT_LOG(DEBUG, \"Close\");\n-\n-\thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n-\tpci_dev = RTE_ETH_DEV_TO_PCI(dev);\n-\n-\t/*\n-\t * We assume that the DPDK application is stopping all the\n-\t * threads/queues before calling the device close function.\n-\t */\n-\n-\tnfp_net_disable_queues(dev);\n-\n-\t/* Clear queues */\n-\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n-\t\tnfp_net_reset_tx_queue(\n-\t\t\t(struct nfp_net_txq *)dev->data->tx_queues[i]);\n-\t}\n-\n-\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n-\t\tnfp_net_reset_rx_queue(\n-\t\t\t(struct nfp_net_rxq *)dev->data->rx_queues[i]);\n-\t}\n-\n-\t/* Only free PF resources after all physical ports have been closed */\n-\tif (pci_dev->id.device_id == PCI_DEVICE_ID_NFP4000_PF_NIC ||\n-\t    pci_dev->id.device_id == PCI_DEVICE_ID_NFP6000_PF_NIC) {\n-\t\tstruct nfp_pf_dev *pf_dev;\n-\t\tpf_dev = NFP_NET_DEV_PRIVATE_TO_PF(dev->data->dev_private);\n-\n-\t\t/* Mark this port as unused and free device priv resources*/\n-\t\tnn_cfg_writeb(hw, NFP_NET_CFG_LSC, 0xff);\n-\t\tpf_dev->ports[hw->idx] = NULL;\n-\t\trte_eth_dev_release_port(dev);\n-\n-\t\tfor (i = 0; i < pf_dev->total_phyports; i++) {\n-\t\t\t/* Check to see if ports are still in use */\n-\t\t\tif (pf_dev->ports[i])\n-\t\t\t\treturn 0;\n-\t\t}\n-\n-\t\t/* Now it is safe to free all PF resources */\n-\t\tPMD_INIT_LOG(INFO, \"Freeing PF resources\");\n-\t\tnfp_cpp_area_free(pf_dev->ctrl_area);\n-\t\tnfp_cpp_area_free(pf_dev->hwqueues_area);\n-\t\tfree(pf_dev->hwinfo);\n-\t\tfree(pf_dev->sym_tbl);\n-\t\tnfp_cpp_free(pf_dev->cpp);\n-\t\trte_free(pf_dev);\n-\t}\n-\n-\trte_intr_disable(&pci_dev->intr_handle);\n-\n-\t/* unregister callback func from eal lib */\n-\trte_intr_callback_unregister(&pci_dev->intr_handle,\n-\t\t\t\t     nfp_net_dev_interrupt_handler,\n-\t\t\t\t     (void *)dev);\n-\n-\t/*\n-\t * The ixgbe PMD driver disables the pcie master on the\n-\t * device. The i40e does not...\n-\t */\n-\n-\treturn 0;\n-}\n-\n int\n nfp_net_promisc_enable(struct rte_eth_dev *dev)\n {\n@@ -1620,780 +1312,6 @@ nfp_net_rss_config_default(struct rte_eth_dev *dev)\n \treturn ret;\n }\n \n-\n-/* Initialise and register driver with DPDK Application */\n-static const struct eth_dev_ops nfp_net_eth_dev_ops = {\n-\t.dev_configure\t\t= nfp_net_configure,\n-\t.dev_start\t\t= nfp_net_start,\n-\t.dev_stop\t\t= nfp_net_stop,\n-\t.dev_set_link_up\t= nfp_net_set_link_up,\n-\t.dev_set_link_down\t= nfp_net_set_link_down,\n-\t.dev_close\t\t= nfp_net_close,\n-\t.promiscuous_enable\t= nfp_net_promisc_enable,\n-\t.promiscuous_disable\t= nfp_net_promisc_disable,\n-\t.link_update\t\t= nfp_net_link_update,\n-\t.stats_get\t\t= nfp_net_stats_get,\n-\t.stats_reset\t\t= nfp_net_stats_reset,\n-\t.dev_infos_get\t\t= nfp_net_infos_get,\n-\t.dev_supported_ptypes_get = nfp_net_supported_ptypes_get,\n-\t.mtu_set\t\t= nfp_net_dev_mtu_set,\n-\t.mac_addr_set           = nfp_set_mac_addr,\n-\t.vlan_offload_set\t= nfp_net_vlan_offload_set,\n-\t.reta_update\t\t= nfp_net_reta_update,\n-\t.reta_query\t\t= nfp_net_reta_query,\n-\t.rss_hash_update\t= nfp_net_rss_hash_update,\n-\t.rss_hash_conf_get\t= nfp_net_rss_hash_conf_get,\n-\t.rx_queue_setup\t\t= nfp_net_rx_queue_setup,\n-\t.rx_queue_release\t= nfp_net_rx_queue_release,\n-\t.tx_queue_setup\t\t= nfp_net_tx_queue_setup,\n-\t.tx_queue_release\t= nfp_net_tx_queue_release,\n-\t.rx_queue_intr_enable   = nfp_rx_queue_intr_enable,\n-\t.rx_queue_intr_disable  = nfp_rx_queue_intr_disable,\n-};\n-\n-\n-static int\n-nfp_net_init(struct rte_eth_dev *eth_dev)\n-{\n-\tstruct rte_pci_device *pci_dev;\n-\tstruct nfp_pf_dev *pf_dev;\n-\tstruct nfp_net_hw *hw;\n-\n-\tuint64_t tx_bar_off = 0, rx_bar_off = 0;\n-\tuint32_t start_q;\n-\tint stride = 4;\n-\tint port = 0;\n-\tint err;\n-\n-\tPMD_INIT_FUNC_TRACE();\n-\n-\tpci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n-\n-\t/* Use backpointer here to the PF of this eth_dev */\n-\tpf_dev = NFP_NET_DEV_PRIVATE_TO_PF(eth_dev->data->dev_private);\n-\n-\t/* NFP can not handle DMA addresses requiring more than 40 bits */\n-\tif (rte_mem_check_dma_mask(40)) {\n-\t\tRTE_LOG(ERR, PMD, \"device %s can not be used:\",\n-\t\t\t\t   pci_dev->device.name);\n-\t\tRTE_LOG(ERR, PMD, \"\\trestricted dma mask to 40 bits!\\n\");\n-\t\treturn -ENODEV;\n-\t};\n-\n-\tif ((pci_dev->id.device_id == PCI_DEVICE_ID_NFP4000_PF_NIC) ||\n-\t    (pci_dev->id.device_id == PCI_DEVICE_ID_NFP6000_PF_NIC)) {\n-\t\tport = ((struct nfp_net_hw *)eth_dev->data->dev_private)->idx;\n-\t\tif (port < 0 || port > 7) {\n-\t\t\tPMD_DRV_LOG(ERR, \"Port value is wrong\");\n-\t\t\treturn -ENODEV;\n-\t\t}\n-\n-\t\t/* Use PF array of physical ports to get pointer to\n-\t\t * this specific port\n-\t\t */\n-\t\thw = pf_dev->ports[port];\n-\n-\t\tPMD_INIT_LOG(DEBUG, \"Working with physical port number: %d, \"\n-\t\t\t\t    \"NFP internal port number: %d\",\n-\t\t\t\t    port, hw->nfp_idx);\n-\n-\t} else {\n-\t\thw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);\n-\t}\n-\n-\teth_dev->dev_ops = &nfp_net_eth_dev_ops;\n-\teth_dev->rx_queue_count = nfp_net_rx_queue_count;\n-\teth_dev->rx_pkt_burst = &nfp_net_recv_pkts;\n-\teth_dev->tx_pkt_burst = &nfp_net_xmit_pkts;\n-\n-\t/* For secondary processes, the primary has done all the work */\n-\tif (rte_eal_process_type() != RTE_PROC_PRIMARY)\n-\t\treturn 0;\n-\n-\trte_eth_copy_pci_info(eth_dev, pci_dev);\n-\n-\thw->device_id = pci_dev->id.device_id;\n-\thw->vendor_id = pci_dev->id.vendor_id;\n-\thw->subsystem_device_id = pci_dev->id.subsystem_device_id;\n-\thw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;\n-\n-\tPMD_INIT_LOG(DEBUG, \"nfp_net: device (%u:%u) %u:%u:%u:%u\",\n-\t\t     pci_dev->id.vendor_id, pci_dev->id.device_id,\n-\t\t     pci_dev->addr.domain, pci_dev->addr.bus,\n-\t\t     pci_dev->addr.devid, pci_dev->addr.function);\n-\n-\thw->ctrl_bar = (uint8_t *)pci_dev->mem_resource[0].addr;\n-\tif (hw->ctrl_bar == NULL) {\n-\t\tPMD_DRV_LOG(ERR,\n-\t\t\t\"hw->ctrl_bar is NULL. BAR0 not configured\");\n-\t\treturn -ENODEV;\n-\t}\n-\n-\tif (hw->is_phyport) {\n-\t\tif (port == 0) {\n-\t\t\thw->ctrl_bar = pf_dev->ctrl_bar;\n-\t\t} else {\n-\t\t\tif (!pf_dev->ctrl_bar)\n-\t\t\t\treturn -ENODEV;\n-\t\t\t/* Use port offset in pf ctrl_bar for this\n-\t\t\t * ports control bar\n-\t\t\t */\n-\t\t\thw->ctrl_bar = pf_dev->ctrl_bar +\n-\t\t\t\t       (port * NFP_PF_CSR_SLICE_SIZE);\n-\t\t}\n-\t}\n-\n-\tPMD_INIT_LOG(DEBUG, \"ctrl bar: %p\", hw->ctrl_bar);\n-\n-\thw->max_rx_queues = nn_cfg_readl(hw, NFP_NET_CFG_MAX_RXRINGS);\n-\thw->max_tx_queues = nn_cfg_readl(hw, NFP_NET_CFG_MAX_TXRINGS);\n-\n-\t/* Work out where in the BAR the queues start. */\n-\tswitch (pci_dev->id.device_id) {\n-\tcase PCI_DEVICE_ID_NFP4000_PF_NIC:\n-\tcase PCI_DEVICE_ID_NFP6000_PF_NIC:\n-\tcase PCI_DEVICE_ID_NFP6000_VF_NIC:\n-\t\tstart_q = nn_cfg_readl(hw, NFP_NET_CFG_START_TXQ);\n-\t\ttx_bar_off = (uint64_t)start_q * NFP_QCP_QUEUE_ADDR_SZ;\n-\t\tstart_q = nn_cfg_readl(hw, NFP_NET_CFG_START_RXQ);\n-\t\trx_bar_off = (uint64_t)start_q * NFP_QCP_QUEUE_ADDR_SZ;\n-\t\tbreak;\n-\tdefault:\n-\t\tPMD_DRV_LOG(ERR, \"nfp_net: no device ID matching\");\n-\t\terr = -ENODEV;\n-\t\tgoto dev_err_ctrl_map;\n-\t}\n-\n-\tPMD_INIT_LOG(DEBUG, \"tx_bar_off: 0x%\" PRIx64 \"\", tx_bar_off);\n-\tPMD_INIT_LOG(DEBUG, \"rx_bar_off: 0x%\" PRIx64 \"\", rx_bar_off);\n-\n-\tif (hw->is_phyport) {\n-\t\thw->tx_bar = pf_dev->hw_queues + tx_bar_off;\n-\t\thw->rx_bar = pf_dev->hw_queues + rx_bar_off;\n-\t\teth_dev->data->dev_private = hw;\n-\t} else {\n-\t\thw->tx_bar = (uint8_t *)pci_dev->mem_resource[2].addr +\n-\t\t\t     tx_bar_off;\n-\t\thw->rx_bar = (uint8_t *)pci_dev->mem_resource[2].addr +\n-\t\t\t     rx_bar_off;\n-\t}\n-\n-\tPMD_INIT_LOG(DEBUG, \"ctrl_bar: %p, tx_bar: %p, rx_bar: %p\",\n-\t\t     hw->ctrl_bar, hw->tx_bar, hw->rx_bar);\n-\n-\tnfp_net_cfg_queue_setup(hw);\n-\n-\t/* Get some of the read-only fields from the config BAR */\n-\thw->ver = nn_cfg_readl(hw, NFP_NET_CFG_VERSION);\n-\thw->cap = nn_cfg_readl(hw, NFP_NET_CFG_CAP);\n-\thw->max_mtu = nn_cfg_readl(hw, NFP_NET_CFG_MAX_MTU);\n-\thw->mtu = RTE_ETHER_MTU;\n-\n-\t/* VLAN insertion is incompatible with LSOv2 */\n-\tif (hw->cap & NFP_NET_CFG_CTRL_LSO2)\n-\t\thw->cap &= ~NFP_NET_CFG_CTRL_TXVLAN;\n-\n-\tif (NFD_CFG_MAJOR_VERSION_of(hw->ver) < 2)\n-\t\thw->rx_offset = NFP_NET_RX_OFFSET;\n-\telse\n-\t\thw->rx_offset = nn_cfg_readl(hw, NFP_NET_CFG_RX_OFFSET_ADDR);\n-\n-\tPMD_INIT_LOG(INFO, \"VER: %u.%u, Maximum supported MTU: %d\",\n-\t\t\t   NFD_CFG_MAJOR_VERSION_of(hw->ver),\n-\t\t\t   NFD_CFG_MINOR_VERSION_of(hw->ver), hw->max_mtu);\n-\n-\tPMD_INIT_LOG(INFO, \"CAP: %#x, %s%s%s%s%s%s%s%s%s%s%s%s%s%s\", hw->cap,\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_PROMISC ? \"PROMISC \" : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_L2BC    ? \"L2BCFILT \" : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_L2MC    ? \"L2MCFILT \" : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_RXCSUM  ? \"RXCSUM \"  : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_TXCSUM  ? \"TXCSUM \"  : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_RXVLAN  ? \"RXVLAN \"  : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_TXVLAN  ? \"TXVLAN \"  : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_SCATTER ? \"SCATTER \" : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_GATHER  ? \"GATHER \"  : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR ? \"LIVE_ADDR \"  : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_LSO     ? \"TSO \"     : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_LSO2     ? \"TSOv2 \"     : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_RSS     ? \"RSS \"     : \"\",\n-\t\t     hw->cap & NFP_NET_CFG_CTRL_RSS2     ? \"RSSv2 \"     : \"\");\n-\n-\thw->ctrl = 0;\n-\n-\thw->stride_rx = stride;\n-\thw->stride_tx = stride;\n-\n-\tPMD_INIT_LOG(INFO, \"max_rx_queues: %u, max_tx_queues: %u\",\n-\t\t     hw->max_rx_queues, hw->max_tx_queues);\n-\n-\t/* Initializing spinlock for reconfigs */\n-\trte_spinlock_init(&hw->reconfig_lock);\n-\n-\t/* Allocating memory for mac addr */\n-\teth_dev->data->mac_addrs = rte_zmalloc(\"mac_addr\",\n-\t\t\t\t\t       RTE_ETHER_ADDR_LEN, 0);\n-\tif (eth_dev->data->mac_addrs == NULL) {\n-\t\tPMD_INIT_LOG(ERR, \"Failed to space for MAC address\");\n-\t\terr = -ENOMEM;\n-\t\tgoto dev_err_queues_map;\n-\t}\n-\n-\tif (hw->is_phyport) {\n-\t\tnfp_net_pf_read_mac(pf_dev, port);\n-\t\tnfp_net_write_mac(hw, (uint8_t *)&hw->mac_addr);\n-\t}\n-\n-\tif (!rte_is_valid_assigned_ether_addr(\n-\t\t    (struct rte_ether_addr *)&hw->mac_addr)) {\n-\t\tPMD_INIT_LOG(INFO, \"Using random mac address for port %d\",\n-\t\t\t\t   port);\n-\t\t/* Using random mac addresses for VFs */\n-\t\trte_eth_random_addr(&hw->mac_addr[0]);\n-\t\tnfp_net_write_mac(hw, (uint8_t *)&hw->mac_addr);\n-\t}\n-\n-\t/* Copying mac address to DPDK eth_dev struct */\n-\trte_ether_addr_copy((struct rte_ether_addr *)hw->mac_addr,\n-\t\t\t&eth_dev->data->mac_addrs[0]);\n-\n-\tif (!(hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR))\n-\t\teth_dev->data->dev_flags |= RTE_ETH_DEV_NOLIVE_MAC_ADDR;\n-\n-\teth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;\n-\n-\tPMD_INIT_LOG(INFO, \"port %d VendorID=0x%x DeviceID=0x%x \"\n-\t\t     \"mac=%02x:%02x:%02x:%02x:%02x:%02x\",\n-\t\t     eth_dev->data->port_id, pci_dev->id.vendor_id,\n-\t\t     pci_dev->id.device_id,\n-\t\t     hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],\n-\t\t     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);\n-\n-\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n-\t\t/* Registering LSC interrupt handler */\n-\t\trte_intr_callback_register(&pci_dev->intr_handle,\n-\t\t\t\t\t   nfp_net_dev_interrupt_handler,\n-\t\t\t\t\t   (void *)eth_dev);\n-\t\t/* Telling the firmware about the LSC interrupt entry */\n-\t\tnn_cfg_writeb(hw, NFP_NET_CFG_LSC, NFP_NET_IRQ_LSC_IDX);\n-\t\t/* Recording current stats counters values */\n-\t\tnfp_net_stats_reset(eth_dev);\n-\t}\n-\n-\treturn 0;\n-\n-dev_err_queues_map:\n-\t\tnfp_cpp_area_free(hw->hwqueues_area);\n-dev_err_ctrl_map:\n-\t\tnfp_cpp_area_free(hw->ctrl_area);\n-\n-\treturn err;\n-}\n-\n-#define DEFAULT_FW_PATH       \"/lib/firmware/netronome\"\n-\n-static int\n-nfp_fw_upload(struct rte_pci_device *dev, struct nfp_nsp *nsp, char *card)\n-{\n-\tstruct nfp_cpp *cpp = nsp->cpp;\n-\tint fw_f;\n-\tchar *fw_buf;\n-\tchar fw_name[125];\n-\tchar serial[40];\n-\tstruct stat file_stat;\n-\toff_t fsize, bytes;\n-\n-\t/* Looking for firmware file in order of priority */\n-\n-\t/* First try to find a firmware image specific for this device */\n-\tsnprintf(serial, sizeof(serial),\n-\t\t\t\"serial-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\",\n-\t\tcpp->serial[0], cpp->serial[1], cpp->serial[2], cpp->serial[3],\n-\t\tcpp->serial[4], cpp->serial[5], cpp->interface >> 8,\n-\t\tcpp->interface & 0xff);\n-\n-\tsnprintf(fw_name, sizeof(fw_name), \"%s/%s.nffw\", DEFAULT_FW_PATH,\n-\t\t\tserial);\n-\n-\tPMD_DRV_LOG(DEBUG, \"Trying with fw file: %s\", fw_name);\n-\tfw_f = open(fw_name, O_RDONLY);\n-\tif (fw_f >= 0)\n-\t\tgoto read_fw;\n-\n-\t/* Then try the PCI name */\n-\tsnprintf(fw_name, sizeof(fw_name), \"%s/pci-%s.nffw\", DEFAULT_FW_PATH,\n-\t\t\tdev->device.name);\n-\n-\tPMD_DRV_LOG(DEBUG, \"Trying with fw file: %s\", fw_name);\n-\tfw_f = open(fw_name, O_RDONLY);\n-\tif (fw_f >= 0)\n-\t\tgoto read_fw;\n-\n-\t/* Finally try the card type and media */\n-\tsnprintf(fw_name, sizeof(fw_name), \"%s/%s\", DEFAULT_FW_PATH, card);\n-\tPMD_DRV_LOG(DEBUG, \"Trying with fw file: %s\", fw_name);\n-\tfw_f = open(fw_name, O_RDONLY);\n-\tif (fw_f < 0) {\n-\t\tPMD_DRV_LOG(INFO, \"Firmware file %s not found.\", fw_name);\n-\t\treturn -ENOENT;\n-\t}\n-\n-read_fw:\n-\tif (fstat(fw_f, &file_stat) < 0) {\n-\t\tPMD_DRV_LOG(INFO, \"Firmware file %s size is unknown\", fw_name);\n-\t\tclose(fw_f);\n-\t\treturn -ENOENT;\n-\t}\n-\n-\tfsize = file_stat.st_size;\n-\tPMD_DRV_LOG(INFO, \"Firmware file found at %s with size: %\" PRIu64 \"\",\n-\t\t\t    fw_name, (uint64_t)fsize);\n-\n-\tfw_buf = malloc((size_t)fsize);\n-\tif (!fw_buf) {\n-\t\tPMD_DRV_LOG(INFO, \"malloc failed for fw buffer\");\n-\t\tclose(fw_f);\n-\t\treturn -ENOMEM;\n-\t}\n-\tmemset(fw_buf, 0, fsize);\n-\n-\tbytes = read(fw_f, fw_buf, fsize);\n-\tif (bytes != fsize) {\n-\t\tPMD_DRV_LOG(INFO, \"Reading fw to buffer failed.\"\n-\t\t\t\t   \"Just %\" PRIu64 \" of %\" PRIu64 \" bytes read\",\n-\t\t\t\t   (uint64_t)bytes, (uint64_t)fsize);\n-\t\tfree(fw_buf);\n-\t\tclose(fw_f);\n-\t\treturn -EIO;\n-\t}\n-\n-\tPMD_DRV_LOG(INFO, \"Uploading the firmware ...\");\n-\tnfp_nsp_load_fw(nsp, fw_buf, bytes);\n-\tPMD_DRV_LOG(INFO, \"Done\");\n-\n-\tfree(fw_buf);\n-\tclose(fw_f);\n-\n-\treturn 0;\n-}\n-\n-static int\n-nfp_fw_setup(struct rte_pci_device *dev, struct nfp_cpp *cpp,\n-\t     struct nfp_eth_table *nfp_eth_table, struct nfp_hwinfo *hwinfo)\n-{\n-\tstruct nfp_nsp *nsp;\n-\tconst char *nfp_fw_model;\n-\tchar card_desc[100];\n-\tint err = 0;\n-\n-\tnfp_fw_model = nfp_hwinfo_lookup(hwinfo, \"assembly.partno\");\n-\n-\tif (nfp_fw_model) {\n-\t\tPMD_DRV_LOG(INFO, \"firmware model found: %s\", nfp_fw_model);\n-\t} else {\n-\t\tPMD_DRV_LOG(ERR, \"firmware model NOT found\");\n-\t\treturn -EIO;\n-\t}\n-\n-\tif (nfp_eth_table->count == 0 || nfp_eth_table->count > 8) {\n-\t\tPMD_DRV_LOG(ERR, \"NFP ethernet table reports wrong ports: %u\",\n-\t\t       nfp_eth_table->count);\n-\t\treturn -EIO;\n-\t}\n-\n-\tPMD_DRV_LOG(INFO, \"NFP ethernet port table reports %u ports\",\n-\t\t\t   nfp_eth_table->count);\n-\n-\tPMD_DRV_LOG(INFO, \"Port speed: %u\", nfp_eth_table->ports[0].speed);\n-\n-\tsnprintf(card_desc, sizeof(card_desc), \"nic_%s_%dx%d.nffw\",\n-\t\t\tnfp_fw_model, nfp_eth_table->count,\n-\t\t\tnfp_eth_table->ports[0].speed / 1000);\n-\n-\tnsp = nfp_nsp_open(cpp);\n-\tif (!nsp) {\n-\t\tPMD_DRV_LOG(ERR, \"NFP error when obtaining NSP handle\");\n-\t\treturn -EIO;\n-\t}\n-\n-\tnfp_nsp_device_soft_reset(nsp);\n-\terr = nfp_fw_upload(dev, nsp, card_desc);\n-\n-\tnfp_nsp_close(nsp);\n-\treturn err;\n-}\n-\n-static int nfp_init_phyports(struct nfp_pf_dev *pf_dev)\n-{\n-\tstruct nfp_net_hw *hw;\n-\tstruct rte_eth_dev *eth_dev;\n-\tstruct nfp_eth_table *nfp_eth_table = NULL;\n-\tint ret = 0;\n-\tint i;\n-\n-\tnfp_eth_table = nfp_eth_read_ports(pf_dev->cpp);\n-\tif (!nfp_eth_table) {\n-\t\tPMD_INIT_LOG(ERR, \"Error reading NFP ethernet table\");\n-\t\tret = -EIO;\n-\t\tgoto error;\n-\t}\n-\n-\t/* Loop through all physical ports on PF */\n-\tfor (i = 0; i < pf_dev->total_phyports; i++) {\n-\t\tconst unsigned int numa_node = rte_socket_id();\n-\t\tchar port_name[RTE_ETH_NAME_MAX_LEN];\n-\n-\t\tsnprintf(port_name, sizeof(port_name), \"%s_port%d\",\n-\t\t\t pf_dev->pci_dev->device.name, i);\n-\n-\t\t/* Allocate a eth_dev for this phyport */\n-\t\teth_dev = rte_eth_dev_allocate(port_name);\n-\t\tif (!eth_dev) {\n-\t\t\tret = -ENODEV;\n-\t\t\tgoto port_cleanup;\n-\t\t}\n-\n-\t\t/* Allocate memory for this phyport */\n-\t\teth_dev->data->dev_private =\n-\t\t\trte_zmalloc_socket(port_name, sizeof(struct nfp_net_hw),\n-\t\t\t\t\t   RTE_CACHE_LINE_SIZE, numa_node);\n-\t\tif (!eth_dev->data->dev_private) {\n-\t\t\tret = -ENOMEM;\n-\t\t\trte_eth_dev_release_port(eth_dev);\n-\t\t\tgoto port_cleanup;\n-\t\t}\n-\n-\t\thw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);\n-\n-\t\t/* Add this device to the PF's array of physical ports */\n-\t\tpf_dev->ports[i] = hw;\n-\n-\t\thw->pf_dev = pf_dev;\n-\t\thw->cpp = pf_dev->cpp;\n-\t\thw->eth_dev = eth_dev;\n-\t\thw->idx = i;\n-\t\thw->nfp_idx = nfp_eth_table->ports[i].index;\n-\t\thw->is_phyport = true;\n-\n-\t\teth_dev->device = &pf_dev->pci_dev->device;\n-\n-\t\t/* ctrl/tx/rx BAR mappings and remaining init happens in\n-\t\t * nfp_net_init\n-\t\t */\n-\t\tret = nfp_net_init(eth_dev);\n-\n-\t\tif (ret) {\n-\t\t\tret = -ENODEV;\n-\t\t\tgoto port_cleanup;\n-\t\t}\n-\n-\t\trte_eth_dev_probing_finish(eth_dev);\n-\n-\t} /* End loop, all ports on this PF */\n-\tret = 0;\n-\tgoto eth_table_cleanup;\n-\n-port_cleanup:\n-\tfor (i = 0; i < pf_dev->total_phyports; i++) {\n-\t\tif (pf_dev->ports[i] && pf_dev->ports[i]->eth_dev) {\n-\t\t\tstruct rte_eth_dev *tmp_dev;\n-\t\t\ttmp_dev = pf_dev->ports[i]->eth_dev;\n-\t\t\trte_eth_dev_release_port(tmp_dev);\n-\t\t\tpf_dev->ports[i] = NULL;\n-\t\t}\n-\t}\n-eth_table_cleanup:\n-\tfree(nfp_eth_table);\n-error:\n-\treturn ret;\n-}\n-\n-static int nfp_pf_init(struct rte_pci_device *pci_dev)\n-{\n-\tstruct nfp_pf_dev *pf_dev = NULL;\n-\tstruct nfp_cpp *cpp;\n-\tstruct nfp_hwinfo *hwinfo;\n-\tstruct nfp_rtsym_table *sym_tbl;\n-\tstruct nfp_eth_table *nfp_eth_table = NULL;\n-\tchar name[RTE_ETH_NAME_MAX_LEN];\n-\tint total_ports;\n-\tint ret = -ENODEV;\n-\tint err;\n-\n-\tif (!pci_dev)\n-\t\treturn ret;\n-\n-\t/*\n-\t * When device bound to UIO, the device could be used, by mistake,\n-\t * by two DPDK apps, and the UIO driver does not avoid it. This\n-\t * could lead to a serious problem when configuring the NFP CPP\n-\t * interface. Here we avoid this telling to the CPP init code to\n-\t * use a lock file if UIO is being used.\n-\t */\n-\tif (pci_dev->kdrv == RTE_PCI_KDRV_VFIO)\n-\t\tcpp = nfp_cpp_from_device_name(pci_dev, 0);\n-\telse\n-\t\tcpp = nfp_cpp_from_device_name(pci_dev, 1);\n-\n-\tif (!cpp) {\n-\t\tPMD_INIT_LOG(ERR, \"A CPP handle can not be obtained\");\n-\t\tret = -EIO;\n-\t\tgoto error;\n-\t}\n-\n-\thwinfo = nfp_hwinfo_read(cpp);\n-\tif (!hwinfo) {\n-\t\tPMD_INIT_LOG(ERR, \"Error reading hwinfo table\");\n-\t\tret = -EIO;\n-\t\tgoto error;\n-\t}\n-\n-\tnfp_eth_table = nfp_eth_read_ports(cpp);\n-\tif (!nfp_eth_table) {\n-\t\tPMD_INIT_LOG(ERR, \"Error reading NFP ethernet table\");\n-\t\tret = -EIO;\n-\t\tgoto hwinfo_cleanup;\n-\t}\n-\n-\tif (nfp_fw_setup(pci_dev, cpp, nfp_eth_table, hwinfo)) {\n-\t\tPMD_INIT_LOG(ERR, \"Error when uploading firmware\");\n-\t\tret = -EIO;\n-\t\tgoto eth_table_cleanup;\n-\t}\n-\n-\t/* Now the symbol table should be there */\n-\tsym_tbl = nfp_rtsym_table_read(cpp);\n-\tif (!sym_tbl) {\n-\t\tPMD_INIT_LOG(ERR, \"Something is wrong with the firmware\"\n-\t\t\t\t\" symbol table\");\n-\t\tret = -EIO;\n-\t\tgoto eth_table_cleanup;\n-\t}\n-\n-\ttotal_ports = nfp_rtsym_read_le(sym_tbl, \"nfd_cfg_pf0_num_ports\", &err);\n-\tif (total_ports != (int)nfp_eth_table->count) {\n-\t\tPMD_DRV_LOG(ERR, \"Inconsistent number of ports\");\n-\t\tret = -EIO;\n-\t\tgoto sym_tbl_cleanup;\n-\t}\n-\n-\tPMD_INIT_LOG(INFO, \"Total physical ports: %d\", total_ports);\n-\n-\tif (total_ports <= 0 || total_ports > 8) {\n-\t\tPMD_INIT_LOG(ERR, \"nfd_cfg_pf0_num_ports symbol with wrong value\");\n-\t\tret = -ENODEV;\n-\t\tgoto sym_tbl_cleanup;\n-\t}\n-\t/* Allocate memory for the PF \"device\" */\n-\tsnprintf(name, sizeof(name), \"nfp_pf%d\", 0);\n-\tpf_dev = rte_zmalloc(name, sizeof(*pf_dev), 0);\n-\tif (!pf_dev) {\n-\t\tret = -ENOMEM;\n-\t\tgoto sym_tbl_cleanup;\n-\t}\n-\n-\t/* Populate the newly created PF device */\n-\tpf_dev->cpp = cpp;\n-\tpf_dev->hwinfo = hwinfo;\n-\tpf_dev->sym_tbl = sym_tbl;\n-\tpf_dev->total_phyports = total_ports;\n-\n-\tif (total_ports > 1)\n-\t\tpf_dev->multiport = true;\n-\n-\tpf_dev->pci_dev = pci_dev;\n-\n-\t/* Map the symbol table */\n-\tpf_dev->ctrl_bar = nfp_rtsym_map(pf_dev->sym_tbl, \"_pf0_net_bar0\",\n-\t\t\t\t     pf_dev->total_phyports * 32768,\n-\t\t\t\t     &pf_dev->ctrl_area);\n-\tif (!pf_dev->ctrl_bar) {\n-\t\tPMD_INIT_LOG(ERR, \"nfp_rtsym_map fails for _pf0_net_ctrl_bar\");\n-\t\tret = -EIO;\n-\t\tgoto pf_cleanup;\n-\t}\n-\n-\tPMD_INIT_LOG(DEBUG, \"ctrl bar: %p\", pf_dev->ctrl_bar);\n-\n-\t/* configure access to tx/rx vNIC BARs */\n-\tpf_dev->hw_queues = nfp_cpp_map_area(pf_dev->cpp, 0, 0,\n-\t\t\t\t\t      NFP_PCIE_QUEUE(0),\n-\t\t\t\t\t      NFP_QCP_QUEUE_AREA_SZ,\n-\t\t\t\t\t      &pf_dev->hwqueues_area);\n-\tif (!pf_dev->hw_queues) {\n-\t\tPMD_INIT_LOG(ERR, \"nfp_rtsym_map fails for net.qc\");\n-\t\tret = -EIO;\n-\t\tgoto ctrl_area_cleanup;\n-\t}\n-\n-\tPMD_INIT_LOG(DEBUG, \"tx/rx bar address: 0x%p\", pf_dev->hw_queues);\n-\n-\t/* Initialize and prep physical ports now\n-\t * This will loop through all physical ports\n-\t */\n-\tret = nfp_init_phyports(pf_dev);\n-\tif (ret) {\n-\t\tPMD_INIT_LOG(ERR, \"Could not create physical ports\");\n-\t\tgoto hwqueues_cleanup;\n-\t}\n-\n-\t/* register the CPP bridge service here for primary use */\n-\tnfp_register_cpp_service(pf_dev->cpp);\n-\n-\treturn 0;\n-\n-hwqueues_cleanup:\n-\tnfp_cpp_area_free(pf_dev->hwqueues_area);\n-ctrl_area_cleanup:\n-\tnfp_cpp_area_free(pf_dev->ctrl_area);\n-pf_cleanup:\n-\trte_free(pf_dev);\n-sym_tbl_cleanup:\n-\tfree(sym_tbl);\n-eth_table_cleanup:\n-\tfree(nfp_eth_table);\n-hwinfo_cleanup:\n-\tfree(hwinfo);\n-error:\n-\treturn ret;\n-}\n-\n-/*\n- * When attaching to the NFP4000/6000 PF on a secondary process there\n- * is no need to initialize the PF again. Only minimal work is required\n- * here\n- */\n-static int nfp_pf_secondary_init(struct rte_pci_device *pci_dev)\n-{\n-\tstruct nfp_cpp *cpp;\n-\tstruct nfp_rtsym_table *sym_tbl;\n-\tint total_ports;\n-\tint i;\n-\tint err;\n-\n-\tif (!pci_dev)\n-\t\treturn -ENODEV;\n-\n-\t/*\n-\t * When device bound to UIO, the device could be used, by mistake,\n-\t * by two DPDK apps, and the UIO driver does not avoid it. This\n-\t * could lead to a serious problem when configuring the NFP CPP\n-\t * interface. Here we avoid this telling to the CPP init code to\n-\t * use a lock file if UIO is being used.\n-\t */\n-\tif (pci_dev->kdrv == RTE_PCI_KDRV_VFIO)\n-\t\tcpp = nfp_cpp_from_device_name(pci_dev, 0);\n-\telse\n-\t\tcpp = nfp_cpp_from_device_name(pci_dev, 1);\n-\n-\tif (!cpp) {\n-\t\tPMD_INIT_LOG(ERR, \"A CPP handle can not be obtained\");\n-\t\treturn -EIO;\n-\t}\n-\n-\t/*\n-\t * We don't have access to the PF created in the primary process\n-\t * here so we have to read the number of ports from firmware\n-\t */\n-\tsym_tbl = nfp_rtsym_table_read(cpp);\n-\tif (!sym_tbl) {\n-\t\tPMD_INIT_LOG(ERR, \"Something is wrong with the firmware\"\n-\t\t\t\t\" symbol table\");\n-\t\treturn -EIO;\n-\t}\n-\n-\ttotal_ports = nfp_rtsym_read_le(sym_tbl, \"nfd_cfg_pf0_num_ports\", &err);\n-\n-\tfor (i = 0; i < total_ports; i++) {\n-\t\tstruct rte_eth_dev *eth_dev;\n-\t\tchar port_name[RTE_ETH_NAME_MAX_LEN];\n-\n-\t\tsnprintf(port_name, sizeof(port_name), \"%s_port%d\",\n-\t\t\t pci_dev->device.name, i);\n-\n-\t\tPMD_DRV_LOG(DEBUG, \"Secondary attaching to port %s\",\n-\t\t    port_name);\n-\t\teth_dev = rte_eth_dev_attach_secondary(port_name);\n-\t\tif (!eth_dev) {\n-\t\t\tRTE_LOG(ERR, EAL,\n-\t\t\t\"secondary process attach failed, \"\n-\t\t\t\"ethdev doesn't exist\");\n-\t\t\treturn -ENODEV;\n-\t\t}\n-\t\teth_dev->process_private = cpp;\n-\t\teth_dev->dev_ops = &nfp_net_eth_dev_ops;\n-\t\teth_dev->rx_queue_count = nfp_net_rx_queue_count;\n-\t\teth_dev->rx_pkt_burst = &nfp_net_recv_pkts;\n-\t\teth_dev->tx_pkt_burst = &nfp_net_xmit_pkts;\n-\t\trte_eth_dev_probing_finish(eth_dev);\n-\t}\n-\n-\t/* Register the CPP bridge service for the secondary too */\n-\tnfp_register_cpp_service(cpp);\n-\n-\treturn 0;\n-}\n-\n-static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n-\t\t\t    struct rte_pci_device *dev)\n-{\n-\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n-\t\treturn nfp_pf_init(dev);\n-\telse\n-\t\treturn nfp_pf_secondary_init(dev);\n-}\n-\n-static const struct rte_pci_id pci_id_nfp_pf_net_map[] = {\n-\t{\n-\t\tRTE_PCI_DEVICE(PCI_VENDOR_ID_NETRONOME,\n-\t\t\t       PCI_DEVICE_ID_NFP4000_PF_NIC)\n-\t},\n-\t{\n-\t\tRTE_PCI_DEVICE(PCI_VENDOR_ID_NETRONOME,\n-\t\t\t       PCI_DEVICE_ID_NFP6000_PF_NIC)\n-\t},\n-\t{\n-\t\t.vendor_id = 0,\n-\t},\n-};\n-\n-static int nfp_pci_uninit(struct rte_eth_dev *eth_dev)\n-{\n-\tstruct rte_pci_device *pci_dev;\n-\tuint16_t port_id;\n-\n-\tpci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n-\n-\tif (pci_dev->id.device_id == PCI_DEVICE_ID_NFP4000_PF_NIC ||\n-\t    pci_dev->id.device_id == PCI_DEVICE_ID_NFP6000_PF_NIC) {\n-\t\t/* Free up all physical ports under PF */\n-\t\tRTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device)\n-\t\t\trte_eth_dev_close(port_id);\n-\t\t/*\n-\t\t * Ports can be closed and freed but hotplugging is not\n-\t\t * currently supported\n-\t\t */\n-\t\treturn -ENOTSUP;\n-\t}\n-\n-\t/* VF cleanup, just free private port data */\n-\treturn nfp_net_close(eth_dev);\n-}\n-\n-static int eth_nfp_pci_remove(struct rte_pci_device *pci_dev)\n-{\n-\treturn rte_eth_dev_pci_generic_remove(pci_dev, nfp_pci_uninit);\n-}\n-\n-static struct rte_pci_driver rte_nfp_net_pf_pmd = {\n-\t.id_table = pci_id_nfp_pf_net_map,\n-\t.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,\n-\t.probe = nfp_pf_pci_probe,\n-\t.remove = eth_nfp_pci_remove,\n-};\n-\n-RTE_PMD_REGISTER_PCI(net_nfp_pf, rte_nfp_net_pf_pmd);\n-RTE_PMD_REGISTER_PCI_TABLE(net_nfp_pf, pci_id_nfp_pf_net_map);\n-RTE_PMD_REGISTER_KMOD_DEP(net_nfp_pf, \"* igb_uio | uio_pci_generic | vfio\");\n RTE_LOG_REGISTER_SUFFIX(nfp_logtype_init, init, NOTICE);\n RTE_LOG_REGISTER_SUFFIX(nfp_logtype_driver, driver, NOTICE);\n /*\n",
    "prefixes": [
        "v2",
        "6/7"
    ]
}