[PATCH] net/ice/base: support E824S and E825 devices
Add support for E824S and E825 family devices. Signed-off-by: Robin Zhang --- drivers/net/ice/base/ice_common.c | 6 ++ drivers/net/ice/base/ice_devids.h | 13 + drivers/net/ice/ice_ethdev.c | 6 ++ 3 files changed, 25 insertions(+) diff --git a/drivers/net/ice/base/ice_common.c b/drivers/net/ice/base/ice_common.c index ae55bebaa2..db87bacd97 100644 --- a/drivers/net/ice/base/ice_common.c +++ b/drivers/net/ice/base/ice_common.c @@ -167,6 +167,12 @@ static enum ice_status ice_set_mac_type(struct ice_hw *hw) case ICE_DEV_ID_E823C_QSFP: case ICE_DEV_ID_E823C_SFP: case ICE_DEV_ID_E823C_SGMII: + case ICE_DEV_ID_E824S: + case ICE_DEV_ID_E825C_BACKPLANE: + case ICE_DEV_ID_E825C_QSFP: + case ICE_DEV_ID_E825C_SFP: + case ICE_DEV_ID_E825C_1GBE: + case ICE_DEV_ID_E825X: hw->mac_type = ICE_MAC_GENERIC; break; default: diff --git a/drivers/net/ice/base/ice_devids.h b/drivers/net/ice/base/ice_devids.h index e52bb71403..96f2528c5e 100644 --- a/drivers/net/ice/base/ice_devids.h +++ b/drivers/net/ice/base/ice_devids.h @@ -58,5 +58,18 @@ #define ICE_DEV_ID_E822L_10G_BASE_T0x1899 /* Intel(R) Ethernet Connection E822-L 1GbE */ #define ICE_DEV_ID_E822L_SGMII 0x189A +/* Intel(R) Ethernet Connection E824-S */ +#define ICE_DEV_ID_E824S 0x0DBD +/* Intel(R) Ethernet Connection E825-C for backplane */ +#define ICE_DEV_ID_E825C_BACKPLANE 0x579C +/* Intel(R) Ethernet Connection E825-C for QSFP */ +#define ICE_DEV_ID_E825C_QSFP 0x579D +/* Intel(R) Ethernet Connection E825-C for SFP */ +#define ICE_DEV_ID_E825C_SFP 0x579E +/* Intel(R) Ethernet Connection E825-C 1GbE */ +#define ICE_DEV_ID_E825C_1GBE 0x579F +/* Intel(R) Ethernet Connection E825-X */ +#define ICE_DEV_ID_E825X 0x0DCD + #endif /* _ICE_DEVIDS_H_ */ diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index 13a7a9702a..e9a28faa72 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -192,6 +192,12 @@ static const struct rte_pci_id pci_id_ice_map[] = { { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E822L_SFP) }, { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E822L_10G_BASE_T) }, { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E822L_SGMII) }, + { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E824S) }, + { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E825C_BACKPLANE) }, + { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E825C_QSFP) }, + { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E825C_SFP) }, + { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E825C_1GBE) }, + { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E825X) }, { .vendor_id = 0, /* sentinel */ }, }; -- 2.34.1
Re: [PATCH v3 05/25] net/spnic: add mgmt module
On Tue, 28 Dec 2021 07:59:18 -0800 Stephen Hemminger wrote: > On Fri, 24 Dec 2021 16:32:23 +0800 > Yanling Song wrote: > > > +static void nic_event_handler(void *hwdev > > This is one example of something this driver does a lot. > It casts away the hardware device structure to void * then reassigns > it to the the hardware structure. This is the classic type unsafe C > style code. If possible keep the type information. Ok. The change will be included in V5 since V4 was pushed already.
Re: [PATCH v4 02/25] net/spnic: initialize the HW interface
> > @@ -35,11 +68,42 @@ static int spnic_func_init(struct rte_eth_dev > > *eth_dev) pci_dev->addr.domain, pci_dev->addr.bus, > > pci_dev->addr.devid, pci_dev->addr.function); > > > > + eth_dev->data->dev_flags |= > > RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; > > Please do not use the temporary macro. Please review this patch: > > f30e69b41f94 ("ethdev: add device flag to bypass auto-filled queue > xstats") > Ok. RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS will be removed in V5.
Re: [PATCH v3 00/25] Net/SPNIC: support SPNIC into DPDK 22.03
On Tue, 28 Dec 2021 07:55:23 -0800 Stephen Hemminger wrote: > On Tue, 28 Dec 2021 15:01:20 +0800 > Yanling Song wrote: > > > On Fri, 24 Dec 2021 09:44:57 -0800 > > Stephen Hemminger wrote: > > > > > On Fri, 24 Dec 2021 16:32:18 +0800 > > > Yanling Song wrote: > > > > > > > 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 > > > > > > > > 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(); > > > > > > Overall looks good. > > > > > > Please use a consistent prefix to all globally visible symbols to > > > avoid any possible name clashes when statically linking. > > > > > > $ nm ./build/drivers/librte_net_spnic.a | grep ' t ' | grep -v > > > spnic_ | grep -v rte_ 06f0 t remove_aeq > > > 0040 t fault_event_handler > > > 0060 t ffm_event_msg_handler > > > 16c0 t alloc_mbox_info > > > 0ca0 t send_mbox_to_func > > > 0890 t send_tlp_mbox_to_func > > > 00c0 t pciinitfn_net_spnic > > > 0890 t clean_queue_offload_ctxt > > > > > > > > Good point. There are some external functions which have no spnic_ > > prefix. and there are also some static functions which have no > > spnic_ prefix. > > Since static functions only works in the file, it doesn't matter to > > add prefix or not. My plan is to add spnic_ prefix to those external > > functions. Is it ok to you? > > > > > > Yes, that is what this script was looking for, external functions > with no prefix Ok. Changes will be included in V5.
[PATCH v5 00/26] 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 v5->v4: 1. Add prefix "spinc_" for external functions; 2. Remove temporary MACRO: RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS 3. Do not use void* for keeping the type information 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 (26): 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 net/spnic: Fix reviewers comments 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| 201 ++ drivers/net/spnic/base/spnic_hw_cfg.h| 125 + drivers/net/spnic/base/spnic_hw_comm.c | 483 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 | 770 ++ 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 | 366 +++ 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 | 183 ++ drivers/net/spnic/base/spnic_nic_event.h | 24 + drivers/net/spnic/base/spnic_wq.c| 138 + 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 | 728 + 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, 16558 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
[PATCH v5 01/26] 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 v5 03/26] 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..a8f59ffd41 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 spnic_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..560639a70f 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 spnic_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..34bd27dfee --- /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
[PATCH v5 04/26] 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 v5 05/26] 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 v5 02/26] 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 v5 08/26] 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..ac76b2632e --- /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 v5 07/26] 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 v5 06/26] 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 v5 10/26] 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 83a8e98408..36e87ffe40 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 df59d7874f..cf2b2ded01 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 spnic_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 2d4ba70bf0..108f6eef23 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 = spnic_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(
[PATCH v5 09/26] 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 ac76b2632e..83a8e98408 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 5003d048e6..df59d7874f 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 spnic_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..2d4ba70bf0 --- /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 spnic_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
[PATCH v5 12/26] 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 4ce607e813..8c04295258 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 = spnic_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 af0ffc519e..609864ce77 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 spnic_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 6c6a3eb586..13c2456590 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 + *
[PATCH v5 11/26] 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 v5 14/26] 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 c1f567179b..c69c37c7c8 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 v5 13/26] 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 8c04295258..85eca39d68 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 = spnic_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 = spnic_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 = spnic_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 = spnic_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; +
[PATCH v5 18/26] 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 85eca39d68..8f4249980b 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 d67e8d0aec..f2d24be8ab 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 v5 17/26] 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 892803501e..d67e8d0aec 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 v5 21/26] 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 c9f6612c60..e8989b9681 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 v5 15/26] 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 c69c37c7c8..bceccbe0d4 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 v5 16/26] 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 bceccbe0d4..892803501e 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 v5 22/26] 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 52ad2d1148..32d52bd81e 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 = spnic_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 = spnic_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_tab
[PATCH v5 20/26] 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 8f4249980b..52ad2d1148 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 = spnic_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 9b926119d8..2e00bdece5 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 b9694b8da8..c9f6612c60 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-
[PATCH v5 19/26] 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 f2d24be8ab..b9694b8da8 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 v5 26/26] net/spnic: Fix reviewers comments
Fix reviewers comments: 1. Remove temporary MACRO: RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS 2. Do not use void* for keeping the type information Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_cmdq.c | 14 +-- drivers/net/spnic/base/spnic_cmdq.h | 6 +- drivers/net/spnic/base/spnic_hw_cfg.c| 49 -- drivers/net/spnic/base/spnic_hw_cfg.h| 16 ++-- drivers/net/spnic/base/spnic_hw_comm.c | 32 --- drivers/net/spnic/base/spnic_hw_comm.h | 22 ++--- drivers/net/spnic/base/spnic_hwdev.c | 8 +- drivers/net/spnic/base/spnic_hwif.c | 52 +-- drivers/net/spnic/base/spnic_hwif.h | 22 ++--- drivers/net/spnic/base/spnic_mgmt.c | 9 +- drivers/net/spnic/base/spnic_mgmt.h | 4 +- drivers/net/spnic/base/spnic_nic_cfg.c | 110 +++ drivers/net/spnic/base/spnic_nic_cfg.h | 84 - drivers/net/spnic/base/spnic_nic_event.c | 30 +++ drivers/net/spnic/base/spnic_nic_event.h | 10 +-- drivers/net/spnic/base/spnic_wq.c| 3 +- drivers/net/spnic/base/spnic_wq.h| 2 +- drivers/net/spnic/spnic_ethdev.c | 11 ++- drivers/net/spnic/spnic_io.c | 34 +++ drivers/net/spnic/spnic_io.h | 10 +-- drivers/net/spnic/spnic_rx.c | 4 +- drivers/net/spnic/spnic_tx.c | 4 +- 22 files changed, 252 insertions(+), 284 deletions(-) diff --git a/drivers/net/spnic/base/spnic_cmdq.c b/drivers/net/spnic/base/spnic_cmdq.c index b8950f91c2..62189d20a3 100644 --- a/drivers/net/spnic/base/spnic_cmdq.c +++ b/drivers/net/spnic/base/spnic_cmdq.c @@ -160,9 +160,9 @@ bool spnic_cmdq_idle(struct spnic_cmdq *cmdq) true : false); } -struct spnic_cmd_buf *spnic_alloc_cmd_buf(void *hwdev) +struct spnic_cmd_buf *spnic_alloc_cmd_buf(struct spnic_hwdev *hwdev) { - struct spnic_cmdqs *cmdqs = ((struct spnic_hwdev *)hwdev)->cmdqs; + struct spnic_cmdqs *cmdqs = hwdev->cmdqs; struct spnic_cmd_buf *cmd_buf; cmd_buf = rte_zmalloc(NULL, sizeof(*cmd_buf), 0); @@ -491,7 +491,7 @@ static int cmdq_sync_cmd_detail_resp(struct spnic_cmdq *cmdq, return err; } -static int cmdq_params_valid(void *hwdev, struct spnic_cmd_buf *buf_in) +static int cmdq_params_valid(struct spnic_hwdev *hwdev, struct spnic_cmd_buf *buf_in) { if (!buf_in || !hwdev) { PMD_DRV_LOG(ERR, "Invalid CMDQ buffer or hwdev is NULL"); @@ -520,11 +520,11 @@ static int wait_cmdqs_enable(struct spnic_cmdqs *cmdqs) return -EBUSY; } -int spnic_cmdq_direct_resp(void *hwdev, enum spnic_mod_type mod, u8 cmd, +int spnic_cmdq_direct_resp(struct spnic_hwdev *hwdev, enum spnic_mod_type mod, u8 cmd, struct spnic_cmd_buf *buf_in, u64 *out_param, u32 timeout) { - struct spnic_cmdqs *cmdqs = ((struct spnic_hwdev *)hwdev)->cmdqs; + struct spnic_cmdqs *cmdqs = hwdev->cmdqs; int err; err = cmdq_params_valid(hwdev, buf_in); @@ -543,11 +543,11 @@ int spnic_cmdq_direct_resp(void *hwdev, enum spnic_mod_type mod, u8 cmd, mod, cmd, buf_in, out_param, timeout); } -int spnic_cmdq_detail_resp(void *hwdev, enum spnic_mod_type mod, u8 cmd, +int spnic_cmdq_detail_resp(struct spnic_hwdev *hwdev, enum spnic_mod_type mod, u8 cmd, struct spnic_cmd_buf *buf_in, struct spnic_cmd_buf *buf_out, u32 timeout) { - struct spnic_cmdqs *cmdqs = ((struct spnic_hwdev *)hwdev)->cmdqs; + struct spnic_cmdqs *cmdqs = hwdev->cmdqs; int err; err = cmdq_params_valid(hwdev, buf_in); diff --git a/drivers/net/spnic/base/spnic_cmdq.h b/drivers/net/spnic/base/spnic_cmdq.h index 9a08262860..bee899361c 100644 --- a/drivers/net/spnic/base/spnic_cmdq.h +++ b/drivers/net/spnic/base/spnic_cmdq.h @@ -225,7 +225,7 @@ int spnic_reinit_cmdq_ctxts(struct spnic_hwdev *hwdev); bool spnic_cmdq_idle(struct spnic_cmdq *cmdq); -struct spnic_cmd_buf *spnic_alloc_cmd_buf(void *hwdev); +struct spnic_cmd_buf *spnic_alloc_cmd_buf(struct spnic_hwdev *hwdev); void spnic_free_cmd_buf(struct spnic_cmd_buf *cmd_buf); @@ -233,11 +233,11 @@ void spnic_free_cmd_buf(struct spnic_cmd_buf *cmd_buf); * PF/VF sends cmd to ucode by cmdq, and return 0 if success. * timeout=0, use default timeout. */ -int spnic_cmdq_direct_resp(void *hwdev, enum spnic_mod_type mod, u8 cmd, +int spnic_cmdq_direct_resp(struct spnic_hwdev *hwdev, enum spnic_mod_type mod, u8 cmd, struct spnic_cmd_buf *buf_in, u64 *out_param, u32 timeout); -int spnic_cmdq_detail_resp(void *hwdev, enum spnic_mod_type mod, u8 cmd, +int spnic_cmdq_detail_resp(struct spnic_hwdev *hwdev, enum spnic_mod_type mod, u8 cmd, struct spnic_cmd_buf *buf_in, struct spnic_cmd_buf *buf_out, u32 timeout); diff -
[PATCH v5 25/26] 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
[PATCH v5 23/26] 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 be1c9c5894..c959e48727 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 v5 24/26] 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 32d52bd81e..78561a5c64 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 3c996e2838..c73191dc81 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 c959e48727..05a0fd588d 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_
Understanding Flow API action RSS
Hi all, In 'rte_flow.h', there is 'struct rte_flow_action_rss'. In it, 'queue' is to provide "Queue indices to use". But it is unclear whether the order of elements is meaningful or not. Does that matter? Can queue indices repeat? An ethdev may have "global" RSS setting with an indirection table of some fixed size (say, 512). In what comes to flow rules, does that size matter? When the user selects 'RTE_ETH_HASH_FUNCTION_DEFAULT' in action RSS, does that allow the PMD to configure an arbitrary, non-Toeplitz hash algorithm? Please advise.
[RFC 0/3] Add support for GRE optional fields matching
This patch set adds support for matching optional fields of GRE header. The optional fields are checksum, key and sequence number. Currently, key field is supported with pattern gre_key item '.. / gre / gre_key value is xx / ..' with field gre_key in misc, but misc does not support matching of checksum and sequence number of GRE. To support matching of checksum and sequence number fields in GRE, rdma-core needs the capbility of misc5 and support tunnel_header 0-3. Since tunnel_header1 is used to match checksum, tunnel_header2 for key and tunnel_header3 for sequence by hardware. If checksum and sequence number not present in the pattern, use misc as before for the matching. Application can still use gre_key item 'gre_key value is xx' for key matching, the effect is the same if use 'gre_option key is xx'. If using gre_option item, the flags in gre item should be correspondingly set. For example, if using gre_option to match checksum, the c_bit should be set '1' (.. / gre c_bit is 1 / gre_option checksum is xx / ..). Sean Zhang (3): ethdev: support GRE optional fields app/testpmd: add gre_option item command net/mlx5: support matching on optional fields of GRE app/test-pmd/cmdline_flow.c | 57 doc/guides/prog_guide/rte_flow.rst | 16 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 6 ++ drivers/common/mlx5/mlx5_devx_cmds.c| 3 + drivers/net/mlx5/linux/mlx5_os.c| 2 + drivers/net/mlx5/mlx5.h | 1 + drivers/net/mlx5/mlx5_flow.c| 94 drivers/net/mlx5/mlx5_flow.h| 6 ++ drivers/net/mlx5/mlx5_flow_dv.c | 133 lib/ethdev/rte_flow.c | 1 + lib/ethdev/rte_flow.h | 18 11 files changed, 337 insertions(+) -- 1.8.3.1
[RFC 1/3] ethdev: support GRE optional fields
Add flow pattern items and header format for matching optional fields (checksum/key/sequence) in GRE header. And the flags in gre item should be correspondingly set with the new added items. Signed-off-by: Sean Zhang --- doc/guides/prog_guide/rte_flow.rst | 16 lib/ethdev/rte_flow.c | 1 + lib/ethdev/rte_flow.h | 18 ++ 3 files changed, 35 insertions(+) diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index c51ed88..48d5685 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1113,6 +1113,22 @@ This should be preceded by item ``GRE``. - Value to be matched is a big-endian 32 bit integer. - When this item present it implicitly match K bit in default mask as "1" +Item: ``GRE_OPTION`` + + +Matches a GRE optional fields (checksum/key/sequence). +This should be preceded by item ``GRE``. + +- ``checksum``: checksum. +- ``key``: key. +- ``sequence``: sequence. +- The items in GRE_OPTION do not change bit flags(c_bit/k_bit/s_bit) in GRE + item. The bit flags need be set with GRE item by application. When the items + present, the corresponding bits in GRE spec and mask should be set "1" by + application, it means to match specified value of the fields. When the items + no present, but the corresponding bits in GRE spec and mask is "1", it means + to match any value of the fields. + Item: ``FUZZY`` ^^^ diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index a93f68a..03bd1df 100644 --- a/lib/ethdev/rte_flow.c +++ b/lib/ethdev/rte_flow.c @@ -139,6 +139,7 @@ struct rte_flow_desc_data { MK_FLOW_ITEM(META, sizeof(struct rte_flow_item_meta)), MK_FLOW_ITEM(TAG, sizeof(struct rte_flow_item_tag)), MK_FLOW_ITEM(GRE_KEY, sizeof(rte_be32_t)), + MK_FLOW_ITEM(GRE_OPTION, sizeof(struct rte_gre_hdr_option)), MK_FLOW_ITEM(GTP_PSC, sizeof(struct rte_flow_item_gtp_psc)), MK_FLOW_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), MK_FLOW_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index 1031fb2..27b4140 100644 --- a/lib/ethdev/rte_flow.h +++ b/lib/ethdev/rte_flow.h @@ -660,6 +660,13 @@ enum rte_flow_item_type { * See struct rte_flow_item_ppp. */ RTE_FLOW_ITEM_TYPE_PPP, + + /** +* Matches GRE optional fields. +* +* See struct rte_gre_hdr_option. +*/ + RTE_FLOW_ITEM_TYPE_GRE_OPTION, }; /** @@ -1196,6 +1203,17 @@ struct rte_flow_item_gre { #endif /** + * RTE_FLOW_ITEM_TYPE_GRE_OPTION. + * + * Matches GRE optional fields in header. + */ +struct rte_gre_hdr_option { + rte_be16_t checksum; + rte_be32_t key; + rte_be32_t sequence; +}; + +/** * RTE_FLOW_ITEM_TYPE_FUZZY * * Fuzzy pattern match, expect faster than default. -- 1.8.3.1
[RFC 2/3] app/testpmd: add gre_option item command
Add gre_option command for matching optional fields(checksum/key/sequence) in GRE header. The item must follow gre item, and the item does not change the flags in gre item, the application should set the flags in gre item correspondingly. Application can still use gre_key item 'gre_key value is xx' for key matching, the effect is the same with using 'gre_option key is xx'. The examples for gre_option are as follows: To match on checksum field with value 0x11: testpmd> ... pattern / eth / gre c_bit is 1 / gre_option checksum is 0x11 / end .. To match on checksum field with value 0x11 and any value of key: testpmd> ... pattern / eth / gre c_bit is 1 k_bit is 1 / gre_option checksum is 0x11 / end .. To match on checksum field with value 0x11 and no key field in packet: testpmd> ... pattern / eth / gre c_bit is 1 k_bit is 0 / gre_option checksum is 0x11 / end .. The invalid patterns for gre_option are as follows: testpmd> ... pattern / eth / gre / gre_option checksum is 0x11 / end .. (c_bit in gre item not present) testpmd> ... pattern / eth / gre c_bit is 0 / gre_option checksum is 0x11 / end .. (c_bit is unset for gre item, but checksum is specified by gre_option item) Signed-off-by: Sean Zhang --- app/test-pmd/cmdline_flow.c | 57 + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 6 +++ 2 files changed, 63 insertions(+) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index bbe3dc0..4e714c2 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -271,6 +271,10 @@ enum index { ITEM_META_DATA, ITEM_GRE_KEY, ITEM_GRE_KEY_VALUE, + ITEM_GRE_OPTION, + ITEM_GRE_OPTION_CHECKSUM, + ITEM_GRE_OPTION_KEY, + ITEM_GRE_OPTION_SEQUENCE, ITEM_GTP_PSC, ITEM_GTP_PSC_QFI, ITEM_GTP_PSC_PDU_T, @@ -1042,6 +1046,7 @@ struct parse_action_priv { ITEM_ICMP6_ND_OPT_TLA_ETH, ITEM_META, ITEM_GRE_KEY, + ITEM_GRE_OPTION, ITEM_GTP_PSC, ITEM_PPPOES, ITEM_PPPOED, @@ -1232,6 +1237,14 @@ struct parse_action_priv { ZERO, }; +static const enum index item_gre_option[] = { + ITEM_GRE_OPTION_CHECKSUM, + ITEM_GRE_OPTION_KEY, + ITEM_GRE_OPTION_SEQUENCE, + ITEM_NEXT, + ZERO, +}; + static const enum index item_gtp[] = { ITEM_GTP_FLAGS, ITEM_GTP_MSG_TYPE, @@ -3479,6 +3492,37 @@ static int comp_set_modify_field_id(struct context *, const struct token *, item_param), .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), }, + [ITEM_GRE_OPTION] = { + .name = "gre_option", + .help = "match GRE optional fields", + .priv = PRIV_ITEM(GRE_OPTION, sizeof(struct rte_gre_hdr_option)), + .next = NEXT(item_gre_option), + .call = parse_vc, + }, + [ITEM_GRE_OPTION_CHECKSUM] = { + .name = "checksum", + .help = "match GRE checksum", + .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_gre_hdr_option, +checksum)), + }, + [ITEM_GRE_OPTION_KEY] = { + .name = "key", + .help = "match GRE key", + .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_gre_hdr_option, +key)), + }, + [ITEM_GRE_OPTION_SEQUENCE] = { + .name = "sequence", + .help = "match GRE sequence", + .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_gre_hdr_option, +sequence)), + }, [ITEM_GTP_PSC] = { .name = "gtp_psc", .help = "match GTP extension header with type 0x85", @@ -9235,6 +9279,19 @@ static int comp_set_modify_field_id(struct context *, const struct token *, ((const struct rte_flow_item_flex *) item->spec)->length : 0; break; + case RTE_FLOW_ITEM_TYPE_GRE_OPTION: + size = 0; + if (item->spec) { + const struct rte_gre_hdr_option *opt = item->spec; + if (opt->checksum) + size += 4; + if (opt->key) + size += 4; + if (opt->sequence) +
[RFC 3/3] net/mlx5: support matching on optional fields of GRE
This patch adds matching on the optional fields (checksum/key/sequence) of GRE header. The matching of checksum and sequence fields requests support from rdma-core with capability of misc5 and tunner_header 0-3. For patterns without checksum and sequence specified, keep using misc for matching as before, but for patterns with checksum or sequence, validate capability first and then use misc5 for the matching. Signed-off-by: Sean Zhang --- drivers/common/mlx5/mlx5_devx_cmds.c | 3 + drivers/net/mlx5/linux/mlx5_os.c | 2 + drivers/net/mlx5/mlx5.h | 1 + drivers/net/mlx5/mlx5_flow.c | 94 + drivers/net/mlx5/mlx5_flow.h | 6 ++ drivers/net/mlx5/mlx5_flow_dv.c | 133 +++ 6 files changed, 239 insertions(+) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index e52b995..3accb7b 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -1027,6 +1027,9 @@ struct mlx5_devx_obj * attr->flow.tunnel_header_0_1 = MLX5_GET (flow_table_nic_cap, hcattr, ft_field_support_2_nic_receive.tunnel_header_0_1); + attr->flow.tunnel_header_2_3 = MLX5_GET + (flow_table_nic_cap, hcattr, +ft_field_support_2_nic_receive.tunnel_header_2_3); attr->pkt_integrity_match = mlx5_devx_query_pkt_integrity_match(hcattr); attr->inner_ipv4_ihl = MLX5_GET (flow_table_nic_cap, hcattr, diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index c29fe3d..3bfcb5c 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -1385,6 +1385,8 @@ } if (config->hca_attr.flow.tunnel_header_0_1) sh->tunnel_header_0_1 = 1; + if (config->hca_attr.flow.tunnel_header_2_3) + sh->tunnel_header_2_3 = 1; #endif #ifdef HAVE_MLX5_DR_CREATE_ACTION_ASO if (config->hca_attr.flow_hit_aso && diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 8466531..9b5685a 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -1150,6 +1150,7 @@ struct mlx5_dev_ctx_shared { uint32_t meter_aso_en:1; /* Flow Meter ASO is supported. */ uint32_t ct_aso_en:1; /* Connection Tracking ASO is supported. */ uint32_t tunnel_header_0_1:1; /* tunnel_header_0_1 is supported. */ + uint32_t tunnel_header_2_3:1; /* tunnel_header_2_3 is supported. */ uint32_t misc5_cap:1; /* misc5 matcher parameter is supported. */ uint32_t reclaim_mode:1; /* Reclaim memory. */ uint32_t dr_drop_action_en:1; /* Use DR drop action. */ diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index f34e4b8..ad948c3 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -2802,6 +2802,100 @@ struct mlx5_flow_tunnel_info { } /** + * Validate GRE optional item. + * + * @param[in] dev + * Pointer to the Ethernet device structure. + * @param[in] item + * Item specification. + * @param[in] item_flags + * Bit flags to mark detected items. + * @param[in] attr + * Flow rule attributes. + * @param[in] gre_item + * Pointer to gre_item + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_flow_validate_item_gre_option(struct rte_eth_dev *dev, + const struct rte_flow_item *item, + uint64_t item_flags, + const struct rte_flow_attr *attr, + const struct rte_flow_item *gre_item, + struct rte_flow_error *error) +{ + const struct rte_flow_item_gre *gre_spec = gre_item->spec; + const struct rte_flow_item_gre *gre_mask = gre_item->mask; + const struct rte_gre_hdr_option *spec = item->spec; + const struct rte_gre_hdr_option *mask = item->mask; + struct mlx5_priv *priv = dev->data->dev_private; + int ret = 0; + + if (!(item_flags & MLX5_FLOW_LAYER_GRE)) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "No preceding GRE header"); + if (item_flags & MLX5_FLOW_LAYER_INNER) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "GRE option following a wrong item"); + if (!gre_mask) + gre_mask = &rte_flow_item_gre_mask; + + struct rte_gre_hdr_option gre_option_default_mask = { + .checksum = 0x, + .key = 0x, + .sequence = 0x, + }; + +
RE: [PATCH v2 1/1] net/ixgbe: check ixgbe filter init failure
> -Original Message- > From: Yunjian Wang > Sent: Friday, December 24, 2021 19:27 > To: dev@dpdk.org > Cc: Wang, Haiyue ; dingxiaoxi...@huawei.com; > xudin...@huawei.com; Yunjian Wang > ; sta...@dpdk.org > Subject: [PATCH v2 1/1] net/ixgbe: check ixgbe filter init failure > > The function ixgbe_fdir_filter_init() and ixgbe_l2_tn_filter_init() > could return errors, the return value need to be checked and returned. > > Fixes: 080e3c0ee989 ("net/ixgbe: store flow director filter") > Fixes: d0c0c416ef1f ("net/ixgbe: store L2 tunnel filter") > Cc: sta...@dpdk.org > > Signed-off-by: Yunjian Wang > --- > v2: update code suggested by Haiyue Wang > --- > drivers/net/ixgbe/ixgbe_ethdev.c | 32 +++- > 1 file changed, 23 insertions(+), 9 deletions(-) > Thanks! Acked-by: Haiyue Wang > -- > 2.27.0
[PATCH v6 02/26] 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 | 65 +++ drivers/net/spnic/spnic_ethdev.h | 48 +- 8 files changed, 1211 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 v6 00/26] 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 v6->v5, No real changes: 1. Move the fix of RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS from patch 26 to patch 2; 2. Change the description of patch 26. v5->v4: 1. Add prefix "spinc_" for external functions; 2. Remove temporary MACRO: RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS 3. Do not use void* for keeping the type information 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 (26): 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 net/spnic: fixes unsafe C style code 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| 201 ++ drivers/net/spnic/base/spnic_hw_cfg.h| 125 + drivers/net/spnic/base/spnic_hw_comm.c | 483 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 | 770 ++ 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 | 366 +++ 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 | 183 ++ drivers/net/spnic/base/spnic_nic_event.h | 24 + drivers/net/spnic/base/spnic_wq.c| 138 + drivers/net/spnic/base/spnic_wq.h| 123 + drivers/net/spnic/meson.build| 20 + drivers/net/spnic/spnic_ethdev.c | 3211 ++ drivers/net/spnic/spnic_ethdev.h | 95 + drivers/net/spnic/spnic_io.c | 728 + 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, 16557 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/sp
[PATCH v6 01/26] 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 v6 03/26] 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..a8f59ffd41 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 spnic_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..560639a70f 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 spnic_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..34bd27dfee --- /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
[PATCH v6 07/26] 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 v6 05/26] 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 v6 08/26] 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..ac76b2632e --- /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 v6 04/26] 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 v6 10/26] 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 83a8e98408..36e87ffe40 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 df59d7874f..cf2b2ded01 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 spnic_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 2d4ba70bf0..108f6eef23 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 = spnic_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(
[PATCH v6 09/26] 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 ac76b2632e..83a8e98408 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 5003d048e6..df59d7874f 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 spnic_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..2d4ba70bf0 --- /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 spnic_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
[PATCH v6 06/26] 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 v6 14/26] 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 a10011e536..ed9e19190d 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 v6 12/26] 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 4ce607e813..8c04295258 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 = spnic_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 af0ffc519e..609864ce77 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 spnic_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 969dcf0d29..5911b1dba1 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 + *
[PATCH v6 11/26] 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 v6 13/26] 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 8c04295258..85eca39d68 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 = spnic_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 = spnic_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 = spnic_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 = spnic_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; +
[PATCH v6 16/26] 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 e7552f7286..531a094445 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 v6 15/26] 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 ed9e19190d..e7552f7286 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); @@ -1547,6 +1584,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); @@ -1557,6 +1601,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); @@ -1601,6 +1646,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 v6 25/26] 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
[PATCH v6 17/26] 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 531a094445..b0903b65fb 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 v6 18/26] 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 85eca39d68..8f4249980b 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 b0903b65fb..654fc55b6c 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 v6 19/26] 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 654fc55b6c..b10b55f22c 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 v6 20/26] 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 8f4249980b..52ad2d1148 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 = spnic_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 9b926119d8..2e00bdece5 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 b10b55f22c..1b90212024 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-
[PATCH v6 21/26] 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 1b90212024..820f34da2f 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 v6 22/26] 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 52ad2d1148..32d52bd81e 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 = spnic_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 = spnic_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_tab
[PATCH v6 23/26] 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 0565a7876e..d6aab64a57 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 v6 24/26] 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 32d52bd81e..78561a5c64 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 3c996e2838..c73191dc81 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 d6aab64a57..035ad0d1e7 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 v6 26/26] net/spnic: fixes unsafe C style code
Use the hardware structure instead of void* as parameter of function to keep the type information Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_cmdq.c | 14 +-- drivers/net/spnic/base/spnic_cmdq.h | 6 +- drivers/net/spnic/base/spnic_hw_cfg.c| 49 -- drivers/net/spnic/base/spnic_hw_cfg.h| 16 ++-- drivers/net/spnic/base/spnic_hw_comm.c | 32 --- drivers/net/spnic/base/spnic_hw_comm.h | 22 ++--- drivers/net/spnic/base/spnic_hwdev.c | 8 +- drivers/net/spnic/base/spnic_hwif.c | 52 +-- drivers/net/spnic/base/spnic_hwif.h | 22 ++--- drivers/net/spnic/base/spnic_mgmt.c | 9 +- drivers/net/spnic/base/spnic_mgmt.h | 4 +- drivers/net/spnic/base/spnic_nic_cfg.c | 110 +++ drivers/net/spnic/base/spnic_nic_cfg.h | 84 - drivers/net/spnic/base/spnic_nic_event.c | 30 +++ drivers/net/spnic/base/spnic_nic_event.h | 10 +-- drivers/net/spnic/base/spnic_wq.c| 3 +- drivers/net/spnic/base/spnic_wq.h| 2 +- drivers/net/spnic/spnic_ethdev.c | 10 +-- drivers/net/spnic/spnic_io.c | 34 +++ drivers/net/spnic/spnic_io.h | 10 +-- drivers/net/spnic/spnic_rx.c | 4 +- drivers/net/spnic/spnic_tx.c | 4 +- 22 files changed, 252 insertions(+), 283 deletions(-) diff --git a/drivers/net/spnic/base/spnic_cmdq.c b/drivers/net/spnic/base/spnic_cmdq.c index b8950f91c2..62189d20a3 100644 --- a/drivers/net/spnic/base/spnic_cmdq.c +++ b/drivers/net/spnic/base/spnic_cmdq.c @@ -160,9 +160,9 @@ bool spnic_cmdq_idle(struct spnic_cmdq *cmdq) true : false); } -struct spnic_cmd_buf *spnic_alloc_cmd_buf(void *hwdev) +struct spnic_cmd_buf *spnic_alloc_cmd_buf(struct spnic_hwdev *hwdev) { - struct spnic_cmdqs *cmdqs = ((struct spnic_hwdev *)hwdev)->cmdqs; + struct spnic_cmdqs *cmdqs = hwdev->cmdqs; struct spnic_cmd_buf *cmd_buf; cmd_buf = rte_zmalloc(NULL, sizeof(*cmd_buf), 0); @@ -491,7 +491,7 @@ static int cmdq_sync_cmd_detail_resp(struct spnic_cmdq *cmdq, return err; } -static int cmdq_params_valid(void *hwdev, struct spnic_cmd_buf *buf_in) +static int cmdq_params_valid(struct spnic_hwdev *hwdev, struct spnic_cmd_buf *buf_in) { if (!buf_in || !hwdev) { PMD_DRV_LOG(ERR, "Invalid CMDQ buffer or hwdev is NULL"); @@ -520,11 +520,11 @@ static int wait_cmdqs_enable(struct spnic_cmdqs *cmdqs) return -EBUSY; } -int spnic_cmdq_direct_resp(void *hwdev, enum spnic_mod_type mod, u8 cmd, +int spnic_cmdq_direct_resp(struct spnic_hwdev *hwdev, enum spnic_mod_type mod, u8 cmd, struct spnic_cmd_buf *buf_in, u64 *out_param, u32 timeout) { - struct spnic_cmdqs *cmdqs = ((struct spnic_hwdev *)hwdev)->cmdqs; + struct spnic_cmdqs *cmdqs = hwdev->cmdqs; int err; err = cmdq_params_valid(hwdev, buf_in); @@ -543,11 +543,11 @@ int spnic_cmdq_direct_resp(void *hwdev, enum spnic_mod_type mod, u8 cmd, mod, cmd, buf_in, out_param, timeout); } -int spnic_cmdq_detail_resp(void *hwdev, enum spnic_mod_type mod, u8 cmd, +int spnic_cmdq_detail_resp(struct spnic_hwdev *hwdev, enum spnic_mod_type mod, u8 cmd, struct spnic_cmd_buf *buf_in, struct spnic_cmd_buf *buf_out, u32 timeout) { - struct spnic_cmdqs *cmdqs = ((struct spnic_hwdev *)hwdev)->cmdqs; + struct spnic_cmdqs *cmdqs = hwdev->cmdqs; int err; err = cmdq_params_valid(hwdev, buf_in); diff --git a/drivers/net/spnic/base/spnic_cmdq.h b/drivers/net/spnic/base/spnic_cmdq.h index 9a08262860..bee899361c 100644 --- a/drivers/net/spnic/base/spnic_cmdq.h +++ b/drivers/net/spnic/base/spnic_cmdq.h @@ -225,7 +225,7 @@ int spnic_reinit_cmdq_ctxts(struct spnic_hwdev *hwdev); bool spnic_cmdq_idle(struct spnic_cmdq *cmdq); -struct spnic_cmd_buf *spnic_alloc_cmd_buf(void *hwdev); +struct spnic_cmd_buf *spnic_alloc_cmd_buf(struct spnic_hwdev *hwdev); void spnic_free_cmd_buf(struct spnic_cmd_buf *cmd_buf); @@ -233,11 +233,11 @@ void spnic_free_cmd_buf(struct spnic_cmd_buf *cmd_buf); * PF/VF sends cmd to ucode by cmdq, and return 0 if success. * timeout=0, use default timeout. */ -int spnic_cmdq_direct_resp(void *hwdev, enum spnic_mod_type mod, u8 cmd, +int spnic_cmdq_direct_resp(struct spnic_hwdev *hwdev, enum spnic_mod_type mod, u8 cmd, struct spnic_cmd_buf *buf_in, u64 *out_param, u32 timeout); -int spnic_cmdq_detail_resp(void *hwdev, enum spnic_mod_type mod, u8 cmd, +int spnic_cmdq_detail_resp(struct spnic_hwdev *hwdev, enum spnic_mod_type mod, u8 cmd, struct spnic_cmd_buf *buf_in, struct spnic_cmd_buf *buf_out, u32 timeout); diff --git a/drivers/net/spnic/base/spnic_hw_c