preparation for the rte_flow offload of nfp PMD
Subsystems (2)
v9 cover preparation for the rte_flow offload of nfp PMD
* Changes since v8
- Update the nfp.rst
- Fix the 'app_hw' to 'app_fw'
- Remove the ovs compatible header file
- Remove the use of rte_eth_dev_configure()/rte_eth_rx_burst()/rte_eth_dev_start() API
* Changes since v7
- Adjust the logics to make sure not break the pci probe process
- Change 'app' to 'app_fw' in all logics to avoid confuse
- Fix problem about log level
* Changes since v6
- Fix the compile error
* Changes since v5
- Compare integer with 0 explicitly
- Change helper macro to function
- Implement the dummy functions
- Remove some unnecessary logics
* Changes since v4
- Remove the unneeded '__rte_unused' attribute
- Fixup a potential memory leak problem
* Changes since v3
- Add the 'Depends-on' tag
* Changes since v2
- Remove the use of rte_panic()
* Changes since v1
- Fix the compile error
Depends-on: series-23707 ("Add support of NFP3800 chip and firmware with NFDk")
Chaoyong He (12):
net/nfp: move app specific attributes to own struct net/nfp: simplify initialization and remove dead code net/nfp: move app specific init logic to own function net/nfp: add initial flower firmware support net/nfp: add flower PF setup logic
net/nfp: add flower PF related routines net/nfp: add flower ctrl VNIC related logics net/nfp: move common rxtx function for flower use net/nfp: add flower ctrl VNIC rxtx logic net/nfp: add flower representor framework net/nfp: move rxtx function to header file net/nfp: add flower PF rxtx logic
doc/guides/nics/nfp.rst | 32 + doc/guides/rel_notes/release_22_11.rst | 9 + drivers/net/nfp/flower/nfp_flower.c | 1310 +++++++++++++++++++++++ drivers/net/nfp/flower/nfp_flower.h | 70 ++ drivers/net/nfp/flower/nfp_flower_cmsg.c | 185 ++++ drivers/net/nfp/flower/nfp_flower_cmsg.h | 173 +++ drivers/net/nfp/flower/nfp_flower_ctrl.c | 250 +++++ drivers/net/nfp/flower/nfp_flower_ctrl.h | 13 + drivers/net/nfp/flower/nfp_flower_representor.c | 664 ++++++++++++ drivers/net/nfp/flower/nfp_flower_representor.h | 39 + drivers/net/nfp/meson.build | 4 + drivers/net/nfp/nfp_common.c | 2 +- drivers/net/nfp/nfp_common.h | 35 +- drivers/net/nfp/nfp_cpp_bridge.c | 88 +- drivers/net/nfp/nfp_cpp_bridge.h | 6 +- drivers/net/nfp/nfp_ethdev.c | 347 +++--- drivers/net/nfp/nfp_ethdev_vf.c | 2 +- drivers/net/nfp/nfp_rxtx.c | 123 +-- drivers/net/nfp/nfp_rxtx.h | 121 +++ drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c | 31 +- 20 files changed, 3222 insertions(+), 282 deletions(-) create mode 100644 drivers/net/nfp/flower/nfp_flower.c create mode 100644 drivers/net/nfp/flower/nfp_flower.h create mode 100644 drivers/net/nfp/flower/nfp_flower_cmsg.c create mode 100644 drivers/net/nfp/flower/nfp_flower_cmsg.h create mode 100644 drivers/net/nfp/flower/nfp_flower_ctrl.c create mode 100644 drivers/net/nfp/flower/nfp_flower_ctrl.h create mode 100644 drivers/net/nfp/flower/nfp_flower_representor.c create mode 100644 drivers/net/nfp/flower/nfp_flower_representor.h
Signature · 1 line
1.8.3.1
PATCH v9 1/12 net/nfp: move app specific attributes to own struct
The NFP card can load different application firmwares. Currently only the CoreNIC application firmware is supported. This commit makes needed infrastructure changes in order to support other application firmwares too.
Clearer separation is made between the PF device and any application firmware specific concepts. The PF struct is now generic regardless of the application firmware loaded. A new struct is also made for the CoreNIC application firmware. Future additions to support other application firmwares should also add an application firmware specific struct.
--- drivers/net/nfp/nfp_common.h | 30 ++++++- drivers/net/nfp/nfp_ethdev.c | 194 +++++++++++++++++++++++++++---------------- 2 files changed, 149 insertions(+), 75 deletions(-)
drivers/net/nfp/nfp_common.h +26 -4
@@ -111,6 +111,11 @@#include <linux/types.h> #include <rte_io.h> +/* Firmware application ID's */ +enum nfp_app_fw_id { +NFP_APP_FW_CORE_NIC =0x1 , +}; +/* nfp_qcp_ptr - Read or Write Pointer of a queue */ enum nfp_qcp_ptr {NFP_QCP_READ_PTR =0 ,
@@ -121,8 +126,10 @@ struct nfp_pf_dev {/* Backpointer to associated pci device */ struct rte_pci_device *pci_dev; -/* Array of physical ports belonging to this PF */ -struct nfp_net_hw *ports[NFP_MAX_PHYPORTS ]; +enum nfp_app_fw_id app_fw_id; + +/* Pointer to the app running on the PF */ +void *app_fw_priv;/* Current values for control */ uint32_t ctrl;
@@ -151,8 +158,6 @@ struct nfp_pf_dev {struct nfp_cpp_area *msix_area;uint8_t *hw_queues; -uint8_t total_phyports; -bool multiport;union eth_table_entry *eth_table;
@@ -161,6 +166,20 @@ struct nfp_pf_dev {uint32_t nfp_cpp_service_id; }; +struct nfp_app_fw_nic { +/* Backpointer to the PF device */ +struct nfp_pf_dev *pf_dev; + +/* +* Array of physical ports belonging to the this CoreNIC app +* This is really a list of vNIC's. One for each physical port +*/ +struct nfp_net_hw *ports[NFP_MAX_PHYPORTS ]; + +bool multiport; +uint8_t total_phyports; +}; +struct nfp_net_hw {/* Backpointer to the PF this port belongs to */ struct nfp_pf_dev *pf_dev;
@@ -424,6 +443,9 @@ int nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev,#define NFP_NET_DEV_PRIVATE_TO_PF (dev_priv)\ (((struct nfp_net_hw *)dev_priv)->pf_dev) +#define NFP_PRIV_TO_APP_FW_NIC (app_fw_priv)\ + ((struct nfp_app_fw_nic *)app_fw_priv) +#endif /* _NFP_COMMON_H_ */ /* * Local variables:
drivers/net/nfp/nfp_ethdev.c +123 -71
398 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v9 2/12 net/nfp: simplify initialization and remove dead code
In reply to Chaoyong HeCalling nfp_net_init() is only done for the corenic firmware flavor and it is guaranteed to always be called from the primary process, so the explicit check for RTE_PROC_PRIMARY can be dropped.
The calling graph of nfp_net_init() already guaranteed the free of resources when it fail, so remove the necessary free logics inside it.
While at it remove the unused member is_phyport from struct nfp_net_hw.
--- drivers/net/nfp/nfp_common.h | 1 - drivers/net/nfp/nfp_ethdev.c | 40 +++++++++++----------------------------- 2 files changed, 11 insertions(+), 30 deletions(-)
drivers/net/nfp/nfp_common.h +0 -1
@@ -235,7 +235,6 @@ struct nfp_net_hw {uint8_t idx;/* Internal port number as seen from NFP */ uint8_t nfp_idx; -bool is_phyport;union eth_table_entry *eth_table;
drivers/net/nfp/nfp_ethdev.c +11 -29
@@ -417,7 +417,6 @@uint32_t start_q;int stride =4 ;int port =0 ; -int err;PMD_INIT_FUNC_TRACE ();
@@ -452,10 +451,6 @@PMD_INIT_LOG (DEBUG ,"Working with physical port number: %d, " "NFP internal port number: %d" , port, hw->nfp_idx); -/* For secondary processes, the primary has done all the work */ -if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) -return 0 ; -rte_eth_copy_pci_info (eth_dev, pci_dev); hw->device_id = pci_dev->id.device_id;
@@ -506,8 +501,7 @@break ;default :PMD_DRV_LOG (ERR ,"nfp_net: no device ID matching" ); - err = -ENODEV ; - goto dev_err_ctrl_map; +return -ENODEV ; }PMD_INIT_LOG (DEBUG ,"tx_bar_off: 0x%" PRIx64"" , tx_bar_off);
@@ -573,8 +567,7 @@ RTE_ETHER_ADDR_LEN, 0);if (eth_dev->data->mac_addrs ==NULL ) {PMD_INIT_LOG (ERR ,"Failed to space for MAC address" ); - err = -ENOMEM ; - goto dev_err_queues_map; +return -ENOMEM ; }nfp_net_pf_read_mac (app_fw_nic, port);
@@ -604,24 +597,15 @@ hw->mac_addr[0 ], hw->mac_addr[1 ], hw->mac_addr[2 ], hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]); -if (rte_eal_process_type () ==RTE_PROC_PRIMARY ) { -/* Registering LSC interrupt handler */ -rte_intr_callback_register (pci_dev->intr_handle, - nfp_net_dev_interrupt_handler, (void *)eth_dev); -/* Telling the firmware about the LSC interrupt entry */ -nn_cfg_writeb (hw,NFP_NET_CFG_LSC ,NFP_NET_IRQ_LSC_IDX ); -/* Recording current stats counters values */ -nfp_net_stats_reset (eth_dev); - } +/* Registering LSC interrupt handler */ +rte_intr_callback_register (pci_dev->intr_handle, + nfp_net_dev_interrupt_handler, (void *)eth_dev); +/* Telling the firmware about the LSC interrupt entry */ +nn_cfg_writeb (hw,NFP_NET_CFG_LSC ,NFP_NET_IRQ_LSC_IDX ); +/* Recording current stats counters values */ +nfp_net_stats_reset (eth_dev);return 0 ; - -dev_err_queues_map: -nfp_cpp_area_free (hw->hwqueues_area); -dev_err_ctrl_map: -nfp_cpp_area_free (hw->ctrl_area); - -return err; }#define DEFAULT_FW_PATH "/lib/firmware/netronome"
@@ -820,7 +804,6 @@ hw->eth_dev = eth_dev; hw->idx = i; hw->nfp_idx = nfp_eth_table->ports[i].index; - hw->is_phyport = true; eth_dev->device = &pf_dev->pci_dev->device;
@@ -886,8 +869,7 @@if (cpp ==NULL ) {PMD_INIT_LOG (ERR ,"A CPP handle can not be obtained" ); - ret = -EIO ; - goto error; +return -EIO ; } hwinfo =nfp_hwinfo_read (cpp);
@@ -1008,7 +990,7 @@free (hwinfo); cpp_cleanup:nfp_cpp_free (cpp); -error: +return ret; }
Signature · 1 line
1.8.3.1
PATCH v9 3/12 net/nfp: move app specific init logic to own function
In reply to Chaoyong HeThe NFP card can load different firmware applications. This commit move the init logic of corenic app of the secondary process into its own function.
--- drivers/net/nfp/nfp_ethdev.c | 90 +++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 30 deletions(-)
drivers/net/nfp/nfp_ethdev.c +60 -30
@@ -994,6 +994,49 @@return ret; } +static int +nfp_secondary_init_app_fw_nic (struct rte_pci_device *pci_dev, +struct nfp_rtsym_table *sym_tbl, +struct nfp_cpp *cpp) +{ +int i; +int err =0 ; +int ret =0 ; +int total_vnics; +struct nfp_net_hw *hw; + +/* Read the number of vNIC's created for the PF */ + total_vnics =nfp_rtsym_read_le (sym_tbl,"nfd_cfg_pf0_num_ports" , &err); +if (err !=0 || total_vnics <=0 || total_vnics >8 ) { +PMD_INIT_LOG (ERR ,"nfd_cfg_pf0_num_ports symbol with wrong value" ); +return -ENODEV ; + } + +for (i =0 ; i < total_vnics; i++) { +struct rte_eth_dev *eth_dev; +char port_name[RTE_ETH_NAME_MAX_LEN ]; +snprintf (port_name,sizeof (port_name),"%s_port%d" , + pci_dev->device.name, i); + +PMD_INIT_LOG (DEBUG ,"Secondary attaching to port %s" , port_name); + eth_dev =rte_eth_dev_attach_secondary (port_name); +if (eth_dev ==NULL ) { +PMD_INIT_LOG (ERR ,"Secondary process attach to port %s failed" , port_name); + ret = -ENODEV ; +break ; + } + + eth_dev->process_private = cpp; + hw =NFP_NET_DEV_PRIVATE_TO_HW (eth_dev->data->dev_private); +if (nfp_net_ethdev_ops_mount (hw, eth_dev)) +return -EINVAL ; + +rte_eth_dev_probing_finish (eth_dev); + } + +return ret; +} +/* * When attaching to the NFP4000/6000 PF on a secondary process there * is no need to initialise the PF again. Only minimal work is required
@@ -1002,12 +1045,10 @@static int nfp_pf_secondary_init (struct rte_pci_device *pci_dev) { -int i;int err =0 ;int ret =0 ; -int total_ports;struct nfp_cpp *cpp; -struct nfp_net_hw *hw; +enum nfp_app_fw_id app_fw_id;struct nfp_rtsym_table *sym_tbl;if (pci_dev ==NULL )
@@ -1041,37 +1082,26 @@return -EIO ; } - total_ports =nfp_rtsym_read_le (sym_tbl,"nfd_cfg_pf0_num_ports" , &err); -if (err !=0 || total_ports <=0 || total_ports >8 ) { -PMD_INIT_LOG (ERR ,"nfd_cfg_pf0_num_ports symbol with wrong value" ); - ret = -ENODEV ; +/* Read the app ID of the firmware loaded */ + app_fw_id =nfp_rtsym_read_le (sym_tbl,"_pf0_net_app_id" , &err); +if (err !=0 ) { +PMD_INIT_LOG (ERR ,"Couldn't read app_fw_id from fw" ); goto sym_tbl_cleanup; } -for (i =0 ; i < total_ports; i++) { -struct rte_eth_dev *eth_dev; -char port_name[RTE_ETH_NAME_MAX_LEN ]; - -snprintf (port_name,sizeof (port_name),"%s_port%d" , - pci_dev->device.name, i); - -PMD_DRV_LOG (DEBUG ,"Secondary attaching to port %s" , port_name); - eth_dev =rte_eth_dev_attach_secondary (port_name); -if (eth_dev ==NULL ) { -RTE_LOG (ERR ,EAL , -"secondary process attach failed, ethdev doesn't exist" ); - ret = -ENODEV ; -break ; +switch (app_fw_id) { +case NFP_APP_FW_CORE_NIC : +PMD_INIT_LOG (INFO ,"Initializing coreNIC" ); + ret =nfp_secondary_init_app_fw_nic (pci_dev, sym_tbl, cpp); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not initialize coreNIC!" ); + goto sym_tbl_cleanup; } - - 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; - -rte_eth_dev_probing_finish (eth_dev); +break ; +default : +PMD_INIT_LOG (ERR ,"Unsupported Firmware loaded" ); + ret = -EINVAL ; + goto sym_tbl_cleanup; }/* Register the CPP bridge service for the secondary too */
Signature · 1 line
1.8.3.1
PATCH v9 4/12 net/nfp: add initial flower firmware support
In reply to Chaoyong HeAdds the basic probing infrastructure to support the flower firmware application.
Adds the cpp service, used for some user tools.
--- doc/guides/nics/nfp.rst | 13 +++++ doc/guides/rel_notes/release_22_11.rst | 7 +++ drivers/net/nfp/flower/nfp_flower.c | 45 +++++++++++++++++ drivers/net/nfp/flower/nfp_flower.h | 16 +++++++ drivers/net/nfp/meson.build | 1 + drivers/net/nfp/nfp_common.h | 1 + drivers/net/nfp/nfp_cpp_bridge.c | 88 +++++++++++++++++++++++++++++----- drivers/net/nfp/nfp_cpp_bridge.h | 6 ++- drivers/net/nfp/nfp_ethdev.c | 31 +++++++++++- 9 files changed, 192 insertions(+), 16 deletions(-) create mode 100644 drivers/net/nfp/flower/nfp_flower.c create mode 100644 drivers/net/nfp/flower/nfp_flower.h
doc/guides/nics/nfp.rst +13 -0
@@ -181,3 +181,16 @@ System configuration -k option shows the device driver, if any, that devices are bound to. Depending on the modules loaded at this point the new PCI devices may be bound to nfp_netvf driver. + + +Flow offload +------------ + +Use the flower firmware application, some type of Netronome's SmartNICs can +offload the flow into cards. + +The flower firmware application requires the PMD running two services: + + * PF vNIC service: handling the feedback traffic. + * ctrl vNIC service: communicate between PMD and firmware through + control message.
doc/guides/rel_notes/release_22_11.rst +7 -0
@@ -55,6 +55,13 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Updated Netronome nfp driver.** + + Add the needed data structures and logics to support the offload of rte_flow: + + * Added the support of flower firmware. + * Added the flower service infrastructure. + Removed Items -------------
drivers/net/nfp/flower/nfp_flower.c new file +45 -0
45 lines not on this page · raw message
drivers/net/nfp/flower/nfp_flower.h new file +16 -0
@@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(c) 2022 Corigine, Inc. +* All rights reserved. +*/ + +#ifndef _NFP_FLOWER_H_ +#define _NFP_FLOWER_H_ + +/* The flower application's private structure */ +struct nfp_app_fw_flower { +}; + +int nfp_init_app_fw_flower (struct nfp_pf_dev *pf_dev); +int nfp_secondary_init_app_fw_flower (struct nfp_cpp *cpp); + +#endif /* _NFP_FLOWER_H_ */
drivers/net/nfp/meson.build +1 -0
@@ -6,6 +6,7 @@ if not is_linux or not dpdk_conf.get('RTE_ARCH_64') reason = 'only supported on 64-bit Linux' endif sources = files( + 'flower/nfp_flower.c', 'nfpcore/nfp_cpp_pcie_ops.c', 'nfpcore/nfp_nsp.c', 'nfpcore/nfp_cppcore.c',
drivers/net/nfp/nfp_common.h +1 -0
@@ -114,6 +114,7 @@/* Firmware application ID's */ enum nfp_app_fw_id {NFP_APP_FW_CORE_NIC =0x1 , +NFP_APP_FW_FLOWER_NIC =0x3 , };/* nfp_qcp_ptr - Read or Write Pointer of a queue */
drivers/net/nfp/nfp_cpp_bridge.c +76 -12
105 lines not on this page · raw message
drivers/net/nfp/nfp_cpp_bridge.h +4 -2
@@ -16,6 +16,8 @@#ifndef _NFP_CPP_BRIDGE_H_#define _NFP_CPP_BRIDGE_H_ +#include "nfp_common.h" +#define NFP_CPP_MEMIO_BOUNDARY (1 << 20)#define NFP_BRIDGE_OP_READ 20#define NFP_BRIDGE_OP_WRITE 30
@@ -24,8 +26,8 @@#define NFP_IOCTL 'n'#define NFP_IOCTL_CPP_IDENTIFICATION _IOW(NFP_IOCTL, 0x8f, uint32_t) -void nfp_register_cpp_service (struct nfp_cpp *cpp); -int32_t nfp_cpp_bridge_service_func (void *args); +int nfp_enable_cpp_service (struct nfp_cpp *cpp); +int nfp_map_service (uint32_t service_id);#endif /* _NFP_CPP_BRIDGE_H_ */ /*
drivers/net/nfp/nfp_ethdev.c +29 -2
@@ -38,6 +38,8 @@#include "nfp_ctrl.h" #include "nfp_cpp_bridge.h" +#include "flower/nfp_flower.h" +static int nfp_net_pf_read_mac (struct nfp_app_fw_nic *app_fw_nic,int port) {
@@ -967,6 +969,14 @@ goto hwqueues_cleanup; }break ; +case NFP_APP_FW_FLOWER_NIC : +PMD_INIT_LOG (INFO ,"Initializing Flower" ); + ret =nfp_init_app_fw_flower (pf_dev); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not initialize Flower!" ); + goto hwqueues_cleanup; + } +break ;default :PMD_INIT_LOG (ERR ,"Unsupported Firmware loaded" ); ret = -EINVAL ;
@@ -974,7 +984,12 @@ }/* register the CPP bridge service here for primary use */ -nfp_register_cpp_service (pf_dev->cpp); + ret =nfp_enable_cpp_service (pf_dev->cpp); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Enable cpp service failed." ); + ret = -EINVAL ; + goto hwqueues_cleanup; + }return 0 ;
@@ -1098,6 +1113,14 @@ goto sym_tbl_cleanup; }break ; +case NFP_APP_FW_FLOWER_NIC : +PMD_INIT_LOG (INFO ,"Initializing Flower" ); + ret =nfp_secondary_init_app_fw_flower (cpp); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not initialize Flower!" ); + goto sym_tbl_cleanup; + } +break ;default :PMD_INIT_LOG (ERR ,"Unsupported Firmware loaded" ); ret = -EINVAL ;
@@ -1105,7 +1128,11 @@ }/* Register the CPP bridge service for the secondary too */ -nfp_register_cpp_service (cpp); + ret =nfp_enable_cpp_service (cpp); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Enable cpp service failed." ); + ret = -EINVAL ; + } sym_tbl_cleanup:free (sym_tbl);
Signature · 1 line
1.8.3.1
PATCH v9 5/12 net/nfp: add flower PF setup logic
In reply to Chaoyong HeAdds the vNIC initialization logic for the flower PF vNIC. The flower firmware application exposes this vNIC for the purposes of fallback traffic in the switchdev use-case.
Adds minimal dev_ops for this PF vNIC device. Because the device is being exposed externally to DPDK it needs to implements a minimal set of dev_ops.
--- drivers/net/nfp/flower/nfp_flower.c | 369 +++++++++++++++++++++++++++++++++++- drivers/net/nfp/flower/nfp_flower.h | 8 + drivers/net/nfp/nfp_common.h | 3 + 3 files changed, 377 insertions(+), 3 deletions(-)
drivers/net/nfp/flower/nfp_flower.c +366 -3
@@ -14,12 +14,312 @@#include "../nfp_logs.h" #include "../nfp_ctrl.h" #include "../nfp_cpp_bridge.h" +#include "../nfp_rxtx.h" +#include "../nfpcore/nfp_mip.h" +#include "../nfpcore/nfp_rtsym.h" +#include "../nfpcore/nfp_nsp.h" #include "nfp_flower.h" +#define MAX_PKT_BURST 32 +#define MBUF_PRIV_SIZE 128 +#define MEMPOOL_CACHE_SIZE 512 +#define DEFAULT_FLBUF_SIZE 9216 + +#define PF_VNIC_NB_DESC 1024 + +static const struct rte_eth_rxconf rx_conf = { + .rx_free_thresh =DEFAULT_RX_FREE_THRESH , + .rx_drop_en =1 , +}; + +static const struct rte_eth_txconf tx_conf = { + .tx_thresh = { + .pthresh =DEFAULT_TX_PTHRESH , + .hthresh =DEFAULT_TX_HTHRESH , + .wthresh =DEFAULT_TX_WTHRESH , + }, + .tx_free_thresh =DEFAULT_TX_FREE_THRESH , +}; + +static const struct eth_dev_ops nfp_flower_pf_vnic_ops = { + .dev_infos_get = nfp_net_infos_get, +}; + +struct dp_packet { +struct rte_mbuf mbuf; +uint32_t source; +}; + +static void +nfp_flower_pf_mp_init(__rte_unused struct rte_mempool *mp, + __rte_unused void *opaque_arg, +void *packet, + __rte_unused unsigned int i) +{ +struct dp_packet *pkt = packet; +/* Indicate that this pkt is from DPDK */ + pkt->source =3 ; +} + +static struct rte_mempool * +nfp_flower_pf_mp_create (void ) +{ +uint32_t nb_mbufs; +unsigned int numa_node; +struct rte_mempool *pktmbuf_pool; +uint32_t n_rxd =PF_VNIC_NB_DESC ; +uint32_t n_txd =PF_VNIC_NB_DESC ; + + nb_mbufs =RTE_MAX (n_rxd + n_txd +MAX_PKT_BURST +MEMPOOL_CACHE_SIZE ,81920U ); + + numa_node =rte_socket_id (); + pktmbuf_pool =rte_pktmbuf_pool_create ("flower_pf_mbuf_pool" , nb_mbufs, +MEMPOOL_CACHE_SIZE ,MBUF_PRIV_SIZE , +RTE_MBUF_DEFAULT_BUF_SIZE , numa_node); +if (pktmbuf_pool ==NULL ) { +PMD_INIT_LOG (ERR ,"Cannot init pf vnic mbuf pool" ); +return NULL ; + } + +rte_mempool_obj_iter (pktmbuf_pool, nfp_flower_pf_mp_init,NULL ); + +return pktmbuf_pool; +} + +static int +nfp_flower_init_vnic_common (struct nfp_net_hw *hw,const char *vnic_type) +{ +uint32_t start_q; +uint64_t rx_bar_off; +uint64_t tx_bar_off; +const int stride =4 ; +struct nfp_pf_dev *pf_dev; +struct rte_pci_device *pci_dev; + + pf_dev = hw->pf_dev; + pci_dev = hw->pf_dev->pci_dev; + +/* NFP can not handle DMA addresses requiring more than 40 bits */ +if (rte_mem_check_dma_mask (40 )) { +PMD_INIT_LOG (ERR ,"Device %s can not be used: restricted dma mask to 40 bits!\n" , + pci_dev->device.name); +return -ENODEV ; + }; + + hw->device_id = pci_dev->id.device_id; + hw->vendor_id = pci_dev->id.vendor_id; + hw->subsystem_device_id = pci_dev->id.subsystem_device_id; + hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id; + +PMD_INIT_LOG (DEBUG ,"%s vNIC ctrl bar: %p" , vnic_type, hw->ctrl_bar); + +/* Read the number of available rx/tx queues from hardware */ + 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 ); + +/* Work out where in the BAR the queues start */ + start_q =nn_cfg_readl (hw,NFP_NET_CFG_START_TXQ ); + tx_bar_off = (uint64_t )start_q *NFP_QCP_QUEUE_ADDR_SZ ; + start_q =nn_cfg_readl (hw,NFP_NET_CFG_START_RXQ ); + rx_bar_off = (uint64_t )start_q *NFP_QCP_QUEUE_ADDR_SZ ; + + hw->tx_bar = pf_dev->hw_queues + tx_bar_off; + hw->rx_bar = pf_dev->hw_queues + rx_bar_off; + +/* 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 ); +/* Set the current MTU to the maximum supported */ + hw->mtu = hw->max_mtu; + hw->flbufsz =DEFAULT_FLBUF_SIZE ; + +/* read the Rx offset configured from firmware */ +if (NFD_CFG_MAJOR_VERSION_of (hw->ver) <2 ) + hw->rx_offset =NFP_NET_RX_OFFSET ; +else + hw->rx_offset =nn_cfg_readl (hw,NFP_NET_CFG_RX_OFFSET_ADDR ); + + hw->ctrl =0 ; + hw->stride_rx = stride; + hw->stride_tx = stride; + +/* Reuse cfg queue setup function */ +nfp_net_cfg_queue_setup (hw); + +PMD_INIT_LOG (INFO ,"%s vNIC max_rx_queues: %u, max_tx_queues: %u" , + vnic_type, hw->max_rx_queues, hw->max_tx_queues); + +/* Initializing spinlock for reconfigs */ +rte_spinlock_init (&hw->reconfig_lock); + +return 0 ; +} + +static int +nfp_flower_init_pf_vnic (struct nfp_net_hw *hw) +{ +int ret; +uint16_t i; +uint16_t n_txq; +uint16_t n_rxq; +unsigned int numa_node; +struct rte_mempool *mp; +struct nfp_pf_dev *pf_dev; +struct rte_eth_dev *eth_dev; +struct nfp_app_fw_flower *app_fw_flower; + +static const struct rte_eth_conf port_conf = { + .rxmode = { + .mq_mode =RTE_ETH_MQ_RX_RSS , + .offloads =RTE_ETH_RX_OFFLOAD_CHECKSUM , + }, + }; + +/* Set up some pointers here for ease of use */ + pf_dev = hw->pf_dev; + app_fw_flower =NFP_PRIV_TO_APP_FW_FLOWER (pf_dev->app_fw_priv); + +/* +* Perform the "common" part of setting up a flower vNIC. +* Mostly reading configuration from hardware. +*/ + ret =nfp_flower_init_vnic_common (hw,"pf_vnic" ); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not init pf vnic" ); +return -EINVAL ; + } + + hw->eth_dev =rte_eth_dev_allocate ("nfp_pf_vnic" ); +if (hw->eth_dev ==NULL ) { +PMD_INIT_LOG (ERR ,"Could not allocate pf vnic" ); +return -ENOMEM ; + } + +/* Grab the pointer to the newly created rte_eth_dev here */ + eth_dev = hw->eth_dev; + + numa_node =rte_socket_id (); + +/* Create a mbuf pool for the PF */ + app_fw_flower->pf_pktmbuf_pool =nfp_flower_pf_mp_create (); +if (app_fw_flower->pf_pktmbuf_pool ==NULL ) { +PMD_INIT_LOG (ERR ,"Could not create mempool for pf vnic" ); + ret = -ENOMEM ; + goto port_release; + } + + mp = app_fw_flower->pf_pktmbuf_pool; + +/* Add Rx/Tx functions */ + eth_dev->dev_ops = &nfp_flower_pf_vnic_ops; + +/* PF vNIC gets a random MAC */ + eth_dev->data->mac_addrs =rte_zmalloc ("mac_addr" ,RTE_ETHER_ADDR_LEN ,0 ); +if (eth_dev->data->mac_addrs ==NULL ) { +PMD_INIT_LOG (ERR ,"Could not allocate mac addr" ); + ret = -ENOMEM ; + goto mempool_cleanup; + } + +rte_eth_random_addr (eth_dev->data->mac_addrs->addr_bytes); +rte_eth_dev_probing_finish (eth_dev); + +/* Configure the PF device now */ + n_rxq = hw->max_rx_queues; + n_txq = hw->max_tx_queues; +memcpy (ð_dev->data->dev_conf, &port_conf,sizeof (struct rte_eth_conf )); + eth_dev->data->rx_queues =rte_zmalloc ("ethdev->rx_queues" , +sizeof (eth_dev->data->rx_queues[0 ]) * n_rxq,RTE_CACHE_LINE_SIZE ); +if (eth_dev->data->rx_queues ==NULL ) { +PMD_INIT_LOG (ERR ,"rte_zmalloc failed for PF vNIC rx queues" ); + ret = -ENOMEM ; + goto mac_cleanup; + } + + eth_dev->data->tx_queues =rte_zmalloc ("ethdev->tx_queues" , +sizeof (eth_dev->data->tx_queues[0 ]) * n_txq,RTE_CACHE_LINE_SIZE ); +if (eth_dev->data->tx_queues ==NULL ) { +PMD_INIT_LOG (ERR ,"rte_zmalloc failed for PF vNIC tx queues" ); + ret = -ENOMEM ; + goto rx_queue_free; + } + +/* Fill in some of the eth_dev fields */ + eth_dev->device = &pf_dev->pci_dev->device; + eth_dev->data->nb_tx_queues = n_rxq; + eth_dev->data->nb_rx_queues = n_txq; + eth_dev->data->dev_private = hw; + eth_dev->data->dev_configured =1 ; + +/* Set up the Rx queues */ +for (i =0 ; i < n_rxq; i++) { + ret =nfp_net_rx_queue_setup (eth_dev, i,PF_VNIC_NB_DESC , numa_node, + &rx_conf, mp); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Configure flower PF vNIC Rx queue %d failed" , i); + goto rx_queue_cleanup; + } + } + +/* Set up the Tx queues */ +for (i =0 ; i < n_txq; i++) { + ret =nfp_net_nfd3_tx_queue_setup (eth_dev, i,PF_VNIC_NB_DESC , numa_node, + &tx_conf); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Configure flower PF vNIC Tx queue %d failed" , i); + goto tx_queue_cleanup; + } + } + +return 0 ; + +tx_queue_cleanup: +for (i =0 ; i < n_txq; i++) +nfp_net_tx_queue_release (eth_dev, i); +rx_queue_cleanup: +for (i =0 ; i < n_rxq; i++) +nfp_net_rx_queue_release (eth_dev, i); +rte_free (eth_dev->data->tx_queues); +rx_queue_free: +rte_free (eth_dev->data->rx_queues); +mac_cleanup: +rte_free (eth_dev->data->mac_addrs); +mempool_cleanup: +rte_mempool_free (mp); +port_release: +rte_eth_dev_release_port (hw->eth_dev); + +return ret; +} + +__rte_unused static void +nfp_flower_cleanup_pf_vnic (struct nfp_net_hw *hw) +{ +uint16_t i; +struct nfp_app_fw_flower *app_fw_flower; + + app_fw_flower =NFP_PRIV_TO_APP_FW_FLOWER (hw->pf_dev->app_fw_priv); + +for (i =0 ; i < hw->max_tx_queues; i++) +nfp_net_tx_queue_release (hw->eth_dev, i); + +for (i =0 ; i < hw->max_tx_queues; i++) +nfp_net_rx_queue_release (hw->eth_dev, i); + +rte_free (hw->eth_dev->data->tx_queues); +rte_free (hw->eth_dev->data->rx_queues); +rte_free (hw->eth_dev->data->mac_addrs); +rte_mempool_free (app_fw_flower->pf_pktmbuf_pool); +rte_eth_dev_release_port (hw->eth_dev); +} +int nfp_init_app_fw_flower (struct nfp_pf_dev *pf_dev) { +int ret;unsigned int numa_node; +struct nfp_net_hw *pf_hw;struct nfp_app_fw_flower *app_fw_flower; numa_node =rte_socket_id ();
@@ -34,12 +334,75 @@ pf_dev->app_fw_priv = app_fw_flower; +/* Allocate memory for the PF AND ctrl vNIC here (hence the * 2) */ + pf_hw =rte_zmalloc_socket ("nfp_pf_vnic" ,2 *sizeof (struct nfp_net_adapter ), +RTE_CACHE_LINE_SIZE , numa_node); +if (pf_hw ==NULL ) { +PMD_INIT_LOG (ERR ,"Could not malloc nfp pf vnic" ); + ret = -ENOMEM ; + goto app_cleanup; + } + +/* Grab the number of physical ports present on hardware */ + app_fw_flower->nfp_eth_table =nfp_eth_read_ports (pf_dev->cpp); +if (app_fw_flower->nfp_eth_table ==NULL ) { +PMD_INIT_LOG (ERR ,"error reading nfp ethernet table" ); + ret = -EIO ; + goto vnic_cleanup; + } + +/* Map the PF ctrl bar */ + pf_dev->ctrl_bar =nfp_rtsym_map (pf_dev->sym_tbl,"_pf0_net_bar0" , +32768 , &pf_dev->ctrl_area); +if (pf_dev->ctrl_bar ==NULL ) { +PMD_INIT_LOG (ERR ,"Cloud not map the PF vNIC ctrl bar" ); + ret = -ENODEV ; + goto eth_tbl_cleanup; + } + +/* Fill in the PF vNIC and populate app struct */ + app_fw_flower->pf_hw = pf_hw; + pf_hw->ctrl_bar = pf_dev->ctrl_bar; + pf_hw->pf_dev = pf_dev; + pf_hw->cpp = pf_dev->cpp; + + ret =nfp_flower_init_pf_vnic (app_fw_flower->pf_hw); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not initialize flower PF vNIC" ); + goto pf_cpp_area_cleanup; + } +return 0 ; + +pf_cpp_area_cleanup: +nfp_cpp_area_free (pf_dev->ctrl_area); +eth_tbl_cleanup: +free (app_fw_flower->nfp_eth_table); +vnic_cleanup: +rte_free (pf_hw); +app_cleanup: +rte_free (app_fw_flower); + +return ret; }int -nfp_secondary_init_app_fw_flower(__rte_unused struct nfp_cpp *cpp) +nfp_secondary_init_app_fw_flower (struct nfp_cpp *cpp) { -PMD_INIT_LOG (ERR ,"Flower firmware not supported" ); -return -ENOTSUP ; +struct rte_eth_dev *eth_dev; +const char *port_name ="pf_vnic_eth_dev" ; + +PMD_INIT_LOG (DEBUG ,"Secondary attaching to port %s" , port_name); + + eth_dev =rte_eth_dev_attach_secondary (port_name); +if (eth_dev ==NULL ) { +PMD_INIT_LOG (ERR ,"Secondary process attach to port %s failed" , port_name); +return -ENODEV ; + } + + eth_dev->process_private = cpp; + eth_dev->dev_ops = &nfp_flower_pf_vnic_ops; +rte_eth_dev_probing_finish (eth_dev); + +return 0 ; }
drivers/net/nfp/flower/nfp_flower.h +8 -0
@@ -8,6 +8,14 @@/* The flower application's private structure */ struct nfp_app_fw_flower { +/* Pointer to a mempool for the PF vNIC */ +struct rte_mempool *pf_pktmbuf_pool; + +/* Pointer to the PF vNIC */ +struct nfp_net_hw *pf_hw; + +/* the eth table as reported by firmware */ +struct nfp_eth_table *nfp_eth_table; };int nfp_init_app_fw_flower (struct nfp_pf_dev *pf_dev);
drivers/net/nfp/nfp_common.h +3 -0
@@ -446,6 +446,9 @@ int nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev,#define NFP_PRIV_TO_APP_FW_NIC (app_fw_priv)\ ((struct nfp_app_fw_nic *)app_fw_priv) +#define NFP_PRIV_TO_APP_FW_FLOWER (app_fw_priv)\ + ((struct nfp_app_fw_flower *)app_fw_priv) +#endif /* _NFP_COMMON_H_ */ /* * Local variables:
Signature · 1 line
1.8.3.1
Re: [PATCH v9 05/12] net/nfp: add flower PF setup logic
Quoted 10 lines · Chaoyong He
Adds the vNIC initialization logic for the flower PF vNIC. The flower firmware application exposes this vNIC for the purposes of fallback traffic in the switchdev use-case.
Adds minimal
dev_opsfor this PF vNIC device. Because the device is being exposed externally to DPDK it needs to implements a minimal set ofdev_ops.Signed-off-by Chaoyong He <[email protected]>Reviewed-by Niklas Söderlund <[email protected]>
<...>
Quoted 32 lines
drivers/net/nfp/flower/nfp_flower.c +32
-0+ +struct dp_packet { +struct rte_mbuf mbuf; +uint32_t source; +}; + +static void +nfp_flower_pf_mp_init(__rte_unused struct rte_mempool *mp, + __rte_unused void *opaque_arg, +void *packet, + __rte_unused unsigned int i) +{ +struct dp_packet *pkt = packet; +/* Indicate that this pkt is from DPDK */ + pkt->source =3 ; +} + +static struct rte_mempool * +nfp_flower_pf_mp_create (void ) +{ +uint32_t nb_mbufs; +unsigned int numa_node; +struct rte_mempool *pktmbuf_pool; +uint32_t n_rxd =PF_VNIC_NB_DESC ; +uint32_t n_txd =PF_VNIC_NB_DESC ; + + nb_mbufs =RTE_MAX (n_rxd + n_txd +MAX_PKT_BURST +MEMPOOL_CACHE_SIZE ,81920U ); + + numa_node =rte_socket_id (); + pktmbuf_pool =rte_pktmbuf_pool_create ("flower_pf_mbuf_pool" , nb_mbufs, +MEMPOOL_CACHE_SIZE ,MBUF_PRIV_SIZE , +RTE_MBUF_DEFAULT_BUF_SIZE , numa_node);
drivers/net/nfp/flower/nfp_flower.c line 88
Quoted 10 lines
drivers/net/nfp/flower/nfp_flower.c +10
-0+if (pktmbuf_pool ==NULL ) { +PMD_INIT_LOG (ERR ,"Cannot init pf vnic mbuf pool" ); +return NULL ; + } + +rte_mempool_obj_iter (pktmbuf_pool, nfp_flower_pf_mp_init,NULL ); + +return pktmbuf_pool; +} +
Hi Chaoyong,
Again, similar comment to previous versions, what I understand is this new flower FW supports HW flow filter and intended use case is for OvS HW acceleration. But is DPDK driver need to know OvS data structures, like "struct dp_packet", can it be transparent to application, I am sure there are other devices offloading some OvS task to HW.
@Ian, @David,
Can you please comment on above usage, do you guys see any way to escape from OvS specific code in the driver?
RE: [PATCH v9 05/12] net/nfp: add flower PF setup logic
Quoted 69 lines · Chaoyong He
Quoted 10 lines
Adds the vNIC initialization logic for the flower PF vNIC. The flower firmware application exposes this vNIC for the purposes of fallback traffic in the switchdev use-case.
Adds minimal
dev_opsfor this PF vNIC device. Because the device is being exposed externally to DPDK it needs to implements a minimal set ofdev_ops.Signed-off-by Chaoyong He <[email protected]>Reviewed-by Niklas Söderlund <[email protected]><...>
Quoted 21 lines
drivers/net/nfp/flower/nfp_flower.c +21
-0+ +struct dp_packet { +struct rte_mbuf mbuf; +uint32_t source; +}; + +static void +nfp_flower_pf_mp_init(__rte_unused struct rte_mempool *mp, + __rte_unused void *opaque_arg, +void *packet, + __rte_unused unsigned int i) +{ +struct dp_packet *pkt = packet; +/* Indicate that this pkt is from DPDK */ + pkt->source =3 ; +} + +static struct rte_mempool * +nfp_flower_pf_mp_create (void ) +{ +uint32_t nb_mbufs;drivers/net/nfp/flower/nfp_flower.c
Quoted 10 lines
drivers/net/nfp/flower/nfp_flower.c +10
-0+unsigned int numa_node; +struct rte_mempool *pktmbuf_pool; +uint32_t n_rxd =PF_VNIC_NB_DESC ; +uint32_t n_txd =PF_VNIC_NB_DESC ; + + nb_mbufs =RTE_MAX (n_rxd + n_txd +MAX_PKT_BURST + +MEMPOOL_CACHE_SIZE ,81920U ); + + numa_node =rte_socket_id (); + pktmbuf_pool = rte_pktmbuf_pool_create("flower_pf_mbuf_pool",
nb_mbufs,drivers/net/nfp/flower/nfp_flower.c
Quoted 8 lines
drivers/net/nfp/flower/nfp_flower.c +8
-0+MEMPOOL_CACHE_SIZE ,MBUF_PRIV_SIZE , + RTE_MBUF_DEFAULT_BUF_SIZE, numa_node); +if (pktmbuf_pool ==NULL ) { +PMD_INIT_LOG (ERR ,"Cannot init pf vnic mbuf pool" ); +return NULL ; + } + + rte_mempool_obj_iter(pktmbuf_pool, nfp_flower_pf_mp_init,NULL);
drivers/net/nfp/flower/nfp_flower.c line 88
Quoted 4 lines
drivers/net/nfp/flower/nfp_flower.c +4
-0+ +return pktmbuf_pool; +} +Hi Chaoyong,
Again, similar comment to previous versions, what I understand is this new flower FW supports HW flow filter and intended use case is for OvS HW acceleration.
But is DPDK driver need to know OvS data structures, like "structdp_packet", can it be transparent to application, I am sure there are other devices offloading some OvS task to HW.
Quoted 4 lines
@Ian, @David,
Can you please comment on above usage, do you guys see any way to escape from OvS specific code in the driver?
Firstly, I'll explain why we must include some OvS specific code in the driver. If we don't set the pkt->source = 3, the OvS will coredump like this:
``` (gdb) bt #0 0x00007fe1d48fd387 in raise () from /lib64/libc.so.6 #1 0x00007fe1d48fea78 in abort () from /lib64/libc.so.6 #2 0x00007fe1d493ff67 in __libc_message () from /lib64/libc.so.6 #3 0x00007fe1d4948329 in _int_free () from /lib64/libc.so.6 #4 0x000000000049c006 in dp_packet_uninit (b=0x1f262db80) at lib/dp-packet.c:135 #5 0x000000000061440a in dp_packet_delete (b=0x1f262db80) at lib/dp-packet.h:261 #6 0x0000000000619aa0 in dpdk_copy_batch_to_mbuf (netdev=0x1f0a04a80, batch=0x7fe1b40050c0) at lib/netdev-dpdk.c:274 #7 0x0000000000619b46 in netdev_dpdk_common_send (netdev=0x1f0a04a80, batch=0x7fe1b40050c0, stats=0x7fe1be7321f0) at #8 0x000000000061a0ba in netdev_dpdk_eth_send (netdev=0x1f0a04a80, qid=0, batch=0x7fe1b40050c0, concurrent_txq=true) #9 0x00000000004fbd10 in netdev_send (netdev=0x1f0a04a80, qid=0, batch=0x7fe1b40050c0, concurrent_txq=true) at lib/n #10 0x00000000004aa663 in dp_netdev_pmd_flush_output_on_port (pmd=0x7fe1be735010, p=0x7fe1b4005090) at lib/dpif-netde #11 0x00000000004aa85d in dp_netdev_pmd_flush_output_packets (pmd=0x7fe1be735010, force=false) at lib/dpif-netdev.c:5 #12 0x00000000004aaaef in dp_netdev_process_rxq_port (pmd=0x7fe1be735010, rxq=0x16f3f80, port_no=3) at lib/dpif-netde #13 0x00000000004af17a in pmd_thread_main (f_=0x7fe1be735010) at lib/dpif-netdev.c:6958 #14 0x000000000057da80 in ovsthread_wrapper (aux_=0x1608b30) at lib/ovs-thread.c:422 #15 0x00007fe1d51a6ea5 in start_thread () from /lib64/libpthread.so.0 #16 0x00007fe1d49c5b0d in clone () from /lib64/libc.so.6 ```
The logic in function dp_packet_delete() run into the wrong branch.
Then, why just our PMD need do this, and other PMDs don't? Generally, it's greatly dependent on the hardware.
The Netronome's Network Flow Processor 4xxx (NFP-4xxx) card is the target card of these series patches. Which only has one PF but has 2 physical ports, and the NFP PMD can work with up to 8 ports on the same PF device. Other PMDs hardware seems all 'one PF <--> one physical port'.
For the use case of OvS, we should add the representor port of 'physical port' to the bridge, not the representor port of PF like other PMDs.
We use a two-layer poll mode architecture. (Other PMDs are simple poll mode architecture)
In the RX direction:
1. When the physical port or vf receives pkts, the firmware will prepend a meta-data(indicating the input port) into the pkt.
2. We use the PF vNIC as a multiplexer, which keeps polling pkts from the firmware.
3. The PF vNIC will parse the meta-data, and enqueue the pkt into the corresponding rte_ring of the representor port of physical port or vf.
4. The OVS will polling pkts from the RX function of representor port, which dequeue pkts from the rte_ring.
In the TX direction:
1. The OVS send the pkts from the TX functions of representor port.
2. The representor port will prepend a meta-data(indicating the output port) into the pkt and send the pkt to firmware through the queue 0 of PF vNIC.
3. The firmware will parse the meta-data, and forward the pkt to the corresponding physical port or vf.
So the OvS won't create the mempool for us and we must create it ourselves for the PF vNIC to use.
Hopefully, I explained the things clearly. Thanks.
Re: [PATCH v9 05/12] net/nfp: add flower PF setup logic
I don't understand your logic fully,
but I understand you need special code to make your hardware work with OvS, meaning:
- OvS must have a special handling for your HW
- other applications won't work
Tell me I misunderstand,
but I feel we should not accept this patch,
there is probably a better way to manage the specific of your HW.
You said "NFP PMD can work with up to 8 ports on the same PF device." Let's imagine you have 8 ports for 1 PF device.
Do you allocate 8 ethdev ports?
If yes, then each ethdev should do the internal work,
and nothing is needed at application level.
21/09/2022 04:50, Chaoyong He:
Quoted 62 lines
Quoted 10 lines · Chaoyong He
Hi Chaoyong,
Again, similar comment to previous versions, what I understand is this new flower FW supports HW flow filter and intended use case is for OvS HW acceleration.
But is DPDK driver need to know OvS data structures, like "structdp_packet", can it be transparent to application, I am sure there are other devices offloading some OvS task to HW.Quoted 4 lines
@Ian, @David,
Can you please comment on above usage, do you guys see any way to escape from OvS specific code in the driver?
Firstly, I'll explain why we must include some OvS specific code in the driver. If we don't set the
pkt->source = 3, the OvS will coredump like this:``` (gdb) bt #0 0x00007fe1d48fd387 in raise () from /lib64/libc.so.6 #1 0x00007fe1d48fea78 in abort () from /lib64/libc.so.6 #2 0x00007fe1d493ff67 in __libc_message () from /lib64/libc.so.6 #3 0x00007fe1d4948329 in _int_free () from /lib64/libc.so.6 #4 0x000000000049c006 in dp_packet_uninit (b=0x1f262db80) at lib/dp-packet.c:135 #5 0x000000000061440a in dp_packet_delete (b=0x1f262db80) at lib/dp-packet.h:261 #6 0x0000000000619aa0 in dpdk_copy_batch_to_mbuf (netdev=0x1f0a04a80, batch=0x7fe1b40050c0) at lib/netdev-dpdk.c:274 #7 0x0000000000619b46 in netdev_dpdk_common_send (netdev=0x1f0a04a80, batch=0x7fe1b40050c0, stats=0x7fe1be7321f0) at #8 0x000000000061a0ba in netdev_dpdk_eth_send (netdev=0x1f0a04a80, qid=0, batch=0x7fe1b40050c0, concurrent_txq=true) #9 0x00000000004fbd10 in netdev_send (netdev=0x1f0a04a80, qid=0, batch=0x7fe1b40050c0, concurrent_txq=true) at lib/n #10 0x00000000004aa663 in dp_netdev_pmd_flush_output_on_port (pmd=0x7fe1be735010, p=0x7fe1b4005090) at lib/dpif-netde #11 0x00000000004aa85d in dp_netdev_pmd_flush_output_packets (pmd=0x7fe1be735010, force=false) at lib/dpif-netdev.c:5 #12 0x00000000004aaaef in dp_netdev_process_rxq_port (pmd=0x7fe1be735010, rxq=0x16f3f80, port_no=3) at lib/dpif-netde #13 0x00000000004af17a in pmd_thread_main (f_=0x7fe1be735010) at lib/dpif-netdev.c:6958 #14 0x000000000057da80 in ovsthread_wrapper (aux_=0x1608b30) at lib/ovs-thread.c:422 #15 0x00007fe1d51a6ea5 in start_thread () from /lib64/libpthread.so.0 #16 0x00007fe1d49c5b0d in clone () from /lib64/libc.so.6 ```The logic in function
dp_packet_delete()run into the wrong branch.Then, why just our PMD need do this, and other PMDs don't? Generally, it's greatly dependent on the hardware.
The Netronome's Network Flow Processor 4xxx (NFP-4xxx) card is the target card of these series patches. Which only has one PF but has 2 physical ports, and the NFP PMD can work with up to 8 ports on the same PF device. Other PMDs hardware seems all 'one PF <--> one physical port'.
For the use case of OvS, we should add the representor port of 'physical port' to the bridge, not the representor port of PF like other PMDs.
We use a two-layer poll mode architecture. (Other PMDs are simple poll mode architecture)
In the RX direction:
1. When the physical port or vf receives pkts, the firmware will prepend a meta-data(indicating the input port) into the pkt.
2. We use the PF vNIC as a multiplexer, which keeps polling pkts from the firmware.
3. The PF vNIC will parse the meta-data, and enqueue the pkt into the correspondingrte_ringof the representor port of physical port or vf.
4. The OVS will polling pkts from the RX function of representor port, which dequeue pkts from therte_ring.
In the TX direction:
1. The OVS send the pkts from the TX functions of representor port.
2. The representor port will prepend a meta-data(indicating the output port) into the pkt and send the pkt to firmware through the queue 0 of PF vNIC.
3. The firmware will parse the meta-data, and forward the pkt to the corresponding physical port or vf.So the OvS won't create the mempool for us and we must create it ourselves for the PF vNIC to use.
Hopefully, I explained the things clearly. Thanks.
RE: [PATCH v9 05/12] net/nfp: add flower PF setup logic
Quoted 11 lines
Subject: Re: [PATCH v9 05/12] net/nfp: add flower PF setup logic
I don't understand your logic fully,
but I understand you need special code to make your hardware work with OvS,
meaning:
- OvS must have a special handling for your HW
- other applications won't work
Tell me I misunderstand,
but I feel we should not accept this patch, there is probably a better way to manage the specific of your HW.
OvS need not do anything special handling for our HW.
Other applications won't work -- Sorry I don't understand your mean at this point.
Quoted 5 lines
You said "NFP PMD can work with up to 8 ports on the same PF device." Let's imagine you have 8 ports for 1 PF device.
Do you allocate 8 ethdev ports?
If yes, then each ethdev should do the internal work, and nothing is needed at application level.
No, we still just create 1 PF vNIC to handle the feedback traffic. Of course we will 8 representor port for physical port.
Quoted 88 lines
21/09/2022 04:50, Chaoyong He:
Quoted 24 lines
Quoted 10 lines · Chaoyong He
Hi Chaoyong,
Again, similar comment to previous versions, what I understand is this new flower FW supports HW flow filter and intended use case is for OvS HW acceleration.
But is DPDK driver need to know OvS data structures, like "structdp_packet", can it be transparent to application, I am sure there are other devices offloading some OvS task to HW.Quoted 4 lines
@Ian, @David,
Can you please comment on above usage, do you guys see any way to escape from OvS specific code in the driver?
Firstly, I'll explain why we must include some OvS specific code in the driver. If we don't set the
pkt->source = 3, the OvS will coredump like this:
```
(gdb) bt#0 0x00007fe1d48fd387 in raise () from /lib64/libc.so.6 #1 0x00007fe1d48fea78 in abort () from /lib64/libc.so.6 #2 0x00007fe1d493ff67 in __libc_message () from /lib64/libc.so.6 #3 0x00007fe1d4948329 in _int_free () from /lib64/libc.so.6 #4 0x000000000049c006 in dp_packet_uninit (b=0x1f262db80) atQuoted 4 lines
lib/dp-packet.c:135
#50x000000000061440aindp_packet_delete(b=0x1f262db80) atlib/dp-packet.h:261
#60x0000000000619aa0indpdk_copy_batch_to_mbuf(netdev=0x1f0a04a80,
Quoted 2 lines
batch=0x7fe1b40050c0) at
lib/netdev-dpdk.c:274
#70x0000000000619b46innetdev_dpdk_common_send(netdev=0x1f0a04a80,
Quoted 19 lines
batch=0x7fe1b40050c0, stats=0x7fe1be7321f0) at
#80x000000000061a0bainnetdev_dpdk_eth_send(netdev=0x1f0a04a80, qid=0, batch=0x7fe1b40050c0, concurrent_txq=true)
#90x00000000004fbd10innetdev_send(netdev=0x1f0a04a80, qid=0, batch=0x7fe1b40050c0, concurrent_txq=true) at lib/n
#100x00000000004aa663indp_netdev_pmd_flush_output_on_port(pmd=0x7fe1be735010, p=0x7fe1b4005090) atlib/dpif-netde#110x00000000004aa85dindp_netdev_pmd_flush_output_packets(pmd=0x7fe1be735010, force=false) atlib/dpif-netdev.c:5#120x00000000004aaaefindp_netdev_process_rxq_port(pmd=0x7fe1be735010, rxq=0x16f3f80, port_no=3) atlib/dpif-netde#130x00000000004af17ainpmd_thread_main(f_=0x7fe1be735010) atlib/dpif-netdev.c:6958
#140x000000000057da80inovsthread_wrapper(aux_=0x1608b30) atlib/ovs-thread.c:422
#150x00007fe1d51a6ea5instart_thread() from/lib64/libpthread.so.0#160x00007fe1d49c5b0din clone () from/lib64/libc.so.6``` The logic in functiondp_packet_delete()run into the wrong branch.Quoted 4 lines
Then, why just our PMD need do this, and other PMDs don't? Generally, it's greatly dependent on the hardware.
The Netronome's Network Flow Processor 4xxx (NFP-4xxx) card is the
target card of these series patches.
Quoted 1 line
Which only has one PF but has 2 physical ports, and the NFP PMD can work
with up to 8 ports on the same PF device.
Quoted 3 lines
Other PMDs hardware seems all 'one PF <--> one physical port'.
For the use case of OvS, we should add the representor port of 'physical
port' to the bridge, not the representor port of PF like other PMDs.
Quoted 4 lines
We use a two-layer poll mode architecture. (Other PMDs are simple poll mode architecture) In the RX direction:
1. When the physical port or vf receives pkts, the firmware will prepend ameta-data(indicating the input port) into the pkt.
Quoted 1 line
2. We use the PF vNIC as a multiplexer, which keeps polling pkts from the
firmware.
Quoted 1 line
3. The PF vNIC will parse the meta-data, and enqueue the pkt into the
corresponding
rte_ringof the representor port of physical port or vf.Quoted 1 line
4. The OVS will polling pkts from the RX function of representor port, which
dequeue pkts from the
rte_ring.Quoted 3 lines
In the TX direction:
1. The OVS send the pkts from the TX functions of representor port.
2. The representor port will prepend a meta-data(indicating the outputport) into the pkt and send the pkt to firmware through the queue 0 of PF vNIC.
Quoted 1 line
3. The firmware will parse the meta-data, and forward the pkt to the
corresponding physical port or vf.
Quoted 2 lines
So the OvS won't create the mempool for us and we must create it
ourselves for the PF vNIC to use.
Quoted 2 lines
Hopefully, I explained the things clearly. Thanks.
PATCH v9 6/12 net/nfp: add flower PF related routines
In reply to Chaoyong HeAdds the start/stop/close routine of the flower PF vNIC. And we reuse the configure/link_update routine.
--- drivers/net/nfp/flower/nfp_flower.c | 193 +++++++++++++++++++++++++++++++++++- 1 file changed, 192 insertions(+), 1 deletion(-)
drivers/net/nfp/flower/nfp_flower.c +192 -1
@@ -7,6 +7,7 @@#include <ethdev_driver.h> #include <rte_service_component.h> #include <rte_malloc.h> +#include <rte_alarm.h> #include <ethdev_pci.h> #include <ethdev_driver.h>
@@ -41,8 +42,168 @@ .tx_free_thresh = DEFAULT_TX_FREE_THRESH, }; +static int +nfp_flower_pf_start (struct rte_eth_dev *dev) +{ +int ret; +uint32_t new_ctrl; +uint32_t update =0 ; +struct nfp_net_hw *hw; + + hw =NFP_NET_DEV_PRIVATE_TO_HW (dev->data->dev_private); + +/* Disabling queues just in case... */ +nfp_net_disable_queues (dev); + +/* Enabling the required queues in the device */ +nfp_net_enable_queues (dev); + + new_ctrl =nfp_check_offloads (dev); + +/* Writing configuration parameters in the device */ +nfp_net_params_setup (hw); + +nfp_net_rss_config_default (dev); + update |=NFP_NET_CFG_UPDATE_RSS ; + +if (hw->cap &NFP_NET_CFG_CTRL_RSS2 ) + new_ctrl |=NFP_NET_CFG_CTRL_RSS2 ; +else + new_ctrl |=NFP_NET_CFG_CTRL_RSS ; + +/* Enable device */ + new_ctrl |=NFP_NET_CFG_CTRL_ENABLE ; + + update |=NFP_NET_CFG_UPDATE_GEN |NFP_NET_CFG_UPDATE_RING ; + +if (hw->cap &NFP_NET_CFG_CTRL_RINGCFG ) + new_ctrl |=NFP_NET_CFG_CTRL_RINGCFG ; + +nn_cfg_writel (hw,NFP_NET_CFG_CTRL , new_ctrl); + +/* If an error when reconfig we avoid to change hw state */ + ret =nfp_net_reconfig (hw, new_ctrl, update); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Failed to reconfig PF vnic" ); +return -EIO ; + } + + hw->ctrl = new_ctrl; + +/* Setup the freelist ring */ + ret =nfp_net_rx_freelist_setup (dev); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Error with flower PF vNIC freelist setup" ); +return -EIO ; + } + +return 0 ; +} + +/* Stop device: disable rx and tx functions to allow for reconfiguring. */ +static int +nfp_flower_pf_stop (struct rte_eth_dev *dev) +{ +uint16_t i; +struct nfp_net_hw *hw; +struct nfp_net_txq *this_tx_q; +struct nfp_net_rxq *this_rx_q; + + hw =NFP_NET_DEV_PRIVATE_TO_HW (dev->data->dev_private); + +nfp_net_disable_queues (dev); + +/* Clear queues */ +for (i =0 ; i < dev->data->nb_tx_queues; i++) { + this_tx_q = (struct nfp_net_txq *)dev->data->tx_queues[i]; +nfp_net_reset_tx_queue (this_tx_q); + } + +for (i =0 ; i < dev->data->nb_rx_queues; i++) { + this_rx_q = (struct nfp_net_rxq *)dev->data->rx_queues[i]; +nfp_net_reset_rx_queue (this_rx_q); + } + +if (rte_eal_process_type () ==RTE_PROC_PRIMARY ) +/* Configure the physical port down */ +nfp_eth_set_configured (hw->cpp, hw->nfp_idx,0 ); +else +nfp_eth_set_configured (dev->process_private, hw->nfp_idx,0 ); + +return 0 ; +} + +/* Reset and stop device. The device can not be restarted. */ +static int +nfp_flower_pf_close (struct rte_eth_dev *dev) +{ +uint16_t i; +struct nfp_net_hw *hw; +struct nfp_pf_dev *pf_dev; +struct nfp_net_txq *this_tx_q; +struct nfp_net_rxq *this_rx_q; +struct rte_pci_device *pci_dev; +struct nfp_app_fw_flower *app_fw_flower; + +if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) +return 0 ; + + pf_dev =NFP_NET_DEV_PRIVATE_TO_PF (dev->data->dev_private); + hw =NFP_NET_DEV_PRIVATE_TO_HW (dev->data->dev_private); + pci_dev =RTE_ETH_DEV_TO_PCI (dev); + app_fw_flower =NFP_PRIV_TO_APP_FW_FLOWER (pf_dev->app_fw_priv); + +/* +* We assume that the DPDK application is stopping all the +* threads/queues before calling the device close function. +*/ +nfp_net_disable_queues (dev); + +/* Clear queues */ +for (i =0 ; i < dev->data->nb_tx_queues; i++) { + this_tx_q = (struct nfp_net_txq *)dev->data->tx_queues[i]; +nfp_net_reset_tx_queue (this_tx_q); + } + +for (i =0 ; i < dev->data->nb_rx_queues; i++) { + this_rx_q = (struct nfp_net_rxq *)dev->data->rx_queues[i]; +nfp_net_reset_rx_queue (this_rx_q); + } + +/* Cancel possible impending LSC work here before releasing the port*/ +rte_eal_alarm_cancel (nfp_net_dev_interrupt_delayed_handler, (void *)dev); + +nn_cfg_writeb (hw,NFP_NET_CFG_LSC ,0xff ); + +rte_eth_dev_release_port (dev); + +/* Now it is safe to free all PF resources */ +PMD_DRV_LOG (INFO ,"Freeing PF resources" ); +nfp_cpp_area_free (pf_dev->ctrl_area); +nfp_cpp_area_free (pf_dev->hwqueues_area); +free (pf_dev->hwinfo); +free (pf_dev->sym_tbl); +nfp_cpp_free (pf_dev->cpp); +rte_free (app_fw_flower); +rte_free (pf_dev); + +rte_intr_disable (pci_dev->intr_handle); + +/* unregister callback func from eal lib */ +rte_intr_callback_unregister (pci_dev->intr_handle, + nfp_net_dev_interrupt_handler, (void *)dev); + +return 0 ; +} +static const struct eth_dev_ops nfp_flower_pf_vnic_ops = { .dev_infos_get = nfp_net_infos_get, + .link_update = nfp_net_link_update, + .dev_configure = nfp_net_configure, + + .dev_start = nfp_flower_pf_start, + .dev_stop = nfp_flower_pf_stop, + .dev_close = nfp_flower_pf_close, };struct dp_packet {
@@ -293,7 +454,7 @@ struct dp_packet {return ret; } -__rte_unused static void +static void nfp_flower_cleanup_pf_vnic (struct nfp_net_hw *hw) {uint16_t i;
@@ -314,6 +475,27 @@ struct dp_packet {rte_eth_dev_release_port (hw->eth_dev); } +static int +nfp_flower_start_pf_vnic (struct nfp_net_hw *hw) +{ +int ret; +struct rte_eth_dev *dev; + + dev = hw->eth_dev; + +/* Start the device */ + ret =nfp_flower_pf_start (dev); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not start pf vnic" ); +return -EINVAL ; + } + + dev->data->dev_started =1 ; +nfp_net_link_update (dev,0 ); + +return 0 ; +} +int nfp_init_app_fw_flower (struct nfp_pf_dev *pf_dev) {
@@ -372,8 +554,17 @@ struct dp_packet { goto pf_cpp_area_cleanup; } +/* Start the PF vNIC */ + ret =nfp_flower_start_pf_vnic (app_fw_flower->pf_hw); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not start flower PF vNIC" ); + goto pf_vnic_cleanup; + } +return 0 ; +pf_vnic_cleanup: +nfp_flower_cleanup_pf_vnic (app_fw_flower->pf_hw); pf_cpp_area_cleanup:nfp_cpp_area_free (pf_dev->ctrl_area); eth_tbl_cleanup:
Signature · 1 line
1.8.3.1
PATCH v9 7/12 net/nfp: add flower ctrl VNIC related logics
In reply to Chaoyong HeAdds the setup/start logic for the ctrl vNIC. This vNIC is used by the PMD and flower firmware application as a communication channel between driver and firmware. In the case of OVS it is also used to communicate flow statistics from hardware to the driver.
A rte_eth device is not exposed to DPDK for this vNIC as it is strictly used internally by flower logic.
Because of the add of ctrl vNIC, a new PCItoCPPBar is needed. Modify the related logics.
--- drivers/net/nfp/flower/nfp_flower.c | 220 +++++++++++++++++++++++++++++ drivers/net/nfp/flower/nfp_flower.h | 6 + drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c | 31 ++-- 3 files changed, 245 insertions(+), 12 deletions(-)
drivers/net/nfp/flower/nfp_flower.c +220 -0
@@ -27,6 +27,7 @@#define DEFAULT_FLBUF_SIZE 9216#define PF_VNIC_NB_DESC 1024 +#define CTRL_VNIC_NB_DESC 512static const struct rte_eth_rxconf rx_conf = { .rx_free_thresh =DEFAULT_RX_FREE_THRESH ,
@@ -206,6 +207,11 @@ .dev_close = nfp_flower_pf_close, }; +static const struct eth_dev_ops nfp_flower_ctrl_vnic_ops = { + .dev_infos_get = nfp_net_infos_get, + .dev_configure = nfp_net_configure, +}; +struct dp_packet {struct rte_mbuf mbuf;uint32_t source;
@@ -496,12 +502,192 @@ struct dp_packet {return 0 ; } +static int +nfp_flower_init_ctrl_vnic (struct nfp_net_hw *hw) +{ +uint32_t i; +int ret =0 ; +uint16_t n_txq; +uint16_t n_rxq; +unsigned int numa_node; +struct rte_mempool *mp; +struct nfp_pf_dev *pf_dev; +struct rte_eth_dev *eth_dev; +struct nfp_app_fw_flower *app_fw_flower; + +/* Set up some pointers here for ease of use */ + pf_dev = hw->pf_dev; + app_fw_flower =NFP_PRIV_TO_APP_FW_FLOWER (pf_dev->app_fw_priv); + + ret =nfp_flower_init_vnic_common (hw,"ctrl_vnic" ); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not init pf vnic" ); +return -EINVAL ; + } + +/* Allocate memory for the eth_dev of the vNIC */ + hw->eth_dev =rte_eth_dev_allocate ("nfp_ctrl_vnic" ); +if (hw->eth_dev ==NULL ) { +PMD_INIT_LOG (ERR ,"Could not allocate ctrl vnic" ); +return -ENOMEM ; + } + +/* Grab the pointer to the newly created rte_eth_dev here */ + eth_dev = hw->eth_dev; + + numa_node =rte_socket_id (); + +/* Create a mbuf pool for the ctrl vNIC */ + app_fw_flower->ctrl_pktmbuf_pool =rte_pktmbuf_pool_create ("ctrl_mbuf_pool" , +4 *CTRL_VNIC_NB_DESC ,64 ,0 ,9216 , numa_node); +if (app_fw_flower->ctrl_pktmbuf_pool ==NULL ) { +PMD_INIT_LOG (ERR ,"create mbuf pool for ctrl vnic failed" ); + ret = -ENOMEM ; + goto port_release; + } + + mp = app_fw_flower->ctrl_pktmbuf_pool; + + eth_dev->dev_ops = &nfp_flower_ctrl_vnic_ops; +rte_eth_dev_probing_finish (eth_dev); + +/* Configure the ctrl vNIC device */ + n_rxq = hw->max_rx_queues; + n_txq = hw->max_tx_queues; + eth_dev->data->rx_queues =rte_zmalloc ("ethdev->rx_queues" , +sizeof (eth_dev->data->rx_queues[0 ]) * n_rxq, +RTE_CACHE_LINE_SIZE ); +if (eth_dev->data->rx_queues ==NULL ) { +PMD_INIT_LOG (ERR ,"rte_zmalloc failed for ctrl vNIC rx queues" ); + ret = -ENOMEM ; + goto mempool_cleanup; + } + + eth_dev->data->tx_queues =rte_zmalloc ("ethdev->tx_queues" , +sizeof (eth_dev->data->tx_queues[0 ]) * n_txq, +RTE_CACHE_LINE_SIZE ); +if (eth_dev->data->tx_queues ==NULL ) { +PMD_INIT_LOG (ERR ,"rte_zmalloc failed for ctrl vNIC tx queues" ); + ret = -ENOMEM ; + goto rx_queue_free; + } + +/* Fill in some of the eth_dev fields */ + eth_dev->device = &pf_dev->pci_dev->device; + eth_dev->data->nb_tx_queues = n_rxq; + eth_dev->data->nb_rx_queues = n_txq; + eth_dev->data->dev_private = hw; + +/* Set up the Rx queues */ +for (i =0 ; i < n_rxq; i++) { + ret =nfp_net_rx_queue_setup (eth_dev, i,CTRL_VNIC_NB_DESC , numa_node, + &rx_conf, mp); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Configure ctrl vNIC Rx queue %d failed" , i); + goto rx_queue_cleanup; + } + } + +/* Set up the Tx queues */ +for (i =0 ; i < n_txq; i++) { + ret =nfp_net_nfd3_tx_queue_setup (eth_dev, i,CTRL_VNIC_NB_DESC , numa_node, + &tx_conf); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Configure ctrl vNIC Tx queue %d failed" , i); + goto tx_queue_cleanup; + } + } + +return 0 ; + +tx_queue_cleanup: +for (i =0 ; i < n_txq; i++) +nfp_net_tx_queue_release (eth_dev, i); +rx_queue_cleanup: +for (i =0 ; i < n_rxq; i++) +nfp_net_rx_queue_release (eth_dev, i); +rte_free (eth_dev->data->tx_queues); +rx_queue_free: +rte_free (eth_dev->data->rx_queues); +mempool_cleanup: +rte_mempool_free (mp); +port_release: +rte_eth_dev_release_port (hw->eth_dev); + +return ret; +} + +static void +nfp_flower_cleanup_ctrl_vnic (struct nfp_net_hw *hw) +{ +uint32_t i; +struct nfp_app_fw_flower *app_fw_flower; + + app_fw_flower =NFP_PRIV_TO_APP_FW_FLOWER (hw->pf_dev->app_fw_priv); + +for (i =0 ; i < hw->max_tx_queues; i++) +nfp_net_tx_queue_release (hw->eth_dev, i); + +for (i =0 ; i < hw->max_rx_queues; i++) +nfp_net_rx_queue_release (hw->eth_dev, i); + +rte_free (hw->eth_dev->data->tx_queues); +rte_free (hw->eth_dev->data->rx_queues); +rte_mempool_free (app_fw_flower->ctrl_pktmbuf_pool); +rte_eth_dev_release_port (hw->eth_dev); +} + +static int +nfp_flower_start_ctrl_vnic (struct nfp_net_hw *hw) +{ +int ret; +uint32_t update; +uint32_t new_ctrl; +struct rte_eth_dev *dev; + + dev = hw->eth_dev; + +/* Disabling queues just in case... */ +nfp_net_disable_queues (dev); + +/* Enabling the required queues in the device */ +nfp_net_enable_queues (dev); + +/* Writing configuration parameters in the device */ +nfp_net_params_setup (hw); + + new_ctrl =NFP_NET_CFG_CTRL_ENABLE ; + update =NFP_NET_CFG_UPDATE_GEN |NFP_NET_CFG_UPDATE_RING | +NFP_NET_CFG_UPDATE_MSIX ; + +rte_wmb (); + +/* If an error when reconfig we avoid to change hw state */ + ret =nfp_net_reconfig (hw, new_ctrl, update); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Failed to reconfig ctrl vnic" ); +return -EIO ; + } + + hw->ctrl = new_ctrl; + +/* Setup the freelist ring */ + ret =nfp_net_rx_freelist_setup (dev); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Error with flower ctrl vNIC freelist setup" ); +return -EIO ; + } + +return 0 ; +} +int nfp_init_app_fw_flower (struct nfp_pf_dev *pf_dev) {int ret;unsigned int numa_node;struct nfp_net_hw *pf_hw; +struct nfp_net_hw *ctrl_hw;struct nfp_app_fw_flower *app_fw_flower; numa_node =rte_socket_id ();
@@ -561,8 +747,42 @@ struct dp_packet { goto pf_vnic_cleanup; } +/* The ctrl vNIC struct comes directly after the PF one */ + app_fw_flower->ctrl_hw = pf_hw +1 ; + ctrl_hw = app_fw_flower->ctrl_hw; + +/* Map the ctrl vNIC ctrl bar */ + ctrl_hw->ctrl_bar =nfp_rtsym_map (pf_dev->sym_tbl,"_pf0_net_ctrl_bar" , +32768 , &ctrl_hw->ctrl_area); +if (ctrl_hw->ctrl_bar ==NULL ) { +PMD_INIT_LOG (ERR ,"Cloud not map the ctrl vNIC ctrl bar" ); + ret = -ENODEV ; + goto pf_vnic_cleanup; + } + +/* Now populate the ctrl vNIC */ + ctrl_hw->pf_dev = pf_dev; + ctrl_hw->cpp = pf_dev->cpp; + + ret =nfp_flower_init_ctrl_vnic (app_fw_flower->ctrl_hw); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not initialize flower ctrl vNIC" ); + goto ctrl_cpp_area_cleanup; + } + +/* Start the ctrl vNIC */ + ret =nfp_flower_start_ctrl_vnic (app_fw_flower->ctrl_hw); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not start flower ctrl vNIC" ); + goto ctrl_vnic_cleanup; + } +return 0 ; +ctrl_vnic_cleanup: +nfp_flower_cleanup_ctrl_vnic (app_fw_flower->ctrl_hw); +ctrl_cpp_area_cleanup: +nfp_cpp_area_free (ctrl_hw->ctrl_area); pf_vnic_cleanup:nfp_flower_cleanup_pf_vnic (app_fw_flower->pf_hw); pf_cpp_area_cleanup:
drivers/net/nfp/flower/nfp_flower.h +6 -0
@@ -14,6 +14,12 @@ struct nfp_app_fw_flower {/* Pointer to the PF vNIC */ struct nfp_net_hw *pf_hw; +/* Pointer to a mempool for the ctrlvNIC */ +struct rte_mempool *ctrl_pktmbuf_pool; + +/* Pointer to the ctrl vNIC */ +struct nfp_net_hw *ctrl_hw; +/* the eth table as reported by firmware */ struct nfp_eth_table *nfp_eth_table; };
drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c +19 -12
@@ -91,7 +91,10 @@* @refcnt: number of current users * @iomem: mapped IO memory */ +#define NFP_BAR_MIN 1 +#define NFP_BAR_MID 5#define NFP_BAR_MAX 7 +struct nfp_bar {struct nfp_pcie_user *nfp;uint32_t barcfg;
@@ -292,6 +295,7 @@ struct nfp_pcie_user {* BAR0.0: Reserved for General Mapping (for MSI-X access to PCIe SRAM) * * Halving PCItoCPPBars for primary and secondary processes. +* For CoreNIC firmware: * NFP PMD just requires two fixed slots, one for configuration BAR, * and another for accessing the hw queues. Another slot is needed * for setting the link up or down. Secondary processes do not need
@@ -301,6 +305,9 @@ struct nfp_pcie_user {* supported. Due to this requirement and future extensions requiring * new slots per process, only one secondary process is supported by * now. +* For Flower firmware: +* NFP PMD need another fixed slots, used as the configureation BAR +* for ctrl vNIC. */ static int nfp_enable_bars (struct nfp_pcie_user *nfp)
@@ -309,11 +316,11 @@ struct nfp_pcie_user {int x, start, end;if (rte_eal_process_type () ==RTE_PROC_PRIMARY ) { - start =4 ; - end =1 ; + start =NFP_BAR_MID ; + end =NFP_BAR_MIN ; }else { - start =7 ; - end =4 ; + start =NFP_BAR_MAX ; + end =NFP_BAR_MID ; }for (x = start; x > end; x--) { bar = &nfp->bar[x -1 ];
@@ -341,11 +348,11 @@ struct nfp_pcie_user {int x, start, end;if (rte_eal_process_type () ==RTE_PROC_PRIMARY ) { - start =4 ; - end =1 ; + start =NFP_BAR_MID ; + end =NFP_BAR_MIN ; }else { - start =7 ; - end =4 ; + start =NFP_BAR_MAX ; + end =NFP_BAR_MID ; }for (x = start; x > end; x--) { bar = &nfp->bar[x -1 ];
@@ -364,11 +371,11 @@ struct nfp_pcie_user {int x, start, end;if (rte_eal_process_type () ==RTE_PROC_PRIMARY ) { - start =4 ; - end =1 ; + start =NFP_BAR_MID ; + end =NFP_BAR_MIN ; }else { - start =7 ; - end =4 ; + start =NFP_BAR_MAX ; + end =NFP_BAR_MID ; }for (x = start; x > end; x--) {
Signature · 1 line
1.8.3.1
Re: [PATCH v9 07/12] net/nfp: add flower ctrl VNIC related logics
Quoted 8 lines · Chaoyong He
Adds the setup/start logic for the ctrl vNIC. This vNIC is used by the PMD and flower firmware application as a communication channel between driver and firmware. In the case of OVS it is also used to communicate flow statistics from hardware to the driver.
A
rte_ethdevice is not exposed to DPDK for this vNIC as it is strictly used internally by flower logic.
Hi Chaoyong,
Similar comment with previous versions, interface is created using regular 'rte_eth_dev_allocate()' API, I think interface will be visible to application, I can't understand the need of creating an interface for control.
What is the communication method between driver and FW?
Since one of the following patches (09/12) introduces Rx/Tx for ctrl interface, is device interface is control packets (similar to network data packets)?
Quoted 5 lines
Because of the add of ctrl vNIC, a new PCItoCPPBar is needed. Modify the related logics.
Signed-off-by Chaoyong He <[email protected]>Reviewed-by Niklas Söderlund <[email protected]>
<...>
RE: [PATCH v9 07/12] net/nfp: add flower ctrl VNIC related logics
Quoted 13 lines · Chaoyong He
Quoted 2 lines
Adds the setup/start logic for the ctrl vNIC. This vNIC is used by the PMD and flower firmware application as a communication channel
between
Quoted 6 lines
driver and firmware. In the case of OVS it is also used to communicate flow statistics from hardware to the driver.
A
rte_ethdevice is not exposed to DPDK for this vNIC as it is strictly used internally by flower logic.Hi Chaoyong,
Quoted 8 lines
Similar comment with previous versions, interface is created using regular '
rte_eth_dev_allocate()' API, I think interface will be visible to application, I can't understand the need of creating an interface for control.What is the communication method between driver and FW?
Since one of the following patches (09/12) introduces Rx/Tx for ctrl interface, is device interface is control packets (similar to network data packets)?
Basically, the 'control message' is exist in the form of normal data packets.
When we use the flower firmware application, there exist two types of packets for now, and they are identified only from the prepend meta-data.
Bit 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
-----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Word +---------------+---------------+---------------+---------------+
0 | type | type | type | type |
+---------------+---------------+---------------+---------------+
The 'control message' packets are processed by the ctrl vNIC. The 'normal' packets are processed by the pf vNIC.
The communication method between driver and firmware is decided by the designment of hardware and firmware.
The kernel driver also has the same ctrl vNIC and pf vNIC ethdev and the usage is same.
Quoted 7 lines
Quoted 5 lines
Because of the add of ctrl vNIC, a new PCItoCPPBar is needed. Modify the related logics.
Signed-off-by Chaoyong He <[email protected]>Reviewed-by Niklas Söderlund <[email protected]><...>
Re: [PATCH v9 07/12] net/nfp: add flower ctrl VNIC related logics
21/09/2022 04:02, Chaoyong He:
Quoted 11 lines
Quoted 11 lines · Chaoyong He
Quoted 2 lines
Adds the setup/start logic for the ctrl vNIC. This vNIC is used by the PMD and flower firmware application as a communication channel
between
Quoted 6 lines
driver and firmware. In the case of OVS it is also used to communicate flow statistics from hardware to the driver.
A
rte_ethdevice is not exposed to DPDK for this vNIC as it is strictly used internally by flower logic.
Quoted 5 lines
Quoted 5 lines
Hi Chaoyong,
Similar comment with previous versions, interface is created using regular '
rte_eth_dev_allocate()' API, I think interface will be visible to application, I can't understand the need of creating an interface for control.
You didn't reply to this.
Why the control port should be exposed to the application? We recommend not using ethdev for this.
Quoted 28 lines
Quoted 4 lines
What is the communication method between driver and FW?
Since one of the following patches (09/12) introduces Rx/Tx for ctrl interface, is device interface is control packets (similar to network data packets)?Basically, the 'control message' is exist in the form of normal data packets.
When we use the flower firmware application, there exist two types of packets for now, and they are identified only from the prepend meta-data.
Bit 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
-----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Word +---------------+---------------+---------------+---------------+
0 | type | type | type | type |+---------------+---------------+---------------+---------------+The 'control message' packets are processed by the ctrl vNIC. The 'normal' packets are processed by the pf vNIC.
The communication method between driver and firmware is decided by the designment of hardware and firmware.
The kernel driver also has the same ctrl vNIC and pf vNIC ethdev and the usage is same.
Quoted 5 lines
Quoted 5 lines
Because of the add of ctrl vNIC, a new PCItoCPPBar is needed. Modify the related logics.
Signed-off-by Chaoyong He <[email protected]>Reviewed-by Niklas Söderlund <[email protected]>
RE: [PATCH v9 07/12] net/nfp: add flower ctrl VNIC related logics
Quoted 14 lines
21/09/2022 04:02, Chaoyong He:
Quoted 13 lines
Quoted 13 lines · Chaoyong He
Quoted 2 lines
Adds the setup/start logic for the ctrl vNIC. This vNIC is used by the PMD and flower firmware application as a communication channel
between
Quoted 6 lines
driver and firmware. In the case of OVS it is also used to communicate flow statistics from hardware to the driver.
A
rte_ethdevice is not exposed to DPDK for this vNIC as it is strictly used internally by flower logic.Hi Chaoyong,
Quoted 9 lines
Quoted 3 lines
Quoted 3 lines
Similar comment with previous versions, interface is created using regular '
rte_eth_dev_allocate()' API, I think interface will be visible to application, I can't understand the need of creating an interfacefor control.
You didn't reply to this.
Why the control port should be exposed to the application? We recommend not using ethdev for this.
Actually, in the v1--v5 of this patch series, we did create a control port which is not in the rte_eth_devices[] array, so it won't exposed to the application.
Quoted 35 lines
Quoted 4 lines
Quoted 4 lines
What is the communication method between driver and FW?
Since one of the following patches (09/12) introduces Rx/Tx for ctrl interface, is device interface is control packets (similar to network datapackets)?
Quoted 12 lines
Quoted 1 line
Basically, the 'control message' is exist in the form of normal data packets.
When we use the flower firmware application, there exist two types of packets for now, and they are identified only from the prepend meta-data.
Bit 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
-----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Word +---------------+---------------+---------------+---------------+
0 | type | type | type | type |Quoted 5 lines
+---------------+---------------+---------------+---------------+
The 'control message' packets are processed by the ctrl vNIC. The 'normal' packets are processed by the pf vNIC.The communication method between driver and firmware is decided by
the
Quoted 3 lines
designment of hardware and firmware.
The kernel driver also has the same ctrl vNIC and pf vNIC ethdev and the
usage is same.
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Because of the add of ctrl vNIC, a new PCItoCPPBar is needed. Modify the related logics.
Signed-off-by Chaoyong He <[email protected]>Reviewed-by Niklas Söderlund <[email protected]>
PATCH v9 8/12 net/nfp: move common rxtx function for flower use
In reply to Chaoyong HeMove some common Rx and Tx logic to the header file so that they can be re-used by flower Tx and Rx logic.
--- drivers/net/nfp/nfp_rxtx.c | 32 +------------------------------- drivers/net/nfp/nfp_rxtx.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 31 deletions(-)
drivers/net/nfp/nfp_rxtx.c +1 -31
@@ -116,12 +116,6 @@return count; } -static inline void -nfp_net_mbuf_alloc_failed (struct nfp_net_rxq *rxq) -{ - rte_eth_devices[rxq->port_id].data->rx_mbuf_alloc_failed++; -} -/* * nfp_net_set_hash - Set mbuf hash data *
@@ -583,7 +577,7 @@* @txq: TX queue to work with * Returns number of descriptors freed */ -static int +int nfp_net_tx_free_bufs (struct nfp_net_txq *txq) {uint32_t qcp_rd_p;
@@ -774,30 +768,6 @@return 0 ; } -/* Leaving always free descriptors for avoiding wrapping confusion */ -static inline -uint32_t nfp_net_nfd3_free_tx_desc (struct nfp_net_txq *txq) -{ -if (txq->wr_p >= txq->rd_p) -return txq->tx_count - (txq->wr_p - txq->rd_p) -8 ; -else -return txq->rd_p - txq->wr_p -8 ; -} - -/* -* nfp_net_txq_full - Check if the TX queue free descriptors -* is below tx_free_threshold -* -* @txq: TX queue to check -* -* This function uses the host copy* of read/write pointers -*/ -static inline -uint32_t nfp_net_nfd3_txq_full (struct nfp_net_txq *txq) -{ -return (nfp_net_nfd3_free_tx_desc (txq) < txq->tx_free_thresh); -} -/* nfp_net_tx_tso - Set TX descriptor for TSO */ static inline void nfp_net_nfd3_tx_tso(struct nfp_net_txq *txq, struct nfp_net_nfd3_tx_desc *txd,
drivers/net/nfp/nfp_rxtx.h +31 -0
@@ -330,6 +330,36 @@ struct nfp_net_rxq {int rx_qcidx; }__rte_aligned (64 ); +static inline void +nfp_net_mbuf_alloc_failed (struct nfp_net_rxq *rxq) +{ + rte_eth_devices[rxq->port_id].data->rx_mbuf_alloc_failed++; +} + +/* Leaving always free descriptors for avoiding wrapping confusion */ +static inline uint32_t +nfp_net_nfd3_free_tx_desc (struct nfp_net_txq *txq) +{ +if (txq->wr_p >= txq->rd_p) +return txq->tx_count - (txq->wr_p - txq->rd_p) -8 ; +else +return txq->rd_p - txq->wr_p -8 ; +} + +/* +* nfp_net_nfd3_txq_full - Check if the TX queue free descriptors +* is below tx_free_threshold +* +* @txq: TX queue to check +* +* This function uses the host copy* of read/write pointers +*/ +static inline uint32_t +nfp_net_nfd3_txq_full (struct nfp_net_txq *txq) +{ +return (nfp_net_nfd3_free_tx_desc (txq) < txq->tx_free_thresh); +} +int nfp_net_rx_freelist_setup (struct rte_eth_dev *dev);uint32_t nfp_net_rx_queue_count (void *rx_queue); uint16_t nfp_net_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
@@ -355,6 +385,7 @@ int nfp_net_nfdk_tx_queue_setup(struct rte_eth_dev *dev,uint16_t nfp_net_nfdk_xmit_pkts (void *tx_queue,struct rte_mbuf **tx_pkts,uint16_t nb_pkts); +int nfp_net_tx_free_bufs (struct nfp_net_txq *txq);#endif /* _NFP_RXTX_H_ */ /*
Signature · 1 line
1.8.3.1
PATCH v9 9/12 net/nfp: add flower ctrl VNIC rxtx logic
In reply to Chaoyong HeAdds the Rx and Tx function for the ctrl VNIC. The logic is mostly identical to the normal Rx and Tx functionality of the NFP PMD.
Make use of the ctrl VNIC service logic to service the ctrl vNIC Rx path.
--- doc/guides/rel_notes/release_22_11.rst | 1 + drivers/net/nfp/flower/nfp_flower.c | 59 ++++++++ drivers/net/nfp/flower/nfp_flower.h | 21 +++ drivers/net/nfp/flower/nfp_flower_ctrl.c | 250 +++++++++++++++++++++++++++++++ drivers/net/nfp/flower/nfp_flower_ctrl.h | 13 ++ drivers/net/nfp/meson.build | 1 + 6 files changed, 345 insertions(+) create mode 100644 drivers/net/nfp/flower/nfp_flower_ctrl.c create mode 100644 drivers/net/nfp/flower/nfp_flower_ctrl.h
doc/guides/rel_notes/release_22_11.rst +1 -0
@@ -61,6 +61,7 @@ New Features * Added the support of flower firmware. * Added the flower service infrastructure. + * Added the control message interactive channels between PMD and firmware. Removed Items
drivers/net/nfp/flower/nfp_flower.c +59 -0
77 lines not on this page · raw message
drivers/net/nfp/flower/nfp_flower.h +21 -0
@@ -6,8 +6,23 @@ #ifndef _NFP_FLOWER_H_ #define _NFP_FLOWER_H_ +enum nfp_flower_service { + NFP_FLOWER_SERVICE_CTRL, + NFP_FLOWER_SERVICE_MAX, +}; +/* + * Flower fallback and ctrl path always adds and removes + * 8 bytes of prepended data. Tx descriptors must point + * to the correct packet data offset after metadata has + * been added + */ +#define FLOWER_PKT_DATA_OFFSET 8 + /* The flower application's private structure */ struct nfp_app_fw_flower { + /* List of rte_service ID's */ + uint32_t service_ids[NFP_FLOWER_SERVICE_MAX]; + /* Pointer to a mempool for the PF vNIC */ struct rte_mempool *pf_pktmbuf_pool;
@@ -22,6 +37,12 @@ struct nfp_app_fw_flower {/* the eth table as reported by firmware */ struct nfp_eth_table *nfp_eth_table; + +/* Ctrl vNIC Rx counter */ +uint64_t ctrl_vnic_rx_count; + +/* Ctrl vNIC Tx counter */ +uint64_t ctrl_vnic_tx_count; };int nfp_init_app_fw_flower (struct nfp_pf_dev *pf_dev);
drivers/net/nfp/flower/nfp_flower_ctrl.c new file +250 -0
250 lines not on this page · raw message
drivers/net/nfp/flower/nfp_flower_ctrl.h new file +13 -0
@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright (c) 2022 Corigine, Inc. +* All rights reserved. +*/ + +#ifndef _NFP_FLOWER_CTRL_H_ +#define _NFP_FLOWER_CTRL_H_ + +void nfp_flower_ctrl_vnic_poll (struct nfp_app_fw_flower *app_fw_flower); +uint16_t nfp_flower_ctrl_vnic_xmit (struct nfp_app_fw_flower *app_fw_flower, +struct rte_mbuf *mbuf); + +#endif /* _NFP_FLOWER_CTRL_H_ */
drivers/net/nfp/meson.build +1 -0
@@ -7,6 +7,7 @@ if not is_linux or not dpdk_conf.get('RTE_ARCH_64') endif sources = files( 'flower/nfp_flower.c', + 'flower/nfp_flower_ctrl.c', 'nfpcore/nfp_cpp_pcie_ops.c', 'nfpcore/nfp_nsp.c', 'nfpcore/nfp_cppcore.c',
Signature · 1 line
1.8.3.1
PATCH v9 10/12 net/nfp: add flower representor framework
In reply to Chaoyong HeAdds the framework to support flower representors. The number of VF representors are parsed from the command line. For physical port representors the current logic aims to create a representor for each physical port present on the hardware.
An eth_dev is created for each physical port and VF, and flower firmware requires a MAC repr cmsg to be transmitted to firmware with info about the number of physical ports configured.
Reify messages are sent to hardware for each physical port representor. An rte_ring is also created per representor so that traffic can be pushed and pulled to this interface.
To up and down the real device represented by a flower representor port a port mod message is used to convey that info to the firmware. This message will be used in the dev_ops callbacks of flower representors.
Each cmsg generated by the driver is prepended with a cmsg header. This commit also adds the logic to fill in the header of cmsgs.
Also add the Rx and Tx path for flower representors. For Rx packets are dequeued from the representor ring and passed to the eth_dev. For Tx the first queue of the PF vNIC is used. Metadata about the representor is added before the packet is sent down to firmware.
--- doc/guides/nics/nfp.rst | 6 + doc/guides/rel_notes/release_22_11.rst | 1 + drivers/net/nfp/flower/nfp_flower.c | 7 + drivers/net/nfp/flower/nfp_flower.h | 18 + drivers/net/nfp/flower/nfp_flower_cmsg.c | 185 +++++++ drivers/net/nfp/flower/nfp_flower_cmsg.h | 173 ++++++ drivers/net/nfp/flower/nfp_flower_representor.c | 664 ++++++++++++++++++++++++ drivers/net/nfp/flower/nfp_flower_representor.h | 39 ++ drivers/net/nfp/meson.build | 2 + 9 files changed, 1095 insertions(+) create mode 100644 drivers/net/nfp/flower/nfp_flower_cmsg.c create mode 100644 drivers/net/nfp/flower/nfp_flower_cmsg.h create mode 100644 drivers/net/nfp/flower/nfp_flower_representor.c create mode 100644 drivers/net/nfp/flower/nfp_flower_representor.h
doc/guides/nics/nfp.rst +6 -0
@@ -194,3 +194,9 @@ The flower firmware application requires the PMD running two services: * PF vNIC service: handling the feedback traffic. * ctrl vNIC service: communicate between PMD and firmware through control message. + +To achieve the offload of flow, the representor ports are exposed to OVS. +The flower firmware application support representor port for VF and physical +port. There will always exist a representor port for each physical port, +and the number of the representor port for VF is specified by the user through +parameter.
doc/guides/rel_notes/release_22_11.rst +1 -0
@@ -62,6 +62,7 @@ New Features * Added the support of flower firmware. * Added the flower service infrastructure. * Added the control message interactive channels between PMD and firmware. + * Added the support of representor port. Removed Items
drivers/net/nfp/flower/nfp_flower.c +7 -0
@@ -21,6 +21,7 @@#include "../nfpcore/nfp_nsp.h" #include "nfp_flower.h" #include "nfp_flower_ctrl.h" +#include "nfp_flower_representor.h" #define MAX_PKT_BURST 32#define MBUF_PRIV_SIZE 128
@@ -836,6 +837,12 @@ struct dp_packet { goto ctrl_vnic_cleanup; } + ret =nfp_flower_repr_create (app_fw_flower); +if (ret !=0 ) { +PMD_INIT_LOG (ERR ,"Could not create representor ports" ); + goto ctrl_vnic_cleanup; + } +return 0 ; ctrl_vnic_cleanup:
drivers/net/nfp/flower/nfp_flower.h +18 -0
@@ -18,8 +18,20 @@ enum nfp_flower_service {*/ #define FLOWER_PKT_DATA_OFFSET 8 +#define MAX_FLOWER_PHYPORTS 8 +#define MAX_FLOWER_VFS 64 +/* The flower application's private structure */ struct nfp_app_fw_flower { +/* switch domain for this app */ +uint16_t switch_domain_id; + +/* Number of VF representors */ +uint8_t num_vf_reprs; + +/* Number of phyport representors */ +uint8_t num_phyport_reprs; +/* List of rte_service ID's */ uint32_t service_ids[NFP_FLOWER_SERVICE_MAX ];
@@ -43,6 +55,12 @@ struct nfp_app_fw_flower {/* Ctrl vNIC Tx counter */ uint64_t ctrl_vnic_tx_count; + +/* Array of phyport representors */ +struct nfp_flower_representor *phy_reprs[MAX_FLOWER_PHYPORTS ]; + +/* Array of VF representors */ +struct nfp_flower_representor *vf_reprs[MAX_FLOWER_VFS ]; };int nfp_init_app_fw_flower (struct nfp_pf_dev *pf_dev);
drivers/net/nfp/flower/nfp_flower_cmsg.c new file +185 -0
185 lines not on this page · raw message
drivers/net/nfp/flower/nfp_flower_cmsg.h new file +173 -0
173 lines not on this page · raw message
drivers/net/nfp/flower/nfp_flower_representor.c new file +664 -0
664 lines not on this page · raw message
drivers/net/nfp/flower/nfp_flower_representor.h new file +39 -0
@@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(c) 2022 Corigine, Inc. +* All rights reserved. +*/ + +#ifndef _NFP_FLOWER_REPRESENTOR_H_ +#define _NFP_FLOWER_REPRESENTOR_H_ + +/* +* enum nfp_repr_type - type of representor +* @NFP_REPR_TYPE_PHYS_PORT: external NIC port +* @NFP_REPR_TYPE_PF: physical function +* @NFP_REPR_TYPE_VF: virtual function +* @NFP_REPR_TYPE_MAX: number of representor types +*/ +enum nfp_repr_type { +NFP_REPR_TYPE_PHYS_PORT =0 , +NFP_REPR_TYPE_PF , +NFP_REPR_TYPE_VF , +NFP_REPR_TYPE_MAX , +}; + +struct nfp_flower_representor { +uint16_t vf_id; +uint16_t switch_domain_id; +uint32_t repr_type; +uint32_t port_id; +uint32_t nfp_idx;/* only valid for the repr of physical port */ +char name[RTE_ETH_NAME_MAX_LEN ]; +struct rte_ether_addr mac_addr; +struct nfp_app_fw_flower *app_fw_flower; +struct rte_ring *ring; +struct rte_eth_link link; +struct rte_eth_stats repr_stats; +}; + +int nfp_flower_repr_create (struct nfp_app_fw_flower *app_fw_flower); + +#endif /* _NFP_FLOWER_REPRESENTOR_H_ */
drivers/net/nfp/meson.build +2 -0
@@ -7,7 +7,9 @@ if not is_linux or not dpdk_conf.get('RTE_ARCH_64') endif sources = files( 'flower/nfp_flower.c', + 'flower/nfp_flower_cmsg.c', 'flower/nfp_flower_ctrl.c', + 'flower/nfp_flower_representor.c', 'nfpcore/nfp_cpp_pcie_ops.c', 'nfpcore/nfp_nsp.c', 'nfpcore/nfp_cppcore.c',
Signature · 1 line
1.8.3.1
PATCH v9 11/12 net/nfp: move rxtx function to header file
In reply to Chaoyong HeThe flower firmware application makes use of the same Rx and Tx checksum logic as the normal PMD. Expose it so that flower firmware application also can make use of it.
--- drivers/net/nfp/nfp_common.c | 2 +- drivers/net/nfp/nfp_ethdev.c | 2 +- drivers/net/nfp/nfp_ethdev_vf.c | 2 +- drivers/net/nfp/nfp_rxtx.c | 91 +---------------------------------------- drivers/net/nfp/nfp_rxtx.h | 90 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 93 deletions(-)
drivers/net/nfp/nfp_common.c +1 -1
@@ -38,9 +38,9 @@#include "nfpcore/nfp_nsp.h" #include "nfp_common.h" +#include "nfp_ctrl.h" #include "nfp_rxtx.h" #include "nfp_logs.h" -#include "nfp_ctrl.h" #include "nfp_cpp_bridge.h" #include <sys/types.h>
drivers/net/nfp/nfp_ethdev.c +1 -1
@@ -33,9 +33,9 @@#include "nfpcore/nfp_nsp.h" #include "nfp_common.h" +#include "nfp_ctrl.h" #include "nfp_rxtx.h" #include "nfp_logs.h" -#include "nfp_ctrl.h" #include "nfp_cpp_bridge.h" #include "flower/nfp_flower.h"
drivers/net/nfp/nfp_ethdev_vf.c +1 -1
@@ -19,9 +19,9 @@#include "nfpcore/nfp_rtsym.h" #include "nfp_common.h" +#include "nfp_ctrl.h" #include "nfp_rxtx.h" #include "nfp_logs.h" -#include "nfp_ctrl.h" static void nfp_netvf_read_mac (struct nfp_net_hw *hw)
drivers/net/nfp/nfp_rxtx.c +1 -90
111 lines not on this page · raw message
drivers/net/nfp/nfp_rxtx.h +90 -0
96 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v9 12/12 net/nfp: add flower PF rxtx logic
In reply to Chaoyong HeImplements the flower Rx logic. Fallback packets are multiplexed to the correct representor port based on the prepended metadata. The Rx poll is set to run on the existing service infrastructure.
For Tx the existing NFP Tx logic is duplicated to keep the Tx two paths distinct. Flower fallback also adds 8 bytes of metadata to the start of the packet that has to be adjusted for in the Tx descriptor.
--- doc/guides/nics/nfp.rst | 13 ++ drivers/net/nfp/flower/nfp_flower.c | 425 ++++++++++++++++++++++++++++++++++++ drivers/net/nfp/flower/nfp_flower.h | 1 + 3 files changed, 439 insertions(+)
doc/guides/nics/nfp.rst +13 -0
@@ -200,3 +200,16 @@ The flower firmware application support representor port for VF and physical port. There will always exist a representor port for each physical port, and the number of the representor port for VF is specified by the user through parameter. + +In the Rx direction, the flower firmware application will prepend the input +port information into metadata for each packet which can't offloaded. The PF +vNIC service will keep polling packets from the firmware, and multiplex them +to the corresponding representor port. + +In the Tx direction, the representor port will prepend the output port +information into metadata for each packet, and then send it to firmware through +PF vNIC. + +The ctrl vNIC service handling various control message, like the creation and +configuration of representor port, the pattern and action of flow rules, the +statistics of flow rules, and so on.
drivers/net/nfp/flower/nfp_flower.c +425 -0
461 lines not on this page · raw message
drivers/net/nfp/flower/nfp_flower.h +1 -0
@@ -7,6 +7,7 @@#define _NFP_FLOWER_H_enum nfp_flower_service { +NFP_FLOWER_SERVICE_PF ,NFP_FLOWER_SERVICE_CTRL ,NFP_FLOWER_SERVICE_MAX , };
Signature · 1 line
1.8.3.1
Quoted 35 lines · Chaoyong He
* Changes since v8
- Update thenfp.rst
- Fix the 'app_hw' to 'app_fw'
- Remove the ovs compatible header file
- Remove the use of rte_eth_dev_configure()/rte_eth_rx_burst()/rte_eth_dev_start() API* Changes since v7
- Adjust the logics to make sure not break the pci probe process
- Change 'app' to 'app_fw' in all logics to avoid confuse
- Fix problem about log level* Changes since v6
- Fix the compile error* Changes since v5
- Compare integer with 0 explicitly
- Change helper macro to function
- Implement the dummy functions
- Remove some unnecessary logics* Changes since v4
- Remove the unneeded '__rte_unused' attribute
- Fixup a potential memory leak problem* Changes since v3
- Add the 'Depends-on' tag* Changes since v2
- Remove the use ofrte_panic()* Changes since v1
- Fix the compile errorDepends-on: series-23707 ("Add support of NFP3800 chip and firmware with NFDk")
Quoted 14 lines
Chaoyong He (12):
net/nfp: move app specific attributes to own struct net/nfp: simplify initialization and remove dead code net/nfp: move app specific init logic to own function net/nfp: add initial flower firmware support net/nfp: add flower PF setup logic
net/nfp: add flower PF related routines net/nfp: add flower ctrl VNIC related logics net/nfp: move common rxtx function for flower use net/nfp: add flower ctrl VNIC rxtx logic net/nfp: add flower representor framework net/nfp: move rxtx function to header file net/nfp: add flower PF rxtx logic
Hi Chaoyong,
Patchset looks good, except from two issues we have discussed before, those issues are:
* Creating a new ethdev just for driver-FW control communication
* Application (OvS) specific code in the driver
I commented them separately and cc'ed more folks, we can proceed when above are resolved.
Thanks,
ferruh