different firmware to each SmartNIC.
.. Note::
- Currently the NFP PMD supports using the PF with Agilio Basic Firmware. See
- https://help.netronome.com/support/solutions for more information on the
- various firmwares supported by the Netronome Agilio CX smartNIC.
+ Currently the NFP PMD supports using the PF with Agilio Firmware with NFD3
+ and Agilio Firmware with NFDk. See https://help.netronome.com/support/solutions
+ for more information on the various firmwares supported by the Netronome
+ Agilio CX smartNIC.
PF multiport support
--------------------
* **Updated Netronome nfp driver.**
* Added support for NFP3800 NIC.
+ * Added support for firmware with NFDk.
* **Updated VMware vmxnet3 networking driver.**
* - define more STS bits
*/
#define NFP_NET_CFG_VERSION 0x0030
+#define NFP_NET_CFG_VERSION_DP_NFD3 0
+#define NFP_NET_CFG_VERSION_DP_NFDK 1
#define NFP_NET_CFG_VERSION_RESERVED_MASK (0xff << 24)
#define NFP_NET_CFG_VERSION_CLASS_MASK (0xff << 16)
#define NFP_NET_CFG_VERSION_CLASS(x) (((x) & 0xff) << 16)
.rx_queue_intr_disable = nfp_rx_queue_intr_disable,
};
+static inline int
+nfp_net_ethdev_ops_mount(struct nfp_net_hw *hw, struct rte_eth_dev *eth_dev)
+{
+ switch (NFD_CFG_CLASS_VER_of(hw->ver)) {
+ case NFP_NET_CFG_VERSION_DP_NFD3:
+ break;
+ case NFP_NET_CFG_VERSION_DP_NFDK:
+ if (NFD_CFG_MAJOR_VERSION_of(hw->ver) < 5) {
+ PMD_DRV_LOG(ERR, "NFDK must use ABI 5 or newer, found: %d",
+ NFD_CFG_MAJOR_VERSION_of(hw->ver));
+ return -EINVAL;
+ }
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "The version of firmware is not correct.");
+ return -EINVAL;
+ }
+
+ eth_dev->dev_ops = &nfp_net_nfd3_eth_dev_ops;
+ eth_dev->rx_queue_count = nfp_net_rx_queue_count;
+ eth_dev->rx_pkt_burst = &nfp_net_recv_pkts;
+ eth_dev->tx_pkt_burst = &nfp_net_nfd3_xmit_pkts;
+
+ return 0;
+}
+
static int
nfp_net_init(struct rte_eth_dev *eth_dev)
{
PMD_INIT_LOG(DEBUG, "Working with physical port number: %d, "
"NFP internal port number: %d", port, hw->nfp_idx);
- eth_dev->dev_ops = &nfp_net_nfd3_eth_dev_ops;
- eth_dev->rx_queue_count = nfp_net_rx_queue_count;
- eth_dev->rx_pkt_burst = &nfp_net_recv_pkts;
- eth_dev->tx_pkt_burst = &nfp_net_nfd3_xmit_pkts;
-
/* For secondary processes, the primary has done all the work */
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
PMD_INIT_LOG(DEBUG, "ctrl bar: %p", hw->ctrl_bar);
+ hw->ver = nn_cfg_readl(hw, NFP_NET_CFG_VERSION);
+
+ if (nfp_net_ethdev_ops_mount(hw, eth_dev))
+ return -EINVAL;
+
hw->max_rx_queues = nn_cfg_readl(hw, NFP_NET_CFG_MAX_RXRINGS);
hw->max_tx_queues = nn_cfg_readl(hw, NFP_NET_CFG_MAX_TXRINGS);
nfp_net_cfg_queue_setup(hw);
/* Get some of the read-only fields from the config BAR */
- hw->ver = nn_cfg_readl(hw, NFP_NET_CFG_VERSION);
hw->cap = nn_cfg_readl(hw, NFP_NET_CFG_CAP);
hw->max_mtu = nn_cfg_readl(hw, NFP_NET_CFG_MAX_MTU);
hw->mtu = RTE_ETHER_MTU;
int err;
int total_ports;
struct nfp_cpp *cpp;
+ struct nfp_net_hw *hw;
struct nfp_rtsym_table *sym_tbl;
if (pci_dev == NULL)
"secondary process attach failed, ethdev doesn't exist");
return -ENODEV;
}
+
+ hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+
+ if (nfp_net_ethdev_ops_mount(hw, eth_dev))
+ return -EINVAL;
+
eth_dev->process_private = cpp;
- eth_dev->dev_ops = &nfp_net_nfd3_eth_dev_ops;
- eth_dev->rx_queue_count = nfp_net_rx_queue_count;
- eth_dev->rx_pkt_burst = &nfp_net_recv_pkts;
- eth_dev->tx_pkt_burst = &nfp_net_nfd3_xmit_pkts;
+
rte_eth_dev_probing_finish(eth_dev);
}
.rx_queue_intr_disable = nfp_rx_queue_intr_disable,
};
+static inline int
+nfp_netvf_ethdev_ops_mount(struct nfp_net_hw *hw, struct rte_eth_dev *eth_dev)
+{
+ switch (NFD_CFG_CLASS_VER_of(hw->ver)) {
+ case NFP_NET_CFG_VERSION_DP_NFD3:
+ break;
+ case NFP_NET_CFG_VERSION_DP_NFDK:
+ if (NFD_CFG_MAJOR_VERSION_of(hw->ver) < 5) {
+ PMD_DRV_LOG(ERR, "NFDK must use ABI 5 or newer, found: %d",
+ NFD_CFG_MAJOR_VERSION_of(hw->ver));
+ return -EINVAL;
+ }
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "The version of firmware is not correct.");
+ return -EINVAL;
+ }
+
+ eth_dev->dev_ops = &nfp_netvf_nfd3_eth_dev_ops;
+ eth_dev->rx_queue_count = nfp_net_rx_queue_count;
+ eth_dev->rx_pkt_burst = &nfp_net_recv_pkts;
+ eth_dev->tx_pkt_burst = &nfp_net_nfd3_xmit_pkts;
+
+ return 0;
+}
+
static int
nfp_netvf_init(struct rte_eth_dev *eth_dev)
{
hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
- eth_dev->dev_ops = &nfp_netvf_nfd3_eth_dev_ops;
- eth_dev->rx_queue_count = nfp_net_rx_queue_count;
- eth_dev->rx_pkt_burst = &nfp_net_recv_pkts;
- eth_dev->tx_pkt_burst = &nfp_net_nfd3_xmit_pkts;
+ hw->ctrl_bar = (uint8_t *)pci_dev->mem_resource[0].addr;
+ if (hw->ctrl_bar == NULL) {
+ PMD_DRV_LOG(ERR,
+ "hw->ctrl_bar is NULL. BAR0 not configured");
+ return -ENODEV;
+ }
+
+ PMD_INIT_LOG(DEBUG, "ctrl bar: %p", hw->ctrl_bar);
+
+ hw->ver = nn_cfg_readl(hw, NFP_NET_CFG_VERSION);
+
+ if (nfp_netvf_ethdev_ops_mount(hw, eth_dev))
+ return -EINVAL;
/* For secondary processes, the primary has done all the work */
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
pci_dev->addr.domain, pci_dev->addr.bus,
pci_dev->addr.devid, pci_dev->addr.function);
- hw->ctrl_bar = (uint8_t *)pci_dev->mem_resource[0].addr;
- if (hw->ctrl_bar == NULL) {
- PMD_DRV_LOG(ERR,
- "hw->ctrl_bar is NULL. BAR0 not configured");
- return -ENODEV;
- }
-
- PMD_INIT_LOG(DEBUG, "ctrl bar: %p", hw->ctrl_bar);
-
hw->max_rx_queues = nn_cfg_readl(hw, NFP_NET_CFG_MAX_RXRINGS);
hw->max_tx_queues = nn_cfg_readl(hw, NFP_NET_CFG_MAX_TXRINGS);
nfp_net_cfg_queue_setup(hw);
/* Get some of the read-only fields from the config BAR */
- hw->ver = nn_cfg_readl(hw, NFP_NET_CFG_VERSION);
hw->cap = nn_cfg_readl(hw, NFP_NET_CFG_CAP);
hw->max_mtu = nn_cfg_readl(hw, NFP_NET_CFG_MAX_MTU);
hw->mtu = RTE_ETHER_MTU;