[PATCH v4 00/25] Net/SPNIC: support SPNIC into DPDK 22.03
The patchsets introduce SPNIC driver for Ramaxel's SPNxx serial NIC cards into DPDK 22.03. Ramaxel Memory Technology is a company which supply a lot of electric products: storage, communication, PCB... SPNxxx is a serial PCIE interface NIC cards: SPN110: 2 PORTs *25G SPN120: 4 PORTs *25G SPN130: 2 PORTs *100G The following is main features of our SPNIC: - TSO - LRO - Flow control - SR-IOV(Partially supported) - VLAN offload - VLAN filter - CRC offload - Promiscuous mode - RSS v3->v4: 1. Fix ABI test failure; 2. Remove some descriptions in spnic.rst. v2->v3: 1. Fix clang compiling failure. v1->v2: 1. Fix coding style issues and compiling failures; 2. Only support linux in meson.build; 3. Use CLOCK_MONOTONIC_COARSE instead of CLOCK_MONOTONIC/CLOCK_MONOTONIC_RAW; 4. Fix time_before(); 5. Remove redundant checks in spnic_dev_configure(); Yanling Song (25): drivers/net: introduce a new PMD driver net/spnic: initialize the HW interface net/spnic: add mbox message channel net/spnic: introduce event queue net/spnic: add mgmt module net/spnic: add cmdq and work queue net/spnic: add interface handling cmdq message net/spnic: add hardware info initialization net/spnic: support MAC and link event handling net/spnic: add function info initialization net/spnic: add queue pairs context initialization net/spnic: support mbuf handling of Tx/Rx net/spnic: support Rx congfiguration net/spnic: add port/vport enable net/spnic: support IO packets handling net/spnic: add device configure/version/info net/spnic: support RSS configuration update and get net/spnic: support VLAN filtering and offloading net/spnic: support promiscuous and allmulticast Rx modes net/spnic: support flow control net/spnic: support getting Tx/Rx queues info net/spnic: net/spnic: support xstats statistics net/spnic: support VFIO interrupt net/spnic: support Tx/Rx queue start/stop net/spnic: add doc infrastructure MAINTAINERS |6 + doc/guides/nics/features/spnic.ini | 39 + doc/guides/nics/index.rst|1 + doc/guides/nics/spnic.rst| 55 + drivers/net/meson.build |1 + drivers/net/spnic/base/meson.build | 37 + drivers/net/spnic/base/spnic_cmd.h | 222 ++ drivers/net/spnic/base/spnic_cmdq.c | 875 ++ drivers/net/spnic/base/spnic_cmdq.h | 248 ++ drivers/net/spnic/base/spnic_compat.h| 184 ++ drivers/net/spnic/base/spnic_csr.h | 104 + drivers/net/spnic/base/spnic_eqs.c | 661 + drivers/net/spnic/base/spnic_eqs.h | 102 + drivers/net/spnic/base/spnic_hw_cfg.c| 212 ++ drivers/net/spnic/base/spnic_hw_cfg.h| 125 + drivers/net/spnic/base/spnic_hw_comm.c | 485 drivers/net/spnic/base/spnic_hw_comm.h | 204 ++ drivers/net/spnic/base/spnic_hwdev.c | 514 drivers/net/spnic/base/spnic_hwdev.h | 143 + drivers/net/spnic/base/spnic_hwif.c | 774 ++ drivers/net/spnic/base/spnic_hwif.h | 155 ++ drivers/net/spnic/base/spnic_mbox.c | 1194 drivers/net/spnic/base/spnic_mbox.h | 202 ++ drivers/net/spnic/base/spnic_mgmt.c | 367 +++ drivers/net/spnic/base/spnic_mgmt.h | 110 + drivers/net/spnic/base/spnic_nic_cfg.c | 1348 + drivers/net/spnic/base/spnic_nic_cfg.h | 1110 drivers/net/spnic/base/spnic_nic_event.c | 185 ++ drivers/net/spnic/base/spnic_nic_event.h | 24 + drivers/net/spnic/base/spnic_wq.c| 139 + drivers/net/spnic/base/spnic_wq.h| 123 + drivers/net/spnic/meson.build| 20 + drivers/net/spnic/spnic_ethdev.c | 3212 ++ drivers/net/spnic/spnic_ethdev.h | 95 + drivers/net/spnic/spnic_io.c | 738 + drivers/net/spnic/spnic_io.h | 154 ++ drivers/net/spnic/spnic_rx.c | 937 +++ drivers/net/spnic/spnic_rx.h | 326 +++ drivers/net/spnic/spnic_tx.c | 858 ++ drivers/net/spnic/spnic_tx.h | 297 ++ drivers/net/spnic/version.map|3 + 41 files changed, 16589 insertions(+) create mode 100644 doc/guides/nics/features/spnic.ini create mode 100644 doc/guides/nics/spnic.rst create mode 100644 drivers/net/spnic/base/meson.build create mode 100644 drivers/net/spnic/base/spnic_cmd.h create mode 100644 drivers/net/spnic/base/spnic_cmdq.c create mode 100644 drivers/net/spnic/base/spnic_cmdq.h create mode 100644 drivers/net/spnic/base/spnic_compat.h create mode 100644 drivers/net/spnic/base/spnic_csr.h create mode 100644 drivers/net/spnic/base/spnic_eqs.c create mode 100644 drivers/net/spnic/base/spnic_eqs.h create mode 100644 drivers/net/spnic/base/spnic_hw_cfg.c create mode 100644 drivers/net/spnic/base/spnic_hw_cfg.h create mode 100644 drivers/net/spnic/base/spnic_hw_comm.c create mode 100644 drivers/net/spnic/base/spnic_hw_comm.h create mode 100644 drivers/net/spnic/base/
[PATCH v4 01/25] drivers/net: introduce a new PMD driver
Introduce a new PMD driver which names spnic. Now, this driver only implements module entry without doing anything else. Signed-off-by: Yanling Song --- drivers/net/meson.build | 1 + drivers/net/spnic/base/meson.build| 26 drivers/net/spnic/base/spnic_compat.h | 184 ++ drivers/net/spnic/meson.build | 17 +++ drivers/net/spnic/spnic_ethdev.c | 107 +++ drivers/net/spnic/spnic_ethdev.h | 28 drivers/net/spnic/version.map | 3 + 7 files changed, 366 insertions(+) create mode 100644 drivers/net/spnic/base/meson.build create mode 100644 drivers/net/spnic/base/spnic_compat.h create mode 100644 drivers/net/spnic/meson.build create mode 100644 drivers/net/spnic/spnic_ethdev.c create mode 100644 drivers/net/spnic/spnic_ethdev.h create mode 100644 drivers/net/spnic/version.map diff --git a/drivers/net/meson.build b/drivers/net/meson.build index 2355d1cde8..a5c715f59c 100644 --- a/drivers/net/meson.build +++ b/drivers/net/meson.build @@ -53,6 +53,7 @@ drivers = [ 'ring', 'sfc', 'softnic', + 'spnic', 'tap', 'thunderx', 'txgbe', diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build new file mode 100644 index 00..e83a473881 --- /dev/null +++ b/drivers/net/spnic/base/meson.build @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2021 Ramaxel Memory Technology, Ltd + +sources = [ +] + +extra_flags = [] +# The driver runs only on arch64 machine, remove 32bit warnings +if not dpdk_conf.get('RTE_ARCH_64') +extra_flags += ['-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast'] +endif + +foreach flag: extra_flags +if cc.has_argument(flag) +cflags += flag +endif +endforeach + +deps += ['hash'] +cflags += ['-DHW_CONVERT_ENDIAN'] +c_args = cflags + +base_lib = static_library('spnic_base', sources, + dependencies: [static_rte_eal, static_rte_ethdev, static_rte_bus_pci, static_rte_hash], + c_args: c_args) +base_objs = base_lib.extract_all_objects() diff --git a/drivers/net/spnic/base/spnic_compat.h b/drivers/net/spnic/base/spnic_compat.h new file mode 100644 index 00..97f817cba9 --- /dev/null +++ b/drivers/net/spnic/base/spnic_compat.h @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Ramaxel Memory Technology, Ltd + */ + +#ifndef _SPNIC_COMPAT_H_ +#define _SPNIC_COMPAT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef uint8_t u8; +typedef int8_ts8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef int32_t s32; +typedef uint64_t u64; + +#ifndef BIT +#define BIT(n) (1 << (n)) +#endif + +#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16)) +#define lower_32_bits(n) ((u32)(n)) + +#define SPNIC_MEM_ALLOC_ALIGN_MIN 1 + +#define SPNIC_DRIVER_NAME "spnic" + +extern int spnic_logtype; + +#define PMD_DRV_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, spnic_logtype, \ + SPNIC_DRIVER_NAME ": " fmt "\n", ##args) + +/* Bit order interface */ +#define cpu_to_be16(o) rte_cpu_to_be_16(o) +#define cpu_to_be32(o) rte_cpu_to_be_32(o) +#define cpu_to_be64(o) rte_cpu_to_be_64(o) +#define cpu_to_le32(o) rte_cpu_to_le_32(o) +#define be16_to_cpu(o) rte_be_to_cpu_16(o) +#define be32_to_cpu(o) rte_be_to_cpu_32(o) +#define be64_to_cpu(o) rte_be_to_cpu_64(o) +#define le32_to_cpu(o) rte_le_to_cpu_32(o) + +#define ARRAY_LEN(arr) ((sizeof(arr) / sizeof((arr)[0]))) + +#define SPNIC_MUTEX_TIMEOUT10 +#define SPNIC_S_TO_MS_UNIT 1000 +#define SPNIC_S_TO_NS_UNIT 100 + +static inline unsigned long clock_gettime_ms(void) +{ + struct timespec tv; + + (void)clock_gettime(CLOCK_MONOTONIC_COARSE, &tv); + + return (unsigned long)tv.tv_sec * SPNIC_S_TO_MS_UNIT + + (unsigned long)tv.tv_nsec / SPNIC_S_TO_NS_UNIT; +} + +#define jiffiesclock_gettime_ms() +#define msecs_to_jiffies(ms) (ms) + +#define time_after(a, b) ((long)((b) - (a)) < 0) +#define time_before(a, b) time_after(b, a) + +/** + * Convert data to big endian 32 bit format + * + * @param data + * The data to convert + * @param len + * Length of data to convert, must be Multiple of 4B + */ +static inline void spnic_cpu_to_be32(void *data, int len) +{ + int i, chunk_sz = sizeof(u32); + u32 *mem = data; + + if (!data) + return; + + len = len / chunk_sz; + + for (i = 0; i < len; i++) { + *mem = cpu_to_be32(*mem); + mem++; + } +} + +/** + * Convert data from big endian 32 bit format + * + * @param data + * The data to convert + * @param len + * Length of data to convert, must be Multiple of 4B + */ +static inline void spnic_be32_to_cpu(void *data, int len) +{ +
[PATCH v4 03/25] net/spnic: add mbox message channel
This patch adds a message channel named mbox which can send message form PF/VF driver to hardware or sned message from VF to PF. Signed-off-by: Yanling Song --- drivers/net/spnic/base/meson.build |3 +- drivers/net/spnic/base/spnic_hwdev.c | 69 ++ drivers/net/spnic/base/spnic_hwdev.h |6 + drivers/net/spnic/base/spnic_mbox.c | 1158 ++ drivers/net/spnic/base/spnic_mbox.h | 202 + drivers/net/spnic/base/spnic_mgmt.h | 36 + 6 files changed, 1473 insertions(+), 1 deletion(-) create mode 100644 drivers/net/spnic/base/spnic_mbox.c create mode 100644 drivers/net/spnic/base/spnic_mbox.h create mode 100644 drivers/net/spnic/base/spnic_mgmt.h diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build index edd6e94772..de80eef7c4 100644 --- a/drivers/net/spnic/base/meson.build +++ b/drivers/net/spnic/base/meson.build @@ -3,7 +3,8 @@ sources = [ 'spnic_hwdev.c', - 'spnic_hwif.c' + 'spnic_hwif.c', + 'spnic_mbox.c' ] extra_flags = [] diff --git a/drivers/net/spnic/base/spnic_hwdev.c b/drivers/net/spnic/base/spnic_hwdev.c index de73f244fd..bcecbaa895 100644 --- a/drivers/net/spnic/base/spnic_hwdev.c +++ b/drivers/net/spnic/base/spnic_hwdev.c @@ -5,8 +5,66 @@ #include "spnic_compat.h" #include "spnic_csr.h" #include "spnic_hwif.h" +#include "spnic_mgmt.h" +#include "spnic_mbox.h" #include "spnic_hwdev.h" +int vf_handle_pf_comm_mbox(void *handle, __rte_unused void *pri_handle, + __rte_unused u16 cmd, __rte_unused void *buf_in, + __rte_unused u16 in_size, __rte_unused void *buf_out, + __rte_unused u16 *out_size) +{ + struct spnic_hwdev *hwdev = handle; + + if (!hwdev) + return -EINVAL; + + PMD_DRV_LOG(WARNING, "Unsupported pf mbox event %d to process", cmd); + + return 0; +} + +static int init_mgmt_channel(struct spnic_hwdev *hwdev) +{ + int err; + + err = spnic_func_to_func_init(hwdev); + if (err) { + PMD_DRV_LOG(ERR, "Init mailbox channel failed"); + goto func_to_func_init_err; + } + + return 0; + +func_to_func_init_err: + + return err; +} + +static void free_mgmt_channel(struct spnic_hwdev *hwdev) +{ + spnic_func_to_func_free(hwdev); +} + + +static int spnic_init_comm_ch(struct spnic_hwdev *hwdev) +{ + int err; + + err = init_mgmt_channel(hwdev); + if (err) { + PMD_DRV_LOG(ERR, "Init mgmt channel failed"); + return err; + } + + return 0; +} + +static void spnic_uninit_comm_ch(struct spnic_hwdev *hwdev) +{ + free_mgmt_channel(hwdev); +} + int spnic_init_hwdev(struct spnic_hwdev *hwdev) { int err; @@ -25,8 +83,17 @@ int spnic_init_hwdev(struct spnic_hwdev *hwdev) goto init_hwif_err; } + err = spnic_init_comm_ch(hwdev); + if (err) { + PMD_DRV_LOG(ERR, "Init communication channel failed"); + goto init_comm_ch_err; + } + return 0; +init_comm_ch_err: + spnic_free_hwif(hwdev); + init_hwif_err: rte_free(hwdev->chip_fault_stats); @@ -35,6 +102,8 @@ int spnic_init_hwdev(struct spnic_hwdev *hwdev) void spnic_free_hwdev(struct spnic_hwdev *hwdev) { + spnic_uninit_comm_ch(hwdev); + spnic_free_hwif(hwdev); rte_free(hwdev->chip_fault_stats); diff --git a/drivers/net/spnic/base/spnic_hwdev.h b/drivers/net/spnic/base/spnic_hwdev.h index c89a4fa840..4a20e34754 100644 --- a/drivers/net/spnic/base/spnic_hwdev.h +++ b/drivers/net/spnic/base/spnic_hwdev.h @@ -17,12 +17,18 @@ struct spnic_hwdev { uint16_t port_id; struct spnic_hwif *hwif; + struct spnic_mbox *func_to_func; u8 *chip_fault_stats; u16 max_vfs; u16 link_status; }; +int vf_handle_pf_comm_mbox(void *handle, __rte_unused void *pri_handle, + __rte_unused u16 cmd, __rte_unused void *buf_in, + __rte_unused u16 in_size, __rte_unused void *buf_out, + __rte_unused u16 *out_size); + int spnic_init_hwdev(struct spnic_hwdev *hwdev); void spnic_free_hwdev(struct spnic_hwdev *hwdev); diff --git a/drivers/net/spnic/base/spnic_mbox.c b/drivers/net/spnic/base/spnic_mbox.c new file mode 100644 index 00..0a15017874 --- /dev/null +++ b/drivers/net/spnic/base/spnic_mbox.c @@ -0,0 +1,1158 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Ramaxel Memory Technology, Ltd + */ + +#include +#include +#include "spnic_compat.h" +#include "spnic_hwdev.h" +#include "spnic_csr.h" +#include "spnic_hwif.h" +#include "spnic_mgmt.h" +#include "spnic_mbox.h" + +#define SPNIC_MBOX_INT_DST_FUNC_SHIFT 0 +#define SPNIC_MBOX_INT_DST_AEQN_SHIFT 10 +#define SPNIC_MBOX_INT_SRC_RESP_AEQN_SHIFT 12 +#def
[PATCH v4 04/25] net/spnic: introduce event queue
This patch introduce event queue to receive response message from hardware or destiation function when a source function send mbox to it. This commit implements the related data structure, initialization and interfaces handling the message. Signed-off-by: Yanling Song --- drivers/net/spnic/base/meson.build | 1 + drivers/net/spnic/base/spnic_eqs.c | 606 +++ drivers/net/spnic/base/spnic_eqs.h | 102 + drivers/net/spnic/base/spnic_hwdev.c | 44 +- drivers/net/spnic/base/spnic_hwdev.h | 22 + drivers/net/spnic/base/spnic_mbox.c | 20 +- 6 files changed, 790 insertions(+), 5 deletions(-) create mode 100644 drivers/net/spnic/base/spnic_eqs.c create mode 100644 drivers/net/spnic/base/spnic_eqs.h diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build index de80eef7c4..ce7457f400 100644 --- a/drivers/net/spnic/base/meson.build +++ b/drivers/net/spnic/base/meson.build @@ -2,6 +2,7 @@ # Copyright(c) 2021 Ramaxel Memory Technology, Ltd sources = [ + 'spnic_eqs.c', 'spnic_hwdev.c', 'spnic_hwif.c', 'spnic_mbox.c' diff --git a/drivers/net/spnic/base/spnic_eqs.c b/drivers/net/spnic/base/spnic_eqs.c new file mode 100644 index 00..7953976441 --- /dev/null +++ b/drivers/net/spnic/base/spnic_eqs.c @@ -0,0 +1,606 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Ramaxel Memory Technology, Ltd + */ + +#include +#include +#include +#include "spnic_compat.h" +#include "spnic_hwdev.h" +#include "spnic_hwif.h" +#include "spnic_csr.h" +#include "spnic_eqs.h" +#include "spnic_mgmt.h" +#include "spnic_mbox.h" + +#define AEQ_CTRL_0_INTR_IDX_SHIFT 0 +#define AEQ_CTRL_0_DMA_ATTR_SHIFT 12 +#define AEQ_CTRL_0_PCI_INTF_IDX_SHIFT 20 +#define AEQ_CTRL_0_INTR_MODE_SHIFT 31 + +#define AEQ_CTRL_0_INTR_IDX_MASK 0x3FFU +#define AEQ_CTRL_0_DMA_ATTR_MASK 0x3FU +#define AEQ_CTRL_0_PCI_INTF_IDX_MASK 0x7U +#define AEQ_CTRL_0_INTR_MODE_MASK 0x1U + +#define AEQ_CTRL_0_SET(val, member)\ + (((val) & AEQ_CTRL_0_##member##_MASK) << \ + AEQ_CTRL_0_##member##_SHIFT) + +#define AEQ_CTRL_0_CLEAR(val, member) \ + ((val) & (~(AEQ_CTRL_0_##member##_MASK \ + << AEQ_CTRL_0_##member##_SHIFT))) + +#define AEQ_CTRL_1_LEN_SHIFT 0 +#define AEQ_CTRL_1_ELEM_SIZE_SHIFT 24 +#define AEQ_CTRL_1_PAGE_SIZE_SHIFT 28 + +#define AEQ_CTRL_1_LEN_MASK0x1FU +#define AEQ_CTRL_1_ELEM_SIZE_MASK 0x3U +#define AEQ_CTRL_1_PAGE_SIZE_MASK 0xFU + +#define AEQ_CTRL_1_SET(val, member)\ + (((val) & AEQ_CTRL_1_##member##_MASK) << \ + AEQ_CTRL_1_##member##_SHIFT) + +#define AEQ_CTRL_1_CLEAR(val, member) \ + ((val) & (~(AEQ_CTRL_1_##member##_MASK \ + << AEQ_CTRL_1_##member##_SHIFT))) + +#define SPNIC_EQ_PROD_IDX_MASK 0xF +#define SPNIC_TASK_PROCESS_EQE_LIMIT 1024 +#define SPNIC_EQ_UPDATE_CI_STEP 64 + +#define EQ_ELEM_DESC_TYPE_SHIFT0 +#define EQ_ELEM_DESC_SRC_SHIFT 7 +#define EQ_ELEM_DESC_SIZE_SHIFT8 +#define EQ_ELEM_DESC_WRAPPED_SHIFT 31 + +#define EQ_ELEM_DESC_TYPE_MASK 0x7FU +#define EQ_ELEM_DESC_SRC_MASK 0x1U +#define EQ_ELEM_DESC_SIZE_MASK 0xFFU +#define EQ_ELEM_DESC_WRAPPED_MASK 0x1U + +#define EQ_ELEM_DESC_GET(val, member) \ + (((val) >> EQ_ELEM_DESC_##member##_SHIFT) & \ + EQ_ELEM_DESC_##member##_MASK) + +#define EQ_CI_SIMPLE_INDIR_CI_SHIFT0 +#define EQ_CI_SIMPLE_INDIR_ARMED_SHIFT 21 +#define EQ_CI_SIMPLE_INDIR_AEQ_IDX_SHIFT 30 + +#define EQ_CI_SIMPLE_INDIR_CI_MASK 0x1FU +#define EQ_CI_SIMPLE_INDIR_ARMED_MASK 0x1U +#define EQ_CI_SIMPLE_INDIR_AEQ_IDX_MASK0x3U + +#define EQ_CI_SIMPLE_INDIR_SET(val, member)\ + (((val) & EQ_CI_SIMPLE_INDIR_##member##_MASK) << \ + EQ_CI_SIMPLE_INDIR_##member##_SHIFT) + +#define EQ_CI_SIMPLE_INDIR_CLEAR(val, member) \ + ((val) & (~(EQ_CI_SIMPLE_INDIR_##member##_MASK \ + << EQ_CI_SIMPLE_INDIR_##member##_SHIFT))) + +#define EQ_WRAPPED(eq) ((u32)(eq)->wrapped << EQ_VALID_SHIFT) + +#define EQ_CONS_IDX(eq)((eq)->cons_idx | \ + ((u32)(eq)->wrapped << EQ_WRAPPED_SHIFT)) +#define GET_EQ_NUM_PAGES(eq, size) \ + ((u16)(RTE_ALIGN((u32)((eq)->eq_len * (
[PATCH v4 06/25] net/spnic: add cmdq and work queue
This commit introduce cmdq and work queue which can be used to send bulk message data(up to 2KB) to hardware. cmdq provides a mechanism to encapsulate the message to be sent and handle the response data or status. work queue is used to manager the wqe in which includes message data buffer description, ctrl info, header info and response message data buffer. This patch implements the initialization and data structure. Signed-off-by: Yanling Song --- drivers/net/spnic/base/meson.build | 4 +- drivers/net/spnic/base/spnic_cmdq.c| 202 ++ drivers/net/spnic/base/spnic_cmdq.h| 228 + drivers/net/spnic/base/spnic_hw_comm.c | 222 drivers/net/spnic/base/spnic_hw_comm.h | 176 +++ drivers/net/spnic/base/spnic_hwdev.c | 215 +++ drivers/net/spnic/base/spnic_hwdev.h | 8 +- drivers/net/spnic/base/spnic_wq.h | 57 +++ 8 files changed, 1109 insertions(+), 3 deletions(-) create mode 100644 drivers/net/spnic/base/spnic_cmdq.c create mode 100644 drivers/net/spnic/base/spnic_cmdq.h create mode 100644 drivers/net/spnic/base/spnic_hw_comm.c create mode 100644 drivers/net/spnic/base/spnic_hw_comm.h create mode 100644 drivers/net/spnic/base/spnic_wq.h diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build index 3f6a060b37..5e4efac7be 100644 --- a/drivers/net/spnic/base/meson.build +++ b/drivers/net/spnic/base/meson.build @@ -7,7 +7,9 @@ sources = [ 'spnic_hwif.c', 'spnic_mbox.c', 'spnic_mgmt.c', - 'spnic_nic_event.c' + 'spnic_nic_event.c', + 'spnic_cmdq.c', + 'spnic_hw_comm.c', ] extra_flags = [] diff --git a/drivers/net/spnic/base/spnic_cmdq.c b/drivers/net/spnic/base/spnic_cmdq.c new file mode 100644 index 00..ccfcf739a0 --- /dev/null +++ b/drivers/net/spnic/base/spnic_cmdq.c @@ -0,0 +1,202 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Ramaxel Memory Technology, Ltd + */ + +#include + +#include "spnic_compat.h" +#include "spnic_hwdev.h" +#include "spnic_hwif.h" +#include "spnic_wq.h" +#include "spnic_cmd.h" +#include "spnic_mgmt.h" +#include "spnic_cmdq.h" + +#define CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT 0 +#define CMDQ_CTXT_EQ_ID_SHIFT 53 +#define CMDQ_CTXT_CEQ_ARM_SHIFT61 +#define CMDQ_CTXT_CEQ_EN_SHIFT 62 +#define CMDQ_CTXT_HW_BUSY_BIT_SHIFT63 + +#define CMDQ_CTXT_CURR_WQE_PAGE_PFN_MASK 0xF +#define CMDQ_CTXT_EQ_ID_MASK 0xFF +#define CMDQ_CTXT_CEQ_ARM_MASK 0x1 +#define CMDQ_CTXT_CEQ_EN_MASK 0x1 +#define CMDQ_CTXT_HW_BUSY_BIT_MASK 0x1 + +#define CMDQ_CTXT_PAGE_INFO_SET(val, member) \ + (((u64)(val) & CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT) + +#define CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT 0 +#define CMDQ_CTXT_CI_SHIFT 52 + +#define CMDQ_CTXT_WQ_BLOCK_PFN_MASK0xF +#define CMDQ_CTXT_CI_MASK 0xFFF + +#define CMDQ_CTXT_BLOCK_INFO_SET(val, member) \ + (((u64)(val) & CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT) + +#define WAIT_CMDQ_ENABLE_TIMEOUT 300 + +static int init_cmdq(struct spnic_cmdq *cmdq, struct spnic_hwdev *hwdev, +struct spnic_wq *wq, enum spnic_cmdq_type q_type) +{ + void *db_base = NULL; + int err = 0; + size_t errcode_size; + size_t cmd_infos_size; + + cmdq->wq = wq; + cmdq->cmdq_type = q_type; + cmdq->wrapped = 1; + + rte_spinlock_init(&cmdq->cmdq_lock); + + errcode_size = wq->q_depth * sizeof(*cmdq->errcode); + cmdq->errcode = rte_zmalloc(NULL, errcode_size, 0); + if (!cmdq->errcode) { + PMD_DRV_LOG(ERR, "Allocate errcode for cmdq failed"); + return -ENOMEM; + } + + cmd_infos_size = wq->q_depth * sizeof(*cmdq->cmd_infos); + cmdq->cmd_infos = rte_zmalloc(NULL, cmd_infos_size, 0); + if (!cmdq->cmd_infos) { + PMD_DRV_LOG(ERR, "Allocate cmd info for cmdq failed"); + err = -ENOMEM; + goto cmd_infos_err; + } + + err = spnic_alloc_db_addr(hwdev, &db_base, NULL); + if (err) + goto alloc_db_err; + + cmdq->db_base = (u8 *)db_base; + + return 0; + +alloc_db_err: + rte_free(cmdq->cmd_infos); + +cmd_infos_err: + rte_free(cmdq->errcode); + + return err; +} + +static void free_cmdq(struct spnic_hwdev *hwdev, struct spnic_cmdq *cmdq) +{ + spnic_free_db_addr(hwdev, cmdq->db_base, NULL); + rte_free(cmdq->cmd_infos); + rte_free(cmdq->errcode); +} + +static int spnic_set_cmdq_ctxts(struct spnic_hwdev *hwdev) +{ + struct spnic_cmd
[PATCH v4 05/25] net/spnic: add mgmt module
Mgmt module manage the message gerenated from the hardware. This patch implements mgmt module initialization, related event processing and message command definition. Signed-off-by: Yanling Song --- drivers/net/spnic/base/meson.build | 4 +- drivers/net/spnic/base/spnic_cmd.h | 222 ++ drivers/net/spnic/base/spnic_eqs.c | 46 ++- drivers/net/spnic/base/spnic_hwdev.c | 91 +- drivers/net/spnic/base/spnic_hwdev.h | 66 +++- drivers/net/spnic/base/spnic_mbox.c | 16 + drivers/net/spnic/base/spnic_mgmt.c | 367 +++ drivers/net/spnic/base/spnic_mgmt.h | 74 + drivers/net/spnic/base/spnic_nic_event.c | 162 ++ drivers/net/spnic/base/spnic_nic_event.h | 29 ++ 10 files changed, 1066 insertions(+), 11 deletions(-) create mode 100644 drivers/net/spnic/base/spnic_cmd.h create mode 100644 drivers/net/spnic/base/spnic_mgmt.c create mode 100644 drivers/net/spnic/base/spnic_nic_event.c create mode 100644 drivers/net/spnic/base/spnic_nic_event.h diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build index ce7457f400..3f6a060b37 100644 --- a/drivers/net/spnic/base/meson.build +++ b/drivers/net/spnic/base/meson.build @@ -5,7 +5,9 @@ sources = [ 'spnic_eqs.c', 'spnic_hwdev.c', 'spnic_hwif.c', - 'spnic_mbox.c' + 'spnic_mbox.c', + 'spnic_mgmt.c', + 'spnic_nic_event.c' ] extra_flags = [] diff --git a/drivers/net/spnic/base/spnic_cmd.h b/drivers/net/spnic/base/spnic_cmd.h new file mode 100644 index 00..4f0c46f900 --- /dev/null +++ b/drivers/net/spnic/base/spnic_cmd.h @@ -0,0 +1,222 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Ramaxel Memory Technology, Ltd + */ + +#ifndef _SPNIC_CMD_H_ +#define _SPNIC_CMD_H_ + +#define NIC_RSS_TEMP_ID_TO_CTX_LT_IDX(tmp_id) tmp_id +/* Begin of one temp tbl */ +#define NIC_RSS_TEMP_ID_TO_INDIR_LT_IDX(tmp_id)((tmp_id) << 4) +/* 4 ctx in one entry */ +#define NIC_RSS_CTX_TBL_ENTRY_SIZE 0x10 +/* Entry size = 16B, 16 entry/template */ +#define NIC_RSS_INDIR_TBL_ENTRY_SIZE 0x10 +/* Entry size = 16B, so entry_num = 256B/16B */ +#define NIC_RSS_INDIR_TBL_ENTRY_NUM0x10 + +#define NIC_UP_RSS_INVALID_TEMP_ID 0xFF +#define NIC_UP_RSS_INVALID_FUNC_ID 0x +#define NIC_UP_RSS_INVALID 0x00 +#define NIC_UP_RSS_EN 0x01 +#define NIC_UP_RSS_INVALID_GROUP_ID0x7F + +#define NIC_RSS_CMD_TEMP_ALLOC 0x01 +#define NIC_RSS_CMD_TEMP_FREE 0x02 + +#define SPNIC_RSS_TYPE_VALID_SHIFT 23 +#define SPNIC_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24 +#define SPNIC_RSS_TYPE_IPV6_EXT_SHIFT 25 +#define SPNIC_RSS_TYPE_TCP_IPV6_SHIFT 26 +#define SPNIC_RSS_TYPE_IPV6_SHIFT 27 +#define SPNIC_RSS_TYPE_TCP_IPV4_SHIFT 28 +#define SPNIC_RSS_TYPE_IPV4_SHIFT 29 +#define SPNIC_RSS_TYPE_UDP_IPV6_SHIFT 30 +#define SPNIC_RSS_TYPE_UDP_IPV4_SHIFT 31 +#define SPNIC_RSS_TYPE_SET(val, member)\ + (((u32)(val) & 0x1) << SPNIC_RSS_TYPE_##member##_SHIFT) + +#define SPNIC_RSS_TYPE_GET(val, member)\ + (((u32)(val) >> SPNIC_RSS_TYPE_##member##_SHIFT) & 0x1) + +/* NIC CMDQ MODE */ +typedef enum spnic_ucode_cmd { + SPNIC_UCODE_CMD_MODIFY_QUEUE_CTX = 0, + SPNIC_UCODE_CMD_CLEAN_QUEUE_CONTEXT, + SPNIC_UCODE_CMD_ARM_SQ, + SPNIC_UCODE_CMD_ARM_RQ, + SPNIC_UCODE_CMD_SET_RSS_INDIR_TABLE, + SPNIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE, + SPNIC_UCODE_CMD_GET_RSS_INDIR_TABLE, + SPNIC_UCODE_CMD_GET_RSS_CONTEXT_TABLE, + SPNIC_UCODE_CMD_SET_IQ_ENABLE, + SPNIC_UCODE_CMD_SET_RQ_FLUSH = 10, + SPNIC_UCODE_CMD_MODIFY_VLAN_CTX, + SPNIC_UCODE_CMD_DPI_FLOW +} cmdq_nic_subtype_e; + +/* + * Commands between NIC and MPU + */ +enum spnic_cmd { + SPNIC_CMD_VF_REGISTER = 0, /* only for PFD and VFD */ + + /* FUNC CFG */ + SPNIC_CMD_SET_FUNC_TBL = 5, + SPNIC_CMD_SET_VPORT_ENABLE, + SPNIC_CMD_SET_RX_MODE, + SPNIC_CMD_SQ_CI_ATTR_SET, + SPNIC_CMD_GET_VPORT_STAT, + SPNIC_CMD_CLEAN_VPORT_STAT, + SPNIC_CMD_CLEAR_QP_RESOURCE, + SPNIC_CMD_CFG_FLEX_QUEUE, + /* LRO CFG */ + SPNIC_CMD_CFG_RX_LRO, + SPNIC_CMD_CFG_LRO_TIMER, + SPNIC_CMD_FEATURE_NEGO, + + /* MAC & VLAN CFG */ + SPNIC_CMD_GET_MAC = 20, + SPNIC_CMD_SET_MAC, + SPNIC_CMD_DEL_MAC, + SPNIC_CMD_UPDATE_MAC, + SPNIC_CMD_GET_ALL_DEFAULT_MAC, + + SPNIC_CMD_CFG_FUNC_VLAN, + SPNIC_CMD_SET_VLAN_FILTER_EN, + SPNIC_CMD_SET_RX_VLAN_OFFLOAD, + + /* SR-IOV */ + SPNIC_CMD_CFG_VF_VLAN = 40, + SPNIC_CMD_SET_SPOOPCHK_STATE, + /* RATE LIMIT */ + SPNIC_CMD_SET_MAX_MIN_RATE, + + /* RSS CFG */ + SPNIC_CMD_RSS_CFG = 60, + SPNIC_CMD_RSS_TEMP_MGR, +
[PATCH v4 02/25] net/spnic: initialize the HW interface
Add HW interface registers and initialize the HW interface. Signed-off-by: Yanling Song --- drivers/net/spnic/base/meson.build | 2 + drivers/net/spnic/base/spnic_csr.h | 104 drivers/net/spnic/base/spnic_hwdev.c | 41 ++ drivers/net/spnic/base/spnic_hwdev.h | 29 + drivers/net/spnic/base/spnic_hwif.c | 774 +++ drivers/net/spnic/base/spnic_hwif.h | 155 ++ drivers/net/spnic/spnic_ethdev.c | 66 +++ drivers/net/spnic/spnic_ethdev.h | 48 +- 8 files changed, 1212 insertions(+), 7 deletions(-) create mode 100644 drivers/net/spnic/base/spnic_csr.h create mode 100644 drivers/net/spnic/base/spnic_hwdev.c create mode 100644 drivers/net/spnic/base/spnic_hwdev.h create mode 100644 drivers/net/spnic/base/spnic_hwif.c create mode 100644 drivers/net/spnic/base/spnic_hwif.h diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build index e83a473881..edd6e94772 100644 --- a/drivers/net/spnic/base/meson.build +++ b/drivers/net/spnic/base/meson.build @@ -2,6 +2,8 @@ # Copyright(c) 2021 Ramaxel Memory Technology, Ltd sources = [ + 'spnic_hwdev.c', + 'spnic_hwif.c' ] extra_flags = [] diff --git a/drivers/net/spnic/base/spnic_csr.h b/drivers/net/spnic/base/spnic_csr.h new file mode 100644 index 00..b4cf7c2593 --- /dev/null +++ b/drivers/net/spnic/base/spnic_csr.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Ramaxel Memory Technology, Ltd + */ + +#ifndef _SPNIC_CSR_H_ +#define _SPNIC_CSR_H_ + +#define PCI_VENDOR_ID_RAMAXEL 0x1E81 + +/* Device ids */ +#define SPNIC_DEV_ID_PF0x9020 +#define SPNIC_DEV_ID_VF0x9001 + +/* + * Bit30/bit31 for bar index flag + * 00: bar0 + * 01: bar1 + * 10: bar2 + * 11: bar3 + */ +#define SPNIC_CFG_REGS_FLAG0x4000 + +#define SPNIC_MGMT_REGS_FLAG 0xC000 + +#define SPNIC_REGS_FLAG_MASK 0x3FFF + +#define SPNIC_VF_CFG_REG_OFFSET 0x2000 + +#define SPNIC_HOST_CSR_BASE_ADDR (SPNIC_MGMT_REGS_FLAG + 0x6000) +#define SPNIC_CSR_GLOBAL_BASE_ADDR (SPNIC_MGMT_REGS_FLAG + 0x6400) + +/* HW interface registers */ +#define SPNIC_CSR_FUNC_ATTR0_ADDR (SPNIC_CFG_REGS_FLAG + 0x0) +#define SPNIC_CSR_FUNC_ATTR1_ADDR (SPNIC_CFG_REGS_FLAG + 0x4) +#define SPNIC_CSR_FUNC_ATTR2_ADDR (SPNIC_CFG_REGS_FLAG + 0x8) +#define SPNIC_CSR_FUNC_ATTR3_ADDR (SPNIC_CFG_REGS_FLAG + 0xC) +#define SPNIC_CSR_FUNC_ATTR4_ADDR (SPNIC_CFG_REGS_FLAG + 0x10) +#define SPNIC_CSR_FUNC_ATTR5_ADDR (SPNIC_CFG_REGS_FLAG + 0x14) +#define SPNIC_CSR_FUNC_ATTR6_ADDR (SPNIC_CFG_REGS_FLAG + 0x18) + +#define SPNIC_FUNC_CSR_MAILBOX_DATA_OFF0x80 +#define SPNIC_FUNC_CSR_MAILBOX_CONTROL_OFF (SPNIC_CFG_REGS_FLAG + 0x0100) +#define SPNIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF (SPNIC_CFG_REGS_FLAG + 0x0104) +#define SPNIC_FUNC_CSR_MAILBOX_RESULT_H_OFF(SPNIC_CFG_REGS_FLAG + 0x0108) +#define SPNIC_FUNC_CSR_MAILBOX_RESULT_L_OFF(SPNIC_CFG_REGS_FLAG + 0x010C) + +#define SPNIC_PPF_ELECTION_OFFSET 0x0 +#define SPNIC_MPF_ELECTION_OFFSET 0x20 + +#define SPNIC_CSR_PPF_ELECTION_ADDR\ + (SPNIC_HOST_CSR_BASE_ADDR + SPNIC_PPF_ELECTION_OFFSET) + +#define SPNIC_CSR_GLOBAL_MPF_ELECTION_ADDR \ + (SPNIC_HOST_CSR_BASE_ADDR + SPNIC_MPF_ELECTION_OFFSET) + +#define SPNIC_CSR_DMA_ATTR_TBL_ADDR(SPNIC_CFG_REGS_FLAG + 0x380) +#define SPNIC_CSR_DMA_ATTR_INDIR_IDX_ADDR (SPNIC_CFG_REGS_FLAG + 0x390) + +/* MSI-X registers */ +#define SPNIC_CSR_MSIX_INDIR_IDX_ADDR (SPNIC_CFG_REGS_FLAG + 0x310) +#define SPNIC_CSR_MSIX_CTRL_ADDR (SPNIC_CFG_REGS_FLAG + 0x300) +#define SPNIC_CSR_MSIX_CNT_ADDR(SPNIC_CFG_REGS_FLAG + 0x304) +#define SPNIC_CSR_FUNC_MSI_CLR_WR_ADDR (SPNIC_CFG_REGS_FLAG + 0x58) + +#define SPNIC_MSI_CLR_INDIR_RESEND_TIMER_CLR_SHIFT 0 +#define SPNIC_MSI_CLR_INDIR_INT_MSK_SET_SHIFT 1 +#define SPNIC_MSI_CLR_INDIR_INT_MSK_CLR_SHIFT 2 +#define SPNIC_MSI_CLR_INDIR_AUTO_MSK_SET_SHIFT 3 +#define SPNIC_MSI_CLR_INDIR_AUTO_MSK_CLR_SHIFT 4 +#define SPNIC_MSI_CLR_INDIR_SIMPLE_INDIR_IDX_SHIFT 22 + +#define SPNIC_MSI_CLR_INDIR_RESEND_TIMER_CLR_MASK 0x1U +#define SPNIC_MSI_CLR_INDIR_INT_MSK_SET_MASK 0x1U +#define SPNIC_MSI_CLR_INDIR_INT_MSK_CLR_MASK 0x1U +#define SPNIC_MSI_CLR_INDIR_AUTO_MSK_SET_MASK 0x1U +#define SPNIC_MSI_CLR_INDIR_AUTO_MSK_CLR_MASK 0x1U +#define SPNIC_MSI_CLR_INDIR_SIMPLE_INDIR_IDX_MASK 0x3FFU + +#define SPNIC_MSI_CLR_INDIR_SET(val, member) \ + (((val) & SPNIC_MSI_CLR_INDIR_##member##_MASK) << \ + SPNIC_MSI_CLR_INDIR_##member##_SHIFT) + +/* EQ registers */ +#de
[PATCH v4 07/25] net/spnic: add interface handling cmdq message
This commit adds cmdq_sync_cmd_direct_resp() and cmdq_sync_cmd_detail_resp() interfaces by which driver can send cmdq message using wqe a data structure describe the buffer. Signed-off-by: Yanling Song --- drivers/net/spnic/base/meson.build | 1 + drivers/net/spnic/base/spnic_cmdq.c| 673 + drivers/net/spnic/base/spnic_cmdq.h| 20 + drivers/net/spnic/base/spnic_hw_comm.c | 41 ++ drivers/net/spnic/base/spnic_hwdev.c | 8 +- drivers/net/spnic/base/spnic_hwdev.h | 13 + drivers/net/spnic/base/spnic_wq.c | 139 + drivers/net/spnic/base/spnic_wq.h | 70 ++- 8 files changed, 960 insertions(+), 5 deletions(-) create mode 100644 drivers/net/spnic/base/spnic_wq.c diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build index 5e4efac7be..da6d6ee4a2 100644 --- a/drivers/net/spnic/base/meson.build +++ b/drivers/net/spnic/base/meson.build @@ -10,6 +10,7 @@ sources = [ 'spnic_nic_event.c', 'spnic_cmdq.c', 'spnic_hw_comm.c', + 'spnic_wq.c' ] extra_flags = [] diff --git a/drivers/net/spnic/base/spnic_cmdq.c b/drivers/net/spnic/base/spnic_cmdq.c index ccfcf739a0..b8950f91c2 100644 --- a/drivers/net/spnic/base/spnic_cmdq.c +++ b/drivers/net/spnic/base/spnic_cmdq.c @@ -12,6 +12,71 @@ #include "spnic_mgmt.h" #include "spnic_cmdq.h" +#define CMDQ_CMD_TIMEOUT 30 /* Millisecond */ + +#define UPPER_8_BITS(data) (((data) >> 8) & 0xFF) +#define LOWER_8_BITS(data) ((data) & 0xFF) + +#define CMDQ_DB_INFO_HI_PROD_IDX_SHIFT 0 +#define CMDQ_DB_INFO_HI_PROD_IDX_MASK 0xFFU + +#define CMDQ_DB_INFO_SET(val, member) \ + u32)(val)) & CMDQ_DB_INFO_##member##_MASK) \ + << CMDQ_DB_INFO_##member##_SHIFT) +#define CMDQ_DB_INFO_UPPER_32(val) ((u64)(val) << 32) + +#define CMDQ_DB_HEAD_QUEUE_TYPE_SHIFT 23 +#define CMDQ_DB_HEAD_CMDQ_TYPE_SHIFT 24 +#define CMDQ_DB_HEAD_SRC_TYPE_SHIFT27 +#define CMDQ_DB_HEAD_QUEUE_TYPE_MASK 0x1U +#define CMDQ_DB_HEAD_CMDQ_TYPE_MASK0x7U +#define CMDQ_DB_HEAD_SRC_TYPE_MASK 0x1FU +#define CMDQ_DB_HEAD_SET(val, member) \ + u32)(val)) & CMDQ_DB_HEAD_##member##_MASK) << \ + CMDQ_DB_HEAD_##member##_SHIFT) + +#define CMDQ_CTRL_PI_SHIFT 0 +#define CMDQ_CTRL_CMD_SHIFT16 +#define CMDQ_CTRL_MOD_SHIFT24 +#define CMDQ_CTRL_ACK_TYPE_SHIFT 29 +#define CMDQ_CTRL_HW_BUSY_BIT_SHIFT31 + +#define CMDQ_CTRL_PI_MASK 0xU +#define CMDQ_CTRL_CMD_MASK 0xFFU +#define CMDQ_CTRL_MOD_MASK 0x1FU +#define CMDQ_CTRL_ACK_TYPE_MASK0x3U +#define CMDQ_CTRL_HW_BUSY_BIT_MASK 0x1U + +#define CMDQ_CTRL_SET(val, member) \ + (((u32)(val) & CMDQ_CTRL_##member##_MASK) << CMDQ_CTRL_##member##_SHIFT) + +#define CMDQ_CTRL_GET(val, member) \ + (((val) >> CMDQ_CTRL_##member##_SHIFT) & CMDQ_CTRL_##member##_MASK) + +#define CMDQ_WQE_HEADER_BUFDESC_LEN_SHIFT 0 +#define CMDQ_WQE_HEADER_COMPLETE_FMT_SHIFT 15 +#define CMDQ_WQE_HEADER_DATA_FMT_SHIFT 22 +#define CMDQ_WQE_HEADER_COMPLETE_REQ_SHIFT 23 +#define CMDQ_WQE_HEADER_COMPLETE_SECT_LEN_SHIFT27 +#define CMDQ_WQE_HEADER_CTRL_LEN_SHIFT 29 +#define CMDQ_WQE_HEADER_HW_BUSY_BIT_SHIFT 31 + +#define CMDQ_WQE_HEADER_BUFDESC_LEN_MASK 0xFFU +#define CMDQ_WQE_HEADER_COMPLETE_FMT_MASK 0x1U +#define CMDQ_WQE_HEADER_DATA_FMT_MASK 0x1U +#define CMDQ_WQE_HEADER_COMPLETE_REQ_MASK 0x1U +#define CMDQ_WQE_HEADER_COMPLETE_SECT_LEN_MASK 0x3U +#define CMDQ_WQE_HEADER_CTRL_LEN_MASK 0x3U +#define CMDQ_WQE_HEADER_HW_BUSY_BIT_MASK 0x1U + +#define CMDQ_WQE_HEADER_SET(val, member) \ + (((u32)(val) & CMDQ_WQE_HEADER_##member##_MASK) << \ + CMDQ_WQE_HEADER_##member##_SHIFT) + +#define CMDQ_WQE_HEADER_GET(val, member) \ + (((val) >> CMDQ_WQE_HEADER_##member##_SHIFT) & \ + CMDQ_WQE_HEADER_##member##_MASK) + #define CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT 0 #define CMDQ_CTXT_EQ_ID_SHIFT 53 #define CMDQ_CTXT_CEQ_ARM_SHIFT61 @@ -36,8 +101,523 @@ #define CMDQ_CTXT_BLOCK_INFO_SET(val, member) \ (((u64)(val) & CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT) +#define SAVED_DATA_ARM_SHIFT 31 + +#define SAVED_DATA_ARM_MASK
[PATCH v4 08/25] net/spnic: add hardware info initialization
This commits add hardware info initialization, including that device capability initialization, common feature negotiation, and two interfaces spnic_get_board_info(), spnic_get_mgmt_version() to get hardware info and firmware version. Signed-off-by: Yanling Song --- drivers/net/spnic/base/meson.build | 3 +- drivers/net/spnic/base/spnic_hw_cfg.c | 157 + drivers/net/spnic/base/spnic_hw_cfg.h | 117 ++ drivers/net/spnic/base/spnic_hw_comm.c | 121 +++ drivers/net/spnic/base/spnic_hw_comm.h | 22 drivers/net/spnic/base/spnic_hwdev.c | 70 +++ drivers/net/spnic/base/spnic_hwdev.h | 5 + drivers/net/spnic/base/spnic_mbox.c| 8 ++ 8 files changed, 502 insertions(+), 1 deletion(-) create mode 100644 drivers/net/spnic/base/spnic_hw_cfg.c create mode 100644 drivers/net/spnic/base/spnic_hw_cfg.h diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build index da6d6ee4a2..77a56ca41e 100644 --- a/drivers/net/spnic/base/meson.build +++ b/drivers/net/spnic/base/meson.build @@ -10,7 +10,8 @@ sources = [ 'spnic_nic_event.c', 'spnic_cmdq.c', 'spnic_hw_comm.c', - 'spnic_wq.c' + 'spnic_wq.c', + 'spnic_hw_cfg.c' ] extra_flags = [] diff --git a/drivers/net/spnic/base/spnic_hw_cfg.c b/drivers/net/spnic/base/spnic_hw_cfg.c new file mode 100644 index 00..e8856ce9fe --- /dev/null +++ b/drivers/net/spnic/base/spnic_hw_cfg.c @@ -0,0 +1,157 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Ramaxel Memory Technology, Ltd + */ + +#include "spnic_compat.h" +#include "spnic_mgmt.h" +#include "spnic_mbox.h" +#include "spnic_hwdev.h" +#include "spnic_hwif.h" +#include "spnic_hw_cfg.h" + +static void parse_pub_res_cap(struct service_cap *cap, + struct spnic_cfg_cmd_dev_cap *dev_cap, + enum func_type type) +{ + cap->host_id = dev_cap->host_id; + cap->ep_id = dev_cap->ep_id; + cap->er_id = dev_cap->er_id; + cap->port_id = dev_cap->port_id; + + cap->svc_type = dev_cap->svc_cap_en; + cap->chip_svc_type = cap->svc_type; + + cap->cos_valid_bitmap = dev_cap->valid_cos_bitmap; + cap->flexq_en = dev_cap->flexq_en; + + cap->host_total_function = dev_cap->host_total_func; + cap->max_vf = 0; + if (type == TYPE_PF || type == TYPE_PPF) { + cap->max_vf = dev_cap->max_vf; + cap->pf_num = dev_cap->host_pf_num; + cap->pf_id_start = dev_cap->pf_id_start; + cap->vf_num = dev_cap->host_vf_num; + cap->vf_id_start = dev_cap->vf_id_start; + } + + PMD_DRV_LOG(INFO, "Get public resource capability: "); + PMD_DRV_LOG(INFO, "host_id: 0x%x, ep_id: 0x%x, er_id: 0x%x, " + "port_id: 0x%x", + cap->host_id, cap->ep_id, cap->er_id, cap->port_id); + PMD_DRV_LOG(INFO, "host_total_function: 0x%x, max_vf: 0x%x", + cap->host_total_function, cap->max_vf); + PMD_DRV_LOG(INFO, "host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x", + cap->pf_num, cap->pf_id_start, + cap->vf_num, cap->vf_id_start); +} + +static void parse_l2nic_res_cap(struct service_cap *cap, + struct spnic_cfg_cmd_dev_cap *dev_cap) +{ + struct nic_service_cap *nic_cap = &cap->nic_cap; + + nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1; + nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1; + + PMD_DRV_LOG(INFO, "L2nic resource capbility, max_sqs: 0x%x, " + "max_rqs: 0x%x", + nic_cap->max_sqs, nic_cap->max_rqs); +} + +static void parse_dev_cap(struct spnic_hwdev *dev, + struct spnic_cfg_cmd_dev_cap *dev_cap, + enum func_type type) +{ + struct service_cap *cap = &dev->cfg_mgmt->svc_cap; + + parse_pub_res_cap(cap, dev_cap, type); + + if (IS_NIC_TYPE(dev)) + parse_l2nic_res_cap(cap, dev_cap); +} + +static int get_cap_from_fw(struct spnic_hwdev *hwdev, enum func_type type) +{ + struct spnic_cfg_cmd_dev_cap dev_cap; + u16 out_len = sizeof(dev_cap); + int err; + + memset(&dev_cap, 0, sizeof(dev_cap)); + dev_cap.func_id = spnic_global_func_id(hwdev); + err = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_CFGM, +SPNIC_CFG_CMD_GET_DEV_CAP, +&dev_cap, sizeof(dev_cap), +&dev_cap, &out_len, 0); + if (err || dev_cap.status || !out_len) { + PMD_DRV_LOG(ERR, "Get capability from FW failed, err: %d, " + "status: 0x%x, out size: 0x%x", + err, dev_cap.status, out_len); + return -EFAULT; + } + + parse_dev_cap(hwdev, &dev_c
[PATCH v4 09/25] net/spnic: support MAC and link event handling
This commit adds interfaces to add/remove MAC addresses and registers related ops to struct eth_dev_ops. Furthermore, this commit adds callback to handle link events. Signed-off-by: Yanling Song --- drivers/net/spnic/base/meson.build | 3 +- drivers/net/spnic/base/spnic_hw_cfg.c| 12 + drivers/net/spnic/base/spnic_hw_cfg.h| 2 + drivers/net/spnic/base/spnic_nic_cfg.c | 291 +++ drivers/net/spnic/base/spnic_nic_cfg.h | 180 drivers/net/spnic/base/spnic_nic_event.c | 27 +- drivers/net/spnic/base/spnic_nic_event.h | 9 +- drivers/net/spnic/spnic_ethdev.c | 348 ++- 8 files changed, 861 insertions(+), 11 deletions(-) create mode 100644 drivers/net/spnic/base/spnic_nic_cfg.c create mode 100644 drivers/net/spnic/base/spnic_nic_cfg.h diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build index 77a56ca41e..f4bb4469ae 100644 --- a/drivers/net/spnic/base/meson.build +++ b/drivers/net/spnic/base/meson.build @@ -11,7 +11,8 @@ sources = [ 'spnic_cmdq.c', 'spnic_hw_comm.c', 'spnic_wq.c', - 'spnic_hw_cfg.c' + 'spnic_hw_cfg.c', + 'spnic_nic_cfg.c' ] extra_flags = [] diff --git a/drivers/net/spnic/base/spnic_hw_cfg.c b/drivers/net/spnic/base/spnic_hw_cfg.c index e8856ce9fe..6505f48273 100644 --- a/drivers/net/spnic/base/spnic_hw_cfg.c +++ b/drivers/net/spnic/base/spnic_hw_cfg.c @@ -155,3 +155,15 @@ void spnic_free_capability(void *dev) { rte_free(((struct spnic_hwdev *)dev)->cfg_mgmt); } + +u8 spnic_physical_port_id(void *hwdev) +{ + struct spnic_hwdev *dev = hwdev; + + if (!dev) { + PMD_DRV_LOG(INFO, "Hwdev is NULL for getting physical port id"); + return 0; + } + + return dev->cfg_mgmt->svc_cap.port_id; +} diff --git a/drivers/net/spnic/base/spnic_hw_cfg.h b/drivers/net/spnic/base/spnic_hw_cfg.h index 1b1b598726..9ab51f2875 100644 --- a/drivers/net/spnic/base/spnic_hw_cfg.h +++ b/drivers/net/spnic/base/spnic_hw_cfg.h @@ -112,6 +112,8 @@ struct spnic_cfg_cmd_dev_cap { int spnic_init_capability(void *dev); void spnic_free_capability(void *dev); +u8 spnic_physical_port_id(void *hwdev); + int cfg_mbx_vf_proc_msg(void *hwdev, void *pri_handle, u16 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size); #endif /* _SPNIC_HW_CFG_H_ */ diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c new file mode 100644 index 00..c47bc330a3 --- /dev/null +++ b/drivers/net/spnic/base/spnic_nic_cfg.c @@ -0,0 +1,291 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Ramaxel Memory Technology, Ltd + */ + +#include +#include "spnic_compat.h" +#include "spnic_cmd.h" +#include "spnic_mgmt.h" +#include "spnic_hwif.h" +#include "spnic_mbox.h" +#include "spnic_hwdev.h" +#include "spnic_wq.h" +#include "spnic_cmdq.h" +#include "spnic_nic_cfg.h" +#include "spnic_hw_cfg.h" + +struct vf_msg_handler { + u16 cmd; +}; + +const struct vf_msg_handler vf_cmd_handler[] = { + { + .cmd = SPNIC_CMD_VF_REGISTER, + }, + + { + .cmd = SPNIC_CMD_GET_MAC, + }, + + { + .cmd = SPNIC_CMD_SET_MAC, + }, + + { + .cmd = SPNIC_CMD_DEL_MAC, + }, + + { + .cmd = SPNIC_CMD_UPDATE_MAC, + }, + + { + .cmd = SPNIC_CMD_VF_COS, + }, +}; + +static const struct vf_msg_handler vf_mag_cmd_handler[] = { + { + .cmd = MAG_CMD_GET_LINK_STATUS, + }, +}; + +static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size, + void *buf_out, u16 *out_size); + +int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size, + void *buf_out, u16 *out_size) +{ + u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler); + bool cmd_to_pf = false; + + if (spnic_func_type(hwdev) == TYPE_VF) { + for (i = 0; i < cmd_cnt; i++) { + if (cmd == vf_cmd_handler[i].cmd) + cmd_to_pf = true; + } + } + + if (cmd_to_pf) { + return spnic_mbox_to_pf(hwdev, SPNIC_MOD_L2NIC, cmd, buf_in, + in_size, buf_out, out_size, 0); + } + + return spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_L2NIC, cmd, buf_in, + in_size, buf_out, out_size, 0); +} + +static int spnic_check_mac_info(u8 status, u16 vlan_id) +{ + if ((status && status != SPNIC_MGMT_STATUS_EXIST && +status != SPNIC_PF_SET_VF_ALREADY) || + (vlan_id & CHECK_IPSU_15BIT && +status == SPNIC_MGMT_STATUS_EXIST)) + return -EINVAL; + + return 0; +} + +#define VLAN_N_VID 4096 + +int spnic_set_mac(void *hwdev, const u8 *mac_addr, u16
[PATCH v4 13/25] net/spnic: support Rx congfiguration
This patch Rx/Tx configuration including Rx csum offload, LRO, RSS, VLAN filter and VLAN offload. Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_nic_cfg.c | 525 + drivers/net/spnic/base/spnic_nic_cfg.h | 387 ++ drivers/net/spnic/spnic_ethdev.c | 187 - drivers/net/spnic/spnic_ethdev.h | 2 + drivers/net/spnic/spnic_rx.c | 221 +++ drivers/net/spnic/spnic_rx.h | 31 ++ 6 files changed, 1349 insertions(+), 4 deletions(-) diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c index f6914f6f6d..ddaecba95d 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.c +++ b/drivers/net/spnic/base/spnic_nic_cfg.c @@ -271,6 +271,37 @@ int spnic_get_default_mac(void *hwdev, u8 *mac_addr, int ether_len) return 0; } +static int spnic_config_vlan(void *hwdev, u8 opcode, u16 vlan_id, u16 func_id) +{ + struct spnic_cmd_vlan_config vlan_info; + u16 out_size = sizeof(vlan_info); + int err; + + memset(&vlan_info, 0, sizeof(vlan_info)); + vlan_info.opcode = opcode; + vlan_info.func_id = func_id; + vlan_info.vlan_id = vlan_id; + + err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CFG_FUNC_VLAN, &vlan_info, +sizeof(vlan_info), &vlan_info, &out_size); + if (err || !out_size || vlan_info.msg_head.status) { + PMD_DRV_LOG(ERR, "%s vlan failed, err: %d, status: 0x%x, out size: 0x%x", + opcode == SPNIC_CMD_OP_ADD ? "Add" : "Delete", + err, vlan_info.msg_head.status, out_size); + return -EINVAL; + } + + return 0; +} + +int spnic_del_vlan(void *hwdev, u16 vlan_id, u16 func_id) +{ + if (!hwdev) + return -EINVAL; + + return spnic_config_vlan(hwdev, SPNIC_CMD_OP_DEL, vlan_id, func_id); +} + int spnic_get_port_info(void *hwdev, struct nic_port_info *port_info) { struct spnic_cmd_port_info port_msg; @@ -564,6 +595,500 @@ void spnic_free_nic_hwdev(void *hwdev) spnic_vf_func_free(hwdev); } +int spnic_set_rx_mode(void *hwdev, u32 enable) +{ + struct spnic_rx_mode_config rx_mode_cfg; + u16 out_size = sizeof(rx_mode_cfg); + int err; + + if (!hwdev) + return -EINVAL; + + memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg)); + rx_mode_cfg.func_id = spnic_global_func_id(hwdev); + rx_mode_cfg.rx_mode = enable; + + err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_SET_RX_MODE, +&rx_mode_cfg, sizeof(rx_mode_cfg), +&rx_mode_cfg, &out_size); + if (err || !out_size || rx_mode_cfg.msg_head.status) { + PMD_DRV_LOG(ERR, "Set rx mode failed, err: %d, status: 0x%x, out size: 0x%x", + err, rx_mode_cfg.msg_head.status, out_size); + return -EIO; + } + + return 0; +} + +int spnic_set_rx_vlan_offload(void *hwdev, u8 en) +{ + struct spnic_cmd_vlan_offload vlan_cfg; + u16 out_size = sizeof(vlan_cfg); + int err; + + if (!hwdev) + return -EINVAL; + + memset(&vlan_cfg, 0, sizeof(vlan_cfg)); + vlan_cfg.func_id = spnic_global_func_id(hwdev); + vlan_cfg.vlan_offload = en; + + err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_SET_RX_VLAN_OFFLOAD, +&vlan_cfg, sizeof(vlan_cfg), +&vlan_cfg, &out_size); + if (err || !out_size || vlan_cfg.msg_head.status) { + PMD_DRV_LOG(ERR, "Set rx vlan offload failed, err: %d, status: 0x%x, out size: 0x%x", + err, vlan_cfg.msg_head.status, out_size); + return -EIO; + } + + return 0; +} + +int spnic_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl) +{ + struct spnic_cmd_set_vlan_filter vlan_filter; + u16 out_size = sizeof(vlan_filter); + int err; + + if (!hwdev) + return -EINVAL; + + memset(&vlan_filter, 0, sizeof(vlan_filter)); + vlan_filter.func_id = spnic_global_func_id(hwdev); + vlan_filter.vlan_filter_ctrl = vlan_filter_ctrl; + + err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_SET_VLAN_FILTER_EN, +&vlan_filter, sizeof(vlan_filter), +&vlan_filter, &out_size); + if (err || !out_size || vlan_filter.msg_head.status) { + PMD_DRV_LOG(ERR, "Failed to set vlan filter, err: %d, status: 0x%x, out size: 0x%x", + err, vlan_filter.msg_head.status, out_size); + return -EIO; + } + + return 0; +} + +static int spnic_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en, + u8 lro_max_pkt_len) +{ + struct spnic_cmd_lro_config lro_cfg; + u16 out_size = sizeof(l
[PATCH v4 10/25] net/spnic: add function info initialization
This patch mainly implements function info initialization including mtu, link state, port state, port info and cos as well as the definition of the corresponding data structure. Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_hw_cfg.c | 43 +++ drivers/net/spnic/base/spnic_hw_cfg.h | 6 + drivers/net/spnic/base/spnic_nic_cfg.c | 221 ++ drivers/net/spnic/base/spnic_nic_cfg.h | 213 ++ drivers/net/spnic/spnic_ethdev.c | 382 - drivers/net/spnic/spnic_ethdev.h | 22 +- 6 files changed, 876 insertions(+), 11 deletions(-) diff --git a/drivers/net/spnic/base/spnic_hw_cfg.c b/drivers/net/spnic/base/spnic_hw_cfg.c index 6505f48273..49e16ee89c 100644 --- a/drivers/net/spnic/base/spnic_hw_cfg.c +++ b/drivers/net/spnic/base/spnic_hw_cfg.c @@ -156,6 +156,49 @@ void spnic_free_capability(void *dev) rte_free(((struct spnic_hwdev *)dev)->cfg_mgmt); } +/* * + * @brief spnic_support_nic - function support nic + * @param hwdev: device pointer to hwdev + * @retval true: function support nic + * @retval false: function not support nic + */ +bool spnic_support_nic(void *hwdev) +{ + struct spnic_hwdev *dev = (struct spnic_hwdev *)hwdev; + + if (!hwdev) + return false; + + if (!IS_NIC_TYPE(dev)) + return false; + + return true; +} + +u16 spnic_func_max_sqs(void *hwdev) +{ + struct spnic_hwdev *dev = hwdev; + + if (!dev) { + PMD_DRV_LOG(INFO, "Hwdev is NULL for getting max_sqs"); + return 0; + } + + return dev->cfg_mgmt->svc_cap.nic_cap.max_sqs; +} + +u16 spnic_func_max_rqs(void *hwdev) +{ + struct spnic_hwdev *dev = hwdev; + + if (!dev) { + PMD_DRV_LOG(INFO, "Hwdev is NULL for getting max_rqs"); + return 0; + } + + return dev->cfg_mgmt->svc_cap.nic_cap.max_rqs; +} + u8 spnic_physical_port_id(void *hwdev) { struct spnic_hwdev *dev = hwdev; diff --git a/drivers/net/spnic/base/spnic_hw_cfg.h b/drivers/net/spnic/base/spnic_hw_cfg.h index 9ab51f2875..5019f38ec2 100644 --- a/drivers/net/spnic/base/spnic_hw_cfg.h +++ b/drivers/net/spnic/base/spnic_hw_cfg.h @@ -112,8 +112,14 @@ struct spnic_cfg_cmd_dev_cap { int spnic_init_capability(void *dev); void spnic_free_capability(void *dev); +u16 spnic_func_max_sqs(void *hwdev); +u16 spnic_func_max_rqs(void *hwdev); + u8 spnic_physical_port_id(void *hwdev); int cfg_mbx_vf_proc_msg(void *hwdev, void *pri_handle, u16 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size); + +bool spnic_support_nic(void *hwdev); + #endif /* _SPNIC_HW_CFG_H_ */ diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c index c47bc330a3..886aaea384 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.c +++ b/drivers/net/spnic/base/spnic_nic_cfg.c @@ -265,6 +265,227 @@ int spnic_get_port_info(void *hwdev, struct nic_port_info *port_info) return 0; } + +int spnic_get_link_state(void *hwdev, u8 *link_state) +{ + struct spnic_cmd_link_state get_link; + u16 out_size = sizeof(get_link); + int err; + + if (!hwdev || !link_state) + return -EINVAL; + + memset(&get_link, 0, sizeof(get_link)); + get_link.port_id = spnic_physical_port_id(hwdev); + err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_LINK_STATUS, &get_link, + sizeof(get_link), &get_link, &out_size); + if (err || !out_size || get_link.msg_head.status) { + PMD_DRV_LOG(ERR, "Get link state failed, err: %d, status: 0x%x, out size: 0x%x", + err, get_link.msg_head.status, out_size); + return -EIO; + } + + *link_state = get_link.state; + + return 0; +} + +int spnic_set_vport_enable(void *hwdev, bool enable) +{ + struct spnic_vport_state en_state; + u16 out_size = sizeof(en_state); + int err; + + if (!hwdev) + return -EINVAL; + + memset(&en_state, 0, sizeof(en_state)); + en_state.func_id = spnic_global_func_id(hwdev); + en_state.state = enable ? 1 : 0; + + err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_SET_VPORT_ENABLE, &en_state, +sizeof(en_state), &en_state, &out_size); + if (err || !out_size || en_state.msg_head.status) { + PMD_DRV_LOG(ERR, "Set vport state failed, err: %d, status: 0x%x, out size: 0x%x", + err, en_state.msg_head.status, out_size); + return -EIO; + } + + return 0; +} + +int spnic_set_port_enable(void *hwdev, bool enable) +{ + struct mag_cmd_set_port_enable en_state; + u16 out_size = sizeof(en_state); + int err; + + if (!hwdev) + return -EINVAL; + + if (spnic_func_type(hwdev) == TYPE_VF) + return 0; + + memset(&en_state, 0,
[PATCH v4 11/25] net/spnic: add queue pairs context initialization
This patch adds the initialization of Tx/Rx queues context and negotiation of NIC features. Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_hw_comm.c | 101 drivers/net/spnic/base/spnic_hw_comm.h | 6 + drivers/net/spnic/base/spnic_nic_cfg.c | 76 +++ drivers/net/spnic/base/spnic_nic_cfg.h | 65 ++- drivers/net/spnic/meson.build | 3 +- drivers/net/spnic/spnic_ethdev.c | 57 +- drivers/net/spnic/spnic_io.c | 738 + drivers/net/spnic/spnic_io.h | 154 ++ drivers/net/spnic/spnic_rx.h | 113 drivers/net/spnic/spnic_tx.h | 62 +++ 10 files changed, 1370 insertions(+), 5 deletions(-) create mode 100644 drivers/net/spnic/spnic_io.c create mode 100644 drivers/net/spnic/spnic_io.h create mode 100644 drivers/net/spnic/spnic_rx.h create mode 100644 drivers/net/spnic/spnic_tx.h diff --git a/drivers/net/spnic/base/spnic_hw_comm.c b/drivers/net/spnic/base/spnic_hw_comm.c index 5cb607cf03..1c751f2403 100644 --- a/drivers/net/spnic/base/spnic_hw_comm.c +++ b/drivers/net/spnic/base/spnic_hw_comm.c @@ -217,6 +217,107 @@ int spnic_func_reset(void *hwdev, u64 reset_flag) return 0; } +int spnic_convert_rx_buf_size(u32 rx_buf_sz, u32 *match_sz) +{ + u32 i, num_hw_types, best_match_sz; + + if (unlikely(!match_sz || rx_buf_sz < SPNIC_RX_BUF_SIZE_32B)) + return -EINVAL; + + if (rx_buf_sz >= SPNIC_RX_BUF_SIZE_16K) { + best_match_sz = SPNIC_RX_BUF_SIZE_16K; + goto size_matched; + } + + num_hw_types = sizeof(spnic_hw_rx_buf_size) / + sizeof(spnic_hw_rx_buf_size[0]); + best_match_sz = spnic_hw_rx_buf_size[0]; + for (i = 0; i < num_hw_types; i++) { + if (rx_buf_sz == spnic_hw_rx_buf_size[i]) { + best_match_sz = spnic_hw_rx_buf_size[i]; + break; + } else if (rx_buf_sz < spnic_hw_rx_buf_size[i]) { + break; + } + best_match_sz = spnic_hw_rx_buf_size[i]; + } + +size_matched: + *match_sz = best_match_sz; + + return 0; +} + +static u16 get_hw_rx_buf_size(u32 rx_buf_sz) +{ + u16 num_hw_types = sizeof(spnic_hw_rx_buf_size) / + sizeof(spnic_hw_rx_buf_size[0]); + u16 i; + + for (i = 0; i < num_hw_types; i++) { + if (spnic_hw_rx_buf_size[i] == rx_buf_sz) + return i; + } + + PMD_DRV_LOG(WARNING, "Chip can't support rx buf size of %d", rx_buf_sz); + + return DEFAULT_RX_BUF_SIZE; /* Default 2K */ +} + +int spnic_set_root_ctxt(void *hwdev, u32 rq_depth, u32 sq_depth, u16 rx_buf_sz) +{ + struct spnic_cmd_root_ctxt root_ctxt; + u16 out_size = sizeof(root_ctxt); + int err; + + if (!hwdev) + return -EINVAL; + + memset(&root_ctxt, 0, sizeof(root_ctxt)); + root_ctxt.func_idx = spnic_global_func_id(hwdev); + root_ctxt.set_cmdq_depth = 0; + root_ctxt.cmdq_depth = 0; + root_ctxt.lro_en = 1; + root_ctxt.rq_depth = (u16)ilog2(rq_depth); + root_ctxt.rx_buf_sz = get_hw_rx_buf_size(rx_buf_sz); + root_ctxt.sq_depth = (u16)ilog2(sq_depth); + + err = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM, MGMT_CMD_SET_VAT, +&root_ctxt, sizeof(root_ctxt), +&root_ctxt, &out_size, 0); + if (err || !out_size || root_ctxt.status) { + PMD_DRV_LOG(ERR, "Set root context failed, err: %d, status: 0x%x, out_size: 0x%x", + err, root_ctxt.status, out_size); + return -EFAULT; + } + + return 0; +} + +int spnic_clean_root_ctxt(void *hwdev) +{ + struct spnic_cmd_root_ctxt root_ctxt; + u16 out_size = sizeof(root_ctxt); + int err; + + if (!hwdev) + return -EINVAL; + + memset(&root_ctxt, 0, sizeof(root_ctxt)); + root_ctxt.func_idx = spnic_global_func_id(hwdev); + + err = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM, MGMT_CMD_SET_VAT, +&root_ctxt, sizeof(root_ctxt), +&root_ctxt, &out_size, 0); + if (err || !out_size || root_ctxt.status) { + PMD_DRV_LOG(ERR, "Clean root context failed, err: %d, status: 0x%x, out_size: 0x%x", + err, root_ctxt.status, out_size); + return -EFAULT; + } + + return 0; +} + int spnic_set_cmdq_depth(void *hwdev, u16 cmdq_depth) { struct spnic_cmd_root_ctxt root_ctxt; diff --git a/drivers/net/spnic/base/spnic_hw_comm.h b/drivers/net/spnic/base/spnic_hw_comm.h index cf4328a04b..4573595a89 100644 --- a/drivers/net/spnic/base/spnic_hw_comm.h +++ b/drivers/net/spnic/base/spnic_hw_comm.h @@ -180,6 +180,10 @@ int spnic_get_mgmt_version(void *hwdev, char *mgmt_ver, int max_m
[PATCH v4 12/25] net/spnic: support mbuf handling of Tx/Rx
This patch defines a wqe data structure for hardware to learn the sge info and offload info of packet. Furthermore, this commit implements the interfaces to fill wqe with DPDK mbuf. Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_nic_cfg.c | 23 ++ drivers/net/spnic/base/spnic_nic_cfg.h | 23 ++ drivers/net/spnic/meson.build | 2 + drivers/net/spnic/spnic_ethdev.c | 502 - drivers/net/spnic/spnic_rx.c | 283 ++ drivers/net/spnic/spnic_rx.h | 41 ++ drivers/net/spnic/spnic_tx.c | 334 drivers/net/spnic/spnic_tx.h | 228 +++ 8 files changed, 1435 insertions(+), 1 deletion(-) create mode 100644 drivers/net/spnic/spnic_rx.c create mode 100644 drivers/net/spnic/spnic_tx.c diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c index 25d98d67dd..f6914f6f6d 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.c +++ b/drivers/net/spnic/base/spnic_nic_cfg.c @@ -378,6 +378,29 @@ int spnic_set_port_enable(void *hwdev, bool enable) return 0; } +int spnic_flush_qps_res(void *hwdev) +{ + struct spnic_cmd_clear_qp_resource sq_res; + u16 out_size = sizeof(sq_res); + int err; + + if (!hwdev) + return -EINVAL; + + memset(&sq_res, 0, sizeof(sq_res)); + sq_res.func_id = spnic_global_func_id(hwdev); + + err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CLEAR_QP_RESOURCE, &sq_res, +sizeof(sq_res), &sq_res, &out_size); + if (err || !out_size || sq_res.msg_head.status) { + PMD_DRV_LOG(ERR, "Clear sq resources failed, err: %d, status: 0x%x, out size: 0x%x", + err, sq_res.msg_head.status, out_size); + return -EIO; + } + + return 0; +} + static int spnic_set_function_table(void *hwdev, u32 cfg_bitmap, struct spnic_func_tbl_cfg *cfg) { diff --git a/drivers/net/spnic/base/spnic_nic_cfg.h b/drivers/net/spnic/base/spnic_nic_cfg.h index a7ff44a891..31d2607234 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.h +++ b/drivers/net/spnic/base/spnic_nic_cfg.h @@ -255,6 +255,17 @@ struct spnic_cmd_register_vf { u8 rsvd[39]; }; + +struct spnic_cmd_set_rq_flush { + union { + struct { + u16 global_rq_id; + u16 local_rq_id; + }; + u32 value; + }; +}; + int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size); @@ -381,6 +392,18 @@ int spnic_set_port_enable(void *hwdev, bool enable); */ int spnic_get_link_state(void *hwdev, u8 *link_state); +/** + * Flush queue pairs resource in hardware + * + * @param[in] hwdev + * Device pointer to hwdev + * + * @retval zero : Success + * @retval non-zero : Failure + */ +int spnic_flush_qps_res(void *hwdev); + + /** * Init nic hwdev * diff --git a/drivers/net/spnic/meson.build b/drivers/net/spnic/meson.build index 16056679f8..40ef1353a1 100644 --- a/drivers/net/spnic/meson.build +++ b/drivers/net/spnic/meson.build @@ -13,6 +13,8 @@ objs = [base_objs] sources = files( 'spnic_ethdev.c', 'spnic_io.c', + 'spnic_rx.c', + 'spnic_tx.c' ) includes += include_directories('base') diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index 4205ab43a4..27942e5d68 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -139,6 +139,468 @@ static int spnic_link_update(struct rte_eth_dev *dev, int wait_to_complete) return rte_eth_linkstatus_set(dev, &link); } +static void spnic_reset_rx_queue(struct rte_eth_dev *dev) +{ + struct spnic_rxq *rxq = NULL; + struct spnic_nic_dev *nic_dev; + int q_id = 0; + + nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + + for (q_id = 0; q_id < nic_dev->num_rqs; q_id++) { + rxq = nic_dev->rxqs[q_id]; + + rxq->cons_idx = 0; + rxq->prod_idx = 0; + rxq->delta = rxq->q_depth; + rxq->next_to_update = 0; + } +} + +static void spnic_reset_tx_queue(struct rte_eth_dev *dev) +{ + struct spnic_nic_dev *nic_dev; + struct spnic_txq *txq = NULL; + int q_id = 0; + + nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + + for (q_id = 0; q_id < nic_dev->num_sqs; q_id++) { + txq = nic_dev->txqs[q_id]; + + txq->cons_idx = 0; + txq->prod_idx = 0; + txq->owner = 1; + + /* Clear hardware ci */ + *(u16 *)txq->ci_vaddr_base = 0; + } +} + +/** + * Create the receive queue. + * + * @param[in] dev + * Pointer to ethernet device structure. + * @param[in] qid + * Receive queue index. + * @param[in] nb_desc + * Number of de
[PATCH v4 14/25] net/spnic: add port/vport enable
This patch adds interface to enable port/vport so that the hardware would receive packets to host. Signed-off-by: Yanling Song --- drivers/net/spnic/spnic_ethdev.c | 46 1 file changed, 46 insertions(+) diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index 74d09bafac..0459959ca5 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -855,8 +855,10 @@ static void spnic_deinit_sw_rxtxqs(struct spnic_nic_dev *nic_dev) static int spnic_dev_start(struct rte_eth_dev *eth_dev) { struct spnic_nic_dev *nic_dev; + struct spnic_rxq *rxq = NULL; u64 nic_features; int err; + u16 i; nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev); @@ -916,6 +918,22 @@ static int spnic_dev_start(struct rte_eth_dev *eth_dev) spnic_start_all_sqs(eth_dev); + /* Open virtual port and ready to start packet receiving */ + err = spnic_set_vport_enable(nic_dev->hwdev, true); + if (err) { + PMD_DRV_LOG(ERR, "Enable vport failed, dev_name: %s", + eth_dev->data->name); + goto en_vport_fail; + } + + /* Open physical port and start packet receiving */ + err = spnic_set_port_enable(nic_dev->hwdev, true); + if (err) { + PMD_DRV_LOG(ERR, "Enable physical port failed, dev_name: %s", + eth_dev->data->name); + goto en_port_fail; + } + /* Update eth_dev link status */ if (eth_dev->data->dev_conf.intr_conf.lsc != 0) (void)spnic_link_update(eth_dev, 0); @@ -924,6 +942,20 @@ static int spnic_dev_start(struct rte_eth_dev *eth_dev) return 0; +en_port_fail: + (void)spnic_set_vport_enable(nic_dev->hwdev, false); + +en_vport_fail: + /* Flush tx && rx chip resources in case of setting vport fake fail */ + (void)spnic_flush_qps_res(nic_dev->hwdev); + rte_delay_ms(100); + for (i = 0; i < nic_dev->num_rqs; i++) { + rxq = nic_dev->rxqs[i]; + spnic_remove_rq_from_rx_queue_list(nic_dev, rxq->q_id); + spnic_free_rxq_mbufs(rxq); + eth_dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; + eth_dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; + } start_rqs_fail: spnic_remove_rxtx_configure(eth_dev); @@ -951,6 +983,7 @@ static int spnic_dev_stop(struct rte_eth_dev *dev) { struct spnic_nic_dev *nic_dev; struct rte_eth_link link; + int err; nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); if (!rte_bit_relaxed_test_and_clear32(SPNIC_DEV_START, &nic_dev->dev_status)) { @@ -959,6 +992,19 @@ static int spnic_dev_stop(struct rte_eth_dev *dev) return 0; } + /* Stop phy port and vport */ + err = spnic_set_port_enable(nic_dev->hwdev, false); + if (err) + PMD_DRV_LOG(WARNING, "Disable phy port failed, error: %d, " + "dev_name: %s, port_id: %d", err, dev->data->name, + dev->data->port_id); + + err = spnic_set_vport_enable(nic_dev->hwdev, false); + if (err) + PMD_DRV_LOG(WARNING, "Disable vport failed, error: %d, " + "dev_name: %s, port_id: %d", err, dev->data->name, + dev->data->port_id); + /* Clear recorded link status */ memset(&link, 0, sizeof(link)); (void)rte_eth_linkstatus_set(dev, &link); -- 2.32.0
[PATCH v4 15/25] net/spnic: support IO packets handling
This patch implements rx_pkt_burst() and tx_pkt_burst() to hanld IO packets. For Tx packets, this commit implements parsing ol_flags of mbuf and filling those offload info on wqe so that hardware can process the packets correctly. Furthermore, this commit allocates a mempool to cover scenes with too many mbufs for one packet. For Rx packets, this commit implements filling ol_flags of mbuf and rearming new mbuf and rq wqe. Signed-off-by: Yanling Song --- drivers/net/spnic/spnic_ethdev.c | 48 +++ drivers/net/spnic/spnic_ethdev.h | 7 + drivers/net/spnic/spnic_rx.c | 209 drivers/net/spnic/spnic_rx.h | 137 drivers/net/spnic/spnic_tx.c | 524 +++ drivers/net/spnic/spnic_tx.h | 7 + 6 files changed, 932 insertions(+) diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index 0459959ca5..7bd9aa0b9e 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -970,6 +970,32 @@ static int spnic_dev_start(struct rte_eth_dev *eth_dev) return err; } +static int spnic_copy_mempool_init(struct spnic_nic_dev *nic_dev) +{ + nic_dev->cpy_mpool = rte_mempool_lookup(nic_dev->dev_name); + if (nic_dev->cpy_mpool == NULL) { + nic_dev->cpy_mpool = + rte_pktmbuf_pool_create(nic_dev->dev_name, + SPNIC_COPY_MEMPOOL_DEPTH, 0, 0, + SPNIC_COPY_MBUF_SIZE, rte_socket_id()); + if (nic_dev->cpy_mpool == NULL) { + PMD_DRV_LOG(ERR, "Create copy mempool failed, errno: %d, dev_name: %s", + rte_errno, nic_dev->dev_name); + return -ENOMEM; + } + } + + return 0; +} + +static void spnic_copy_mempool_uninit(struct spnic_nic_dev *nic_dev) +{ + if (nic_dev->cpy_mpool != NULL) { + rte_mempool_free(nic_dev->cpy_mpool); + nic_dev->cpy_mpool = NULL; + } +} + /** * Stop the device. * @@ -986,6 +1012,9 @@ static int spnic_dev_stop(struct rte_eth_dev *dev) int err; nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + if (!nic_dev || !spnic_support_nic(nic_dev->hwdev)) + return 0; + if (!rte_bit_relaxed_test_and_clear32(SPNIC_DEV_START, &nic_dev->dev_status)) { PMD_DRV_LOG(INFO, "Device %s already stopped", nic_dev->dev_name); @@ -1014,6 +1043,11 @@ static int spnic_dev_stop(struct rte_eth_dev *dev) spnic_flush_qps_res(nic_dev->hwdev); + /* +* After set vport disable 100ms, no packets will be send to host +*/ + rte_delay_ms(100); + /* Clean RSS table and rx_mode */ spnic_remove_rxtx_configure(dev); @@ -1054,6 +1088,7 @@ static int spnic_dev_close(struct rte_eth_dev *eth_dev) for (qid = 0; qid < nic_dev->num_rqs; qid++) spnic_rx_queue_release(eth_dev, qid); + spnic_copy_mempool_uninit(nic_dev); spnic_deinit_sw_rxtxqs(nic_dev); spnic_deinit_mac_addr(eth_dev); rte_free(nic_dev->mc_list); @@ -1067,6 +1102,8 @@ static int spnic_dev_close(struct rte_eth_dev *eth_dev) spnic_free_nic_hwdev(nic_dev->hwdev); spnic_free_hwdev(nic_dev->hwdev); + eth_dev->rx_pkt_burst = NULL; + eth_dev->tx_pkt_burst = NULL; eth_dev->dev_ops = NULL; rte_free(nic_dev->hwdev); @@ -1548,6 +1585,13 @@ static int spnic_func_init(struct rte_eth_dev *eth_dev) goto set_default_feature_fail; } + err = spnic_copy_mempool_init(nic_dev); + if (err) { + PMD_DRV_LOG(ERR, "Create copy mempool failed, dev_name: %s", +eth_dev->data->name); + goto init_mpool_fail; + } + spnic_mutex_init(&nic_dev->rx_mode_mutex, NULL); rte_bit_relaxed_set32(SPNIC_DEV_INTR_EN, &nic_dev->dev_status); @@ -1558,6 +1602,7 @@ static int spnic_func_init(struct rte_eth_dev *eth_dev) return 0; +init_mpool_fail: set_default_feature_fail: spnic_deinit_mac_addr(eth_dev); @@ -1602,6 +1647,9 @@ static int spnic_dev_init(struct rte_eth_dev *eth_dev) (rte_eal_process_type() == RTE_PROC_PRIMARY) ? "primary" : "secondary"); + eth_dev->rx_pkt_burst = spnic_recv_pkts; + eth_dev->tx_pkt_burst = spnic_xmit_pkts; + return spnic_func_init(eth_dev); } diff --git a/drivers/net/spnic/spnic_ethdev.h b/drivers/net/spnic/spnic_ethdev.h index 996b4e4b8f..2b59886942 100644 --- a/drivers/net/spnic/spnic_ethdev.h +++ b/drivers/net/spnic/spnic_ethdev.h @@ -4,6 +4,9 @@ #ifndef _SPNIC_ETHDEV_H_ #define _SPNIC_ETHDEV_H_ + +#define SPNIC_COPY_MEMPOOL_DEPTH 128 +#define SPNIC_COPY_MBUF_SIZE 4096 #define SPNIC_DEV_NAME_LEN 32 #define SPNIC_UINT32_BIT_SIZE (
[PATCH v4 17/25] net/spnic: support RSS configuration update and get
This commit implements rss_hash_update and rss_hash_conf_get. Signed-off-by: Yanling Song --- drivers/net/spnic/spnic_ethdev.c | 235 +++ 1 file changed, 235 insertions(+) diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index 50cca24258..cca03b5115 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -1258,6 +1258,233 @@ static int spnic_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) return err; } + +/** + * Update the RSS hash key and RSS hash type. + * + * @param[in] dev + * Pointer to ethernet device structure. + * @param[in] rss_conf + * RSS configuration data. + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_rss_hash_update(struct rte_eth_dev *dev, +struct rte_eth_rss_conf *rss_conf) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct spnic_rss_type rss_type = {0}; + u64 rss_hf = rss_conf->rss_hf; + int err = 0; + + if (nic_dev->rss_state == SPNIC_RSS_DISABLE) { + if (rss_hf != 0) + return -EINVAL; + + PMD_DRV_LOG(INFO, "RSS is not enabled"); + return 0; + } + + if (rss_conf->rss_key_len > SPNIC_RSS_KEY_SIZE) { + PMD_DRV_LOG(ERR, "Invalid RSS key, rss_key_len: %d", + rss_conf->rss_key_len); + return -EINVAL; + } + + if (rss_conf->rss_key) { + err = spnic_rss_set_hash_key(nic_dev->hwdev, nic_dev->rss_key); + if (err) { + PMD_DRV_LOG(ERR, "Set RSS hash key failed"); + return err; + } + memcpy(nic_dev->rss_key, rss_conf->rss_key, + rss_conf->rss_key_len); + } + + rss_type.ipv4 = (rss_hf & (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | + ETH_RSS_NONFRAG_IPV4_OTHER)) ? 1 : 0; + rss_type.tcp_ipv4 = (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) ? 1 : 0; + rss_type.ipv6 = (rss_hf & (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | + ETH_RSS_NONFRAG_IPV6_OTHER)) ? 1 : 0; + rss_type.ipv6_ext = (rss_hf & ETH_RSS_IPV6_EX) ? 1 : 0; + rss_type.tcp_ipv6 = (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) ? 1 : 0; + rss_type.tcp_ipv6_ext = (rss_hf & ETH_RSS_IPV6_TCP_EX) ? 1 : 0; + rss_type.udp_ipv4 = (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) ? 1 : 0; + rss_type.udp_ipv6 = (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) ? 1 : 0; + + err = spnic_set_rss_type(nic_dev->hwdev, rss_type); + if (err) + PMD_DRV_LOG(ERR, "Set RSS type failed"); + + return err; +} + +/** + * Get the RSS hash configuration. + * + * @param[in] dev + * Pointer to ethernet device structure. + * @param[out] rss_conf + * RSS configuration data. + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_rss_conf_get(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct spnic_rss_type rss_type = {0}; + int err; + + if (!rss_conf) + return -EINVAL; + + if (nic_dev->rss_state == SPNIC_RSS_DISABLE) { + rss_conf->rss_hf = 0; + PMD_DRV_LOG(INFO, "RSS is not enabled"); + return 0; + } + + if (rss_conf->rss_key && + rss_conf->rss_key_len >= SPNIC_RSS_KEY_SIZE) { + /* +* Get RSS key from driver to reduce the frequency of the MPU +* accessing the RSS memory. +*/ + rss_conf->rss_key_len = sizeof(nic_dev->rss_key); + memcpy(rss_conf->rss_key, nic_dev->rss_key, + rss_conf->rss_key_len); + } + + err = spnic_get_rss_type(nic_dev->hwdev, &rss_type); + if (err) + return err; + + rss_conf->rss_hf = 0; + rss_conf->rss_hf |= rss_type.ipv4 ? (ETH_RSS_IPV4 | + ETH_RSS_FRAG_IPV4 | ETH_RSS_NONFRAG_IPV4_OTHER) : 0; + rss_conf->rss_hf |= rss_type.tcp_ipv4 ? ETH_RSS_NONFRAG_IPV4_TCP : 0; + rss_conf->rss_hf |= rss_type.ipv6 ? (ETH_RSS_IPV6 | + ETH_RSS_FRAG_IPV6 | ETH_RSS_NONFRAG_IPV6_OTHER) : 0; + rss_conf->rss_hf |= rss_type.ipv6_ext ? ETH_RSS_IPV6_EX : 0; + rss_conf->rss_hf |= rss_type.tcp_ipv6 ? ETH_RSS_NONFRAG_IPV6_TCP : 0; + rss_conf->rss_hf |= rss_type.tcp_ipv6_ext ? ETH_RSS_IPV6_TCP_EX : 0; + rss_conf->rss_hf |= rss_type.udp_ipv4 ? ETH_RSS_NONFRAG_IPV4_UDP : 0; + rss_conf->rss_hf |= rss_type.udp_ipv6 ? ETH_RSS_NONFRAG_IPV6_UDP : 0; + + return 0; +} + +/** + * Get the RETA indirection table. + * + * @param[in] dev + * Pointer to ethernet device structure. + * @param[out] reta_conf + * Pointer to RETA configuration structure array. +
[PATCH v4 16/25] net/spnic: add device configure/version/info
This commit adds the callbacks to configure queue number and mtu as well as query configuration information and firmware version. Signed-off-by: Yanling Song --- drivers/net/spnic/spnic_ethdev.c | 129 ++- 1 file changed, 127 insertions(+), 2 deletions(-) diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index 7bd9aa0b9e..50cca24258 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -71,12 +71,131 @@ enum spnic_rx_mod { #define SPNIC_TXD_ALIGN1 #define SPNIC_RXD_ALIGN1 +static const struct rte_eth_desc_lim spnic_rx_desc_lim = { + .nb_max = SPNIC_MAX_QUEUE_DEPTH, + .nb_min = SPNIC_MIN_QUEUE_DEPTH, + .nb_align = SPNIC_RXD_ALIGN, +}; + +static const struct rte_eth_desc_lim spnic_tx_desc_lim = { + .nb_max = SPNIC_MAX_QUEUE_DEPTH, + .nb_min = SPNIC_MIN_QUEUE_DEPTH, + .nb_align = SPNIC_TXD_ALIGN, +}; + /** - * Deinit mac_vlan table in hardware. + * Ethernet device configuration. * - * @param[in] eth_dev + * Prepare the driver for a given number of TX and RX queues, mtu size + * and configure RSS. + * + * @param[in] dev + * Pointer to ethernet device structure. + * + * @retval zero : Success + * @retval non-zero : Failure. + */ +static int spnic_dev_configure(struct rte_eth_dev *dev) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + + nic_dev->num_sqs = dev->data->nb_tx_queues; + nic_dev->num_rqs = dev->data->nb_rx_queues; + + nic_dev->mtu_size = + SPNIC_PKTLEN_TO_MTU(dev->data->dev_conf.rxmode.mtu); + + if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) + dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH; + + return 0; +} + +/** + * Get information about the device. + * + * @param[in] dev * Pointer to ethernet device structure. + * @param[out] info + * Info structure for ethernet device. + * + * @retval zero : Success + * @retval non-zero : Failure. */ +static int spnic_dev_infos_get(struct rte_eth_dev *dev, + struct rte_eth_dev_info *info) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + + info->max_rx_queues = nic_dev->max_rqs; + info->max_tx_queues = nic_dev->max_sqs; + info->min_rx_bufsize = SPNIC_MIN_RX_BUF_SIZE; + info->max_rx_pktlen = SPNIC_MAX_JUMBO_FRAME_SIZE; + info->max_mac_addrs = SPNIC_MAX_UC_MAC_ADDRS; + info->min_mtu = SPNIC_MIN_MTU_SIZE; + info->max_mtu = SPNIC_MAX_MTU_SIZE; + info->max_lro_pkt_size = SPNIC_MAX_LRO_SIZE; + + info->rx_queue_offload_capa = 0; + info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP | + DEV_RX_OFFLOAD_IPV4_CKSUM | + DEV_RX_OFFLOAD_UDP_CKSUM | + DEV_RX_OFFLOAD_TCP_CKSUM | + DEV_RX_OFFLOAD_SCTP_CKSUM | + DEV_RX_OFFLOAD_VLAN_FILTER | + DEV_RX_OFFLOAD_SCATTER | + DEV_RX_OFFLOAD_TCP_LRO | + DEV_RX_OFFLOAD_RSS_HASH; + + info->tx_queue_offload_capa = 0; + info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT | + DEV_TX_OFFLOAD_IPV4_CKSUM | + DEV_TX_OFFLOAD_UDP_CKSUM | + DEV_TX_OFFLOAD_TCP_CKSUM | + DEV_TX_OFFLOAD_SCTP_CKSUM | + DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | + DEV_TX_OFFLOAD_TCP_TSO | + DEV_TX_OFFLOAD_MULTI_SEGS; + + info->hash_key_size = SPNIC_RSS_KEY_SIZE; + info->reta_size = SPNIC_RSS_INDIR_SIZE; + info->flow_type_rss_offloads = SPNIC_RSS_OFFLOAD_ALL; + + info->rx_desc_lim = spnic_rx_desc_lim; + info->tx_desc_lim = spnic_tx_desc_lim; + + /* Driver-preferred rx/tx parameters */ + info->default_rxportconf.burst_size = SPNIC_DEFAULT_BURST_SIZE; + info->default_txportconf.burst_size = SPNIC_DEFAULT_BURST_SIZE; + info->default_rxportconf.nb_queues = SPNIC_DEFAULT_NB_QUEUES; + info->default_txportconf.nb_queues = SPNIC_DEFAULT_NB_QUEUES; + info->default_rxportconf.ring_size = SPNIC_DEFAULT_RING_SIZE; + info->default_txportconf.ring_size = SPNIC_DEFAULT_RING_SIZE; + + return 0; +} + +static int spnic_fw_version_get(struct rte_eth_dev *dev, char *fw_version, + size_t fw_size) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + char mgmt_ver[MGMT_VERSION_MAX_LEN] = { 0 }; + int err; + + err = spnic_get_mgmt_version(nic_dev->hwdev, mgmt_ver, +SPNIC_MGMT_VERSION_MAX_LEN); + if (err) { +
[PATCH v4 19/25] net/spnic: support promiscuous and allmulticast Rx modes
This commit implements promiscuous_enable/disable() and allmulticast_enable/disable() to configure promiscuous or allmulticast Rx modes. Note: promiscuous rx mode is only supported by PF. Signed-off-by: Yanling Song --- drivers/net/spnic/spnic_ethdev.c | 156 +++ 1 file changed, 156 insertions(+) diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index 5b1c67c90f..a3baa8c481 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -1375,6 +1375,156 @@ static int spnic_vlan_offload_set(struct rte_eth_dev *dev, int mask) return 0; } +/** + * Enable allmulticast mode. + * + * @param[in] dev + * Pointer to ethernet device structure. + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_dev_allmulticast_enable(struct rte_eth_dev *dev) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + u32 rx_mode; + int err; + + err = spnic_mutex_lock(&nic_dev->rx_mode_mutex); + if (err) + return err; + + rx_mode = nic_dev->rx_mode | SPNIC_RX_MODE_MC_ALL; + + err = spnic_set_rx_mode(nic_dev->hwdev, rx_mode); + if (err) { + (void)spnic_mutex_unlock(&nic_dev->rx_mode_mutex); + PMD_DRV_LOG(ERR, "Enable allmulticast failed, error: %d", err); + return err; + } + + nic_dev->rx_mode = rx_mode; + + (void)spnic_mutex_unlock(&nic_dev->rx_mode_mutex); + + PMD_DRV_LOG(INFO, "Enable allmulticast succeed, nic_dev: %s, port_id: %d", + nic_dev->dev_name, dev->data->port_id); + return 0; +} + +/** + * Disable allmulticast mode. + * + * @param[in] dev + * Pointer to ethernet device structure. + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_dev_allmulticast_disable(struct rte_eth_dev *dev) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + u32 rx_mode; + int err; + + err = spnic_mutex_lock(&nic_dev->rx_mode_mutex); + if (err) + return err; + + rx_mode = nic_dev->rx_mode & (~SPNIC_RX_MODE_MC_ALL); + + err = spnic_set_rx_mode(nic_dev->hwdev, rx_mode); + if (err) { + (void)spnic_mutex_unlock(&nic_dev->rx_mode_mutex); + PMD_DRV_LOG(ERR, "Disable allmulticast failed, error: %d", err); + return err; + } + + nic_dev->rx_mode = rx_mode; + + (void)spnic_mutex_unlock(&nic_dev->rx_mode_mutex); + + PMD_DRV_LOG(INFO, "Disable allmulticast succeed, nic_dev: %s, port_id: %d", + nic_dev->dev_name, dev->data->port_id); + return 0; +} + +/** + * Enable promiscuous mode. + * + * @param[in] dev + * Pointer to ethernet device structure. + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_dev_promiscuous_enable(struct rte_eth_dev *dev) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + u32 rx_mode; + int err; + + err = spnic_mutex_lock(&nic_dev->rx_mode_mutex); + if (err) + return err; + + rx_mode = nic_dev->rx_mode | SPNIC_RX_MODE_PROMISC; + + err = spnic_set_rx_mode(nic_dev->hwdev, rx_mode); + if (err) { + (void)spnic_mutex_unlock(&nic_dev->rx_mode_mutex); + PMD_DRV_LOG(ERR, "Enable promiscuous failed"); + return err; + } + + nic_dev->rx_mode = rx_mode; + + (void)spnic_mutex_unlock(&nic_dev->rx_mode_mutex); + + PMD_DRV_LOG(INFO, "Enable promiscuous, nic_dev: %s, port_id: %d, promisc: %d", + nic_dev->dev_name, dev->data->port_id, + dev->data->promiscuous); + return 0; +} + +/** + * Disable promiscuous mode. + * + * @param[in] dev + * Pointer to ethernet device structure. + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_dev_promiscuous_disable(struct rte_eth_dev *dev) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + u32 rx_mode; + int err; + + err = spnic_mutex_lock(&nic_dev->rx_mode_mutex); + if (err) + return err; + + rx_mode = nic_dev->rx_mode & (~SPNIC_RX_MODE_PROMISC); + + err = spnic_set_rx_mode(nic_dev->hwdev, rx_mode); + if (err) { + (void)spnic_mutex_unlock(&nic_dev->rx_mode_mutex); + PMD_DRV_LOG(ERR, "Disable promiscuous failed"); + return err; + } + + nic_dev->rx_mode = rx_mode; + + (void)spnic_mutex_unlock(&nic_dev->rx_mode_mutex); + + PMD_DRV_LOG(INFO, "Disable promiscuous, nic_dev: %s, port_id: %d, promisc: %d", + nic_dev->dev_name, dev->data->port_id, + dev->data->promiscuous); + return 0; +} + /** * Update the RSS hash key and RSS hash type. @@ -1811,6 +1961,10 @@ st
[PATCH v4 18/25] net/spnic: support VLAN filtering and offloading
This commit implements vlan_filter_set() and vlan_offload_set() to support VLAN filtering and offloading. Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_nic_cfg.c | 8 ++ drivers/net/spnic/spnic_ethdev.c | 121 + 2 files changed, 129 insertions(+) diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c index ddaecba95d..d54b017434 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.c +++ b/drivers/net/spnic/base/spnic_nic_cfg.c @@ -294,6 +294,14 @@ static int spnic_config_vlan(void *hwdev, u8 opcode, u16 vlan_id, u16 func_id) return 0; } +int spnic_add_vlan(void *hwdev, u16 vlan_id, u16 func_id) +{ + if (!hwdev) + return -EINVAL; + + return spnic_config_vlan(hwdev, SPNIC_CMD_OP_ADD, vlan_id, func_id); +} + int spnic_del_vlan(void *hwdev, u16 vlan_id, u16 func_id) { if (!hwdev) diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index cca03b5115..5b1c67c90f 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -1258,6 +1258,123 @@ static int spnic_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) return err; } +/** + * Add or delete vlan id. + * + * @param[in] dev + * Pointer to ethernet device structure. + * @param[in] vlan_id + * Vlan id is used to filter vlan packets + * @param[in] enable + * Disable or enable vlan filter function + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, +int enable) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + int err = 0; + u16 func_id; + + if (vlan_id >= RTE_ETHER_MAX_VLAN_ID) + return -EINVAL; + + if (vlan_id == 0) + return 0; + + func_id = spnic_global_func_id(nic_dev->hwdev); + + if (enable) { + /* If vlanid is already set, just return */ + if (spnic_find_vlan_filter(nic_dev, vlan_id)) { + PMD_DRV_LOG(INFO, "Vlan %u has been added, device: %s", + vlan_id, nic_dev->dev_name); + return 0; + } + + err = spnic_add_vlan(nic_dev->hwdev, vlan_id, func_id); + } else { + /* If vlanid can't be found, just return */ + if (!spnic_find_vlan_filter(nic_dev, vlan_id)) { + PMD_DRV_LOG(INFO, "Vlan %u is not in the vlan filter list, device: %s", + vlan_id, nic_dev->dev_name); + return 0; + } + + err = spnic_del_vlan(nic_dev->hwdev, vlan_id, func_id); + } + + if (err) { + PMD_DRV_LOG(ERR, "%s vlan failed, func_id: %d, vlan_id: %d, err: %d", + enable ? "Add" : "Remove", func_id, vlan_id, err); + return err; + } + + spnic_store_vlan_filter(nic_dev, vlan_id, enable); + + PMD_DRV_LOG(INFO, "%s vlan %u succeed, device: %s", + enable ? "Add" : "Remove", vlan_id, nic_dev->dev_name); + + return 0; +} + +/** + * Enable or disable vlan offload. + * + * @param[in] dev + * Pointer to ethernet device structure. + * @param[in] mask + * Definitions used for VLAN setting, vlan filter of vlan strip + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_vlan_offload_set(struct rte_eth_dev *dev, int mask) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; + bool on; + int err; + + /* Enable or disable VLAN filter */ + if (mask & ETH_VLAN_FILTER_MASK) { + on = (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) ? +true : false; + err = spnic_set_vlan_fliter(nic_dev->hwdev, on); + if (err) { + PMD_DRV_LOG(ERR, "%s vlan filter failed, device: %s, port_id: %d, err: %d", + on ? "Enable" : "Disable", + nic_dev->dev_name, dev->data->port_id, err); + return err; + } + + PMD_DRV_LOG(INFO, "%s vlan filter succeed, device: %s, port_id: %d", + on ? "Enable" : "Disable", + nic_dev->dev_name, dev->data->port_id); + } + + /* Enable or disable VLAN stripping */ + if (mask & ETH_VLAN_STRIP_MASK) { + on = (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) ? +true : false; + err = spnic_set_rx_vlan_offload(nic_dev->hwdev, on); + if (err) { + PMD_DRV_LOG(ERR, "%s vlan strip failed, device: %s, port_id: %d, err: %d", +
[PATCH v4 21/25] net/spnic: support getting Tx/Rx queues info
This patch implements rxq_info_get() and txq_info_get() to support getting queue depth and mbuf pool info of specified Tx/Rx queue. Signed-off-by: Yanling Song --- drivers/net/spnic/spnic_ethdev.c | 21 + 1 file changed, 21 insertions(+) diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index 914e488256..67aae4620d 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -1827,6 +1827,23 @@ static int spnic_rss_reta_update(struct rte_eth_dev *dev, return err; } +static void spnic_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, + struct rte_eth_rxq_info *rxq_info) +{ + struct spnic_rxq *rxq = dev->data->rx_queues[queue_id]; + + rxq_info->mp = rxq->mb_pool; + rxq_info->nb_desc = rxq->q_depth; +} + +static void spnic_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, + struct rte_eth_txq_info *txq_qinfo) +{ + struct spnic_txq *txq = dev->data->tx_queues[queue_id]; + + txq_qinfo->nb_desc = txq->q_depth; +} + /** * Update MAC address * @@ -2046,6 +2063,8 @@ static const struct eth_dev_ops spnic_pmd_ops = { .rss_hash_conf_get = spnic_rss_conf_get, .reta_update = spnic_rss_reta_update, .reta_query= spnic_rss_reta_query, + .rxq_info_get = spnic_rxq_info_get, + .txq_info_get = spnic_txq_info_get, .mac_addr_set = spnic_set_mac_addr, .mac_addr_remove = spnic_mac_addr_remove, .mac_addr_add = spnic_mac_addr_add, @@ -2073,6 +2092,8 @@ static const struct eth_dev_ops spnic_pmd_vf_ops = { .rss_hash_conf_get = spnic_rss_conf_get, .reta_update = spnic_rss_reta_update, .reta_query= spnic_rss_reta_query, + .rxq_info_get = spnic_rxq_info_get, + .txq_info_get = spnic_txq_info_get, .mac_addr_set = spnic_set_mac_addr, .mac_addr_remove = spnic_mac_addr_remove, .mac_addr_add = spnic_mac_addr_add, -- 2.32.0
[PATCH v4 20/25] net/spnic: support flow control
This commit implements flow control operations to support related syscalls. Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_nic_cfg.c | 53 ++ drivers/net/spnic/base/spnic_nic_cfg.h | 25 + drivers/net/spnic/spnic_ethdev.c | 77 ++ drivers/net/spnic/spnic_ethdev.h | 1 + 4 files changed, 156 insertions(+) diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c index d54b017434..258c6cf8c7 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.c +++ b/drivers/net/spnic/base/spnic_nic_cfg.c @@ -440,6 +440,59 @@ int spnic_flush_qps_res(void *hwdev) return 0; } +static int spnic_cfg_hw_pause(void *hwdev, u8 opcode, + struct nic_pause_config *nic_pause) +{ + struct spnic_cmd_pause_config pause_info; + u16 out_size = sizeof(pause_info); + int err; + + memset(&pause_info, 0, sizeof(pause_info)); + + pause_info.port_id = spnic_physical_port_id(hwdev); + pause_info.opcode = opcode; + if (opcode == SPNIC_CMD_OP_SET) { + pause_info.auto_neg = nic_pause->auto_neg; + pause_info.rx_pause = nic_pause->rx_pause; + pause_info.tx_pause = nic_pause->tx_pause; + } + + err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CFG_PAUSE_INFO, +&pause_info, sizeof(pause_info), +&pause_info, &out_size); + if (err || !out_size || pause_info.msg_head.status) { + PMD_DRV_LOG(ERR, "%s pause info failed, err: %d, status: 0x%x, out size: 0x%x\n", + opcode == SPNIC_CMD_OP_SET ? "Set" : "Get", + err, pause_info.msg_head.status, out_size); + return -EIO; + } + + if (opcode == SPNIC_CMD_OP_GET) { + nic_pause->auto_neg = pause_info.auto_neg; + nic_pause->rx_pause = pause_info.rx_pause; + nic_pause->tx_pause = pause_info.tx_pause; + } + + return 0; +} + +int spnic_set_pause_info(void *hwdev, struct nic_pause_config nic_pause) +{ + if (!hwdev) + return -EINVAL; + + return spnic_cfg_hw_pause(hwdev, SPNIC_CMD_OP_SET, &nic_pause); +} + +int spnic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause) +{ + if (!hwdev || !nic_pause) + return -EINVAL; + + + return spnic_cfg_hw_pause(hwdev, SPNIC_CMD_OP_GET, nic_pause); +} + static int spnic_set_function_table(void *hwdev, u32 cfg_bitmap, struct spnic_func_tbl_cfg *cfg) { diff --git a/drivers/net/spnic/base/spnic_nic_cfg.h b/drivers/net/spnic/base/spnic_nic_cfg.h index 1044af3dcc..bc4707c05b 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.h +++ b/drivers/net/spnic/base/spnic_nic_cfg.h @@ -560,6 +560,31 @@ int spnic_get_link_state(void *hwdev, u8 *link_state); */ int spnic_flush_qps_res(void *hwdev); +/** + * Set pause info + * + * @param[in] hwdev + * Device pointer to hwdev + * @param[in] nic_pause + * Pause info + * + * @retval zero : Success + * @retval non-zero : Failure + */ +int spnic_set_pause_info(void *hwdev, struct nic_pause_config nic_pause); + +/** + * Get pause info + * + * @param[in] hwdev + * Device pointer to hwdev + * @param[out] nic_pause + * Pause info + * + * @retval zero : Success + * @retval non-zero : Failure + */ +int spnic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause); /** * Init nic hwdev diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index a3baa8c481..914e488256 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -1525,6 +1525,81 @@ static int spnic_dev_promiscuous_disable(struct rte_eth_dev *dev) return 0; } +static int spnic_dev_flow_ctrl_get(struct rte_eth_dev *dev, + struct rte_eth_fc_conf *fc_conf) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct nic_pause_config nic_pause; + int err; + + err = spnic_mutex_lock(&nic_dev->pause_mutuex); + if (err) + return err; + + memset(&nic_pause, 0, sizeof(nic_pause)); + err = spnic_get_pause_info(nic_dev->hwdev, &nic_pause); + if (err) { + (void)spnic_mutex_unlock(&nic_dev->pause_mutuex); + return err; + } + + if (nic_dev->pause_set || !nic_pause.auto_neg) { + nic_pause.rx_pause = nic_dev->nic_pause.rx_pause; + nic_pause.tx_pause = nic_dev->nic_pause.tx_pause; + } + + fc_conf->autoneg = nic_pause.auto_neg; + + if (nic_pause.tx_pause && nic_pause.rx_pause) + fc_conf->mode = RTE_FC_FULL; + else if (nic_pause.tx_pause) + fc_conf->mode = RTE_FC_TX_PAUSE; + else if (nic_pause.rx_pause) + fc_conf->mode
[PATCH v4 22/25] net/spnic: net/spnic: support xstats statistics
This commit implements DFX statistics of physical port, function, Rx queues and Tx queues, which includes MAC statistic, unicast/multicast/broadcast packets statistic, rx_mbuf, tx_busy and etc. Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_nic_cfg.c | 118 ++ drivers/net/spnic/base/spnic_nic_cfg.h | 206 +++ drivers/net/spnic/spnic_ethdev.c | 474 + 3 files changed, 798 insertions(+) diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c index 258c6cf8c7..e740138b8e 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.c +++ b/drivers/net/spnic/base/spnic_nic_cfg.c @@ -493,6 +493,124 @@ int spnic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause) return spnic_cfg_hw_pause(hwdev, SPNIC_CMD_OP_GET, nic_pause); } +int spnic_get_vport_stats(void *hwdev, struct spnic_vport_stats *stats) +{ + struct spnic_port_stats_info stats_info; + struct spnic_cmd_vport_stats vport_stats; + u16 out_size = sizeof(vport_stats); + int err; + + if (!hwdev || !stats) + return -EINVAL; + + memset(&stats_info, 0, sizeof(stats_info)); + memset(&vport_stats, 0, sizeof(vport_stats)); + + stats_info.func_id = spnic_global_func_id(hwdev); + + err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_GET_VPORT_STAT, +&stats_info, sizeof(stats_info), +&vport_stats, &out_size); + if (err || !out_size || vport_stats.msg_head.status) { + PMD_DRV_LOG(ERR, "Get function stats failed, err: %d, status: 0x%x, out size: 0x%x", + err, vport_stats.msg_head.status, out_size); + return -EIO; + } + + memcpy(stats, &vport_stats.stats, sizeof(*stats)); + + return 0; +} + +int spnic_get_phy_port_stats(void *hwdev, struct mag_phy_port_stats *stats) +{ + struct mag_cmd_get_port_stat *port_stats = NULL; + struct mag_cmd_port_stats_info stats_info; + u16 out_size = sizeof(*port_stats); + int err; + + port_stats = rte_zmalloc("port_stats", sizeof(*port_stats), 0); + if (!port_stats) + return -ENOMEM; + + memset(&stats_info, 0, sizeof(stats_info)); + stats_info.port_id = spnic_physical_port_id(hwdev); + + err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT, + &stats_info, sizeof(stats_info), + port_stats, &out_size); + if (err || !out_size || port_stats->head.status) { + PMD_DRV_LOG(ERR, + "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n", + err, port_stats->head.status, out_size); + err = -EIO; + goto out; + } + + memcpy(stats, &port_stats->counter, sizeof(*stats)); + +out: + rte_free(port_stats); + + return err; +} + +int spnic_clear_vport_stats(void *hwdev) +{ + struct spnic_cmd_clear_vport_stats clear_vport_stats; + u16 out_size = sizeof(clear_vport_stats); + int err; + + if (!hwdev) { + PMD_DRV_LOG(ERR, "Hwdev is NULL"); + return -EINVAL; + } + + memset(&clear_vport_stats, 0, sizeof(clear_vport_stats)); + clear_vport_stats.func_id = spnic_global_func_id(hwdev); + + err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CLEAN_VPORT_STAT, +&clear_vport_stats, +sizeof(clear_vport_stats), +&clear_vport_stats, &out_size); + if (err || !out_size || clear_vport_stats.msg_head.status) { + PMD_DRV_LOG(ERR, "Clear vport stats failed, err: %d, status: 0x%x, out size: 0x%x", + err, clear_vport_stats.msg_head.status, out_size); + return -EIO; + } + + return 0; +} + +int spnic_clear_phy_port_stats(void *hwdev) +{ + struct mag_cmd_clr_port_stat *port_stats = NULL; + u16 out_size = sizeof(*port_stats); + int err; + + port_stats = rte_zmalloc("port_stats", sizeof(*port_stats), 0); + if (!port_stats) + return -ENOMEM; + + port_stats->port_id = spnic_physical_port_id(hwdev); + + err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT, + &port_stats, sizeof(port_stats), + port_stats, &out_size); + if (err || !out_size || port_stats->head.status) { + PMD_DRV_LOG(ERR, + "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n", + err, port_stats->head.status, out_size); + err = -EIO; + goto out; + } + +out: + rte_free(port_stats); + + return err; +} + static int spnic_set_function_table(void *hwd
[PATCH v4 23/25] net/spnic: support VFIO interrupt
This commit supports VFIO interrupt for Rx queue and asynchronous event, and implements rx_queue_intr_disable() and rx_queue_intr_enable() to disable/enable the interrupt of specified Rx queue. Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_eqs.c | 11 ++ drivers/net/spnic/spnic_ethdev.c | 218 - drivers/net/spnic/spnic_ethdev.h | 3 + drivers/net/spnic/spnic_rx.c | 2 + 4 files changed, 233 insertions(+), 1 deletion(-) diff --git a/drivers/net/spnic/base/spnic_eqs.c b/drivers/net/spnic/base/spnic_eqs.c index ee52252ecc..513d0329ed 100644 --- a/drivers/net/spnic/base/spnic_eqs.c +++ b/drivers/net/spnic/base/spnic_eqs.c @@ -12,6 +12,7 @@ #include "spnic_eqs.h" #include "spnic_mgmt.h" #include "spnic_mbox.h" +#include "spnic_hw_comm.h" #include "spnic_nic_event.h" #define AEQ_CTRL_0_INTR_IDX_SHIFT 0 @@ -648,3 +649,13 @@ int spnic_aeq_poll_msg(struct spnic_eq *eq, u32 timeout, void *param) return err; } + +void spnic_dev_handle_aeq_event(struct spnic_hwdev *hwdev, void *param) +{ + struct spnic_eq *aeq = &hwdev->aeqs->aeq[0]; + + /* Clear resend timer cnt register */ + spnic_misx_intr_clear_resend_bit(hwdev, aeq->eq_irq.msix_entry_idx, +EQ_MSIX_RESEND_TIMER_CLEAR); + (void)spnic_aeq_poll_msg(aeq, 0, param); +} diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index d1ecf98263..430e8cb340 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -248,6 +248,28 @@ static const struct rte_eth_desc_lim spnic_tx_desc_lim = { .nb_align = SPNIC_TXD_ALIGN, }; +/** + * Interrupt handler triggered by NIC for handling specific event + * + * @param[in] param + * The address of parameter (struct rte_eth_dev *) registered before + */ +static void spnic_dev_interrupt_handler(void *param) +{ + struct rte_eth_dev *dev = param; + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + + if (!rte_bit_relaxed_get32(SPNIC_DEV_INTR_EN, &nic_dev->dev_status)) { + PMD_DRV_LOG(WARNING, + "Intr is disabled, ignore intr event, dev_name: %s, port_id: %d", + nic_dev->dev_name, dev->data->port_id); + return; + } + + /* Aeq0 msg handler */ + spnic_dev_handle_aeq_event(nic_dev->hwdev, param); +} + /** * Ethernet device configuration. * @@ -952,6 +974,46 @@ static void spnic_deinit_mac_addr(struct rte_eth_dev *eth_dev) spnic_delete_mc_addr_list(nic_dev); } +int spnic_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, + uint16_t queue_id) +{ + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = pci_dev->intr_handle; + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + u16 msix_intr; + + if (!rte_intr_dp_is_en(intr_handle)) + return 0; + + if (queue_id >= dev->data->nb_rx_queues) + return -EINVAL; + + msix_intr = (u16)(queue_id + RTE_INTR_VEC_RXTX_OFFSET); + spnic_set_msix_state(nic_dev->hwdev, msix_intr, SPNIC_MSIX_ENABLE); + + return 0; +} + +int spnic_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id) +{ + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = pci_dev->intr_handle; + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + u16 msix_intr; + + if (!rte_intr_dp_is_en(intr_handle)) + return 0; + + if (queue_id >= dev->data->nb_rx_queues) + return -EINVAL; + + msix_intr = (u16)(queue_id + RTE_INTR_VEC_RXTX_OFFSET); + spnic_set_msix_state(nic_dev->hwdev, msix_intr, SPNIC_MSIX_DISABLE); + spnic_misx_intr_clear_resend_bit(nic_dev->hwdev, msix_intr, 1); + + return 0; +} + static int spnic_set_rxtx_configure(struct rte_eth_dev *dev) { struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); @@ -1085,6 +1147,108 @@ static void spnic_remove_all_vlanid(struct rte_eth_dev *dev) } } +static void spnic_disable_interrupt(struct rte_eth_dev *dev) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + + if (!rte_bit_relaxed_get32(SPNIC_DEV_INIT, &nic_dev->dev_status)) + return; + + /* disable rte interrupt */ + rte_intr_disable(pci_dev->intr_handle); + rte_intr_callback_unregister(pci_dev->intr_handle, +spnic_dev_interrupt_handler, (void *)dev); +} + +static void spnic_enable_interrupt(struct rte_eth_dev *dev) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct rte_pci_device *pc
[PATCH v4 24/25] net/spnic: support Tx/Rx queue start/stop
This commit support starting or stopping a specified Rx/Tx queue For Rx queue: when starting rx queue, mbuf will be allocated and fill rq wqe with mbuf info, then add the qid to indirect table of RSS. if the first rx queue is started, the valid bit in function table will be set so that the packets can be received to host. when stopping rx queue, the PMD driver will poll the rx queue until it is empty and release the mbuf, then the PMD driver will remove the qid for RSS indirect table. if the last rx queue is stopped, the valid bit in function table will be cleared. For Rx queue: when stopping tx queue, the PMD driver will wait until all tx packets are sent and then releases all mbuf. Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_nic_cfg.c | 33 drivers/net/spnic/base/spnic_nic_cfg.h | 13 ++ drivers/net/spnic/spnic_ethdev.c | 82 + drivers/net/spnic/spnic_rx.c | 222 + drivers/net/spnic/spnic_rx.h | 4 + 5 files changed, 354 insertions(+) diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c index e740138b8e..862400de71 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.c +++ b/drivers/net/spnic/base/spnic_nic_cfg.c @@ -1289,6 +1289,39 @@ int spnic_vf_get_default_cos(void *hwdev, u8 *cos_id) return 0; } +int spnic_set_rq_flush(void *hwdev, u16 q_id) +{ + struct spnic_cmd_set_rq_flush *rq_flush_msg = NULL; + struct spnic_cmd_buf *cmd_buf = NULL; + u64 out_param = EIO; + int err; + + cmd_buf = spnic_alloc_cmd_buf(hwdev); + if (!cmd_buf) { + PMD_DRV_LOG(ERR, "Failed to allocate cmd buf\n"); + return -ENOMEM; + } + + cmd_buf->size = sizeof(*rq_flush_msg); + + rq_flush_msg = cmd_buf->buf; + rq_flush_msg->local_rq_id = q_id; + rq_flush_msg->value = cpu_to_be32(rq_flush_msg->value); + + err = spnic_cmdq_direct_resp(hwdev, SPNIC_MOD_L2NIC, +SPNIC_UCODE_CMD_SET_RQ_FLUSH, cmd_buf, +&out_param, 0); + if (err || out_param != 0) { + PMD_DRV_LOG(ERR, "Failed to set rq flush, err:%d, out_param: %" PRIu64 "", + err, out_param); + err = -EFAULT; + } + + spnic_free_cmd_buf(cmd_buf); + + return err; +} + static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size) { diff --git a/drivers/net/spnic/base/spnic_nic_cfg.h b/drivers/net/spnic/base/spnic_nic_cfg.h index 560c9e4e7d..7c39a32d7c 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.h +++ b/drivers/net/spnic/base/spnic_nic_cfg.h @@ -1069,6 +1069,19 @@ int spnic_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl); */ int spnic_vf_get_default_cos(void *hwdev, u8 *cos_id); +/** + * Flush rx queue resource + * + * @param[in] hwdev + * Device pointer to hwdev + * @param[in] q_id + * rx queue id + * + * @retval zero : Success + * @retval non-zero : Failure + */ +int spnic_set_rq_flush(void *hwdev, u16 q_id); + /** * Get service feature HW supported * diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index 430e8cb340..d98637c971 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -974,6 +974,80 @@ static void spnic_deinit_mac_addr(struct rte_eth_dev *eth_dev) spnic_delete_mc_addr_list(nic_dev); } +static int spnic_dev_rx_queue_start(__rte_unused struct rte_eth_dev *dev, +__rte_unused uint16_t rq_id) +{ + struct spnic_rxq *rxq = NULL; + int rc; + + if (rq_id < dev->data->nb_rx_queues) { + rxq = dev->data->rx_queues[rq_id]; + + rc = spnic_start_rq(dev, rxq); + if (rc) { + PMD_DRV_LOG(ERR, "Start rx queue failed, eth_dev:%s, queue_idx:%d", + dev->data->name, rq_id); + return rc; + } + + dev->data->rx_queue_state[rq_id] = RTE_ETH_QUEUE_STATE_STARTED; + } + + return 0; +} + +static int spnic_dev_rx_queue_stop(__rte_unused struct rte_eth_dev *dev, + __rte_unused uint16_t rq_id) +{ + struct spnic_rxq *rxq = NULL; + int rc; + + if (rq_id < dev->data->nb_rx_queues) { + rxq = dev->data->rx_queues[rq_id]; + + rc = spnic_stop_rq(dev, rxq); + if (rc) { + PMD_DRV_LOG(ERR, "Stop rx queue failed, eth_dev:%s, queue_idx:%d", + dev->data->name, rq_id); + return rc; + } + + dev->data->rx_queue_state[rq_id] = RTE_ETH_QUEUE_STATE_STOPPED; + } + + return 0; +} + +static int spnic_dev_tx_queue_start(__rte_
[PATCH v4 25/25] net/spnic: add doc infrastructure
This patch adds doc infrastructure for spnic PMD driver. Signed-off-by: Yanling Song --- MAINTAINERS| 6 doc/guides/nics/features/spnic.ini | 39 + doc/guides/nics/index.rst | 1 + doc/guides/nics/spnic.rst | 55 ++ 4 files changed, 101 insertions(+) create mode 100644 doc/guides/nics/features/spnic.ini create mode 100644 doc/guides/nics/spnic.rst diff --git a/MAINTAINERS b/MAINTAINERS index 18d9edaf88..12f6171aef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -919,6 +919,12 @@ F: drivers/net/qede/ F: doc/guides/nics/qede.rst F: doc/guides/nics/features/qede*.ini +Ramaxel SPNIC +M: Yanling Song +F: drivers/net/spnic/ +F: doc/guides/nics/spnic.rst +F: doc/guides/nics/features/spnic.ini + Solarflare sfc_efx M: Andrew Rybchenko F: drivers/common/sfc_efx/ diff --git a/doc/guides/nics/features/spnic.ini b/doc/guides/nics/features/spnic.ini new file mode 100644 index 00..1cec6a59fa --- /dev/null +++ b/doc/guides/nics/features/spnic.ini @@ -0,0 +1,39 @@ +; +; Supported features of 'spnic' network poll mode driver. +; +; Refer to default.ini for the full list of available PMD features. +; +[Features] +Speed capabilities = Y +Link status = Y +Link status event= Y +Queue start/stop = Y +MTU update = Y +Scattered Rx = Y +LRO = Y +TSO = Y +Promiscuous mode = Y +Allmulticast mode= Y +Unicast MAC filter = Y +Multicast MAC filter = Y +RSS hash = Y +RSS key update = Y +RSS reta update = Y +Inner RSS= Y +SR-IOV = Y +Flow control = Y +CRC offload = Y +VLAN filter = Y +VLAN offload = Y +L3 checksum offload = Y +L4 checksum offload = Y +Inner L3 checksum= Y +Inner L4 checksum= Y +Basic stats = Y +Extended stats = Y +Stats per queue = Y +FW version = Y +Multiprocess aware = Y +Linux= Y +x86-64 = Y +ARMv8= Y diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst index 1c94caccea..6d47fa64a1 100644 --- a/doc/guides/nics/index.rst +++ b/doc/guides/nics/index.rst @@ -57,6 +57,7 @@ Network Interface Controller Drivers pfe qede sfc_efx +spnic softnic tap thunderx diff --git a/doc/guides/nics/spnic.rst b/doc/guides/nics/spnic.rst new file mode 100644 index 00..fd04178f8a --- /dev/null +++ b/doc/guides/nics/spnic.rst @@ -0,0 +1,55 @@ +.. SPDX-License-Identifier: BSD-3-Clause +Copyright(c) 2021 Ramaxel Memory Technology, Ltd + + +SPNIC Poll Mode Driver +== + +The spnic PMD (**librte_net_spnic**) provides poll mode driver support +for 25Gbps/100Gbps SPNxxx Network Adapters. + + +Features + + +- Multiple queues for TX and RX +- Receiver Side Scaling(RSS) +- RSS supports IPv4, IPv6, TCPv4, TCPv6, UDPv4 and UDPv6, use inner type for VXLAN as default +- MAC/VLAN filtering +- Checksum offload +- TSO offload +- LRO offload +- Promiscuous mode +- Port hardware statistics +- Link state information +- Link flow control(pause frame) +- Scattered and gather for TX and RX +- SR-IOV - Partially supported VFIO only +- VLAN filter and VLAN offload +- Allmulticast mode +- MTU update +- Unicast MAC filter +- Multicast MAC filter +- Set Link down or up +- FW version +- Multi arch support: x86_64, ARMv8. + +Prerequisites +- + +- Follow the DPDK :ref:`Getting Started Guide for Linux ` to setup the basic DPDK environment. + + +Driver compilation and testing +-- + +Refer to the document :ref:`compiling and testing a PMD for a NIC ` +for details. + +It is highly recommended to upgrade the spnic driver and firmware to avoid the compatibility issues, +and check the work mode with the latest product documents. + +Limitations or Known issues +--- +Build with ICC is not supported yet. +X86-32, Power8, ARMv7 and BSD are not supported yet. -- 2.32.0