Skip to contentSkip to conversation

Net/SPNIC: support SPNIC into DPDK 22.03

PATCH Superseded Yanling Song 2 participants 32 messages Dec 18, 2021 – Dec 23, 2021

Subsystems (2)

v1 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

cover 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

Yanling Song (25):
drivers/net: introduce a new PMD driver net/spnic: initialize the HW interface net/spnic: add mbox message channel
net/spnic: introduce event queue
net/spnic: add mgmt module
net/spnic: add cmdq and work queue
net/spnic: add interface handling cmdq message net/spnic: add hardware info initialization net/spnic: support MAC and link event handling net/spnic: add function info initialization net/spnic: add queue pairs context initialization net/spnic: support mbuf handling of Tx/Rx net/spnic: support Rx congfiguration
net/spnic: add port/vport enable
net/spnic: support IO packets handling net/spnic: add device configure/version/info net/spnic: support RSS configuration update and get net/spnic: support VLAN filtering and offloading net/spnic: support promiscuous and allmulticast Rx modes net/spnic: support flow control
net/spnic: support getting Tx/Rx queues info net/spnic: net/spnic: support xstats statistics net/spnic: support VFIO interrupt
net/spnic: support Tx/Rx queue start/stop net/spnic: add doc infrastructure

 MAINTAINERS                              |    6 +
 doc/guides/nics/features/spnic.ini       |   40 +
 doc/guides/nics/spnic.rst                |   61 +
 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    |  188 ++
 drivers/net/spnic/base/spnic_csr.h       |  104 +
 drivers/net/spnic/base/spnic_eqs.c       |  661 +++++
 drivers/net/spnic/base/spnic_eqs.h       |  102 +
 drivers/net/spnic/base/spnic_hw_cfg.c    |  212 ++
 drivers/net/spnic/base/spnic_hw_cfg.h    |  125 +
 drivers/net/spnic/base/spnic_hw_comm.c   |  485 ++++
 drivers/net/spnic/base/spnic_hw_comm.h   |  204 ++
 drivers/net/spnic/base/spnic_hwdev.c     |  514 ++++
 drivers/net/spnic/base/spnic_hwdev.h     |  143 +
 drivers/net/spnic/base/spnic_hwif.c      |  774 ++++++
 drivers/net/spnic/base/spnic_hwif.h      |  155 ++
 drivers/net/spnic/base/spnic_mbox.c      | 1187 ++++++++
 drivers/net/spnic/base/spnic_mbox.h      |  202 ++
 drivers/net/spnic/base/spnic_mgmt.c      |  367 +++
 drivers/net/spnic/base/spnic_mgmt.h      |  110 +
 drivers/net/spnic/base/spnic_nic_cfg.c   | 1348 +++++++++
 drivers/net/spnic/base/spnic_nic_cfg.h   | 1110 ++++++++
 drivers/net/spnic/base/spnic_nic_event.c |  194 ++
 drivers/net/spnic/base/spnic_nic_event.h |   29 +
 drivers/net/spnic/base/spnic_wq.c        |  139 +
 drivers/net/spnic/base/spnic_wq.h        |  123 +
 drivers/net/spnic/meson.build            |   14 +
 drivers/net/spnic/spnic_ethdev.c         | 3231 ++++++++++++++++++++++
 drivers/net/spnic/spnic_ethdev.h         |   95 +
 drivers/net/spnic/spnic_io.c             |  738 +++++
 drivers/net/spnic/spnic_io.h             |  154 ++
 drivers/net/spnic/spnic_rx.c             |  956 +++++++
 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 +
 40 files changed, 16638 insertions(+)
 create mode 100644 doc/guides/nics/features/spnic.ini
 create mode 100644 doc/guides/nics/spnic.rst
 create mode 100644 drivers/net/spnic/base/meson.build
 create mode 100644 drivers/net/spnic/base/spnic_cmd.h
 create mode 100644 drivers/net/spnic/base/spnic_cmdq.c
 create mode 100644 drivers/net/spnic/base/spnic_cmdq.h
 create mode 100644 drivers/net/spnic/base/spnic_compat.h
 create mode 100644 drivers/net/spnic/base/spnic_csr.h
 create mode 100644 drivers/net/spnic/base/spnic_eqs.c
 create mode 100644 drivers/net/spnic/base/spnic_eqs.h
 create mode 100644 drivers/net/spnic/base/spnic_hw_cfg.c
 create mode 100644 drivers/net/spnic/base/spnic_hw_cfg.h
 create mode 100644 drivers/net/spnic/base/spnic_hw_comm.c
 create mode 100644 drivers/net/spnic/base/spnic_hw_comm.h
 create mode 100644 drivers/net/spnic/base/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
 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.c
 create mode 100644 drivers/net/spnic/base/spnic_mgmt.h
 create mode 100644 drivers/net/spnic/base/spnic_nic_cfg.c
 create mode 100644 drivers/net/spnic/base/spnic_nic_cfg.h
 create mode 100644 drivers/net/spnic/base/spnic_nic_event.c
 create mode 100644 drivers/net/spnic/base/spnic_nic_event.h
 create mode 100644 drivers/net/spnic/base/spnic_wq.c
 create mode 100644 drivers/net/spnic/base/spnic_wq.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/spnic_io.c
 create mode 100644 drivers/net/spnic/spnic_io.h
 create mode 100644 drivers/net/spnic/spnic_rx.c
 create mode 100644 drivers/net/spnic/spnic_rx.h
 create mode 100644 drivers/net/spnic/spnic_tx.c
 create mode 100644 drivers/net/spnic/spnic_tx.h
 create mode 100644 drivers/net/spnic/version.map
Signature · 1 line
2.27.0
#1 lore raw

PATCH 1/25 drivers/net: introduce a new PMD driver

Introduce a new PMD driver which names spnic.
Now, this driver only implements module entry
without doing anything else.

---
 drivers/net/meson.build               |   1 +
 drivers/net/spnic/base/meson.build    |  26 ++++
 drivers/net/spnic/base/spnic_compat.h | 188 ++++++++++++++++++++++++++
 drivers/net/spnic/meson.build         |  11 ++
 drivers/net/spnic/spnic_ethdev.c      | 107 +++++++++++++++
 drivers/net/spnic/spnic_ethdev.h      |  28 ++++
 drivers/net/spnic/version.map         |   3 +
 7 files changed, 364 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
