|
|
a6040a |
From 6a4e7e8918cd7f82e65f82219b1d1f936fe5895f Mon Sep 17 00:00:00 2001
|
|
|
a6040a |
From: Alejandro Lucero <alejandro.lucero@netronome.com>
|
|
|
a6040a |
Date: Thu, 5 Apr 2018 15:42:45 +0100
|
|
|
a6040a |
Subject: [PATCH 2/3] net/nfp: use new CPP interface
|
|
|
a6040a |
|
|
|
a6040a |
PF PMD support was based on NSPU interface. This patch changes the
|
|
|
a6040a |
PMD for using the new CPP user space interface which gives more
|
|
|
a6040a |
flexibility for adding new functionalities.
|
|
|
a6040a |
|
|
|
a6040a |
This change just affects initialization with the datapath being the
|
|
|
a6040a |
same than before.
|
|
|
a6040a |
|
|
|
a6040a |
Signed-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>
|
|
|
a6040a |
(cherry picked from commit 896c265ef954ed22b61b1980b554b8425b300eeb)
|
|
|
a6040a |
---
|
|
|
a6040a |
drivers/net/nfp/Makefile | 17 ++-
|
|
|
a6040a |
drivers/net/nfp/nfp_net.c | 342 +++++++++++++++++++++++++++++-------------
|
|
|
a6040a |
drivers/net/nfp/nfp_net_pmd.h | 16 +-
|
|
|
a6040a |
3 files changed, 264 insertions(+), 111 deletions(-)
|
|
|
a6040a |
|
|
|
a6040a |
diff --git a/drivers/net/nfp/Makefile b/drivers/net/nfp/Makefile
|
|
|
a6040a |
index 4ba066ac4..f71ecde6f 100644
|
|
|
a6040a |
--- a/drivers/net/nfp/Makefile
|
|
|
a6040a |
+++ b/drivers/net/nfp/Makefile
|
|
|
a6040a |
@@ -48,11 +48,24 @@ EXPORT_MAP := rte_pmd_nfp_version.map
|
|
|
a6040a |
|
|
|
a6040a |
LIBABIVER := 1
|
|
|
a6040a |
|
|
|
a6040a |
+VPATH += $(SRCDIR)/nfpcore
|
|
|
a6040a |
+
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_cppcore.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_cpp_pcie_ops.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_mutex.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_resource.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_crc.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_mip.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nffw.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_hwinfo.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_rtsym.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nsp.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nsp_cmds.c
|
|
|
a6040a |
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nsp_eth.c
|
|
|
a6040a |
+
|
|
|
a6040a |
#
|
|
|
a6040a |
# all source are stored in SRCS-y
|
|
|
a6040a |
#
|
|
|
a6040a |
SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_net.c
|
|
|
a6040a |
-SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nfpu.c
|
|
|
a6040a |
-SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nspu.c
|
|
|
a6040a |
|
|
|
a6040a |
include $(RTE_SDK)/mk/rte.lib.mk
|
|
|
a6040a |
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
|
|
|
a6040a |
index 0501156ba..b923d1269 100644
|
|
|
a6040a |
--- a/drivers/net/nfp/nfp_net.c
|
|
|
a6040a |
+++ b/drivers/net/nfp/nfp_net.c
|
|
|
a6040a |
@@ -1,5 +1,5 @@
|
|
|
a6040a |
/*
|
|
|
a6040a |
- * Copyright (c) 2014, 2015 Netronome Systems, Inc.
|
|
|
a6040a |
+ * Copyright (c) 2014-2018 Netronome Systems, Inc.
|
|
|
a6040a |
* All rights reserved.
|
|
|
a6040a |
*
|
|
|
a6040a |
* Small portions derived from code Copyright(c) 2010-2015 Intel Corporation.
|
|
|
a6040a |
@@ -55,7 +55,13 @@
|
|
|
a6040a |
#include <rte_alarm.h>
|
|
|
a6040a |
#include <rte_spinlock.h>
|
|
|
a6040a |
|
|
|
a6040a |
-#include "nfp_nfpu.h"
|
|
|
a6040a |
+#include "nfpcore/nfp_cpp.h"
|
|
|
a6040a |
+#include "nfpcore/nfp_nffw.h"
|
|
|
a6040a |
+#include "nfpcore/nfp_hwinfo.h"
|
|
|
a6040a |
+#include "nfpcore/nfp_mip.h"
|
|
|
a6040a |
+#include "nfpcore/nfp_rtsym.h"
|
|
|
a6040a |
+#include "nfpcore/nfp_nsp.h"
|
|
|
a6040a |
+
|
|
|
a6040a |
#include "nfp_net_pmd.h"
|
|
|
a6040a |
#include "nfp_net_logs.h"
|
|
|
a6040a |
#include "nfp_net_ctrl.h"
|
|
|
a6040a |
@@ -95,12 +101,8 @@ static void nfp_net_stop(struct rte_eth_dev *dev);
|
|
|
a6040a |
static uint16_t nfp_net_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
|
|
|
a6040a |
uint16_t nb_pkts);
|
|
|
a6040a |
|
|
|
a6040a |
-/*
|
|
|
a6040a |
- * The offset of the queue controller queues in the PCIe Target. These
|
|
|
a6040a |
- * happen to be at the same offset on the NFP6000 and the NFP3200 so
|
|
|
a6040a |
- * we use a single macro here.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-#define NFP_PCIE_QUEUE(_q) (0x800 * ((_q) & 0xff))
|
|
|
a6040a |
+/* The offset of the queue controller queues in the PCIe Target */
|
|
|
a6040a |
+#define NFP_PCIE_QUEUE(_q) (0x80000 + (NFP_QCP_QUEUE_ADDR_SZ * ((_q) & 0xff)))
|
|
|
a6040a |
|
|
|
a6040a |
/* Maximum value which can be added to a queue with one transaction */
|
|
|
a6040a |
#define NFP_QCP_MAX_ADD 0x7f
|
|
|
a6040a |
@@ -618,47 +620,29 @@ nfp_net_cfg_queue_setup(struct nfp_net_hw *hw)
|
|
|
a6040a |
#define ETH_ADDR_LEN 6
|
|
|
a6040a |
|
|
|
a6040a |
static void
|
|
|
a6040a |
-nfp_eth_copy_mac_reverse(uint8_t *dst, const uint8_t *src)
|
|
|
a6040a |
+nfp_eth_copy_mac(uint8_t *dst, const uint8_t *src)
|
|
|
a6040a |
{
|
|
|
a6040a |
int i;
|
|
|
a6040a |
|
|
|
a6040a |
for (i = 0; i < ETH_ADDR_LEN; i++)
|
|
|
a6040a |
- dst[ETH_ADDR_LEN - i - 1] = src[i];
|
|
|
a6040a |
+ dst[i] = src[i];
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
static int
|
|
|
a6040a |
nfp_net_pf_read_mac(struct nfp_net_hw *hw, int port)
|
|
|
a6040a |
{
|
|
|
a6040a |
- union eth_table_entry *entry;
|
|
|
a6040a |
- int idx, i;
|
|
|
a6040a |
-
|
|
|
a6040a |
- idx = port;
|
|
|
a6040a |
- entry = hw->eth_table;
|
|
|
a6040a |
-
|
|
|
a6040a |
- /* Reading NFP ethernet table obtained before */
|
|
|
a6040a |
- for (i = 0; i < NSP_ETH_MAX_COUNT; i++) {
|
|
|
a6040a |
- if (!(entry->port & NSP_ETH_PORT_LANES_MASK)) {
|
|
|
a6040a |
- /* port not in use */
|
|
|
a6040a |
- entry++;
|
|
|
a6040a |
- continue;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- if (idx == 0)
|
|
|
a6040a |
- break;
|
|
|
a6040a |
- idx--;
|
|
|
a6040a |
- entry++;
|
|
|
a6040a |
- }
|
|
|
a6040a |
-
|
|
|
a6040a |
- if (i == NSP_ETH_MAX_COUNT)
|
|
|
a6040a |
- return -EINVAL;
|
|
|
a6040a |
+ struct nfp_eth_table *nfp_eth_table;
|
|
|
a6040a |
|
|
|
a6040a |
+ nfp_eth_table = nfp_eth_read_ports(hw->cpp);
|
|
|
a6040a |
/*
|
|
|
a6040a |
* hw points to port0 private data. We need hw now pointing to
|
|
|
a6040a |
* right port.
|
|
|
a6040a |
*/
|
|
|
a6040a |
hw += port;
|
|
|
a6040a |
- nfp_eth_copy_mac_reverse((uint8_t *)&hw->mac_addr,
|
|
|
a6040a |
- (uint8_t *)&entry->mac_addr);
|
|
|
a6040a |
+ nfp_eth_copy_mac((uint8_t *)&hw->mac_addr,
|
|
|
a6040a |
+ (uint8_t *)&nfp_eth_table->ports[port].mac_addr);
|
|
|
a6040a |
|
|
|
a6040a |
+ free(nfp_eth_table);
|
|
|
a6040a |
return 0;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
@@ -809,7 +793,7 @@ nfp_net_start(struct rte_eth_dev *dev)
|
|
|
a6040a |
|
|
|
a6040a |
if (hw->is_pf)
|
|
|
a6040a |
/* Configure the physical port up */
|
|
|
a6040a |
- nfp_nsp_eth_config(hw->nspu_desc, hw->pf_port_idx, 1);
|
|
|
a6040a |
+ nfp_eth_set_configured(hw->cpp, hw->pf_port_idx, 1);
|
|
|
a6040a |
|
|
|
a6040a |
hw->ctrl = new_ctrl;
|
|
|
a6040a |
|
|
|
a6040a |
@@ -860,7 +844,7 @@ nfp_net_stop(struct rte_eth_dev *dev)
|
|
|
a6040a |
|
|
|
a6040a |
if (hw->is_pf)
|
|
|
a6040a |
/* Configure the physical port down */
|
|
|
a6040a |
- nfp_nsp_eth_config(hw->nspu_desc, hw->pf_port_idx, 0);
|
|
|
a6040a |
+ nfp_eth_set_configured(hw->cpp, hw->pf_port_idx, 0);
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
/* Reset and stop device. The device can not be restarted. */
|
|
|
a6040a |
@@ -2633,10 +2617,8 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
|
|
|
a6040a |
uint64_t tx_bar_off = 0, rx_bar_off = 0;
|
|
|
a6040a |
uint32_t start_q;
|
|
|
a6040a |
int stride = 4;
|
|
|
a6040a |
-
|
|
|
a6040a |
- nspu_desc_t *nspu_desc = NULL;
|
|
|
a6040a |
- uint64_t bar_offset;
|
|
|
a6040a |
int port = 0;
|
|
|
a6040a |
+ int err;
|
|
|
a6040a |
|
|
|
a6040a |
PMD_INIT_FUNC_TRACE();
|
|
|
a6040a |
|
|
|
a6040a |
@@ -2657,7 +2639,6 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
|
|
|
a6040a |
|
|
|
a6040a |
/* This points to the specific port private data */
|
|
|
a6040a |
hw = &hwport0[port];
|
|
|
a6040a |
- hw->pf_port_idx = port;
|
|
|
a6040a |
} else {
|
|
|
a6040a |
hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
|
|
|
a6040a |
hwport0 = 0;
|
|
|
a6040a |
@@ -2691,19 +2672,14 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
if (hw->is_pf && port == 0) {
|
|
|
a6040a |
- nspu_desc = hw->nspu_desc;
|
|
|
a6040a |
-
|
|
|
a6040a |
- if (nfp_nsp_map_ctrl_bar(nspu_desc, &bar_offset) != 0) {
|
|
|
a6040a |
- /*
|
|
|
a6040a |
- * A firmware should be there after PF probe so this
|
|
|
a6040a |
- * should not happen.
|
|
|
a6040a |
- */
|
|
|
a6040a |
- RTE_LOG(ERR, PMD, "PF BAR symbol resolution failed\n");
|
|
|
a6040a |
- return -ENODEV;
|
|
|
a6040a |
+ hw->ctrl_bar = nfp_rtsym_map(hw->sym_tbl, "_pf0_net_bar0",
|
|
|
a6040a |
+ hw->total_ports * 32768,
|
|
|
a6040a |
+ &hw->ctrl_area);
|
|
|
a6040a |
+ if (!hw->ctrl_bar) {
|
|
|
a6040a |
+ printf("nfp_rtsym_map fails for _pf0_net_ctrl_bar\n");
|
|
|
a6040a |
+ return -EIO;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
- /* vNIC PF control BAR is a subset of PF PCI device BAR */
|
|
|
a6040a |
- hw->ctrl_bar += bar_offset;
|
|
|
a6040a |
PMD_INIT_LOG(DEBUG, "ctrl bar: %p\n", hw->ctrl_bar);
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
@@ -2727,13 +2703,14 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
|
|
|
a6040a |
case PCI_DEVICE_ID_NFP6000_PF_NIC:
|
|
|
a6040a |
case PCI_DEVICE_ID_NFP6000_VF_NIC:
|
|
|
a6040a |
start_q = nn_cfg_readl(hw, NFP_NET_CFG_START_TXQ);
|
|
|
a6040a |
- tx_bar_off = NFP_PCIE_QUEUE(start_q);
|
|
|
a6040a |
+ tx_bar_off = start_q * NFP_QCP_QUEUE_ADDR_SZ;
|
|
|
a6040a |
start_q = nn_cfg_readl(hw, NFP_NET_CFG_START_RXQ);
|
|
|
a6040a |
- rx_bar_off = NFP_PCIE_QUEUE(start_q);
|
|
|
a6040a |
+ rx_bar_off = start_q * NFP_QCP_QUEUE_ADDR_SZ;
|
|
|
a6040a |
break;
|
|
|
a6040a |
default:
|
|
|
a6040a |
RTE_LOG(ERR, PMD, "nfp_net: no device ID matching\n");
|
|
|
a6040a |
- return -ENODEV;
|
|
|
a6040a |
+ err = -ENODEV;
|
|
|
a6040a |
+ goto dev_err_ctrl_map;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
PMD_INIT_LOG(DEBUG, "tx_bar_off: 0x%" PRIx64 "\n", tx_bar_off);
|
|
|
a6040a |
@@ -2741,17 +2718,19 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
|
|
|
a6040a |
|
|
|
a6040a |
if (hw->is_pf && port == 0) {
|
|
|
a6040a |
/* configure access to tx/rx vNIC BARs */
|
|
|
a6040a |
- nfp_nsp_map_queues_bar(nspu_desc, &bar_offset);
|
|
|
a6040a |
- PMD_INIT_LOG(DEBUG, "tx/rx bar_offset: %" PRIx64 "\n",
|
|
|
a6040a |
- bar_offset);
|
|
|
a6040a |
- hwport0->hw_queues = (uint8_t *)pci_dev->mem_resource[0].addr;
|
|
|
a6040a |
-
|
|
|
a6040a |
- /* vNIC PF tx/rx BARs are a subset of PF PCI device */
|
|
|
a6040a |
- hwport0->hw_queues += bar_offset;
|
|
|
a6040a |
+ hwport0->hw_queues = nfp_cpp_map_area(hw->cpp, 0, 0,
|
|
|
a6040a |
+ NFP_PCIE_QUEUE(0),
|
|
|
a6040a |
+ NFP_QCP_QUEUE_AREA_SZ,
|
|
|
a6040a |
+ &hw->hwqueues_area);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ if (!hwport0->hw_queues) {
|
|
|
a6040a |
+ printf("nfp_rtsym_map fails for net.qc\n");
|
|
|
a6040a |
+ err = -EIO;
|
|
|
a6040a |
+ goto dev_err_ctrl_map;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
|
|
|
a6040a |
- /* Lets seize the chance to read eth table from hw */
|
|
|
a6040a |
- if (nfp_nsp_eth_read_table(nspu_desc, &hw->eth_table))
|
|
|
a6040a |
- return -ENODEV;
|
|
|
a6040a |
+ PMD_INIT_LOG(DEBUG, "tx/rx bar address: 0x%p\n",
|
|
|
a6040a |
+ hwport0->hw_queues);
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
if (hw->is_pf) {
|
|
|
a6040a |
@@ -2811,7 +2790,8 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
|
|
|
a6040a |
eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", ETHER_ADDR_LEN, 0);
|
|
|
a6040a |
if (eth_dev->data->mac_addrs == NULL) {
|
|
|
a6040a |
PMD_INIT_LOG(ERR, "Failed to space for MAC address");
|
|
|
a6040a |
- return -ENOMEM;
|
|
|
a6040a |
+ err = -ENOMEM;
|
|
|
a6040a |
+ goto dev_err_queues_map;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
if (hw->is_pf) {
|
|
|
a6040a |
@@ -2822,6 +2802,8 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
if (!is_valid_assigned_ether_addr((struct ether_addr *)&hw->mac_addr)) {
|
|
|
a6040a |
+ PMD_INIT_LOG(INFO, "Using random mac address for port %d\n",
|
|
|
a6040a |
+ port);
|
|
|
a6040a |
/* Using random mac addresses for VFs */
|
|
|
a6040a |
eth_random_addr(&hw->mac_addr[0]);
|
|
|
a6040a |
nfp_net_write_mac(hw, (uint8_t *)&hw->mac_addr);
|
|
|
a6040a |
@@ -2850,11 +2832,19 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
|
|
|
a6040a |
nfp_net_stats_reset(eth_dev);
|
|
|
a6040a |
|
|
|
a6040a |
return 0;
|
|
|
a6040a |
+
|
|
|
a6040a |
+dev_err_queues_map:
|
|
|
a6040a |
+ nfp_cpp_area_free(hw->hwqueues_area);
|
|
|
a6040a |
+dev_err_ctrl_map:
|
|
|
a6040a |
+ nfp_cpp_area_free(hw->ctrl_area);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ return err;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
static int
|
|
|
a6040a |
nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports,
|
|
|
a6040a |
- nfpu_desc_t *nfpu_desc, void **priv)
|
|
|
a6040a |
+ struct nfp_cpp *cpp, struct nfp_hwinfo *hwinfo,
|
|
|
a6040a |
+ int phys_port, struct nfp_rtsym_table *sym_tbl, void **priv)
|
|
|
a6040a |
{
|
|
|
a6040a |
struct rte_eth_dev *eth_dev;
|
|
|
a6040a |
struct nfp_net_hw *hw;
|
|
|
a6040a |
@@ -2892,12 +2882,16 @@ nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports,
|
|
|
a6040a |
* Then dev_private is adjusted per port.
|
|
|
a6040a |
*/
|
|
|
a6040a |
hw = (struct nfp_net_hw *)(eth_dev->data->dev_private) + port;
|
|
|
a6040a |
- hw->nspu_desc = nfpu_desc->nspu;
|
|
|
a6040a |
- hw->nfpu_desc = nfpu_desc;
|
|
|
a6040a |
+ hw->cpp = cpp;
|
|
|
a6040a |
+ hw->hwinfo = hwinfo;
|
|
|
a6040a |
+ hw->sym_tbl = sym_tbl;
|
|
|
a6040a |
+ hw->pf_port_idx = phys_port;
|
|
|
a6040a |
hw->is_pf = 1;
|
|
|
a6040a |
if (ports > 1)
|
|
|
a6040a |
hw->pf_multiport_enabled = 1;
|
|
|
a6040a |
|
|
|
a6040a |
+ hw->total_ports = ports;
|
|
|
a6040a |
+
|
|
|
a6040a |
eth_dev->device = &dev->device;
|
|
|
a6040a |
rte_eth_copy_pci_info(eth_dev, dev);
|
|
|
a6040a |
|
|
|
a6040a |
@@ -2911,55 +2905,191 @@ nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports,
|
|
|
a6040a |
return ret;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
+#define DEFAULT_FW_PATH "/lib/firmware/netronome"
|
|
|
a6040a |
+
|
|
|
a6040a |
+static int
|
|
|
a6040a |
+nfp_fw_upload(struct rte_pci_device *dev, struct nfp_nsp *nsp, char *card)
|
|
|
a6040a |
+{
|
|
|
a6040a |
+ struct nfp_cpp *cpp = nsp->cpp;
|
|
|
a6040a |
+ int fw_f;
|
|
|
a6040a |
+ char *fw_buf;
|
|
|
a6040a |
+ char fw_name[100];
|
|
|
a6040a |
+ char serial[100];
|
|
|
a6040a |
+ struct stat file_stat;
|
|
|
a6040a |
+ off_t fsize, bytes;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ /* Looking for firmware file in order of priority */
|
|
|
a6040a |
+
|
|
|
a6040a |
+ /* First try to find a firmware image specific for this device */
|
|
|
a6040a |
+ sprintf(serial, "serial-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
|
|
|
a6040a |
+ cpp->serial[0], cpp->serial[1], cpp->serial[2], cpp->serial[3],
|
|
|
a6040a |
+ cpp->serial[4], cpp->serial[5], cpp->interface >> 8,
|
|
|
a6040a |
+ cpp->interface & 0xff);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ sprintf(fw_name, "%s/%s.nffw", DEFAULT_FW_PATH, serial);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ RTE_LOG(DEBUG, PMD, "Trying with fw file: %s\n", fw_name);
|
|
|
a6040a |
+ fw_f = open(fw_name, O_RDONLY);
|
|
|
a6040a |
+ if (fw_f > 0)
|
|
|
a6040a |
+ goto read_fw;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ /* Then try the PCI name */
|
|
|
a6040a |
+ sprintf(fw_name, "%s/pci-%s.nffw", DEFAULT_FW_PATH, dev->device.name);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ RTE_LOG(DEBUG, PMD, "Trying with fw file: %s\n", fw_name);
|
|
|
a6040a |
+ fw_f = open(fw_name, O_RDONLY);
|
|
|
a6040a |
+ if (fw_f > 0)
|
|
|
a6040a |
+ goto read_fw;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ /* Finally try the card type and media */
|
|
|
a6040a |
+ sprintf(fw_name, "%s/%s", DEFAULT_FW_PATH, card);
|
|
|
a6040a |
+ RTE_LOG(DEBUG, PMD, "Trying with fw file: %s\n", fw_name);
|
|
|
a6040a |
+ fw_f = open(fw_name, O_RDONLY);
|
|
|
a6040a |
+ if (fw_f < 0) {
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "Firmware file %s not found.", fw_name);
|
|
|
a6040a |
+ return -ENOENT;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+
|
|
|
a6040a |
+read_fw:
|
|
|
a6040a |
+ if (fstat(fw_f, &file_stat) < 0) {
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "Firmware file %s size is unknown", fw_name);
|
|
|
a6040a |
+ close(fw_f);
|
|
|
a6040a |
+ return -ENOENT;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+
|
|
|
a6040a |
+ fsize = file_stat.st_size;
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "Firmware file found at %s with size: %" PRIu64 "\n",
|
|
|
a6040a |
+ fw_name, (uint64_t)fsize);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ fw_buf = malloc((size_t)fsize);
|
|
|
a6040a |
+ if (!fw_buf) {
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "malloc failed for fw buffer");
|
|
|
a6040a |
+ close(fw_f);
|
|
|
a6040a |
+ return -ENOMEM;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+ memset(fw_buf, 0, fsize);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ bytes = read(fw_f, fw_buf, fsize);
|
|
|
a6040a |
+ if (bytes != fsize) {
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "Reading fw to buffer failed.\n"
|
|
|
a6040a |
+ "Just %" PRIu64 " of %" PRIu64 " bytes read",
|
|
|
a6040a |
+ (uint64_t)bytes, (uint64_t)fsize);
|
|
|
a6040a |
+ free(fw_buf);
|
|
|
a6040a |
+ close(fw_f);
|
|
|
a6040a |
+ return -EIO;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "Uploading the firmware ...");
|
|
|
a6040a |
+ nfp_nsp_load_fw(nsp, fw_buf, bytes);
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "Done");
|
|
|
a6040a |
+
|
|
|
a6040a |
+ free(fw_buf);
|
|
|
a6040a |
+ close(fw_f);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ return 0;
|
|
|
a6040a |
+}
|
|
|
a6040a |
+
|
|
|
a6040a |
+static int
|
|
|
a6040a |
+nfp_fw_setup(struct rte_pci_device *dev, struct nfp_cpp *cpp,
|
|
|
a6040a |
+ struct nfp_eth_table *nfp_eth_table, struct nfp_hwinfo *hwinfo)
|
|
|
a6040a |
+{
|
|
|
a6040a |
+ struct nfp_nsp *nsp;
|
|
|
a6040a |
+ const char *nfp_fw_model;
|
|
|
a6040a |
+ char card_desc[100];
|
|
|
a6040a |
+ int err = 0;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ nfp_fw_model = nfp_hwinfo_lookup(hwinfo, "assembly.partno");
|
|
|
a6040a |
+
|
|
|
a6040a |
+ if (nfp_fw_model) {
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "firmware model found: %s\n", nfp_fw_model);
|
|
|
a6040a |
+ } else {
|
|
|
a6040a |
+ RTE_LOG(ERR, PMD, "firmware model NOT found\n");
|
|
|
a6040a |
+ return -EIO;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+
|
|
|
a6040a |
+ if (nfp_eth_table->count == 0 || nfp_eth_table->count > 8) {
|
|
|
a6040a |
+ RTE_LOG(ERR, PMD, "NFP ethernet table reports wrong ports: %u\n",
|
|
|
a6040a |
+ nfp_eth_table->count);
|
|
|
a6040a |
+ return -EIO;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "NFP ethernet port table reports %u ports\n",
|
|
|
a6040a |
+ nfp_eth_table->count);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "Port speed: %u\n", nfp_eth_table->ports[0].speed);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ sprintf(card_desc, "nic_%s_%dx%d.nffw", nfp_fw_model,
|
|
|
a6040a |
+ nfp_eth_table->count, nfp_eth_table->ports[0].speed / 1000);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ nsp = nfp_nsp_open(cpp);
|
|
|
a6040a |
+ if (!nsp) {
|
|
|
a6040a |
+ RTE_LOG(ERR, PMD, "NFP error when obtaining NSP handle\n");
|
|
|
a6040a |
+ return -EIO;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+
|
|
|
a6040a |
+ nfp_nsp_device_soft_reset(nsp);
|
|
|
a6040a |
+ err = nfp_fw_upload(dev, nsp, card_desc);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ nfp_nsp_close(nsp);
|
|
|
a6040a |
+ return err;
|
|
|
a6040a |
+}
|
|
|
a6040a |
+
|
|
|
a6040a |
static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
|
|
|
a6040a |
struct rte_pci_device *dev)
|
|
|
a6040a |
{
|
|
|
a6040a |
- nfpu_desc_t *nfpu_desc;
|
|
|
a6040a |
- nspu_desc_t *nspu_desc;
|
|
|
a6040a |
- uint64_t offset_symbol;
|
|
|
a6040a |
- uint8_t *bar_offset;
|
|
|
a6040a |
- int major, minor;
|
|
|
a6040a |
+ struct nfp_cpp *cpp;
|
|
|
a6040a |
+ struct nfp_hwinfo *hwinfo;
|
|
|
a6040a |
+ struct nfp_rtsym_table *sym_tbl;
|
|
|
a6040a |
+ struct nfp_eth_table *nfp_eth_table = NULL;
|
|
|
a6040a |
int total_ports;
|
|
|
a6040a |
void *priv = 0;
|
|
|
a6040a |
int ret = -ENODEV;
|
|
|
a6040a |
+ int err;
|
|
|
a6040a |
int i;
|
|
|
a6040a |
|
|
|
a6040a |
if (!dev)
|
|
|
a6040a |
return ret;
|
|
|
a6040a |
|
|
|
a6040a |
- nfpu_desc = rte_malloc("nfp nfpu", sizeof(nfpu_desc_t), 0);
|
|
|
a6040a |
- if (!nfpu_desc)
|
|
|
a6040a |
- return -ENOMEM;
|
|
|
a6040a |
-
|
|
|
a6040a |
- if (nfpu_open(dev, nfpu_desc, 0) < 0) {
|
|
|
a6040a |
- RTE_LOG(ERR, PMD,
|
|
|
a6040a |
- "nfpu_open failed\n");
|
|
|
a6040a |
- goto nfpu_error;
|
|
|
a6040a |
+ cpp = nfp_cpp_from_device_name(dev->device.name);
|
|
|
a6040a |
+ if (!cpp) {
|
|
|
a6040a |
+ RTE_LOG(ERR, PMD, "A CPP handle can not be obtained");
|
|
|
a6040a |
+ ret = -EIO;
|
|
|
a6040a |
+ goto error;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
- nspu_desc = nfpu_desc->nspu;
|
|
|
a6040a |
+ hwinfo = nfp_hwinfo_read(cpp);
|
|
|
a6040a |
+ if (!hwinfo) {
|
|
|
a6040a |
+ RTE_LOG(ERR, PMD, "Error reading hwinfo table");
|
|
|
a6040a |
+ return -EIO;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
|
|
|
a6040a |
+ nfp_eth_table = nfp_eth_read_ports(cpp);
|
|
|
a6040a |
+ if (!nfp_eth_table) {
|
|
|
a6040a |
+ RTE_LOG(ERR, PMD, "Error reading NFP ethernet table\n");
|
|
|
a6040a |
+ return -EIO;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
|
|
|
a6040a |
- /* Check NSP ABI version */
|
|
|
a6040a |
- if (nfp_nsp_get_abi_version(nspu_desc, &major, &minor) < 0) {
|
|
|
a6040a |
- RTE_LOG(INFO, PMD, "NFP NSP not present\n");
|
|
|
a6040a |
+ if (nfp_fw_setup(dev, cpp, nfp_eth_table, hwinfo)) {
|
|
|
a6040a |
+ RTE_LOG(INFO, PMD, "Error when uploading firmware\n");
|
|
|
a6040a |
+ ret = -EIO;
|
|
|
a6040a |
goto error;
|
|
|
a6040a |
}
|
|
|
a6040a |
- PMD_INIT_LOG(INFO, "nspu ABI version: %d.%d\n", major, minor);
|
|
|
a6040a |
|
|
|
a6040a |
- if ((major == 0) && (minor < 20)) {
|
|
|
a6040a |
- RTE_LOG(INFO, PMD, "NFP NSP ABI version too old. Required 0.20 or higher\n");
|
|
|
a6040a |
+ /* Now the symbol table should be there */
|
|
|
a6040a |
+ sym_tbl = nfp_rtsym_table_read(cpp);
|
|
|
a6040a |
+ if (!sym_tbl) {
|
|
|
a6040a |
+ RTE_LOG(ERR, PMD, "Something is wrong with the firmware"
|
|
|
a6040a |
+ " symbol table");
|
|
|
a6040a |
+ ret = -EIO;
|
|
|
a6040a |
goto error;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
- ret = nfp_nsp_fw_setup(nspu_desc, "nfd_cfg_pf0_num_ports",
|
|
|
a6040a |
- &offset_symbol);
|
|
|
a6040a |
- if (ret)
|
|
|
a6040a |
+ total_ports = nfp_rtsym_read_le(sym_tbl, "nfd_cfg_pf0_num_ports", &err;;
|
|
|
a6040a |
+ if (total_ports != (int)nfp_eth_table->count) {
|
|
|
a6040a |
+ RTE_LOG(ERR, PMD, "Inconsistent number of ports\n");
|
|
|
a6040a |
+ ret = -EIO;
|
|
|
a6040a |
goto error;
|
|
|
a6040a |
-
|
|
|
a6040a |
- bar_offset = (uint8_t *)dev->mem_resource[0].addr;
|
|
|
a6040a |
- bar_offset += offset_symbol;
|
|
|
a6040a |
- total_ports = (uint32_t)*bar_offset;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
PMD_INIT_LOG(INFO, "Total pf ports: %d\n", total_ports);
|
|
|
a6040a |
|
|
|
a6040a |
if (total_ports <= 0 || total_ports > 8) {
|
|
|
a6040a |
@@ -2969,18 +3099,15 @@ static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
for (i = 0; i < total_ports; i++) {
|
|
|
a6040a |
- ret = nfp_pf_create_dev(dev, i, total_ports, nfpu_desc, &priv;;
|
|
|
a6040a |
+ ret = nfp_pf_create_dev(dev, i, total_ports, cpp, hwinfo,
|
|
|
a6040a |
+ nfp_eth_table->ports[i].index,
|
|
|
a6040a |
+ sym_tbl, &priv;;
|
|
|
a6040a |
if (ret)
|
|
|
a6040a |
- goto error;
|
|
|
a6040a |
+ break;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
- return 0;
|
|
|
a6040a |
-
|
|
|
a6040a |
error:
|
|
|
a6040a |
- nfpu_close(nfpu_desc);
|
|
|
a6040a |
-nfpu_error:
|
|
|
a6040a |
- rte_free(nfpu_desc);
|
|
|
a6040a |
-
|
|
|
a6040a |
+ free(nfp_eth_table);
|
|
|
a6040a |
return ret;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
@@ -3025,8 +3152,19 @@ static int eth_nfp_pci_remove(struct rte_pci_device *pci_dev)
|
|
|
a6040a |
if ((pci_dev->id.device_id == PCI_DEVICE_ID_NFP4000_PF_NIC) ||
|
|
|
a6040a |
(pci_dev->id.device_id == PCI_DEVICE_ID_NFP6000_PF_NIC)) {
|
|
|
a6040a |
port = get_pf_port_number(eth_dev->data->name);
|
|
|
a6040a |
+ /*
|
|
|
a6040a |
+ * hotplug is not possible with multiport PF although freeing
|
|
|
a6040a |
+ * data structures can be done for first port.
|
|
|
a6040a |
+ */
|
|
|
a6040a |
+ if (port != 0)
|
|
|
a6040a |
+ return -ENOTSUP;
|
|
|
a6040a |
hwport0 = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
|
|
|
a6040a |
hw = &hwport0[port];
|
|
|
a6040a |
+ nfp_cpp_area_free(hw->ctrl_area);
|
|
|
a6040a |
+ nfp_cpp_area_free(hw->hwqueues_area);
|
|
|
a6040a |
+ free(hw->hwinfo);
|
|
|
a6040a |
+ free(hw->sym_tbl);
|
|
|
a6040a |
+ nfp_cpp_free(hw->cpp);
|
|
|
a6040a |
} else {
|
|
|
a6040a |
hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
|
|
|
a6040a |
}
|
|
|
a6040a |
diff --git a/drivers/net/nfp/nfp_net_pmd.h b/drivers/net/nfp/nfp_net_pmd.h
|
|
|
a6040a |
index 1ae0ea626..097c871b5 100644
|
|
|
a6040a |
--- a/drivers/net/nfp/nfp_net_pmd.h
|
|
|
a6040a |
+++ b/drivers/net/nfp/nfp_net_pmd.h
|
|
|
a6040a |
@@ -1,5 +1,5 @@
|
|
|
a6040a |
/*
|
|
|
a6040a |
- * Copyright (c) 2014, 2015 Netronome Systems, Inc.
|
|
|
a6040a |
+ * Copyright (c) 2014-2018 Netronome Systems, Inc.
|
|
|
a6040a |
* All rights reserved.
|
|
|
a6040a |
*
|
|
|
a6040a |
* Redistribution and use in source and binary forms, with or without
|
|
|
a6040a |
@@ -63,6 +63,7 @@ struct nfp_net_adapter;
|
|
|
a6040a |
#define NFP_NET_CRTL_BAR 0
|
|
|
a6040a |
#define NFP_NET_TX_BAR 2
|
|
|
a6040a |
#define NFP_NET_RX_BAR 2
|
|
|
a6040a |
+#define NFP_QCP_QUEUE_AREA_SZ 0x80000
|
|
|
a6040a |
|
|
|
a6040a |
/* Macros for accessing the Queue Controller Peripheral 'CSRs' */
|
|
|
a6040a |
#define NFP_QCP_QUEUE_OFF(_x) ((_x) * 0x800)
|
|
|
a6040a |
@@ -430,20 +431,21 @@ struct nfp_net_hw {
|
|
|
a6040a |
/* Records starting point for counters */
|
|
|
a6040a |
struct rte_eth_stats eth_stats_base;
|
|
|
a6040a |
|
|
|
a6040a |
-#ifdef NFP_NET_LIBNFP
|
|
|
a6040a |
struct nfp_cpp *cpp;
|
|
|
a6040a |
struct nfp_cpp_area *ctrl_area;
|
|
|
a6040a |
- struct nfp_cpp_area *tx_area;
|
|
|
a6040a |
- struct nfp_cpp_area *rx_area;
|
|
|
a6040a |
+ struct nfp_cpp_area *hwqueues_area;
|
|
|
a6040a |
struct nfp_cpp_area *msix_area;
|
|
|
a6040a |
-#endif
|
|
|
a6040a |
+
|
|
|
a6040a |
uint8_t *hw_queues;
|
|
|
a6040a |
uint8_t is_pf;
|
|
|
a6040a |
uint8_t pf_port_idx;
|
|
|
a6040a |
uint8_t pf_multiport_enabled;
|
|
|
a6040a |
+ uint8_t total_ports;
|
|
|
a6040a |
+
|
|
|
a6040a |
union eth_table_entry *eth_table;
|
|
|
a6040a |
- nspu_desc_t *nspu_desc;
|
|
|
a6040a |
- nfpu_desc_t *nfpu_desc;
|
|
|
a6040a |
+
|
|
|
a6040a |
+ struct nfp_hwinfo *hwinfo;
|
|
|
a6040a |
+ struct nfp_rtsym_table *sym_tbl;
|
|
|
a6040a |
};
|
|
|
a6040a |
|
|
|
a6040a |
struct nfp_net_adapter {
|
|
|
a6040a |
--
|
|
|
a6040a |
2.14.3
|
|
|
a6040a |
|