get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 86887,
    "url": "http://patches.dpdk.org/api/patches/86887/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210119115616.1807-2-heinrich.kuhn@netronome.com/",
    "project": {
        "id": 1,
        "url": "http://patches.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": "<20210119115616.1807-2-heinrich.kuhn@netronome.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210119115616.1807-2-heinrich.kuhn@netronome.com",
    "date": "2021-01-19T11:56:16",
    "name": "[1/2] net/nfp: create a separate entity for a NFP PF device",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "afffc5f780a7f58db38feb1788ff666b8dc963f9",
    "submitter": {
        "id": 1523,
        "url": "http://patches.dpdk.org/api/people/1523/?format=api",
        "name": "Heinrich Kuhn",
        "email": "heinrich.kuhn@netronome.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20210119115616.1807-2-heinrich.kuhn@netronome.com/mbox/",
    "series": [
        {
            "id": 14846,
            "url": "http://patches.dpdk.org/api/series/14846/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=14846",
            "date": "2021-01-19T11:56:14",
            "name": "free port private data in dev_close callback",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/14846/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/86887/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/86887/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 7EC89A0A05;\n\tTue, 19 Jan 2021 12:57:17 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8A0C5140D4F;\n\tTue, 19 Jan 2021 12:57:16 +0100 (CET)",
            "from mail-ej1-f43.google.com (mail-ej1-f43.google.com\n [209.85.218.43])\n by mails.dpdk.org (Postfix) with ESMTP id 80D2D140D1D\n for <dev@dpdk.org>; Tue, 19 Jan 2021 12:57:13 +0100 (CET)",
            "by mail-ej1-f43.google.com with SMTP id rv9so9314525ejb.13\n for <dev@dpdk.org>; Tue, 19 Jan 2021 03:57:13 -0800 (PST)",
            "from localhost.localdomain (dsl-197-245-67-23.voxdsl.co.za.\n [197.245.67.23])\n by smtp.gmail.com with ESMTPSA id b17sm2406467ejj.83.2021.01.19.03.57.10\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Tue, 19 Jan 2021 03:57:11 -0800 (PST)"
        ],
        "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=Codzvxj+gU6PEex886Ne9Zejdr4Mu2+AjVYxXLqlmJo=;\n b=lFaDZD50BP/6gw3r4S8bx8PnsIa4XMwtN8OIqfQ/HD1lN3uVagSwE+pJKdpMfi9u44\n poT2jbzqIVCPyywWoi+1GgtdQqPEB47dEUPfmZ7q1YQoM9KCt89e0FcdVP8bZ553Aqqs\n CajwgyK1kplCUiLa/odNbmGEU+fRErNO4DMN4OgCqzbM67Tm8rOWh5gHTilrsCbM3eJY\n +Czktbyx7pLXHL5gmFWn8co62808ch8eq0QqY6roCbUMagGgK40yzR1Hzr/+b1WWYZSx\n 3CulV/VFuj9slFrWT5CDdVXDBebrv7GEp+CBn0ilT4vea7kYe25ZxUj1vpngRX4CnpAN\n ExKA==",
        "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=Codzvxj+gU6PEex886Ne9Zejdr4Mu2+AjVYxXLqlmJo=;\n b=aMyUG0i6OEc1bDp3G8Vk8JokTUGmfpoSUJYrLAE0cyrMpZTktTUrU0QVXBiW7BtvTB\n F9lad1kqPROx74rzKifp1CGPrT4IUvRXv/kqS4xgyE84t00jUmSlnLkGSWERv6t0AHvD\n ddWpyxS0Ua3svTMfO4Iws3l+wITT26KFJtA9BJfK45sV536TGU5G9+2CoS2qhGPsTOKj\n QR0glMHo1IgO3I4Ozz1hd0N1kFKYep2KFywzu6chdD9qsjA/+RMVWFgvdxbbDMpFxAuN\n gPMpv80agD/23FAVOv6qco0YrDLHW/QNjtWBtEn3mIIw0CET1KmMGdqFdG0Al6VqgJGZ\n +VEg==",
        "X-Gm-Message-State": "AOAM531t/NYuCt6iZFDSH/pWZjluIOsifcXvTDQw1LQWt5eJYLjtpKhG\n W1Bkh+t5/xby+CFtob0eDJsngg6VykOXsqkt617KHsSfbhNHkxT/+JfB9mRVEcdt9ebMzxIJPAn\n ox9QsFDjDaCEODoDAB5eSRpxy0UU72KI1MnOQ8oeEfobdMytHJmy0GVC/CFCCkwzd2mc=",
        "X-Google-Smtp-Source": "\n ABdhPJxOjCkZkMKhX5AbEmi1Z9+l9fuqxY4SwI7DeYmp/B9BcO5hFGX9iOL2Hxsh8egXWPNHE7LZKA==",
        "X-Received": "by 2002:a17:906:653:: with SMTP id\n t19mr2762971ejb.44.1611057432683;\n Tue, 19 Jan 2021 03:57:12 -0800 (PST)",
        "From": "Heinrich Kuhn <heinrich.kuhn@netronome.com>",
        "To": "dev@dpdk.org",
        "Cc": "Heinrich Kuhn <heinrich.kuhn@netronome.com>,\n Louis Peens <louis.peens@netronome.com>,\n Simon Horman <simon.horman@netronome.com>",
        "Date": "Tue, 19 Jan 2021 13:56:16 +0200",
        "Message-Id": "<20210119115616.1807-2-heinrich.kuhn@netronome.com>",
        "X-Mailer": "git-send-email 2.30.0",
        "In-Reply-To": "<20210119115616.1807-1-heinrich.kuhn@netronome.com>",
        "References": "<20210119115616.1807-1-heinrich.kuhn@netronome.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH 1/2] net/nfp: create a separate entity for a NFP\n PF device",
        "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": "Before this change memory for the private data of all physical ports\nwhere allocated with single rte_zmalloc() call. Specific port private\ndata was accessed by means of an offset into this memory. This scheme is\nproblematic when attempting to free only one port's private data at a\ntime.\n\nTo address this, a new entity is created called struct nfp_pf_dev. This\nstruct represents the PF device. It has a number of PF specific members.\nNotably it has a pointer of type rte_eth_dev that points to the eth_dev\nassociated with the first physical port of the device. It also has an\narray of nfp_net_hw's containing pointers to all the physical ports\nunder the PF.\n\nMemory is first allocated for the PF and PF specific initialization is\nattempted. Next, all the physical ports under the PF is iterated and\nmemory is allocated separately for the private data of each port. Port 0\nis skipped during this phase because memory has already been allocated\nand an eth_dev already exits for the 0th port.\n\nSigned-off-by: Heinrich Kuhn <heinrich.kuhn@netronome.com>\nReviewed-by: Louis Peens <louis.peens@netronome.com>\nSigned-off-by: Simon Horman <simon.horman@netronome.com>\n---\n drivers/net/nfp/nfp_net.c     | 545 +++++++++++++++++-----------------\n drivers/net/nfp/nfp_net_pmd.h |  67 ++++-\n 2 files changed, 340 insertions(+), 272 deletions(-)",
    "diff": "diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c\nindex 1608bf5ea..9b9bd9e3d 100644\n--- a/drivers/net/nfp/nfp_net.c\n+++ b/drivers/net/nfp/nfp_net.c\n@@ -58,6 +58,8 @@ static int nfp_net_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);\n static int nfp_net_infos_get(struct rte_eth_dev *dev,\n \t\t\t     struct rte_eth_dev_info *dev_info);\n static int nfp_net_init(struct rte_eth_dev *eth_dev);\n+static int nfp_pf_init(struct rte_eth_dev *eth_dev);\n+static int nfp_init_phyports(struct nfp_pf_dev *pf_dev);\n static int nfp_net_link_update(struct rte_eth_dev *dev, int wait_to_complete);\n static int nfp_net_promisc_enable(struct rte_eth_dev *dev);\n static int nfp_net_promisc_disable(struct rte_eth_dev *dev);\n@@ -94,6 +96,12 @@ static int nfp_net_rss_hash_write(struct rte_eth_dev *dev,\n \t\t\tstruct rte_eth_rss_conf *rss_conf);\n static int nfp_set_mac_addr(struct rte_eth_dev *dev,\n \t\t\t     struct rte_ether_addr *mac_addr);\n+static int32_t nfp_cpp_bridge_service_func(void *args);\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 \n /* The offset of the queue controller queues in the PCIe Target */\n #define NFP_PCIE_QUEUE(_q) (0x80000 + (NFP_QCP_QUEUE_ADDR_SZ * ((_q) & 0xff)))\n@@ -486,16 +494,16 @@ nfp_eth_copy_mac(uint8_t *dst, const uint8_t *src)\n }\n \n static int\n-nfp_net_pf_read_mac(struct nfp_net_hw *hw, int port)\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_table = nfp_eth_read_ports(hw->cpp);\n-\t/*\n-\t * hw points to port0 private data. We need hw now pointing to\n-\t * right port.\n-\t */\n-\thw += port;\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@@ -674,12 +682,14 @@ nfp_net_start(struct rte_eth_dev *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@@ -691,7 +701,7 @@ nfp_net_start(struct rte_eth_dev *dev)\n \n \t/* check and configure queue intr-vector mapping */\n \tif (dev->data->dev_conf.intr_conf.rxq != 0) {\n-\t\tif (hw->pf_multiport_enabled) {\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@@ -755,13 +765,13 @@ nfp_net_start(struct rte_eth_dev *dev)\n \t\tgoto error;\n \t}\n \n-\tif (hw->is_pf) {\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->pf_port_idx, 1);\n+\t\t\tnfp_eth_set_configured(hw->cpp, hw->idx, 1);\n \t\telse\n \t\t\tnfp_eth_set_configured(dev->process_private,\n-\t\t\t\t\t       hw->pf_port_idx, 1);\n+\t\t\t\t\t       hw->idx, 1);\n \t}\n \n \thw->ctrl = new_ctrl;\n@@ -811,13 +821,13 @@ nfp_net_stop(struct rte_eth_dev *dev)\n \t\t\t(struct nfp_net_rxq *)dev->data->rx_queues[i]);\n \t}\n \n-\tif (hw->is_pf) {\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->pf_port_idx, 0);\n+\t\t\tnfp_eth_set_configured(hw->cpp, hw->idx, 0);\n \t\telse\n \t\t\tnfp_eth_set_configured(dev->process_private,\n-\t\t\t\t\t       hw->pf_port_idx, 0);\n+\t\t\t\t\t       hw->idx, 0);\n \t}\n \n \treturn 0;\n@@ -833,15 +843,15 @@ nfp_net_set_link_up(struct rte_eth_dev *dev)\n \n \thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \n-\tif (!hw->is_pf)\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->pf_port_idx, 1);\n+\t\treturn nfp_eth_set_configured(hw->cpp, hw->idx, 1);\n \telse\n \t\treturn nfp_eth_set_configured(dev->process_private,\n-\t\t\t\t\t      hw->pf_port_idx, 1);\n+\t\t\t\t\t      hw->idx, 1);\n }\n \n /* Set the link down. */\n@@ -854,15 +864,15 @@ nfp_net_set_link_down(struct rte_eth_dev *dev)\n \n \thw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \n-\tif (!hw->is_pf)\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->pf_port_idx, 0);\n+\t\treturn nfp_eth_set_configured(hw->cpp, hw->idx, 0);\n \telse\n \t\treturn nfp_eth_set_configured(dev->process_private,\n-\t\t\t\t\t      hw->pf_port_idx, 0);\n+\t\t\t\t\t      hw->idx, 0);\n }\n \n /* Reset and stop device. The device can not be restarted. */\n@@ -2732,43 +2742,13 @@ static const struct eth_dev_ops nfp_net_eth_dev_ops = {\n \t.rx_queue_intr_disable  = nfp_rx_queue_intr_disable,\n };\n \n-/*\n- * All eth_dev created got its private data, but before nfp_net_init, that\n- * private data is referencing private data for all the PF ports. This is due\n- * to how the vNIC bars are mapped based on first port, so all ports need info\n- * about port 0 private data. Inside nfp_net_init the private data pointer is\n- * changed to the right address for each port once the bars have been mapped.\n- *\n- * This functions helps to find out which port and therefore which offset\n- * inside the private data array to use.\n- */\n-static int\n-get_pf_port_number(char *name)\n-{\n-\tchar *pf_str = name;\n-\tint size = 0;\n-\n-\twhile ((*pf_str != '_') && (*pf_str != '\\0') && (size++ < 30))\n-\t\tpf_str++;\n-\n-\tif (size == 30)\n-\t\t/*\n-\t\t * This should not happen at all and it would mean major\n-\t\t * implementation fault.\n-\t\t */\n-\t\trte_panic(\"nfp_net: problem with pf device name\\n\");\n-\n-\t/* Expecting _portX with X within [0,7] */\n-\tpf_str += 5;\n-\n-\treturn (int)strtol(pf_str, NULL, 10);\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_net_hw *hw, *hwport0;\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@@ -2780,6 +2760,9 @@ nfp_net_init(struct rte_eth_dev *eth_dev)\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@@ -2790,22 +2773,23 @@ nfp_net_init(struct rte_eth_dev *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\tport = get_pf_port_number(eth_dev->data->name);\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\tPMD_INIT_LOG(DEBUG, \"Working with PF port value %d\", port);\n+\t\t/* This points to the specific port private data */\n+\t\tPMD_INIT_LOG(DEBUG, \"Working with physical port number %d\",\n+\t\t\t\t    port);\n \n-\t\t/* This points to port 0 private data */\n-\t\thwport0 = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);\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\t/* This points to the specific port private data */\n-\t\thw = &hwport0[port];\n \t} else {\n \t\thw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);\n-\t\thwport0 = 0;\n \t}\n \n \teth_dev->dev_ops = &nfp_net_eth_dev_ops;\n@@ -2836,25 +2820,18 @@ nfp_net_init(struct rte_eth_dev *eth_dev)\n \t\treturn -ENODEV;\n \t}\n \n-\tif (hw->is_pf && port == 0) {\n-\t\thw->ctrl_bar = nfp_rtsym_map(hw->sym_tbl, \"_pf0_net_bar0\",\n-\t\t\t\t\t     hw->total_ports * 32768,\n-\t\t\t\t\t     &hw->ctrl_area);\n-\t\tif (!hw->ctrl_bar) {\n-\t\t\tprintf(\"nfp_rtsym_map fails for _pf0_net_ctrl_bar\");\n-\t\t\treturn -EIO;\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-\n-\t\tPMD_INIT_LOG(DEBUG, \"ctrl bar: %p\", hw->ctrl_bar);\n-\t}\n-\n-\tif (port > 0) {\n-\t\tif (!hwport0->ctrl_bar)\n-\t\t\treturn -ENODEV;\n-\n-\t\t/* address based on port0 offset */\n-\t\thw->ctrl_bar = hwport0->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@@ -2881,26 +2858,9 @@ nfp_net_init(struct rte_eth_dev *eth_dev)\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_pf && port == 0) {\n-\t\t/* configure access to tx/rx vNIC BARs */\n-\t\thwport0->hw_queues = nfp_cpp_map_area(hw->cpp, 0, 0,\n-\t\t\t\t\t\t      NFP_PCIE_QUEUE(0),\n-\t\t\t\t\t\t      NFP_QCP_QUEUE_AREA_SZ,\n-\t\t\t\t\t\t      &hw->hwqueues_area);\n-\n-\t\tif (!hwport0->hw_queues) {\n-\t\t\tprintf(\"nfp_rtsym_map fails for net.qc\");\n-\t\t\terr = -EIO;\n-\t\t\tgoto dev_err_ctrl_map;\n-\t\t}\n-\n-\t\tPMD_INIT_LOG(DEBUG, \"tx/rx bar address: 0x%p\",\n-\t\t\t\t    hwport0->hw_queues);\n-\t}\n-\n-\tif (hw->is_pf) {\n-\t\thw->tx_bar = hwport0->hw_queues + tx_bar_off;\n-\t\thw->rx_bar = hwport0->hw_queues + rx_bar_off;\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@@ -2969,8 +2929,8 @@ nfp_net_init(struct rte_eth_dev *eth_dev)\n \t\tgoto dev_err_queues_map;\n \t}\n \n-\tif (hw->is_pf) {\n-\t\tnfp_net_pf_read_mac(hwport0, port);\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} else {\n \t\tnfp_net_vf_read_mac(hw);\n@@ -3369,122 +3329,6 @@ nfp_cpp_bridge_service_func(void *args)\n \treturn 0;\n }\n \n-static int\n-nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports,\n-\t\t  struct nfp_cpp *cpp, struct nfp_hwinfo *hwinfo,\n-\t\t  int phys_port, struct nfp_rtsym_table *sym_tbl, void **priv)\n-{\n-\tstruct rte_eth_dev *eth_dev;\n-\tstruct nfp_net_hw *hw = NULL;\n-\tchar *port_name;\n-\tstruct rte_service_spec service;\n-\tint retval;\n-\n-\tport_name = rte_zmalloc(\"nfp_pf_port_name\", 100, 0);\n-\tif (!port_name)\n-\t\treturn -ENOMEM;\n-\n-\tif (ports > 1)\n-\t\tsnprintf(port_name, 100, \"%s_port%d\", dev->device.name, port);\n-\telse\n-\t\tstrlcat(port_name, dev->device.name, 100);\n-\n-\n-\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n-\t\teth_dev = rte_eth_dev_allocate(port_name);\n-\t\tif (!eth_dev) {\n-\t\t\trte_free(port_name);\n-\t\t\treturn -ENODEV;\n-\t\t}\n-\t\tif (port == 0) {\n-\t\t\t*priv = rte_zmalloc(port_name,\n-\t\t\t\t\t    sizeof(struct nfp_net_adapter) *\n-\t\t\t\t\t    ports, RTE_CACHE_LINE_SIZE);\n-\t\t\tif (!*priv) {\n-\t\t\t\trte_free(port_name);\n-\t\t\t\trte_eth_dev_release_port(eth_dev);\n-\t\t\t\treturn -ENOMEM;\n-\t\t\t}\n-\t\t}\n-\t\teth_dev->data->dev_private = *priv;\n-\n-\t\t/*\n-\t\t * dev_private pointing to port0 dev_private because we need\n-\t\t * to configure vNIC bars based on port0 at nfp_net_init.\n-\t\t * Then dev_private is adjusted per port.\n-\t\t */\n-\t\thw = (struct nfp_net_hw *)(eth_dev->data->dev_private) + port;\n-\t\thw->cpp = cpp;\n-\t\thw->hwinfo = hwinfo;\n-\t\thw->sym_tbl = sym_tbl;\n-\t\thw->pf_port_idx = phys_port;\n-\t\thw->is_pf = 1;\n-\t\tif (ports > 1)\n-\t\t\thw->pf_multiport_enabled = 1;\n-\n-\t\thw->total_ports = ports;\n-\t} else {\n-\t\teth_dev = rte_eth_dev_attach_secondary(port_name);\n-\t\tif (!eth_dev) {\n-\t\t\tRTE_LOG(ERR, EAL, \"secondary process attach failed, \"\n-\t\t\t\t\"ethdev doesn't exist\");\n-\t\t\trte_free(port_name);\n-\t\t\treturn -ENODEV;\n-\t\t}\n-\t\teth_dev->process_private = cpp;\n-\t}\n-\n-\teth_dev->device = &dev->device;\n-\trte_eth_copy_pci_info(eth_dev, dev);\n-\n-\tretval = nfp_net_init(eth_dev);\n-\n-\tif (retval) {\n-\t\tretval = -ENODEV;\n-\t\tgoto probe_failed;\n-\t} else {\n-\t\trte_eth_dev_probing_finish(eth_dev);\n-\t}\n-\n-\trte_free(port_name);\n-\n-\tif (port == 0) {\n-\t\t/*\n-\t\t * The rte_service needs to be created just once per PMD.\n-\t\t * And the cpp handler needs to be linked to the service.\n-\t\t * Secondary processes will be used for debugging DPDK apps\n-\t\t * when requiring to use the CPP interface for accessing NFP\n-\t\t * components. And the cpp handler for secondary processes is\n-\t\t * available at this point.\n-\t\t */\n-\t\tmemset(&service, 0, sizeof(struct rte_service_spec));\n-\t\tsnprintf(service.name, sizeof(service.name), \"nfp_cpp_service\");\n-\t\tservice.callback = nfp_cpp_bridge_service_func;\n-\t\tservice.callback_userdata = (void *)cpp;\n-\n-\t\thw = (struct nfp_net_hw *)(eth_dev->data->dev_private);\n-\n-\t\tif (rte_service_component_register(&service,\n-\t\t\t\t\t\t   &hw->nfp_cpp_service_id))\n-\t\t\tRTE_LOG(ERR, PMD, \"NFP CPP bridge service register() failed\");\n-\t\telse\n-\t\t\tRTE_LOG(DEBUG, PMD, \"NFP CPP bridge service registered\");\n-\t}\n-\n-\treturn retval;\n-\n-probe_failed:\n-\trte_free(port_name);\n-\t/* free ports private data if primary process */\n-\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n-\t\trte_free(eth_dev->data->dev_private);\n-\t\teth_dev->data->dev_private = NULL;\n-\t}\n-\trte_eth_dev_release_port(eth_dev);\n-\n-\treturn retval;\n-}\n-\n #define DEFAULT_FW_PATH       \"/lib/firmware/netronome\"\n \n static int\n@@ -3618,20 +3462,120 @@ nfp_fw_setup(struct rte_pci_device *dev, struct nfp_cpp *cpp,\n \treturn err;\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+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+\tint ret = 0;\n+\tint i;\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\tif (rte_eal_process_type() != RTE_PROC_PRIMARY) {\n+\t\t\teth_dev = rte_eth_dev_attach_secondary(port_name);\n+\t\t\tif (!eth_dev) {\n+\t\t\t\tRTE_LOG(ERR, EAL,\n+\t\t\t\t\"secondary process attach failed, \"\n+\t\t\t\t\"ethdev doesn't exist\");\n+\t\t\t\tret = -ENODEV;\n+\t\t\t\tgoto error;\n+\t\t\t}\n+\n+\t\t\teth_dev->process_private = pf_dev->cpp;\n+\t\t\tgoto nfp_net_init;\n+\t\t}\n+\n+\t\t/* First port has already been initialized */\n+\t\tif (i == 0) {\n+\t\t\teth_dev = pf_dev->eth_dev;\n+\t\t\tgoto skip_dev_alloc;\n+\t\t}\n+\n+\t\t/* Allocate a eth_dev for remaining ports */\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 remaining ports */\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+skip_dev_alloc:\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->is_phyport = true;\n+\n+nfp_net_init:\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+\treturn 0;\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+error:\n+\treturn ret;\n+}\n+\n+static int nfp_pf_init(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct rte_pci_device *pci_dev;\n+\tstruct nfp_net_hw *hw = NULL;\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+\tstruct rte_service_spec service;\n+\tchar name[RTE_ETH_NAME_MAX_LEN];\n \tint total_ports;\n-\tvoid *priv = 0;\n \tint ret = -ENODEV;\n \tint err;\n-\tint i;\n \n-\tif (!dev)\n+\tpci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n+\thw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev);\n+\n+\tif (!pci_dev)\n \t\treturn ret;\n \n \t/*\n@@ -3641,73 +3585,162 @@ static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\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 (dev->kdrv == RTE_PCI_KDRV_VFIO)\n-\t\tcpp = nfp_cpp_from_device_name(dev, 0);\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(dev, 1);\n+\t\tcpp = nfp_cpp_from_device_name(pci_dev, 1);\n \n \tif (!cpp) {\n-\t\tPMD_DRV_LOG(ERR, \"A CPP handle can not be obtained\");\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_DRV_LOG(ERR, \"Error reading hwinfo table\");\n-\t\treturn -EIO;\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_DRV_LOG(ERR, \"Error reading NFP ethernet table\");\n-\t\treturn -EIO;\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 (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n-\t\tif (nfp_fw_setup(dev, cpp, nfp_eth_table, hwinfo)) {\n-\t\t\tPMD_DRV_LOG(INFO, \"Error when uploading firmware\");\n+\t\tif (nfp_fw_setup(pci_dev, cpp, nfp_eth_table, hwinfo)) {\n+\t\t\tPMD_INIT_LOG(ERR, \"Error when uploading firmware\");\n \t\t\tret = -EIO;\n-\t\t\tgoto error;\n+\t\t\tgoto eth_table_cleanup;\n \t\t}\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_DRV_LOG(ERR, \"Something is wrong with the firmware\"\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 error;\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 error;\n+\t\tgoto sym_tbl_cleanup;\n \t}\n-\tPMD_INIT_LOG(INFO, \"Total pf ports: %d\", total_ports);\n+\n+\tPMD_INIT_LOG(INFO, \"Total physical ports: %d\", total_ports);\n \n \tif (total_ports <= 0 || total_ports > 8) {\n-\t\tPMD_DRV_LOG(ERR, \"nfd_cfg_pf0_num_ports symbol with wrong value\");\n+\t\tPMD_INIT_LOG(ERR, \"nfd_cfg_pf0_num_ports symbol with wrong value\");\n \t\tret = -ENODEV;\n-\t\tgoto error;\n+\t\tgoto sym_tbl_cleanup;\n+\t}\n+\t/* Allocate memory for the PF \"device\" */\n+\tsnprintf(name, sizeof(name), \"nfp_pf%d\", eth_dev->data->port_id);\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-\tfor (i = 0; i < total_ports; i++) {\n-\t\tret = nfp_pf_create_dev(dev, i, total_ports, cpp, hwinfo,\n-\t\t\t\t\tnfp_eth_table->ports[i].index,\n-\t\t\t\t\tsym_tbl, &priv);\n-\t\tif (ret)\n-\t\t\tbreak;\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/* The first eth_dev is part of the PF struct */\n+\tpf_dev->eth_dev = eth_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-error:\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/*\n+\t * The rte_service needs to be created just once per PMD.\n+\t * And the cpp handler needs to be linked to the service.\n+\t * Secondary processes will be used for debugging DPDK apps\n+\t * when requiring to use the CPP interface for accessing NFP\n+\t * components. And the cpp handler for secondary processes is\n+\t * available at this point.\n+\t */\n+\tmemset(&service, 0, sizeof(struct rte_service_spec));\n+\tsnprintf(service.name, sizeof(service.name), \"nfp_cpp_service\");\n+\tservice.callback = nfp_cpp_bridge_service_func;\n+\tservice.callback_userdata = (void *)cpp;\n+\n+\tif (rte_service_component_register(&service,\n+\t\t\t\t\t   &hw->nfp_cpp_service_id))\n+\t\tRTE_LOG(ERR, PMD, \"NFP CPP bridge service register() failed\");\n+\telse\n+\t\tRTE_LOG(DEBUG, PMD, \"NFP CPP bridge service registered\");\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+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+\treturn rte_eth_dev_pci_generic_probe(dev,\n+\t\tsizeof(struct nfp_net_hw), nfp_pf_init);\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@@ -3742,34 +3775,14 @@ static int eth_nfp_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n static int eth_nfp_pci_remove(struct rte_pci_device *pci_dev)\n {\n \tstruct rte_eth_dev *eth_dev;\n-\tstruct nfp_net_hw *hw, *hwport0;\n-\tint port = 0;\n \n \teth_dev = rte_eth_dev_allocated(pci_dev->device.name);\n \tif (eth_dev == NULL)\n \t\treturn 0; /* port already released */\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 = get_pf_port_number(eth_dev->data->name);\n-\t\t/*\n-\t\t * hotplug is not possible with multiport PF although freeing\n-\t\t * data structures can be done for first port.\n-\t\t */\n-\t\tif (port != 0)\n-\t\t\treturn -ENOTSUP;\n-\t\thwport0 = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);\n-\t\thw = &hwport0[port];\n-\t\tnfp_cpp_area_free(hw->ctrl_area);\n-\t\tnfp_cpp_area_free(hw->hwqueues_area);\n-\t\tfree(hw->hwinfo);\n-\t\tfree(hw->sym_tbl);\n-\t\tnfp_cpp_free(hw->cpp);\n-\t} else {\n-\t\thw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);\n-\t}\n-\t/* hotplug is not possible with multiport PF */\n-\tif (hw->pf_multiport_enabled)\n+\t    (pci_dev->id.device_id == PCI_DEVICE_ID_NFP6000_PF_NIC))\n \t\treturn -ENOTSUP;\n+\n \treturn rte_eth_dev_pci_generic_remove(pci_dev, NULL);\n }\n \ndiff --git a/drivers/net/nfp/nfp_net_pmd.h b/drivers/net/nfp/nfp_net_pmd.h\nindex 1295c5959..922d94001 100644\n--- a/drivers/net/nfp/nfp_net_pmd.h\n+++ b/drivers/net/nfp/nfp_net_pmd.h\n@@ -102,6 +102,9 @@ struct nfp_net_adapter;\n #define NFD_CFG_MINOR_VERSION(x)    (((x) & 0xff) << 0)\n #define NFD_CFG_MINOR_VERSION_of(x) (((x) >> 0) & 0xff)\n \n+/* Number of supported physical ports */\n+#define NFP_MAX_PHYPORTS\t12\n+\n #include <linux/types.h>\n #include <rte_io.h>\n \n@@ -382,7 +385,60 @@ struct nfp_net_rxq {\n \tint rx_qcidx;\n } __rte_aligned(64);\n \n+struct nfp_pf_dev {\n+\t/* Backpointer to associated pci device */\n+\tstruct rte_pci_device *pci_dev;\n+\n+\t/* First physical port's eth device */\n+\tstruct rte_eth_dev *eth_dev;\n+\n+\t/* Array of physical ports belonging to this PF */\n+\tstruct nfp_net_hw *ports[NFP_MAX_PHYPORTS];\n+\n+\t/* Current values for control */\n+\tuint32_t ctrl;\n+\n+\tuint8_t *ctrl_bar;\n+\tuint8_t *tx_bar;\n+\tuint8_t *rx_bar;\n+\n+\tuint8_t *qcp_cfg;\n+\trte_spinlock_t reconfig_lock;\n+\n+\tuint16_t flbufsz;\n+\tuint16_t device_id;\n+\tuint16_t vendor_id;\n+\tuint16_t subsystem_device_id;\n+\tuint16_t subsystem_vendor_id;\n+#if defined(DSTQ_SELECTION)\n+#if DSTQ_SELECTION\n+\tuint16_t device_function;\n+#endif\n+#endif\n+\n+\tstruct nfp_cpp *cpp;\n+\tstruct nfp_cpp_area *ctrl_area;\n+\tstruct nfp_cpp_area *hwqueues_area;\n+\tstruct nfp_cpp_area *msix_area;\n+\n+\tuint8_t *hw_queues;\n+\tuint8_t total_phyports;\n+\tbool\tmultiport;\n+\n+\tunion eth_table_entry *eth_table;\n+\n+\tstruct nfp_hwinfo *hwinfo;\n+\tstruct nfp_rtsym_table *sym_tbl;\n+\tuint32_t nfp_cpp_service_id;\n+};\n+\n struct nfp_net_hw {\n+\t/* Backpointer to the PF this port belongs to */\n+\tstruct nfp_pf_dev *pf_dev;\n+\n+\t/* Backpointer to the eth_dev of this port*/\n+\tstruct rte_eth_dev *eth_dev;\n+\n \t/* Info from the firmware */\n \tuint32_t ver;\n \tuint32_t cap;\n@@ -427,15 +483,11 @@ struct nfp_net_hw {\n \tstruct nfp_cpp_area *msix_area;\n \n \tuint8_t *hw_queues;\n-\tuint8_t is_pf;\n-\tuint8_t pf_port_idx;\n-\tuint8_t pf_multiport_enabled;\n-\tuint8_t total_ports;\n+\tuint8_t idx;\n+\tbool\tis_phyport;\n \n \tunion eth_table_entry *eth_table;\n \n-\tstruct nfp_hwinfo *hwinfo;\n-\tstruct nfp_rtsym_table *sym_tbl;\n \tuint32_t nfp_cpp_service_id;\n };\n \n@@ -446,6 +498,9 @@ struct nfp_net_adapter {\n #define NFP_NET_DEV_PRIVATE_TO_HW(adapter)\\\n \t(&((struct nfp_net_adapter *)adapter)->hw)\n \n+#define NFP_NET_DEV_PRIVATE_TO_PF(dev_priv)\\\n+\t(((struct nfp_net_hw *)dev_priv)->pf_dev)\n+\n #endif /* _NFP_NET_PMD_H_ */\n /*\n  * Local variables:\n",
    "prefixes": [
        "1/2"
    ]
}