drivers/net/meson.build +1 -0
index 2355d1cde8..a5c715f59c 100644
@@ -53,6 +53,7 @@ drivers = [
         'ring',
         'sfc',
         'softnic',
+	'spnic',
         'tap',
         'thunderx',
         'txgbe',
drivers/net/spnic/base/meson.build new file +26 -0
new file mode 100644
index 0000000000..e83a473881
@@ -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()
drivers/net/spnic/base/spnic_compat.h new file +188 -0

188 lines not on this page · raw message

drivers/net/spnic/meson.build new file +11 -0
new file mode 100644
index 0000000000..042d2fe6e1
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+
+subdir('base')
+objs = [base_objs]
+
+sources = files(
+	'spnic_ethdev.c',
+	)
+
+includes += include_directories('base')
drivers/net/spnic/spnic_ethdev.c new file +107 -0

107 lines not on this page · raw message

drivers/net/spnic/spnic_ethdev.h new file +28 -0
new file mode 100644
index 0000000000..d4ec641d83
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+ */
+
+#ifndef _SPNIC_ETHDEV_H_
+#define _SPNIC_ETHDEV_H_
+
+/* Vendor id */
+#define PCI_VENDOR_ID_RAMAXEL	0x1E81
+
+/* Device ids */
+#define SPNIC_DEV_ID_PF			0x9020
+#define SPNIC_DEV_ID_VF			0x9001
+
+enum spnic_dev_status {
+	SPNIC_DEV_INIT
+};
+
+#define SPNIC_DEV_NAME_LEN		32
+struct spnic_nic_dev {
+	u32 dev_status;
+	char dev_name[SPNIC_DEV_NAME_LEN];
+};
+
+#define SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev) \
+	((struct spnic_nic_dev *)(dev)->data->dev_private)
+
+#endif /* _SPNIC_ETHDEV_H_ */
drivers/net/spnic/version.map new file +3 -0
new file mode 100644
index 0000000000..4a76d1d52d
@@ -0,0 +1,3 @@
+DPDK_21 {
+	local: *;
+};
Signature · 1 line
2.27.0
#2 lore raw

Re: [PATCH v1 01/25] drivers/net: introduce a new PMD driver

drivers/net/spnic/base/spnic_compat.h line 65

Quoted 5 lines · On Sat, 18 Dec 2021 10:51:28 +0800 Yanling Song <[email protected]> wrote:
drivers/net/spnic/base/spnic_compat.h new file +5 -0
+#ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */
+#define CLOCK_TYPE CLOCK_MONOTONIC_RAW
+#else
+#define CLOCK_TYPE CLOCK_MONOTONIC
+#endif

CLOCK_MONOTONIC_RAW was defined in Linux.2.6.28
DPDK does not support any kernels that old, so the #ifdef is not needed.

+
+static inline unsigned long clock_gettime_ms(void) +{
+ struct timespec tv;
+
+ (void)clock_gettime(CLOCK_TYPE, &tv);
+
+ return (unsigned long)tv.tv_sec * SPNIC_S_TO_MS_UNIT +
+ (unsigned long)tv.tv_nsec / SPNIC_S_TO_NS_UNIT;
+}

If all you want is jiffie accuracy, you could use CLOCK_MONOTONIC_COARSE.

+#define jiffies clock_gettime_ms()
+#define msecs_to_jiffies(ms) (ms)

+#define time_before(now, end) ((now) < (end))

Does that simple version of the macro work right if jiffies wraps around? Less of an issue on 64 bit platforms...

The kernel version is effectively.
#define time_before(now, end) ((long)((now) - (end)) < 0)

#3 lore raw

Re: [PATCH v1 01/25] drivers/net: introduce a new PMD driver

Quoted 13 lines · On Sun, 19 Dec 2021 11:40:31 -0800 Stephen Hemminger…

drivers/net/spnic/base/spnic_compat.h line 65

Quoted 5 lines · On Sat, 18 Dec 2021 10:51:28 +0800 Yanling Song <[email protected]> wrote:
drivers/net/spnic/base/spnic_compat.h new file +5 -0
+#ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */
+#define CLOCK_TYPE CLOCK_MONOTONIC_RAW
+#else
+#define CLOCK_TYPE CLOCK_MONOTONIC
+#endif  

CLOCK_MONOTONIC_RAW was defined in Linux.2.6.28
DPDK does not support any kernels that old, so the #ifdef is not needed.

OK. #ifdef will be removed in the next version.

Quoted 12 lines
drivers/net/spnic/base/spnic_compat.h new file +10 -0
+
+static inline unsigned long clock_gettime_ms(void)
+{
+	struct timespec tv;
+
+	(void)clock_gettime(CLOCK_TYPE, &tv);
+
+	return (unsigned long)tv.tv_sec * SPNIC_S_TO_MS_UNIT +
+	       (unsigned long)tv.tv_nsec / SPNIC_S_TO_NS_UNIT;
+}
Quoted 3 lines

If all you want is jiffie accuracy, you could use CLOCK_MONOTONIC_COARSE.

I did not get your point: CLOCK_MONOTONIC is more accurate than CLOCK_MONOTONIC_COARSE, right?

Quoted 11 lines
drivers/net/spnic/base/spnic_compat.h new file +3 -0
+#define jiffies	clock_gettime_ms()
+#define msecs_to_jiffies(ms)	(ms)
 
+#define time_before(now, end)	((now) < (end))

Does that simple version of the macro work right if jiffies wraps around? Less of an issue on 64 bit platforms...

The kernel version is effectively.
#define time_before(now, end) ((long)((now) - (end)) < 0)

OK. Will be changed in the next version.

#4 lore raw

Re: [PATCH v1 01/25] drivers/net: introduce a new PMD driver

Quoted 5 lines · On Wed, 22 Dec 2021 08:54:00 +0800 Yanling Song <[email protected]> wrote:
Quoted 3 lines

If all you want is jiffie accuracy, you could use CLOCK_MONOTONIC_COARSE.

I did not get your point: CLOCK_MONOTONIC is more accurate than CLOCK_MONOTONIC_COARSE, right?

CLOCK_MONOTONIC ends up using the TSC counter and values in the shared page (VDSO) to compute time accurately.

CLOCK_MONOTONIC_COARSE is faster and good enough if you only want ms accuracy. It just reads a value from shared page and avoids the TSC instruction.

#5 lore raw

Re: [PATCH v1 01/25] drivers/net: introduce a new PMD driver

Quoted 9 lines · On Wed, 22 Dec 2021 08:55:22 -0800 Stephen Hemminger…
Quoted 5 lines · On Wed, 22 Dec 2021 08:54:00 +0800 Yanling Song <[email protected]> wrote:
Quoted 3 lines

If all you want is jiffie accuracy, you could use CLOCK_MONOTONIC_COARSE.

I did not get your point: CLOCK_MONOTONIC is more accurate than CLOCK_MONOTONIC_COARSE, right?

Quoted 6 lines

CLOCK_MONOTONIC ends up using the TSC counter and values in the shared page (VDSO) to compute time accurately.

CLOCK_MONOTONIC_COARSE is faster and good enough if you only want ms accuracy. It just reads a value from shared page and avoids the TSC instruction.

OK. Got it. Thanks. Will be included in the next version.

#6 lore raw

PATCH 2/25 net/spnic: initialize the HW interface

In reply to Yanling Song

Add HW interface registers and initialize the HW
interface.

---
 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
drivers/net/spnic/base/meson.build +2 -0
index e83a473881..edd6e94772 100644
@@ -2,6 +2,8 @@
 # Copyright(c) 2021 Ramaxel Memory Technology, Ltd
 
 sources = [
+	'spnic_hwdev.c',
+	'spnic_hwif.c'
 ]
 
 extra_flags = []
drivers/net/spnic/base/spnic_csr.h new file +104 -0

104 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.c new file +41 -0

41 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.h new file +29 -0
new file mode 100644
index 0000000000..a6cb8bc36e
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+ */
+
+#ifndef _SPNIC_HWDEV_H_
+#define _SPNIC_HWDEV_H_
+
+#include <rte_ether.h>
+
+#define SPNIC_CHIP_FAULT_SIZE		(110 * 1024)
+
+struct spnic_hwdev {
+	void *dev_handle; /* Pointer to spnic_nic_dev */
+	void *pci_dev; /* Pointer to rte_pci_device */
+	void *eth_dev; /* Pointer to rte_eth_dev */
+
+	uint16_t port_id;
+
+	struct spnic_hwif *hwif;
+	u8 *chip_fault_stats;
+
+	u16 max_vfs;
+	u16 link_status;
+};
+
+int spnic_init_hwdev(struct spnic_hwdev *hwdev);
+
+void spnic_free_hwdev(struct spnic_hwdev *hwdev);
+#endif /* _SPNIC_HWDEV_H_ */
drivers/net/spnic/base/spnic_hwif.c new file +774 -0

774 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwif.h new file +155 -0

155 lines not on this page · raw message

drivers/net/spnic/spnic_ethdev.c +66 -0

98 lines not on this page · raw message

drivers/net/spnic/spnic_ethdev.h +41 -7

62 lines not on this page · raw message

Signature · 1 line
2.27.0
#7 lore raw

PATCH 3/25 net/spnic: add mbox message channel

In reply to Yanling Song

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.

---
 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
drivers/net/spnic/base/meson.build +2 -1
index edd6e94772..de80eef7c4 100644
@@ -3,7 +3,8 @@
 
 sources = [
 	'spnic_hwdev.c',
-	'spnic_hwif.c'
+	'spnic_hwif.c',
+	'spnic_mbox.c'
 ]
 
 extra_flags = []
drivers/net/spnic/base/spnic_hwdev.c +69 -0

91 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.h +6 -0
index a6cb8bc36e..b3a8b32287 100644
@@ -17,12 +17,18 @@ struct spnic_hwdev {
 	uint16_t port_id;
 
 	struct spnic_hwif *hwif;
+	struct spnic_mbox *func_to_func;
 	u8 *chip_fault_stats;
 
 	u16 max_vfs;
 	u16 link_status;
 };
 
+int vf_handle_pf_comm_mbox(void *handle, __rte_unused void *pri_handle,
+			   __rte_unused u16 cmd, __rte_unused void *buf_in,
+			   __rte_unused u16 in_size, __rte_unused void *buf_out,
+			   __rte_unused u16 *out_size);
+
 int spnic_init_hwdev(struct spnic_hwdev *hwdev);
 
 void spnic_free_hwdev(struct spnic_hwdev *hwdev);
drivers/net/spnic/base/spnic_mbox.c new file +1158 -0

1,158 lines not on this page · raw message

drivers/net/spnic/base/spnic_mbox.h new file +202 -0

202 lines not on this page · raw message

drivers/net/spnic/base/spnic_mgmt.h new file +36 -0
new file mode 100644
index 0000000000..37d0410473
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+ */
+
+#ifndef _SPNIC_MGMT_H_
+#define _SPNIC_MGMT_H_
+
+#define SPNIC_MSG_HANDLER_RES	(-1)
+
+/* Cmdq module type */
+enum spnic_mod_type {
+	SPNIC_MOD_COMM = 0, /* HW communication module */
+	SPNIC_MOD_L2NIC = 1, /* L2NIC module */
+	SPNIC_MOD_ROCE = 2,
+	SPNIC_MOD_PLOG = 3,
+	SPNIC_MOD_TOE = 4,
+	SPNIC_MOD_FLR = 5,
+	SPNIC_MOD_FC = 6,
+	SPNIC_MOD_CFGM = 7, /* Configuration module */
+	SPNIC_MOD_CQM = 8,
+	SPNIC_MOD_VSWITCH = 9,
+	COMM_MOD_FC = 10,
+	SPNIC_MOD_OVS = 11,
+	SPNIC_MOD_DSW = 12,
+	SPNIC_MOD_MIGRATE = 13,
+	SPNIC_MOD_HILINK = 14,
+	SPNIC_MOD_CRYPT = 15, /* Secure crypto module */
+	SPNIC_MOD_HW_MAX = 16, /* Hardware max module id */
+
+	/* Software module id, for PF/VF and multi-host */
+	SPNIC_MOD_SW_FUNC = 17,
+	SPNIC_MOD_IOE = 18,
+	SPNIC_MOD_MAX
+};
+
+#endif /* _SPNIC_MGMT_H_ */
Signature · 1 line
2.27.0
#8 lore raw

PATCH 4/25 net/spnic: introduce event queue

In reply to Yanling Song

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.

---
 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
drivers/net/spnic/base/meson.build +1 -0
index de80eef7c4..ce7457f400 100644
@@ -2,6 +2,7 @@
 # Copyright(c) 2021 Ramaxel Memory Technology, Ltd
 
 sources = [
+	'spnic_eqs.c',
 	'spnic_hwdev.c',
 	'spnic_hwif.c',
 	'spnic_mbox.c'
drivers/net/spnic/base/spnic_eqs.c new file +606 -0

606 lines not on this page · raw message

drivers/net/spnic/base/spnic_eqs.h new file +102 -0

102 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.c +43 -1

74 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.h +22 -0
index b3a8b32287..a0691eed2e 100644
@@ -8,6 +8,21 @@
 #include <rte_ether.h>
 
 #define SPNIC_CHIP_FAULT_SIZE		(110 * 1024)
+struct cfg_mgmt_info;
+struct spnic_hwif;
+struct spnic_aeqs;
+struct spnic_mbox;
+struct spnic_msg_pf_to_mgmt;
+
+struct ffm_intr_info {
+	u8 node_id;
+	/* Error level of the interrupt source */
+	u8 err_level;
+	/* Classification by interrupt source properties */
+	u16 err_type;
+	u32 err_csr_addr;
+	u32 err_csr_value;
+};
 
 struct spnic_hwdev {
 	void *dev_handle; /* Pointer to spnic_nic_dev */
@@ -18,6 +33,9 @@ struct spnic_hwdev {
 
 	struct spnic_hwif *hwif;
 	struct spnic_mbox *func_to_func;
+	struct cfg_mgmt_info *cfg_mgmt;
+	struct spnic_aeqs *aeqs;
+	struct spnic_msg_pf_to_mgmt *pf_to_mgmt;
 	u8 *chip_fault_stats;
 
 	u16 max_vfs;
@@ -29,6 +47,10 @@ int vf_handle_pf_comm_mbox(void *handle, __rte_unused void *pri_handle,
 			   __rte_unused u16 in_size, __rte_unused void *buf_out,
 			   __rte_unused u16 *out_size);
 
+void pf_handle_mgmt_comm_event(void *handle, __rte_unused void *pri_handle,
+			       u16 cmd, void *buf_in, u16 in_size,
+			       void *buf_out, u16 *out_size);
+
 int spnic_init_hwdev(struct spnic_hwdev *hwdev);
 
 void spnic_free_hwdev(struct spnic_hwdev *hwdev);
drivers/net/spnic/base/spnic_mbox.c +16 -4
index d019612cef..1677bd7404 100644
@@ -2,13 +2,13 @@
  * Copyright(c) 2021 Ramaxel Memory Technology, Ltd
  */
 
-#include <rte_atomic.h>
 #include <ethdev_driver.h>
 #include "spnic_compat.h"
 #include "spnic_hwdev.h"
 #include "spnic_csr.h"
-#include "spnic_hwif.h"
 #include "spnic_mgmt.h"
+#include "spnic_hwif.h"
+#include "spnic_eqs.h"
 #include "spnic_mbox.h"
 
 #define SPNIC_MBOX_INT_DST_FUNC_SHIFT				0
@@ -713,7 +713,9 @@ static int spnic_mbox_to_func(struct spnic_mbox *func_to_func,
 	/* Use mbox_resp to hole data which responsed from other function */
 	struct spnic_recv_mbox *mbox_for_resp = NULL;
 	struct mbox_msg_info msg_info = {0};
+	struct spnic_eq *aeq = NULL;
 	u16 mbox_rsp_idx;
+	u32 time;
 	int err;
 
 	mbox_rsp_idx = (dst_func == SPNIC_MGMT_SRC_ID) ?
@@ -748,9 +750,19 @@ static int spnic_mbox_to_func(struct spnic_mbox *func_to_func,
 		goto send_err;
 	}
 
+	time = msecs_to_jiffies(timeout ? timeout : SPNIC_MBOX_COMP_TIME);
+	aeq = &func_to_func->hwdev->aeqs->aeq[SPNIC_MBOX_RSP_MSG_AEQ];
+	err = spnic_aeq_poll_msg(aeq, time, NULL);
+	if (err) {
+		set_mbox_to_func_event(func_to_func, EVENT_TIMEOUT);
+		PMD_DRV_LOG(ERR, "Send mailbox message time out");
+		err = -ETIMEDOUT;
+		goto send_err;
+	}
+
 	if (mod != mbox_for_resp->mod || cmd != mbox_for_resp->cmd) {
-		PMD_DRV_LOG(ERR, "Invalid response mbox message, mod: 0x%x, cmd: 0x%x, expect mod: 0x%x, cmd: 0x%x, timeout0x%x\n",
-			    mbox_for_resp->mod, mbox_for_resp->cmd, mod, cmd, timeout);
+		PMD_DRV_LOG(ERR, "Invalid response mbox message, mod: 0x%x, cmd: 0x%x, expect mod: 0x%x, cmd: 0x%x\n",
+			    mbox_for_resp->mod, mbox_for_resp->cmd, mod, cmd);
 		err = -EFAULT;
 		goto send_err;
 	}
Signature · 1 line
2.27.0
#9 lore raw

PATCH 5/25 net/spnic: add mgmt module

In reply to Yanling Song

Mgmt module manage the message gerenated from the hardware. This patch implements mgmt module initialization, related event processing and message command definition.

---
 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      |  17 ++
 drivers/net/spnic/base/spnic_mgmt.c      | 367 +++++++++++++++++++++++
 drivers/net/spnic/base/spnic_mgmt.h      |  74 +++++
 drivers/net/spnic/base/spnic_nic_event.c | 171 +++++++++++
 drivers/net/spnic/base/spnic_nic_event.h |  34 +++
 10 files changed, 1081 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
drivers/net/spnic/base/meson.build +3 -1
index ce7457f400..3f6a060b37 100644
@@ -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 = []
drivers/net/spnic/base/spnic_cmd.h new file +222 -0

222 lines not on this page · raw message

drivers/net/spnic/base/spnic_eqs.c +45 -1

69 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.c +83 -8

135 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.h +65 -1

84 lines not on this page · raw message

drivers/net/spnic/base/spnic_mbox.c +17 -0
index 1677bd7404..5c39e307be 100644
@@ -6,10 +6,12 @@
 #include "spnic_compat.h"
 #include "spnic_hwdev.h"
 #include "spnic_csr.h"
+#include "spnic_cmd.h"
 #include "spnic_mgmt.h"
 #include "spnic_hwif.h"
 #include "spnic_eqs.h"
 #include "spnic_mbox.h"
+#include "spnic_nic_event.h"
 
 #define SPNIC_MBOX_INT_DST_FUNC_SHIFT				0
 #define SPNIC_MBOX_INT_DST_AEQN_SHIFT				10
@@ -148,6 +150,21 @@ static int recv_vf_mbox_handler(struct spnic_mbox *func_to_func,
 					     recv_mbox->mbox_len,
 					     buf_out, out_size);
 		break;
+	case SPNIC_MOD_L2NIC:
+		err = spnic_vf_event_handler(func_to_func->hwdev,
+					     func_to_func->hwdev->cfg_mgmt,
+					     recv_mbox->cmd, recv_mbox->mbox,
+					     recv_mbox->mbox_len,
+					     buf_out, out_size);
+		break;
+	case SPNIC_MOD_HILINK:
+		err = spnic_vf_mag_event_handler(func_to_func->hwdev,
+						 func_to_func->hwdev->cfg_mgmt,
+						 recv_mbox->cmd,
+						 recv_mbox->mbox,
+						 recv_mbox->mbox_len,
+						 buf_out, out_size);
+		break;
 	default:
 		PMD_DRV_LOG(ERR, "No handler, mod: %d", recv_mbox->mod);
 		err = SPNIC_MBOX_VF_CMD_ERROR;
drivers/net/spnic/base/spnic_mgmt.c new file +367 -0

367 lines not on this page · raw message

drivers/net/spnic/base/spnic_mgmt.h +74 -0

84 lines not on this page · raw message

drivers/net/spnic/base/spnic_nic_event.c new file +171 -0

171 lines not on this page · raw message

drivers/net/spnic/base/spnic_nic_event.h new file +34 -0
new file mode 100644
index 0000000000..eb41d76a7d
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+ */
+
+#ifndef _SPNIC_NIC_EVENT_H_
+#define _SPNIC_NIC_EVENT_H_
+
+struct spnic_cmd_link_state {
+	struct mgmt_msg_head msg_head;
+
+	u8 port_id;
+	u8 state;
+	u16 rsvd1;
+};
+
+void spnic_pf_event_handler(void *hwdev, __rte_unused void *pri_handle,
+			    u16 cmd, void *buf_in, u16 in_size,
+			    void *buf_out, u16 *out_size);
+
+int spnic_vf_event_handler(void *hwdev, __rte_unused void *pri_handle,
+			   u16 cmd, void *buf_in, u16 in_size,
+			   void *buf_out, u16 *out_size);
+
+void spnic_pf_mag_event_handler(void *hwdev, void *pri_handle, u16 cmd,
+				void *buf_in, u16 in_size, void *buf_out,
+				u16 *out_size);
+
+int spnic_vf_mag_event_handler(void *hwdev, void *pri_handle, u16 cmd,
+			       void *buf_in, u16 in_size, void *buf_out,
+			       u16 *out_size);
+
+u8 spnic_nic_sw_aeqe_handler(__rte_unused void *hwdev, u8 event, u8 *data);
+
+#endif /* _SPNIC_NIC_EVENT_H_ */
Signature · 1 line
2.27.0
#10 lore raw

PATCH 6/25 net/spnic: add cmdq and work queue

In reply to Yanling Song

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.

---
 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
drivers/net/spnic/base/meson.build +3 -1
index 3f6a060b37..5e4efac7be 100644
@@ -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 = []
drivers/net/spnic/base/spnic_cmdq.c new file +202 -0

202 lines not on this page · raw message

drivers/net/spnic/base/spnic_cmdq.h new file +228 -0

228 lines not on this page · raw message

drivers/net/spnic/base/spnic_hw_comm.c new file +222 -0

222 lines not on this page · raw message

drivers/net/spnic/base/spnic_hw_comm.h new file +176 -0

176 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.c +215 -0

251 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.h +6 -2
index 4e77d776ee..8c581c7480 100644
@@ -91,13 +91,17 @@ struct spnic_hwdev {
 	void *dev_handle; /* Pointer to spnic_nic_dev */
 	void *pci_dev; /* Pointer to rte_pci_device */
 	void *eth_dev; /* Pointer to rte_eth_dev */
-
+	struct spnic_hwif *hwif;
 	uint16_t port_id;
 
-	struct spnic_hwif *hwif;
+	u32 wq_page_size;
+
 	struct spnic_mbox *func_to_func;
 	struct cfg_mgmt_info *cfg_mgmt;
+
+	struct spnic_cmdqs *cmdqs;
 	struct spnic_aeqs *aeqs;
+
 	struct spnic_msg_pf_to_mgmt *pf_to_mgmt;
 	u8 *chip_fault_stats;
 	struct spnic_hw_stats hw_stats;
drivers/net/spnic/base/spnic_wq.h new file +57 -0

57 lines not on this page · raw message

Signature · 1 line
2.27.0
#11 lore raw

PATCH 7/25 net/spnic: add interface handling cmdq message

In reply to Yanling Song

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.

---
 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
drivers/net/spnic/base/meson.build +1 -0
index 5e4efac7be..da6d6ee4a2 100644
@@ -10,6 +10,7 @@ sources = [
 	'spnic_nic_event.c',
 	'spnic_cmdq.c',
 	'spnic_hw_comm.c',
+	'spnic_wq.c'
 ]
 
 extra_flags = []
drivers/net/spnic/base/spnic_cmdq.c +673 -0

735 lines not on this page · raw message

drivers/net/spnic/base/spnic_cmdq.h +20 -0
index 71753be6e8..ffd540746b 100644
@@ -93,6 +93,7 @@ struct spnic_scmd_bufdesc {
 };
 
 struct spnic_lcmd_bufdesc {
+	struct spnic_sge sge;
 	u32 rsvd1;
 	u64 saved_async_buf;
 	u64 rsvd3;
@@ -112,6 +113,7 @@ struct spnic_ctrl {
 };
 
 struct spnic_sge_resp {
+	struct spnic_sge sge;
 	u32 rsvd;
 };
 
@@ -221,6 +223,24 @@ struct spnic_cmd_buf {
 
 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);
+
+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,
+			   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,
+			   struct spnic_cmd_buf *buf_in,
+			   struct spnic_cmd_buf *buf_out, u32 timeout);
+
 int spnic_cmdqs_init(struct spnic_hwdev *hwdev);
 
 void spnic_cmdqs_free(struct spnic_hwdev *hwdev);
drivers/net/spnic/base/spnic_hw_comm.c +41 -0

53 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.c +5 -3
index 5671cb860c..00b3b41d97 100644
@@ -9,6 +9,7 @@
 #include "spnic_mgmt.h"
 #include "spnic_cmd.h"
 #include "spnic_mbox.h"
+#include "spnic_wq.h"
 #include "spnic_cmdq.h"
 #include "spnic_hwdev.h"
 #include "spnic_hw_comm.h"
@@ -322,9 +323,6 @@ static void free_mgmt_channel(struct spnic_hwdev *hwdev)
 	spnic_aeqs_free(hwdev);
 }
 
-#define SPNIC_DEFAULT_WQ_PAGE_SIZE	0x100000
-#define SPNIC_HW_WQ_PAGE_SIZE		0x1000
-
 static int init_cmdqs_channel(struct spnic_hwdev *hwdev)
 {
 	int err;
@@ -394,6 +392,10 @@ static int spnic_init_comm_ch(struct spnic_hwdev *hwdev)
 static void spnic_uninit_comm_ch(struct spnic_hwdev *hwdev)
 {
 	spnic_comm_cmdqs_free(hwdev);
+
+	if (SPNIC_FUNC_TYPE(hwdev) != TYPE_VF)
+		spnic_set_wq_page_size(hwdev, spnic_global_func_id(hwdev),
+					SPNIC_HW_WQ_PAGE_SIZE);
 	free_mgmt_channel(hwdev);
 }
 
drivers/net/spnic/base/spnic_hwdev.h +13 -0
index 8c581c7480..3b055dd732 100644
@@ -13,6 +13,19 @@ struct spnic_aeqs;
 struct spnic_mbox;
 struct spnic_msg_pf_to_mgmt;
 
+#define MGMT_VERSION_MAX_LEN		32
+
+enum spnic_set_arm_type {
+	SPNIC_SET_ARM_CMDQ,
+	SPNIC_SET_ARM_SQ,
+	SPNIC_SET_ARM_TYPE_NUM
+};
+
+struct spnic_page_addr {
+	void *virt_addr;
+	u64 phys_addr;
+};
+
 struct ffm_intr_info {
 	u8 node_id;
 	/* Error level of the interrupt source */
drivers/net/spnic/base/spnic_wq.c new file +139 -0

139 lines not on this page · raw message

drivers/net/spnic/base/spnic_wq.h +68 -2

99 lines not on this page · raw message

Signature · 1 line
2.27.0
#12 lore raw

PATCH 8/25 net/spnic: add hardware info initialization

In reply to Yanling Song

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.

---
 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
drivers/net/spnic/base/meson.build +2 -1
index da6d6ee4a2..77a56ca41e 100644
@@ -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 = []
drivers/net/spnic/base/spnic_hw_cfg.c new file +157 -0

157 lines not on this page · raw message

drivers/net/spnic/base/spnic_hw_cfg.h new file +117 -0

117 lines not on this page · raw message

drivers/net/spnic/base/spnic_hw_comm.c +121 -0

130 lines not on this page · raw message

drivers/net/spnic/base/spnic_hw_comm.h +22 -0
index c905f49b7a..207f0aaeae 100644
@@ -96,6 +96,18 @@ enum spnic_fw_ver_type {
 	SPNIC_FW_VER_TYPE_CFG,
 };
 
+#define MGMT_MSG_CMD_OP_SET	1
+#define MGMT_MSG_CMD_OP_GET	0
+
+struct comm_cmd_feature_nego {
+	struct mgmt_msg_head head;
+
+	u16 func_id;
+	u8 opcode;	/* 1: set, 0: get */
+	u8 rsvd;
+	u64 s_feature[MAX_FEATURE_QWORD];
+};
+
 struct comm_cmd_dma_attr_config {
 	struct mgmt_msg_head head;
 
@@ -162,6 +174,12 @@ struct interrupt_info {
 	u8 resend_timer_cfg;
 };
 
+int spnic_func_reset(void *hwdev, u64 reset_flag);
+
+int spnic_get_mgmt_version(void *hwdev, char *mgmt_ver, int max_mgmt_len);
+
+int spnic_get_board_info(void *hwdev, struct spnic_board_info *info);
+
 int spnic_get_interrupt_cfg(void *dev, struct interrupt_info *info);
 
 int spnic_set_interrupt_cfg(void *dev, struct interrupt_info info);
@@ -170,6 +188,10 @@ int spnic_set_wq_page_size(void *hwdev, u16 func_idx, u32 page_size);
 
 int spnic_set_cmdq_depth(void *hwdev, u16 cmdq_depth);
 
+int spnic_get_comm_features(void *hwdev, u64 *s_feature, u16 size);
+
+int spnic_set_comm_features(void *hwdev, u64 *s_feature, u16 size);
+
 int spnic_set_dma_attr_tbl(struct spnic_hwdev *hwdev, u32 entry_idx, u8 st,
 			   u8 at, u8 ph, u8 no_snooping, u8 tph_en);
 
drivers/net/spnic/base/spnic_hwdev.c +70 -0

122 lines not on this page · raw message

drivers/net/spnic/base/spnic_hwdev.h +5 -0
index 3b055dd732..d9dce12764 100644
@@ -100,6 +100,7 @@ struct spnic_board_info {
 	u32 cfg_addr;
 };
 
+#define MAX_FEATURE_QWORD	4
 struct spnic_hwdev {
 	void *dev_handle; /* Pointer to spnic_nic_dev */
 	void *pci_dev; /* Pointer to rte_pci_device */
@@ -117,7 +118,11 @@ struct spnic_hwdev {
 
 	struct spnic_msg_pf_to_mgmt *pf_to_mgmt;
 	u8 *chip_fault_stats;
+
 	struct spnic_hw_stats hw_stats;
+	struct spnic_board_info board_info;
+	char mgmt_ver[MGMT_VERSION_MAX_LEN];
+	u64 features[MAX_FEATURE_QWORD];
 
 	u16 max_vfs;
 	u16 link_status;
drivers/net/spnic/base/spnic_mbox.c +8 -0
index 5c39e307be..cdb7d31e8c 100644
@@ -10,6 +10,7 @@
 #include "spnic_mgmt.h"
 #include "spnic_hwif.h"
 #include "spnic_eqs.h"
+#include "spnic_hw_cfg.h"
 #include "spnic_mbox.h"
 #include "spnic_nic_event.h"
 
@@ -150,6 +151,13 @@ static int recv_vf_mbox_handler(struct spnic_mbox *func_to_func,
 					     recv_mbox->mbox_len,
 					     buf_out, out_size);
 		break;
+	case SPNIC_MOD_CFGM:
+		err = cfg_mbx_vf_proc_msg(func_to_func->hwdev,
+					  func_to_func->hwdev->cfg_mgmt,
+					  recv_mbox->cmd, recv_mbox->mbox,
+					  recv_mbox->mbox_len,
+					  buf_out, out_size);
+		break;
 	case SPNIC_MOD_L2NIC:
 		err = spnic_vf_event_handler(func_to_func->hwdev,
 					     func_to_func->hwdev->cfg_mgmt,
Signature · 1 line
2.27.0
#13 lore raw

PATCH 9/25 net/spnic: support MAC and link event handling

In reply to Yanling Song

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.

---
 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
drivers/net/spnic/base/meson.build +2 -1
index 77a56ca41e..f4bb4469ae 100644
@@ -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 = []
drivers/net/spnic/base/spnic_hw_cfg.c +12 -0
index e8856ce9fe..6505f48273 100644
@@ -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;
+}
drivers/net/spnic/base/spnic_hw_cfg.h +2 -0
index 1b1b598726..9ab51f2875 100644
@@ -112,6 +112,8 @@ struct spnic_cfg_cmd_dev_cap {
 int spnic_init_capability(void *dev);
 void spnic_free_capability(void *dev);
 
+u8 spnic_physical_port_id(void *hwdev);
+
 int cfg_mbx_vf_proc_msg(void *hwdev, void *pri_handle, u16 cmd, void *buf_in,
 			u16 in_size, void *buf_out, u16 *out_size);
 #endif /* _SPNIC_HW_CFG_H_ */
drivers/net/spnic/base/spnic_nic_cfg.c new file +291 -0

291 lines not on this page · raw message

drivers/net/spnic/base/spnic_nic_cfg.h new file +180 -0

180 lines not on this page · raw message

drivers/net/spnic/base/spnic_nic_event.c +25 -2
index 07ea036d84..1c3621171a 100644
@@ -9,16 +9,39 @@
 #include "spnic_hwif.h"
 #include "spnic_hwdev.h"
 #include "spnic_mgmt.h"
+#include "spnic_nic_cfg.h"
 #include "spnic_hwdev.h"
 #include "spnic_nic_event.h"
 
-static void get_port_info(u8 link_state, struct rte_eth_link *link)
+void get_port_info(struct spnic_hwdev *hwdev, u8 link_state,
+		   struct rte_eth_link *link)
 {
+	uint32_t port_speed[LINK_SPEED_LEVELS] = {ETH_SPEED_NUM_10M,
+					ETH_SPEED_NUM_100M, ETH_SPEED_NUM_1G,
+					ETH_SPEED_NUM_10G, ETH_SPEED_NUM_25G,
+					ETH_SPEED_NUM_40G, ETH_SPEED_NUM_100G};
+	struct nic_port_info port_info = {0};
+	int err;
+
 	if (!link_state) {
 		link->link_status = ETH_LINK_DOWN;
 		link->link_speed = ETH_SPEED_NUM_NONE;
 		link->link_duplex = ETH_LINK_HALF_DUPLEX;
 		link->link_autoneg = ETH_LINK_FIXED;
+	} else {
+		link->link_status = ETH_LINK_UP;
+
+		err = spnic_get_port_info(hwdev, &port_info);
+		if (err) {
+			link->link_speed = ETH_SPEED_NUM_NONE;
+			link->link_duplex = ETH_LINK_FULL_DUPLEX;
+			link->link_autoneg = ETH_LINK_FIXED;
+		} else {
+			link->link_speed = port_speed[port_info.speed %
+						LINK_SPEED_LEVELS];
+			link->link_duplex = port_info.duplex;
+			link->link_autoneg = port_info.autoneg_state;
+		}
 	}
 }
 
@@ -51,7 +74,7 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
 	spnic_link_event_stats(hwdev, link_status->state);
 
 	/* Link event reported only after set vport enable */
-	get_port_info(link_status->state, &link);
+	get_port_info(dev, link_status->state, &link);
 	err = rte_eth_linkstatus_set((struct rte_eth_dev *)(dev->eth_dev),
 				     &link);
 	if (!err)
drivers/net/spnic/base/spnic_nic_event.h +2 -7
index eb41d76a7d..ac0c072887 100644
@@ -5,13 +5,8 @@
 #ifndef _SPNIC_NIC_EVENT_H_
 #define _SPNIC_NIC_EVENT_H_
 
-struct spnic_cmd_link_state {
-	struct mgmt_msg_head msg_head;
-
-	u8 port_id;
-	u8 state;
-	u16 rsvd1;
-};
+void get_port_info(struct spnic_hwdev *hwdev, u8 link_state,
+		   struct rte_eth_link *link);
 
 void spnic_pf_event_handler(void *hwdev, __rte_unused void *pri_handle,
 			    u16 cmd, void *buf_in, u16 in_size,
drivers/net/spnic/spnic_ethdev.c +347 -1

408 lines not on this page · raw message

Signature · 1 line
2.27.0
#14 lore raw

PATCH 10/25 net/spnic: add function info initialization

In reply to Yanling Song

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.

---
 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(-)
drivers/net/spnic/base/spnic_hw_cfg.c +43 -0
index 6505f48273..49e16ee89c 100644
@@ -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;
drivers/net/spnic/base/spnic_hw_cfg.h +6 -0
index 9ab51f2875..5019f38ec2 100644
@@ -112,8 +112,14 @@ struct spnic_cfg_cmd_dev_cap {
 int spnic_init_capability(void *dev);
 void spnic_free_capability(void *dev);
 
+u16 spnic_func_max_sqs(void *hwdev);
+u16 spnic_func_max_rqs(void *hwdev);
+
 u8 spnic_physical_port_id(void *hwdev);
 
 int cfg_mbx_vf_proc_msg(void *hwdev, void *pri_handle, u16 cmd, void *buf_in,
 			u16 in_size, void *buf_out, u16 *out_size);
+
+bool spnic_support_nic(void *hwdev);
+
 #endif /* _SPNIC_HW_CFG_H_ */
drivers/net/spnic/base/spnic_nic_cfg.c +221 -0

227 lines not on this page · raw message

drivers/net/spnic/base/spnic_nic_cfg.h +213 -0

235 lines not on this page · raw message

drivers/net/spnic/spnic_ethdev.c +372 -10

466 lines not on this page · raw message

drivers/net/spnic/spnic_ethdev.h +21 -1
index 654234aaa4..321db389dc 100644
@@ -4,6 +4,7 @@
 
 #ifndef _SPNIC_ETHDEV_H_
 #define _SPNIC_ETHDEV_H_
+#define SPNIC_DEV_NAME_LEN		32
 
 #define SPNIC_UINT32_BIT_SIZE		(CHAR_BIT * sizeof(uint32_t))
 #define SPNIC_VFTA_SIZE			(4096 / SPNIC_UINT32_BIT_SIZE)
@@ -16,7 +17,25 @@ enum spnic_dev_status {
 	SPNIC_DEV_INTR_EN
 };
 
-#define SPNIC_DEV_NAME_LEN		32
+enum nic_feature_cap {
+	NIC_F_CSUM = BIT(0),
+	NIC_F_SCTP_CRC = BIT(1),
+	NIC_F_TSO = BIT(2),
+	NIC_F_LRO = BIT(3),
+	NIC_F_UFO = BIT(4),
+	NIC_F_RSS = BIT(5),
+	NIC_F_RX_VLAN_FILTER = BIT(6),
+	NIC_F_RX_VLAN_STRIP = BIT(7),
+	NIC_F_TX_VLAN_INSERT = BIT(8),
+	NIC_F_VXLAN_OFFLOAD = BIT(9),
+	NIC_F_IPSEC_OFFLOAD = BIT(10),
+	NIC_F_FDIR = BIT(11),
+	NIC_F_PROMISC = BIT(12),
+	NIC_F_ALLMULTI = BIT(13),
+};
+
+#define DEFAULT_DRV_FEATURE		0x3FFF
+
 struct spnic_nic_dev {
 	struct spnic_hwdev *hwdev; /* Hardware device */
 
@@ -53,6 +72,7 @@ struct spnic_nic_dev {
 	struct rte_ether_addr *mc_list;
 
 	char dev_name[SPNIC_DEV_NAME_LEN];
+	u64 feature_cap;
 	u32 vfta[SPNIC_VFTA_SIZE]; /* VLAN bitmap */
 };
 
Signature · 1 line
2.27.0
#15 lore raw

PATCH 11/25 net/spnic: add queue pairs context initialization

In reply to Yanling Song

This patch adds the initialization of Tx/Rx queues context and negotiation of NIC features.

---
 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
drivers/net/spnic/base/spnic_hw_comm.c +101 -0
index 5cb607cf03..1c751f2403 100644
@@ -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;
drivers/net/spnic/base/spnic_hw_comm.h +6 -0
index 207f0aaeae..f960fbb53f 100644
@@ -180,6 +180,10 @@ int spnic_get_mgmt_version(void *hwdev, char *mgmt_ver, int max_mgmt_len);
 
 int spnic_get_board_info(void *hwdev, struct spnic_board_info *info);
 
+int spnic_set_root_ctxt(void *hwdev, u32 rq_depth, u32 sq_depth, u16 rx_buf_sz);
+
+int spnic_clean_root_ctxt(void *hwdev);
+
 int spnic_get_interrupt_cfg(void *dev, struct interrupt_info *info);
 
 int spnic_set_interrupt_cfg(void *dev, struct interrupt_info info);
@@ -188,6 +192,8 @@ int spnic_set_wq_page_size(void *hwdev, u16 func_idx, u32 page_size);
 
 int spnic_set_cmdq_depth(void *hwdev, u16 cmdq_depth);
 
+int spnic_convert_rx_buf_size(u32 rx_buf_sz, u32 *match_sz);
+
 int spnic_get_comm_features(void *hwdev, u64 *s_feature, u16 size);
 
 int spnic_set_comm_features(void *hwdev, u64 *s_feature, u16 size);
drivers/net/spnic/base/spnic_nic_cfg.c +76 -0

88 lines not on this page · raw message

drivers/net/spnic/base/spnic_nic_cfg.h +64 -1

99 lines not on this page · raw message

drivers/net/spnic/meson.build +2 -1
index 042d2fe6e1..20d5151a8d 100644
@@ -6,6 +6,7 @@ objs = [base_objs]
 
 sources = files(
 	'spnic_ethdev.c',
-	)
+	'spnic_io.c',
+)
 
 includes += include_directories('base')
drivers/net/spnic/spnic_ethdev.c +54 -3

131 lines not on this page · raw message

drivers/net/spnic/spnic_io.c new file +738 -0

738 lines not on this page · raw message

drivers/net/spnic/spnic_io.h new file +154 -0

154 lines not on this page · raw message

drivers/net/spnic/spnic_rx.h new file +113 -0

113 lines not on this page · raw message

drivers/net/spnic/spnic_tx.h new file +62 -0

62 lines not on this page · raw message

Signature · 1 line
2.27.0
#16 lore raw

PATCH 12/25 net/spnic: support mbuf handling of Tx/Rx

In reply to Yanling Song

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.

---
 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           | 302 +++++++++++++++
 drivers/net/spnic/spnic_rx.h           |  41 ++
 drivers/net/spnic/spnic_tx.c           | 334 ++++++++++++++++
 drivers/net/spnic/spnic_tx.h           | 228 +++++++++++
 8 files changed, 1454 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/spnic/spnic_rx.c
 create mode 100644 drivers/net/spnic/spnic_tx.c
drivers/net/spnic/base/spnic_nic_cfg.c +23 -0
index 25d98d67dd..f6914f6f6d 100644
@@ -378,6 +378,29 @@ int spnic_set_port_enable(void *hwdev, bool enable)
 	return 0;
 }
 
+int spnic_flush_qps_res(void *hwdev)
+{
+	struct spnic_cmd_clear_qp_resource sq_res;
+	u16 out_size = sizeof(sq_res);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&sq_res, 0, sizeof(sq_res));
+	sq_res.func_id = spnic_global_func_id(hwdev);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CLEAR_QP_RESOURCE, &sq_res,
+				     sizeof(sq_res), &sq_res, &out_size);
+	if (err || !out_size || sq_res.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Clear sq resources failed, err: %d, status: 0x%x, out size: 0x%x",
+			    err, sq_res.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
 static int spnic_set_function_table(void *hwdev, u32 cfg_bitmap,
 				     struct spnic_func_tbl_cfg *cfg)
 {
drivers/net/spnic/base/spnic_nic_cfg.h +23 -0
index ce9792f8ee..746c1c342d 100644
@@ -255,6 +255,17 @@ struct spnic_cmd_register_vf {
 	u8 rsvd[39];
 };
 
+
+struct spnic_cmd_set_rq_flush {
+	union {
+		struct {
+			u16 global_rq_id;
+			u16 local_rq_id;
+		};
+		u32 value;
+	};
+};
+
 int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
 			   void *buf_out, u16 *out_size);
 
@@ -381,6 +392,18 @@ int spnic_set_port_enable(void *hwdev, bool enable);
  */
 int spnic_get_link_state(void *hwdev, u8 *link_state);
 
+/**
+ * Flush queue pairs resource in hardware
+ *
+ * @param[in] hwdev
+ *   Device pointer to hwdev
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int spnic_flush_qps_res(void *hwdev);
+
+
 /**
  * Init nic hwdev
  *
drivers/net/spnic/meson.build +2 -0
index 20d5151a8d..cd8f316366 100644
@@ -7,6 +7,8 @@ objs = [base_objs]
 sources = files(
 	'spnic_ethdev.c',
 	'spnic_io.c',
+	'spnic_rx.c',
+	'spnic_tx.c'
 )
 
 includes += include_directories('base')
drivers/net/spnic/spnic_ethdev.c +501 -1

566 lines not on this page · raw message

drivers/net/spnic/spnic_rx.c new file +302 -0

302 lines not on this page · raw message

drivers/net/spnic/spnic_rx.h +41 -0

45 lines not on this page · raw message

drivers/net/spnic/spnic_tx.c new file +334 -0

334 lines not on this page · raw message

drivers/net/spnic/spnic_tx.h +228 -0

238 lines not on this page · raw message

Signature · 1 line
2.27.0
#17 lore raw

PATCH 13/25 net/spnic: support Rx congfiguration

In reply to Yanling Song

This patch Rx/Tx configuration including Rx csum offload, LRO, RSS, VLAN filter and VLAN offload.

---
 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(-)
drivers/net/spnic/base/spnic_nic_cfg.c +525 -0
index f6914f6f6d..6c22c4fb3d 100644
@@ -271,6 +271,37 @@ int spnic_get_default_mac(void *hwdev, u8 *mac_addr, int ether_len)
 	return 0;
 }
 
+static int spnic_config_vlan(void *hwdev, u8 opcode, u16 vlan_id, u16 func_id)
+{
+	struct spnic_cmd_vlan_config vlan_info;
+	u16 out_size = sizeof(vlan_info);
+	int err;
+
+	memset(&vlan_info, 0, sizeof(vlan_info));
+	vlan_info.opcode = opcode;
+	vlan_info.func_id = func_id;
+	vlan_info.vlan_id = vlan_id;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CFG_FUNC_VLAN, &vlan_info,
+				     sizeof(vlan_info), &vlan_info, &out_size);
+	if (err || !out_size || vlan_info.msg_head.status) {
+		PMD_DRV_LOG(ERR, "%s vlan failed, err: %d, status: 0x%x, out size: 0x%x",
+			    opcode == SPNIC_CMD_OP_ADD ? "Add" : "Delete",
+			    err, vlan_info.msg_head.status, out_size);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int spnic_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
+{
+	if (!hwdev)
+		return -EINVAL;
+
+	return spnic_config_vlan(hwdev, SPNIC_CMD_OP_DEL, vlan_id, func_id);
+}
+
 int spnic_get_port_info(void *hwdev, struct nic_port_info *port_info)
 {
 	struct spnic_cmd_port_info port_msg;
@@ -564,6 +595,500 @@ void spnic_free_nic_hwdev(void *hwdev)
 	spnic_vf_func_free(hwdev);
 }
 
+int spnic_set_rx_mode(void *hwdev, u32 enable)
+{
+	struct spnic_rx_mode_config rx_mode_cfg;
+	u16 out_size = sizeof(rx_mode_cfg);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
+	rx_mode_cfg.func_id = spnic_global_func_id(hwdev);
+	rx_mode_cfg.rx_mode = enable;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_SET_RX_MODE,
+				     &rx_mode_cfg, sizeof(rx_mode_cfg),
+				     &rx_mode_cfg, &out_size);
+	if (err || !out_size || rx_mode_cfg.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Set rx mode failed, err: %d, status: 0x%x, out size: 0x%x",
+			    err, rx_mode_cfg.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int spnic_set_rx_vlan_offload(void *hwdev, u8 en)
+{
+	struct spnic_cmd_vlan_offload vlan_cfg;
+	u16 out_size = sizeof(vlan_cfg);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&vlan_cfg, 0, sizeof(vlan_cfg));
+	vlan_cfg.func_id = spnic_global_func_id(hwdev);
+	vlan_cfg.vlan_offload = en;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_SET_RX_VLAN_OFFLOAD,
+				     &vlan_cfg, sizeof(vlan_cfg),
+				     &vlan_cfg, &out_size);
+	if (err || !out_size || vlan_cfg.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Set rx vlan offload failed, err: %d, status: 0x%x, out size: 0x%x",
+			    err, vlan_cfg.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int spnic_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
+{
+	struct spnic_cmd_set_vlan_filter vlan_filter;
+	u16 out_size = sizeof(vlan_filter);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&vlan_filter, 0, sizeof(vlan_filter));
+	vlan_filter.func_id = spnic_global_func_id(hwdev);
+	vlan_filter.vlan_filter_ctrl = vlan_filter_ctrl;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_SET_VLAN_FILTER_EN,
+				     &vlan_filter, sizeof(vlan_filter),
+				     &vlan_filter, &out_size);
+	if (err || !out_size || vlan_filter.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Failed to set vlan filter, err: %d, status: 0x%x, out size: 0x%x",
+			    err, vlan_filter.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int spnic_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
+			    u8 lro_max_pkt_len)
+{
+	struct spnic_cmd_lro_config lro_cfg;
+	u16 out_size = sizeof(lro_cfg);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&lro_cfg, 0, sizeof(lro_cfg));
+	lro_cfg.func_id = spnic_global_func_id(hwdev);
+	lro_cfg.opcode = SPNIC_CMD_OP_SET;
+	lro_cfg.lro_ipv4_en = ipv4_en;
+	lro_cfg.lro_ipv6_en = ipv6_en;
+	lro_cfg.lro_max_pkt_len = lro_max_pkt_len;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CFG_RX_LRO, &lro_cfg,
+				     sizeof(lro_cfg), &lro_cfg, &out_size);
+	if (err || !out_size || lro_cfg.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Set lro offload failed, err: %d, status: 0x%x, out size: 0x%x",
+			    err, lro_cfg.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int spnic_set_rx_lro_timer(void *hwdev, u32 timer_value)
+{
+	struct spnic_cmd_lro_timer lro_timer;
+	u16 out_size = sizeof(lro_timer);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&lro_timer, 0, sizeof(lro_timer));
+	lro_timer.opcode = SPNIC_CMD_OP_SET;
+	lro_timer.timer = timer_value;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CFG_LRO_TIMER, &lro_timer,
+				     sizeof(lro_timer), &lro_timer, &out_size);
+	if (err || !out_size || lro_timer.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Set lro timer failed, err: %d, status: 0x%x, out size: 0x%x",
+			    err, lro_timer.msg_head.status, out_size);
+
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int spnic_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
+			    u32 lro_max_pkt_len)
+{
+	u8 ipv4_en = 0, ipv6_en = 0;
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	ipv4_en = lro_en ? 1 : 0;
+	ipv6_en = lro_en ? 1 : 0;
+
+	PMD_DRV_LOG(INFO, "Set LRO max coalesce packet size to %uK",
+		    lro_max_pkt_len);
+
+	err = spnic_set_rx_lro(hwdev, ipv4_en, ipv6_en, (u8)lro_max_pkt_len);
+	if (err)
+		return err;
+
+	/* We don't set LRO timer for VF */
+	if (spnic_func_type(hwdev) == TYPE_VF)
+		return 0;
+
+	PMD_DRV_LOG(INFO, "Set LRO timer to %u", lro_timer);
+
+	return spnic_set_rx_lro_timer(hwdev, lro_timer);
+}
+
+/* RSS config */
+int spnic_rss_template_alloc(void *hwdev)
+{
+	struct spnic_rss_template_mgmt template_mgmt;
+	u16 out_size = sizeof(template_mgmt);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&template_mgmt, 0, sizeof(struct spnic_rss_template_mgmt));
+	template_mgmt.func_id = spnic_global_func_id(hwdev);
+	template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_RSS_TEMP_MGR,
+				     &template_mgmt, sizeof(template_mgmt),
+				     &template_mgmt, &out_size);
+	if (err || !out_size || template_mgmt.msg_head.status) {
+		if (template_mgmt.msg_head.status ==
+		    SPNIC_MGMT_STATUS_TABLE_FULL) {
+			PMD_DRV_LOG(ERR, "There is no more template available");
+			return -ENOSPC;
+		}
+		PMD_DRV_LOG(ERR, "Alloc rss template failed, err: %d, "
+			    "status: 0x%x, out size: 0x%x",
+			    err, template_mgmt.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int spnic_rss_template_free(void *hwdev)
+{
+	struct spnic_rss_template_mgmt template_mgmt;
+	u16 out_size = sizeof(template_mgmt);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&template_mgmt, 0, sizeof(struct spnic_rss_template_mgmt));
+	template_mgmt.func_id = spnic_global_func_id(hwdev);
+	template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_RSS_TEMP_MGR,
+				     &template_mgmt, sizeof(template_mgmt),
+				     &template_mgmt, &out_size);
+	if (err || !out_size || template_mgmt.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Free rss template failed, err: %d, "
+			    "status: 0x%x, out size: 0x%x",
+			    err, template_mgmt.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int spnic_rss_cfg_hash_key(void *hwdev, u8 opcode, u8 *key)
+{
+	struct spnic_cmd_rss_hash_key hash_key;
+	u16 out_size = sizeof(hash_key);
+	int err;
+
+	if (!hwdev || !key)
+		return -EINVAL;
+
+	memset(&hash_key, 0, sizeof(struct spnic_cmd_rss_hash_key));
+	hash_key.func_id = spnic_global_func_id(hwdev);
+	hash_key.opcode = opcode;
+	if (opcode == SPNIC_CMD_OP_SET)
+		memcpy(hash_key.key, key, SPNIC_RSS_KEY_SIZE);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CFG_RSS_HASH_KEY,
+				     &hash_key, sizeof(hash_key),
+				     &hash_key, &out_size);
+	if (err || !out_size || hash_key.msg_head.status) {
+		PMD_DRV_LOG(ERR, "%s hash key failed, err: %d, "
+			    "status: 0x%x, out size: 0x%x",
+			    opcode == SPNIC_CMD_OP_SET ? "Set" : "Get",
+			    err, hash_key.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	if (opcode == SPNIC_CMD_OP_GET)
+		memcpy(key, hash_key.key, SPNIC_RSS_KEY_SIZE);
+
+	return 0;
+}
+
+int spnic_rss_set_hash_key(void *hwdev, u8 *key)
+{
+	if (!hwdev || !key)
+		return -EINVAL;
+
+	return spnic_rss_cfg_hash_key(hwdev, SPNIC_CMD_OP_SET, key);
+}
+
+int spnic_rss_get_hash_key(void *hwdev, u8 *key)
+{
+	if (!hwdev || !key)
+		return -EINVAL;
+
+	return spnic_rss_cfg_hash_key(hwdev, SPNIC_CMD_OP_GET, key);
+}
+
+int spnic_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
+{
+	struct spnic_cmd_buf *cmd_buf = NULL;
+	u16 *indir_tbl = NULL;
+	int err, i;
+
+	if (!hwdev || !indir_table)
+		return -EINVAL;
+
+	cmd_buf = spnic_alloc_cmd_buf(hwdev);
+	if (!cmd_buf) {
+		PMD_DRV_LOG(ERR, "Allocate cmd buf failed");
+		return -ENOMEM;
+	}
+
+	cmd_buf->size = sizeof(struct nic_rss_indirect_tbl);
+	err = spnic_cmdq_detail_resp(hwdev, SPNIC_MOD_L2NIC,
+				     SPNIC_UCODE_CMD_GET_RSS_INDIR_TABLE,
+				     cmd_buf, cmd_buf, 0);
+	if (err) {
+		PMD_DRV_LOG(ERR, "Get rss indir table failed");
+		spnic_free_cmd_buf(cmd_buf);
+		return err;
+	}
+
+	indir_tbl = (u16 *)cmd_buf->buf;
+	for (i = 0; i < SPNIC_RSS_INDIR_SIZE; i++)
+		indir_table[i] = *(indir_tbl + i);
+
+	spnic_free_cmd_buf(cmd_buf);
+	return 0;
+}
+
+int spnic_rss_set_indir_tbl(void *hwdev, const u32 *indir_table)
+{
+	struct nic_rss_indirect_tbl *indir_tbl = NULL;
+	struct spnic_cmd_buf *cmd_buf = NULL;
+	u32 i, size;
+	u32 *temp = NULL;
+	u64 out_param = 0;
+	int err;
+
+	if (!hwdev || !indir_table)
+		return -EINVAL;
+
+	cmd_buf = spnic_alloc_cmd_buf(hwdev);
+	if (!cmd_buf) {
+		PMD_DRV_LOG(ERR, "Allocate cmd buf failed");
+		return -ENOMEM;
+	}
+
+	cmd_buf->size = sizeof(struct nic_rss_indirect_tbl);
+	indir_tbl = (struct nic_rss_indirect_tbl *)cmd_buf->buf;
+	memset(indir_tbl, 0, sizeof(*indir_tbl));
+
+	for (i = 0; i < SPNIC_RSS_INDIR_SIZE; i++)
+		indir_tbl->entry[i] = (u16)(*(indir_table + i));
+
+	size = sizeof(indir_tbl->entry) / sizeof(u32);
+	temp = (u32 *)indir_tbl->entry;
+	for (i = 0; i < size; i++)
+		temp[i] = cpu_to_be32(temp[i]);
+
+	err = spnic_cmdq_direct_resp(hwdev, SPNIC_MOD_L2NIC,
+				     SPNIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
+				     cmd_buf, &out_param, 0);
+	if (err || out_param != 0) {
+		PMD_DRV_LOG(ERR, "Set rss indir table failed");
+		err = -EFAULT;
+	}
+
+	spnic_free_cmd_buf(cmd_buf);
+	return err;
+}
+
+int spnic_set_rss_type(void *hwdev, struct spnic_rss_type rss_type)
+{
+	struct nic_rss_context_tbl *ctx_tbl = NULL;
+	struct spnic_cmd_buf *cmd_buf = NULL;
+	u32 ctx = 0;
+	u64 out_param = 0;
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	cmd_buf = spnic_alloc_cmd_buf(hwdev);
+	if (!cmd_buf) {
+		PMD_DRV_LOG(ERR, "Allocate cmd buf failed");
+		return -ENOMEM;
+	}
+
+	ctx |= SPNIC_RSS_TYPE_SET(1, VALID) |
+	       SPNIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
+	       SPNIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
+	       SPNIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
+	       SPNIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
+	       SPNIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
+	       SPNIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
+	       SPNIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
+	       SPNIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
+
+	cmd_buf->size = sizeof(struct nic_rss_context_tbl);
+	ctx_tbl = (struct nic_rss_context_tbl *)cmd_buf->buf;
+	memset(ctx_tbl, 0, sizeof(*ctx_tbl));
+	ctx_tbl->ctx = cpu_to_be32(ctx);
+
+	/* Cfg the RSS context table by command queue */
+	err = spnic_cmdq_direct_resp(hwdev, SPNIC_MOD_L2NIC,
+				     SPNIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+				     cmd_buf, &out_param, 0);
+
+	spnic_free_cmd_buf(cmd_buf);
+
+	if (err || out_param != 0) {
+		PMD_DRV_LOG(ERR, "Set rss context table failed, err: %d", err);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int spnic_get_rss_type(void *hwdev, struct spnic_rss_type *rss_type)
+{
+	struct spnic_rss_context_table ctx_tbl;
+	u16 out_size = sizeof(ctx_tbl);
+	int err;
+
+	if (!hwdev || !rss_type)
+		return -EINVAL;
+
+	memset(&ctx_tbl, 0, sizeof(struct spnic_rss_context_table));
+	ctx_tbl.func_id = spnic_global_func_id(hwdev);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_GET_RSS_CTX_TBL,
+				     &ctx_tbl, sizeof(ctx_tbl),
+				     &ctx_tbl, &out_size);
+	if (err || !out_size || ctx_tbl.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Get hash type failed, err: %d, status: 0x%x, out size: 0x%x",
+			    err, ctx_tbl.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	rss_type->ipv4	       = SPNIC_RSS_TYPE_GET(ctx_tbl.context, IPV4);
+	rss_type->ipv6	       = SPNIC_RSS_TYPE_GET(ctx_tbl.context, IPV6);
+	rss_type->ipv6_ext     = SPNIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
+	rss_type->tcp_ipv4     = SPNIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
+	rss_type->tcp_ipv6     = SPNIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
+	rss_type->tcp_ipv6_ext = SPNIC_RSS_TYPE_GET(ctx_tbl.context,
+						     TCP_IPV6_EXT);
+	rss_type->udp_ipv4     = SPNIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
+	rss_type->udp_ipv6     = SPNIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
+
+	return 0;
+}
+
+static int spnic_rss_cfg_hash_engine(void *hwdev, u8 opcode, u8 *type)
+{
+	struct spnic_cmd_rss_engine_type hash_type;
+	u16 out_size = sizeof(hash_type);
+	int err;
+
+	if (!hwdev || !type)
+		return -EINVAL;
+
+	memset(&hash_type, 0, sizeof(struct spnic_cmd_rss_engine_type));
+	hash_type.func_id = spnic_global_func_id(hwdev);
+	hash_type.opcode = opcode;
+	if (opcode == SPNIC_CMD_OP_SET)
+		hash_type.hash_engine = *type;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CFG_RSS_HASH_ENGINE,
+				     &hash_type, sizeof(hash_type),
+				     &hash_type, &out_size);
+	if (err || !out_size || hash_type.msg_head.status) {
+		PMD_DRV_LOG(ERR, "%s hash engine failed, err: %d, "
+			    "status: 0x%x, out size: 0x%x",
+			    opcode == SPNIC_CMD_OP_SET ? "Set" : "Get",
+			    err, hash_type.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	if (opcode == SPNIC_CMD_OP_GET)
+		*type = hash_type.hash_engine;
+
+	return 0;
+}
+
+int spnic_rss_get_hash_engine(void *hwdev, u8 *type)
+{
+	if (!hwdev || !type)
+		return -EINVAL;
+
+	return spnic_rss_cfg_hash_engine(hwdev, SPNIC_CMD_OP_GET, type);
+}
+
+int spnic_rss_set_hash_engine(void *hwdev, u8 type)
+{
+	if (!hwdev)
+		return -EINVAL;
+
+	return spnic_rss_cfg_hash_engine(hwdev, SPNIC_CMD_OP_SET, &type);
+}
+
+int spnic_rss_cfg(void *hwdev, u8 rss_en, u8 tc_num, u8 *prio_tc)
+{
+	struct spnic_cmd_rss_config rss_cfg;
+	u16 out_size = sizeof(rss_cfg);
+	int err;
+
+	/* Ucode requires number of TC should be power of 2 */
+	if (!hwdev || !prio_tc || (tc_num & (tc_num - 1)))
+		return -EINVAL;
+
+	memset(&rss_cfg, 0, sizeof(struct spnic_cmd_rss_config));
+	rss_cfg.func_id = spnic_global_func_id(hwdev);
+	rss_cfg.rss_en = rss_en;
+	rss_cfg.rq_priority_number = tc_num ? (u8)ilog2(tc_num) : 0;
+
+	memcpy(rss_cfg.prio_tc, prio_tc, SPNIC_DCB_UP_MAX);
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_RSS_CFG, &rss_cfg,
+				     sizeof(rss_cfg), &rss_cfg, &out_size);
+	if (err || !out_size || rss_cfg.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Set rss cfg failed, err: %d, "
+			    "status: 0x%x, out size: 0x%x",
+			    err, rss_cfg.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
 int spnic_vf_get_default_cos(void *hwdev, u8 *cos_id)
 {
 	struct spnic_cmd_vf_dcb_state vf_dcb;
drivers/net/spnic/base/spnic_nic_cfg.h +387 -0

426 lines not on this page · raw message

drivers/net/spnic/spnic_ethdev.c +183 -4

234 lines not on this page · raw message

drivers/net/spnic/spnic_ethdev.h +2 -0
index 321db389dc..996b4e4b8f 100644
@@ -63,6 +63,8 @@ struct spnic_nic_dev {
 	u32 default_cos;
 	u32 rx_csum_en;
 
+	u8 rss_key[SPNIC_RSS_KEY_SIZE];
+
 	u32 dev_status;
 
 	bool pause_set;
drivers/net/spnic/spnic_rx.c +221 -0

240 lines not on this page · raw message

drivers/net/spnic/spnic_rx.h +31 -0
index 46f4e1276d..0b534f1904 100644
@@ -5,6 +5,23 @@
 #ifndef _SPNIC_RX_H_
 #define _SPNIC_RX_H_
 
+#define SPNIC_DEFAULT_RX_CSUM_OFFLOAD	0xFFF
+
+#define SPNIC_RSS_OFFLOAD_ALL ( \
+	ETH_RSS_IPV4 | \
+	ETH_RSS_FRAG_IPV4 | \
+	ETH_RSS_NONFRAG_IPV4_TCP | \
+	ETH_RSS_NONFRAG_IPV4_UDP | \
+	ETH_RSS_NONFRAG_IPV4_OTHER | \
+	ETH_RSS_IPV6 | \
+	ETH_RSS_FRAG_IPV6 | \
+	ETH_RSS_NONFRAG_IPV6_TCP | \
+	ETH_RSS_NONFRAG_IPV6_UDP | \
+	ETH_RSS_NONFRAG_IPV6_OTHER | \
+	ETH_RSS_IPV6_EX | \
+	ETH_RSS_IPV6_TCP_EX | \
+	ETH_RSS_IPV6_UDP_EX)
+
 struct spnic_rxq_stats {
 	u64 packets;
 	u64 bytes;
@@ -118,7 +135,21 @@ void spnic_free_rxq_mbufs(struct spnic_rxq *rxq);
 
 void spnic_free_all_rxq_mbufs(struct spnic_nic_dev *nic_dev);
 
+int spnic_update_rss_config(struct rte_eth_dev *dev,
+			    struct rte_eth_rss_conf *rss_conf);
+
 int spnic_start_all_rqs(struct rte_eth_dev *eth_dev);
+
+void spnic_add_rq_to_rx_queue_list(struct spnic_nic_dev *nic_dev,
+				    u16 queue_id);
+
+int spnic_refill_indir_rqid(struct spnic_rxq *rxq);
+
+void spnic_init_rx_queue_list(struct spnic_nic_dev *nic_dev);
+
+void spnic_remove_rq_from_rx_queue_list(struct spnic_nic_dev *nic_dev,
+					 u16 queue_id);
+
 /**
  * Get receive queue local ci
  *
Signature · 1 line
2.27.0
#18 lore raw

PATCH 14/25 net/spnic: add port/vport enable

In reply to Yanling Song

This patch adds interface to enable port/vport so that the hardware would receive packets to host.

---
 drivers/net/spnic/spnic_ethdev.c | 46 ++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
drivers/net/spnic/spnic_ethdev.c +46 -0
index db16d4038d..826a34f7fc 100644
@@ -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);
Signature · 1 line
2.27.0
#19 lore raw

PATCH 15/25 net/spnic: support IO packets handling

In reply to Yanling Song

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.

---
 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(+)
drivers/net/spnic/spnic_ethdev.c +48 -0
index 826a34f7fc..b4d20e1a6f 100644
@@ -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);
 }
 
drivers/net/spnic/spnic_ethdev.h +7 -0
index 996b4e4b8f..2b59886942 100644
@@ -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		(CHAR_BIT * sizeof(uint32_t))
@@ -17,6 +20,10 @@ enum spnic_dev_status {
 	SPNIC_DEV_INTR_EN
 };
 
+enum spnic_tx_cvlan_type {
+	SPNIC_TX_TPID0,
+};
+
 enum nic_feature_cap {
 	NIC_F_CSUM = BIT(0),
 	NIC_F_SCTP_CRC = BIT(1),
drivers/net/spnic/spnic_rx.c +209 -0

218 lines not on this page · raw message

drivers/net/spnic/spnic_rx.h +137 -0

151 lines not on this page · raw message

drivers/net/spnic/spnic_tx.c +524 -0

536 lines not on this page · raw message

drivers/net/spnic/spnic_tx.h +7 -0
index d770b15c21..4c2d587104 100644
@@ -4,6 +4,13 @@
 
 #ifndef _SPNIC_TX_H_
 #define _SPNIC_TX_H_
+#define MAX_SINGLE_SGE_SIZE		65536
+#define SPNIC_NONTSO_PKT_MAX_SGE	38
+#define SPNIC_NONTSO_SEG_NUM_VALID(num)	\
+	((num) <= SPNIC_NONTSO_PKT_MAX_SGE)
+
+#define SPNIC_TSO_PKT_MAX_SGE		127
+#define SPNIC_TSO_SEG_NUM_INVALID(num)	((num) > SPNIC_TSO_PKT_MAX_SGE)
 /* Tx offload info */
 struct spnic_tx_offload_info {
 	u8 outer_l2_len;
Signature · 1 line
2.27.0
#20 lore raw

PATCH 16/25 net/spnic: add device configure/version/info

In reply to Yanling Song

This commit adds the callbacks to configure queue number and mtu as well as query configuration information and firmware version.

---
 drivers/net/spnic/spnic_ethdev.c | 148 ++++++++++++++++++++++++++++++-
 1 file changed, 146 insertions(+), 2 deletions(-)
drivers/net/spnic/spnic_ethdev.c +146 -2
index b4d20e1a6f..c97f15e871 100644
@@ -71,12 +71,150 @@ enum spnic_rx_mod {
 #define SPNIC_TXD_ALIGN			1
 #define SPNIC_RXD_ALIGN			1
 
+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;
+
+	if (nic_dev->num_sqs > nic_dev->max_sqs ||
+	    nic_dev->num_rqs > nic_dev->max_rqs) {
+		PMD_DRV_LOG(ERR, "num_sqs: %d or num_rqs: %d larger than max_sqs: %d or max_rqs: %d",
+			    nic_dev->num_sqs, nic_dev->num_rqs,
+			    nic_dev->max_sqs, nic_dev->max_rqs);
+		return -EINVAL;
+	}
+
+	/* The range of mtu is 384~9600 */
+	if (SPNIC_MTU_TO_PKTLEN(dev->data->dev_conf.rxmode.mtu) <
+	    SPNIC_MIN_FRAME_SIZE ||
+	    SPNIC_MTU_TO_PKTLEN(dev->data->dev_conf.rxmode.mtu) >
+	    SPNIC_MAX_JUMBO_FRAME_SIZE) {
+		PMD_DRV_LOG(ERR, "Max rx pkt len out of range, mtu: %d, expect between %d and %d",
+			    dev->data->dev_conf.rxmode.mtu,
+			    SPNIC_MIN_FRAME_SIZE, SPNIC_MAX_JUMBO_FRAME_SIZE);
+		return -EINVAL;
+	}
+
+	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) {
+		PMD_DRV_LOG(ERR, "Get fw version failed");
+		return -EIO;
+	}
+
+	if (fw_size < strlen(mgmt_ver) + 1)
+		return (strlen(mgmt_ver) + 1);
+
+	snprintf(fw_version, fw_size, "%s", mgmt_ver);
+
+	return 0;
+}
 
 /**
  * Set ethernet device link state up.
@@ -1332,6 +1470,9 @@ static int spnic_set_mc_addr_list(struct rte_eth_dev *dev,
 }
 
 static const struct eth_dev_ops spnic_pmd_ops = {
+	.dev_configure                 = spnic_dev_configure,
+	.dev_infos_get                 = spnic_dev_infos_get,
+	.fw_version_get                = spnic_fw_version_get,
 	.dev_set_link_up               = spnic_dev_set_link_up,
 	.dev_set_link_down             = spnic_dev_set_link_down,
 	.link_update                   = spnic_link_update,
@@ -1350,6 +1491,9 @@ static const struct eth_dev_ops spnic_pmd_ops = {
 };
 
 static const struct eth_dev_ops spnic_pmd_vf_ops = {
+	.dev_configure                 = spnic_dev_configure,
+	.dev_infos_get                 = spnic_dev_infos_get,
+	.fw_version_get                = spnic_fw_version_get,
 	.rx_queue_setup                = spnic_rx_queue_setup,
 	.tx_queue_setup                = spnic_tx_queue_setup,
 	.dev_start                     = spnic_dev_start,
Signature · 1 line
2.27.0
#21 lore raw

Re: [PATCH v1 16/25] net/spnic: add device configure/version/info

Quoted 5 lines · On Sat, 18 Dec 2021 10:51:43 +0800 Yanling Song <[email protected]> wrote:
drivers/net/spnic/spnic_ethdev.c +5 -0
+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;

drivers/net/spnic/spnic_ethdev.c enum spnic_rx_mod { · line 112

Quoted 10 lines
drivers/net/spnic/spnic_ethdev.c +10 -0
+	nic_dev->num_rqs = dev->data->nb_rx_queues;
+
+	if (nic_dev->num_sqs > nic_dev->max_sqs ||
+	    nic_dev->num_rqs > nic_dev->max_rqs) {
+		PMD_DRV_LOG(ERR, "num_sqs: %d or num_rqs: %d larger than max_sqs: %d or max_rqs: %d",
+			    nic_dev->num_sqs, nic_dev->num_rqs,
+			    nic_dev->max_sqs, nic_dev->max_rqs);
+		return -EINVAL;
+	}
+

This should already be covered by checks in ethedev:dev_configure.

drivers/net/spnic/spnic_ethdev.c enum spnic_rx_mod { · line 122

Quoted 10 lines
drivers/net/spnic/spnic_ethdev.c +10 -0
+	/* The range of mtu is 384~9600 */
+	if (SPNIC_MTU_TO_PKTLEN(dev->data->dev_conf.rxmode.mtu) <
+	    SPNIC_MIN_FRAME_SIZE ||
+	    SPNIC_MTU_TO_PKTLEN(dev->data->dev_conf.rxmode.mtu) >
+	    SPNIC_MAX_JUMBO_FRAME_SIZE) {
+		PMD_DRV_LOG(ERR, "Max rx pkt len out of range, mtu: %d, expect between %d and %d",
+			    dev->data->dev_conf.rxmode.mtu,
+			    SPNIC_MIN_FRAME_SIZE, SPNIC_MAX_JUMBO_FRAME_SIZE);
+		return -EINVAL;
+	}

Already covered by eth_dev_validate_mtu called from ethdev dev_configure.

#22 lore raw

Re: [PATCH v1 16/25] net/spnic: add device configure/version/info

Quoted 13 lines · On Mon, 20 Dec 2021 08:23:56 +0800 Stephen Hemminger…
Quoted 10 lines · On Sat, 18 Dec 2021 10:51:43 +0800 Yanling Song <[email protected]> wrote:
drivers/net/spnic/spnic_ethdev.c +3 -0
+static int spnic_dev_configure(struct rte_eth_dev *dev)
+{
+	struct spnic_nic_dev *nic_dev =

SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); +

drivers/net/spnic/spnic_ethdev.c +6 -0
+	nic_dev->num_sqs =  dev->data->nb_tx_queues;
+	nic_dev->num_rqs = dev->data->nb_rx_queues;
+
+	if (nic_dev->num_sqs > nic_dev->max_sqs ||
+	    nic_dev->num_rqs > nic_dev->max_rqs) {
+		PMD_DRV_LOG(ERR, "num_sqs: %d or num_rqs: %d
Quoted 8 lines

drivers/net/spnic/spnic_ethdev.c enum spnic_rx_mod { · line 112

Quoted 6 lines

larger than max_sqs: %d or max_rqs: %d",

drivers/net/spnic/spnic_ethdev.c +5 -0
+			    nic_dev->num_sqs, nic_dev->num_rqs,
+			    nic_dev->max_sqs, nic_dev->max_rqs);
+		return -EINVAL;
+	}
+  

This should already be covered by checks in ethedev:dev_configure.

OK. The check will be removed in the next version.

Quoted 17 lines

Review

Quoted 13 lines
drivers/net/spnic/spnic_ethdev.c +6 -0
+	/* The range of mtu is 384~9600 */
+	if (SPNIC_MTU_TO_PKTLEN(dev->data->dev_conf.rxmode.mtu) <
+	    SPNIC_MIN_FRAME_SIZE ||
+	    SPNIC_MTU_TO_PKTLEN(dev->data->dev_conf.rxmode.mtu) >
+	    SPNIC_MAX_JUMBO_FRAME_SIZE) {
+		PMD_DRV_LOG(ERR, "Max rx pkt len out of range,

mtu: %d, expect between %d and %d",

(quoted diff) +2 -0
+			    dev->data->dev_conf.rxmode.mtu,
+			    SPNIC_MIN_FRAME_SIZE,

SPNIC_MAX_JUMBO_FRAME_SIZE);

(quoted diff) +2 -0
+		return -EINVAL;
+	}  

Already covered by eth_dev_validate_mtu called from ethdev dev_configure.

OK. The check will be removed in the next version.

#23 lore raw

PATCH 17/25 net/spnic: support RSS configuration update and get

In reply to Yanling Song

This commit implements rss_hash_update and rss_hash_conf_get.

---
 drivers/net/spnic/spnic_ethdev.c | 235 +++++++++++++++++++++++++++++++
 1 file changed, 235 insertions(+)
drivers/net/spnic/spnic_ethdev.c +235 -0
index c97f15e871..61342db497 100644
@@ -1277,6 +1277,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.
+ * @param[in] reta_size
+ *   Size of the RETA table.
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+static int spnic_rss_reta_query(struct rte_eth_dev *dev,
+				struct rte_eth_rss_reta_entry64 *reta_conf,
+				uint16_t reta_size)
+{
+	struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+	u32 indirtbl[SPNIC_RSS_INDIR_SIZE] = {0};
+	u16 idx, shift;
+	u16 i;
+	int err;
+
+	if (nic_dev->rss_state == SPNIC_RSS_DISABLE) {
+		PMD_DRV_LOG(INFO, "RSS is not enabled");
+		return 0;
+	}
+
+	if (reta_size != SPNIC_RSS_INDIR_SIZE) {
+		PMD_DRV_LOG(ERR, "Invalid reta size, reta_size: %d", reta_size);
+		return -EINVAL;
+	}
+
+	err = spnic_rss_get_indir_tbl(nic_dev->hwdev, indirtbl);
+	if (err) {
+		PMD_DRV_LOG(ERR, "Get RSS retas table failed, error: %d",
+			    err);
+		return err;
+	}
+
+	for (i = 0; i < reta_size; i++) {
+		idx = i / RTE_RETA_GROUP_SIZE;
+		shift = i % RTE_RETA_GROUP_SIZE;
+		if (reta_conf[idx].mask & (1ULL << shift))
+			reta_conf[idx].reta[shift] = (uint16_t)indirtbl[i];
+	}
+
+	return 0;
+}
+
+/**
+ * Update the RETA indirection table.
+ *
+ * @param[in] dev
+ *   Pointer to ethernet device structure.
+ * @param[in] reta_conf
+ *   Pointer to RETA configuration structure array.
+ * @param[in] reta_size
+ *   Size of the RETA table.
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+static int spnic_rss_reta_update(struct rte_eth_dev *dev,
+				 struct rte_eth_rss_reta_entry64 *reta_conf,
+				 uint16_t reta_size)
+{
+	struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+	u32 indirtbl[SPNIC_RSS_INDIR_SIZE] = {0};
+	u16 idx, shift;
+	u16 i;
+	int err;
+
+	if (nic_dev->rss_state == SPNIC_RSS_DISABLE)
+		return 0;
+
+	if (reta_size != SPNIC_RSS_INDIR_SIZE) {
+		PMD_DRV_LOG(ERR, "Invalid reta size, reta_size: %d", reta_size);
+		return -EINVAL;
+	}
+
+	err = spnic_rss_get_indir_tbl(nic_dev->hwdev, indirtbl);
+	if (err)
+		return err;
+
+	/* Update RSS reta table */
+	for (i = 0; i < reta_size; i++) {
+		idx = i / RTE_RETA_GROUP_SIZE;
+		shift = i % RTE_RETA_GROUP_SIZE;
+		if (reta_conf[idx].mask & (1ULL << shift))
+			indirtbl[i] = reta_conf[idx].reta[shift];
+	}
+
+	for (i = 0 ; i < reta_size; i++) {
+		if (indirtbl[i] >= nic_dev->num_rqs) {
+			PMD_DRV_LOG(ERR, "Invalid reta entry, index: %d, num_rqs: %d",
+				    indirtbl[i], nic_dev->num_rqs);
+			return -EFAULT;
+		}
+	}
+
+	err = spnic_rss_set_indir_tbl(nic_dev->hwdev, indirtbl);
+	if (err)
+		PMD_DRV_LOG(ERR, "Set RSS reta table failed");
+
+	return err;
+}
+
 /**
  * Update MAC address
  *
@@ -1484,6 +1711,10 @@ static const struct eth_dev_ops spnic_pmd_ops = {
 	.dev_stop                      = spnic_dev_stop,
 	.dev_close                     = spnic_dev_close,
 	.mtu_set                       = spnic_dev_set_mtu,
+	.rss_hash_update               = spnic_rss_hash_update,
+	.rss_hash_conf_get             = spnic_rss_conf_get,
+	.reta_update                   = spnic_rss_reta_update,
+	.reta_query                    = spnic_rss_reta_query,
 	.mac_addr_set                  = spnic_set_mac_addr,
 	.mac_addr_remove               = spnic_mac_addr_remove,
 	.mac_addr_add                  = spnic_mac_addr_add,
@@ -1503,6 +1734,10 @@ static const struct eth_dev_ops spnic_pmd_vf_ops = {
 	.dev_stop                      = spnic_dev_stop,
 	.dev_close                     = spnic_dev_close,
 	.mtu_set                       = spnic_dev_set_mtu,
+	.rss_hash_update               = spnic_rss_hash_update,
+	.rss_hash_conf_get             = spnic_rss_conf_get,
+	.reta_update                   = spnic_rss_reta_update,
+	.reta_query                    = spnic_rss_reta_query,
 	.mac_addr_set                  = spnic_set_mac_addr,
 	.mac_addr_remove               = spnic_mac_addr_remove,
 	.mac_addr_add                  = spnic_mac_addr_add,
Signature · 1 line
2.27.0
#24 lore raw

PATCH 18/25 net/spnic: support VLAN filtering and offloading

In reply to Yanling Song

This commit implements vlan_filter_set() and vlan_offload_set() to support VLAN filtering and offloading.

---
 drivers/net/spnic/base/spnic_nic_cfg.c |   8 ++
 drivers/net/spnic/spnic_ethdev.c       | 121 +++++++++++++++++++++++++
 2 files changed, 129 insertions(+)
drivers/net/spnic/base/spnic_nic_cfg.c +8 -0
index 6c22c4fb3d..0b1198eb5f 100644
@@ -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)
drivers/net/spnic/spnic_ethdev.c +121 -0

139 lines not on this page · raw message

Signature · 1 line
2.27.0
#25 lore raw

PATCH 19/25 net/spnic: support promiscuous and allmulticast Rx modes

In reply to Yanling Song

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.

---
 drivers/net/spnic/spnic_ethdev.c | 156 +++++++++++++++++++++++++++++++
 1 file changed, 156 insertions(+)
drivers/net/spnic/spnic_ethdev.c +156 -0
index 7f6bd41c55..0b5ef15373 100644
@@ -1394,6 +1394,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.
@@ -1830,6 +1980,10 @@ static const struct eth_dev_ops spnic_pmd_ops = {
 	.mtu_set                       = spnic_dev_set_mtu,
 	.vlan_filter_set               = spnic_vlan_filter_set,
 	.vlan_offload_set              = spnic_vlan_offload_set,
+	.allmulticast_enable           = spnic_dev_allmulticast_enable,
+	.allmulticast_disable          = spnic_dev_allmulticast_disable,
+	.promiscuous_enable            = spnic_dev_promiscuous_enable,
+	.promiscuous_disable           = spnic_dev_promiscuous_disable,
 	.rss_hash_update               = spnic_rss_hash_update,
 	.rss_hash_conf_get             = spnic_rss_conf_get,
 	.reta_update                   = spnic_rss_reta_update,
@@ -1855,6 +2009,8 @@ static const struct eth_dev_ops spnic_pmd_vf_ops = {
 	.mtu_set                       = spnic_dev_set_mtu,
 	.vlan_filter_set               = spnic_vlan_filter_set,
 	.vlan_offload_set              = spnic_vlan_offload_set,
+	.allmulticast_enable           = spnic_dev_allmulticast_enable,
+	.allmulticast_disable          = spnic_dev_allmulticast_disable,
 	.rss_hash_update               = spnic_rss_hash_update,
 	.rss_hash_conf_get             = spnic_rss_conf_get,
 	.reta_update                   = spnic_rss_reta_update,
Signature · 1 line
2.27.0
#26 lore raw

PATCH 20/25 net/spnic: support flow control

In reply to Yanling Song

This commit implements flow control operations
to support related syscalls.

---
 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(+)
drivers/net/spnic/base/spnic_nic_cfg.c +53 -0
index 0b1198eb5f..24336a2096 100644
@@ -440,6 +440,59 @@ int spnic_flush_qps_res(void *hwdev)
 	return 0;
 }
 
+static int spnic_cfg_hw_pause(void *hwdev, u8 opcode,
+			       struct nic_pause_config *nic_pause)
+{
+	struct spnic_cmd_pause_config pause_info;
+	u16 out_size = sizeof(pause_info);
+	int err;
+
+	memset(&pause_info, 0, sizeof(pause_info));
+
+	pause_info.port_id = spnic_physical_port_id(hwdev);
+	pause_info.opcode = opcode;
+	if (opcode == SPNIC_CMD_OP_SET) {
+		pause_info.auto_neg = nic_pause->auto_neg;
+		pause_info.rx_pause = nic_pause->rx_pause;
+		pause_info.tx_pause = nic_pause->tx_pause;
+	}
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CFG_PAUSE_INFO,
+				     &pause_info, sizeof(pause_info),
+				     &pause_info, &out_size);
+	if (err || !out_size || pause_info.msg_head.status) {
+		PMD_DRV_LOG(ERR, "%s pause info failed, err: %d, status: 0x%x, out size: 0x%x\n",
+			    opcode == SPNIC_CMD_OP_SET ? "Set" : "Get",
+			    err, pause_info.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	if (opcode == SPNIC_CMD_OP_GET) {
+		nic_pause->auto_neg = pause_info.auto_neg;
+		nic_pause->rx_pause = pause_info.rx_pause;
+		nic_pause->tx_pause = pause_info.tx_pause;
+	}
+
+	return 0;
+}
+
+int spnic_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
+{
+	if (!hwdev)
+		return -EINVAL;
+
+	return spnic_cfg_hw_pause(hwdev, SPNIC_CMD_OP_SET, &nic_pause);
+}
+
+int spnic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
+{
+	if (!hwdev || !nic_pause)
+		return -EINVAL;
+
+
+	return spnic_cfg_hw_pause(hwdev, SPNIC_CMD_OP_GET, nic_pause);
+}
+
 static int spnic_set_function_table(void *hwdev, u32 cfg_bitmap,
 				     struct spnic_func_tbl_cfg *cfg)
 {
drivers/net/spnic/base/spnic_nic_cfg.h +25 -0
index 3a906b4bc3..2cdaada2ea 100644
@@ -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
drivers/net/spnic/spnic_ethdev.c +77 -0

89 lines not on this page · raw message

drivers/net/spnic/spnic_ethdev.h +1 -0
index 2b59886942..be429945ac 100644
@@ -76,6 +76,7 @@ struct spnic_nic_dev {
 
 	bool pause_set;
 	pthread_mutex_t pause_mutuex;
+	struct nic_pause_config nic_pause;
 
 	struct rte_ether_addr default_addr;
 	struct rte_ether_addr *mc_list;
Signature · 1 line
2.27.0
#27 lore raw

PATCH 21/25 net/spnic: support getting Tx/Rx queues info

In reply to Yanling Song

This patch implements rxq_info_get() and txq_info_get() to support getting queue depth and mbuf pool info of specified Tx/Rx queue.

---
 drivers/net/spnic/spnic_ethdev.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
drivers/net/spnic/spnic_ethdev.c +21 -0
index dc7fcae10f..2cd68e0178 100644
@@ -1846,6 +1846,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
  *
@@ -2065,6 +2082,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,
@@ -2092,6 +2111,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,
Signature · 1 line
2.27.0
#28 lore raw

PATCH 22/25 net/spnic: net/spnic: support xstats statistics

In reply to Yanling Song

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.

---
 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(+)
drivers/net/spnic/base/spnic_nic_cfg.c +118 -0
index 24336a2096..ce77b306db 100644
@@ -493,6 +493,124 @@ int spnic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
 	return spnic_cfg_hw_pause(hwdev, SPNIC_CMD_OP_GET, nic_pause);
 }
 
+int spnic_get_vport_stats(void *hwdev, struct spnic_vport_stats *stats)
+{
+	struct spnic_port_stats_info stats_info;
+	struct spnic_cmd_vport_stats vport_stats;
+	u16 out_size = sizeof(vport_stats);
+	int err;
+
+	if (!hwdev || !stats)
+		return -EINVAL;
+
+	memset(&stats_info, 0, sizeof(stats_info));
+	memset(&vport_stats, 0, sizeof(vport_stats));
+
+	stats_info.func_id = spnic_global_func_id(hwdev);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_GET_VPORT_STAT,
+				     &stats_info, sizeof(stats_info),
+				     &vport_stats, &out_size);
+	if (err || !out_size || vport_stats.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Get function stats failed, err: %d, status: 0x%x, out size: 0x%x",
+			    err, vport_stats.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	memcpy(stats, &vport_stats.stats, sizeof(*stats));
+
+	return 0;
+}
+
+int spnic_get_phy_port_stats(void *hwdev, struct mag_phy_port_stats *stats)
+{
+	struct mag_cmd_get_port_stat *port_stats = NULL;
+	struct mag_cmd_port_stats_info stats_info;
+	u16 out_size = sizeof(*port_stats);
+	int err;
+
+	port_stats = rte_zmalloc("port_stats", sizeof(*port_stats), 0);
+	if (!port_stats)
+		return -ENOMEM;
+
+	memset(&stats_info, 0, sizeof(stats_info));
+	stats_info.port_id = spnic_physical_port_id(hwdev);
+
+	err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT,
+				   &stats_info, sizeof(stats_info),
+				   port_stats, &out_size);
+	if (err || !out_size || port_stats->head.status) {
+		PMD_DRV_LOG(ERR,
+			"Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+			err, port_stats->head.status, out_size);
+		err = -EIO;
+		goto out;
+	}
+
+	memcpy(stats, &port_stats->counter, sizeof(*stats));
+
+out:
+	rte_free(port_stats);
+
+	return err;
+}
+
+int spnic_clear_vport_stats(void *hwdev)
+{
+	struct spnic_cmd_clear_vport_stats clear_vport_stats;
+	u16 out_size = sizeof(clear_vport_stats);
+	int err;
+
+	if (!hwdev) {
+		PMD_DRV_LOG(ERR, "Hwdev is NULL");
+		return -EINVAL;
+	}
+
+	memset(&clear_vport_stats, 0, sizeof(clear_vport_stats));
+	clear_vport_stats.func_id = spnic_global_func_id(hwdev);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CLEAN_VPORT_STAT,
+				     &clear_vport_stats,
+				     sizeof(clear_vport_stats),
+				     &clear_vport_stats, &out_size);
+	if (err || !out_size || clear_vport_stats.msg_head.status) {
+		PMD_DRV_LOG(ERR, "Clear vport stats failed, err: %d, status: 0x%x, out size: 0x%x",
+			    err, clear_vport_stats.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int spnic_clear_phy_port_stats(void *hwdev)
+{
+	struct mag_cmd_clr_port_stat *port_stats = NULL;
+	u16 out_size = sizeof(*port_stats);
+	int err;
+
+	port_stats = rte_zmalloc("port_stats", sizeof(*port_stats), 0);
+	if (!port_stats)
+		return -ENOMEM;
+
+	port_stats->port_id = spnic_physical_port_id(hwdev);
+
+	err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT,
+				   &port_stats, sizeof(port_stats),
+				   port_stats, &out_size);
+	if (err || !out_size || port_stats->head.status) {
+		PMD_DRV_LOG(ERR,
+			"Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+			err, port_stats->head.status, out_size);
+		err = -EIO;
+		goto out;
+	}
+
+out:
+	rte_free(port_stats);
+
+	return err;
+}
+
 static int spnic_set_function_table(void *hwdev, u32 cfg_bitmap,
 				     struct spnic_func_tbl_cfg *cfg)
 {
drivers/net/spnic/base/spnic_nic_cfg.h +206 -0

218 lines not on this page · raw message

drivers/net/spnic/spnic_ethdev.c +474 -0

498 lines not on this page · raw message

Signature · 1 line
2.27.0
#29 lore raw

PATCH 23/25 net/spnic: support VFIO interrupt

In reply to Yanling Song

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.

---
 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(-)
drivers/net/spnic/base/spnic_eqs.c +11 -0
index ee52252ecc..513d0329ed 100644
@@ -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);
+}
drivers/net/spnic/spnic_ethdev.c +217 -1

296 lines not on this page · raw message

drivers/net/spnic/spnic_ethdev.h +3 -0
index be429945ac..fdd0e87e62 100644
@@ -89,4 +89,7 @@ struct spnic_nic_dev {
 #define SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev) \
 	((struct spnic_nic_dev *)(dev)->data->dev_private)
 
+int spnic_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
+int spnic_dev_rx_queue_intr_disable(struct rte_eth_dev *dev,
+				     uint16_t queue_id);
 #endif /* _SPNIC_ETHDEV_H_ */
drivers/net/spnic/spnic_rx.c +2 -0
index 5af836ed41..f990d10be4 100644
@@ -610,6 +610,7 @@ int spnic_start_all_rqs(struct rte_eth_dev *eth_dev)
 		rxq = eth_dev->data->rx_queues[i];
 		spnic_add_rq_to_rx_queue_list(nic_dev, rxq->q_id);
 		spnic_rearm_rxq_mbuf(rxq);
+		spnic_dev_rx_queue_intr_enable(eth_dev, rxq->q_id);
 		eth_dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
 	}
 
@@ -628,6 +629,7 @@ int spnic_start_all_rqs(struct rte_eth_dev *eth_dev)
 		rxq = eth_dev->data->rx_queues[i];
 		spnic_remove_rq_from_rx_queue_list(nic_dev, rxq->q_id);
 		spnic_free_rxq_mbufs(rxq);
+		spnic_dev_rx_queue_intr_disable(eth_dev, rxq->q_id);
 		eth_dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
 	}
 	return err;
Signature · 1 line
2.27.0
#30 lore raw

PATCH 24/25 net/spnic: support Tx/Rx queue start/stop

In reply to Yanling Song

This commit support starting or stopping a specified Rx/Tx queue For Rx queue:
when startting 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 setted 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.

---
 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(+)
drivers/net/spnic/base/spnic_nic_cfg.c +33 -0
index ce77b306db..934f11a881 100644
@@ -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)
 {
drivers/net/spnic/base/spnic_nic_cfg.h +13 -0
index e5e4ffea4b..e4b4a52d32 100644
@@ -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
  *
drivers/net/spnic/spnic_ethdev.c +82 -0

100 lines not on this page · raw message

drivers/net/spnic/spnic_rx.c +222 -0

228 lines not on this page · raw message

drivers/net/spnic/spnic_rx.h +4 -0
index 5ae4b5f1ab..a876f75595 100644
@@ -273,6 +273,10 @@ void spnic_dump_cqe_status(struct spnic_rxq *rxq, u32 *cqe_done_cnt,
 			    u32 *cqe_hole_cnt, u32 *head_ci,
 			    u32 *head_done);
 
+int spnic_stop_rq(struct rte_eth_dev *eth_dev, struct spnic_rxq *rxq);
+
+int spnic_start_rq(struct rte_eth_dev *eth_dev, struct spnic_rxq *rxq);
+
 int spnic_start_all_rqs(struct rte_eth_dev *eth_dev);
 
 u16 spnic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, u16 nb_pkts);
Signature · 1 line
2.27.0
#31 lore raw

PATCH 25/25 net/spnic: add doc infrastructure

In reply to Yanling Song

This patch adds doc infrastructure for spnic PMD driver.

---
 MAINTAINERS                        |  6 +++
 doc/guides/nics/features/spnic.ini | 40 ++++++++++++++++++++
 doc/guides/nics/spnic.rst          | 61 ++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+)
 create mode 100644 doc/guides/nics/features/spnic.ini
 create mode 100644 doc/guides/nics/spnic.rst
MAINTAINERS +6 -0
index 18d9edaf88..12f6171aef 100644
@@ -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 <[email protected]>
+F: drivers/net/spnic/
+F: doc/guides/nics/spnic.rst
+F: doc/guides/nics/features/spnic.ini
+
 Solarflare sfc_efx
 M: Andrew Rybchenko <[email protected]>
 F: drivers/common/sfc_efx/
doc/guides/nics/features/spnic.ini new file +40 -0
new file mode 100644
index 0000000000..bdefcb451b
@@ -0,0 +1,40 @@
+;
+; 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
+Jumbo frame          = 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
\ No newline at end of file
doc/guides/nics/spnic.rst new file +61 -0

61 lines not on this page · raw message

Signature · 1 line
2.27.0