[v6,01/26] drivers/net: introduce a new PMD driver

Message ID fadff6943808766b21a2fb8c37e43310f929eb2e.1640838702.git.songyl@ramaxel.com (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers
Series Net/SPNIC: support SPNIC into DPDK 22.03 |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Yanling Song Dec. 30, 2021, 6:08 a.m. UTC
  Introduce a new PMD driver which names spnic.
Now, this driver only implements module entry
without doing anything else.

Signed-off-by: Yanling Song <songyl@ramaxel.com>
---
 drivers/net/meson.build               |   1 +
 drivers/net/spnic/base/meson.build    |  26 ++++
 drivers/net/spnic/base/spnic_compat.h | 184 ++++++++++++++++++++++++++
 drivers/net/spnic/meson.build         |  17 +++
 drivers/net/spnic/spnic_ethdev.c      | 107 +++++++++++++++
 drivers/net/spnic/spnic_ethdev.h      |  28 ++++
 drivers/net/spnic/version.map         |   3 +
 7 files changed, 366 insertions(+)
 create mode 100644 drivers/net/spnic/base/meson.build
 create mode 100644 drivers/net/spnic/base/spnic_compat.h
 create mode 100644 drivers/net/spnic/meson.build
 create mode 100644 drivers/net/spnic/spnic_ethdev.c
 create mode 100644 drivers/net/spnic/spnic_ethdev.h
 create mode 100644 drivers/net/spnic/version.map
  

Comments

Ferruh Yigit Jan. 19, 2022, 4:58 p.m. UTC | #1
On 12/30/2021 6:08 AM, Yanling Song wrote:
> Introduce a new PMD driver which names spnic.

PMD stands for "Poll mode driver", so "PMD driver" usage is wrong,
can you please update it in the patch title too?

Also domain for patch title can be "net/spnic: ".

> Now, this driver only implements module entry
> without doing anything else.
> 
> Signed-off-by: Yanling Song <songyl@ramaxel.com>
> ---
>   drivers/net/meson.build               |   1 +
>   drivers/net/spnic/base/meson.build    |  26 ++++
>   drivers/net/spnic/base/spnic_compat.h | 184 ++++++++++++++++++++++++++
>   drivers/net/spnic/meson.build         |  17 +++
>   drivers/net/spnic/spnic_ethdev.c      | 107 +++++++++++++++
>   drivers/net/spnic/spnic_ethdev.h      |  28 ++++
>   drivers/net/spnic/version.map         |   3 +
>   7 files changed, 366 insertions(+)
>   create mode 100644 drivers/net/spnic/base/meson.build
>   create mode 100644 drivers/net/spnic/base/spnic_compat.h
>   create mode 100644 drivers/net/spnic/meson.build
>   create mode 100644 drivers/net/spnic/spnic_ethdev.c
>   create mode 100644 drivers/net/spnic/spnic_ethdev.h
>   create mode 100644 drivers/net/spnic/version.map


Can you please add/update following files in this first patch:
- MAINTAINERS (sorted by vendor name)
- doc/guides/nics/spnic.rst
- doc/guides/nics/features/spnic.ini
- doc/guides/nics/index.rst
- doc/guides/rel_notes/release_22_03.rst

Most of them are already in the patch 25/26, so please squash it in this patch,
and I put some comment on the documentation.

> 
> diff --git a/drivers/net/meson.build b/drivers/net/meson.build
> index 2355d1cde8..a5c715f59c 100644
> --- a/drivers/net/meson.build
> +++ b/drivers/net/meson.build
> @@ -53,6 +53,7 @@ drivers = [
>           'ring',
>           'sfc',
>           'softnic',
> +	'spnic',

The indentation in the meson files needs to be fixed, please run 'check-meson.py'
Comment is valid for all meson file updates in other patches.

$ ./devtools/check-meson.py
Error parsing drivers/net/meson.build:54, got some tabulation
Error: Incorrect indent at drivers/net/meson.build:55
Error parsing drivers/net/spnic/meson.build:13, got some tabulation
Error: Incorrect indent at drivers/net/spnic/meson.build:14
Error parsing drivers/net/spnic/meson.build:14, got some tabulation
Error parsing drivers/net/spnic/base/meson.build:23, got some tabulation
Error parsing drivers/net/spnic/base/meson.build:24, got some tabulation


>           'tap',
>           'thunderx',
>           'txgbe',
> diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build
> new file mode 100644
> index 0000000000..e83a473881
> --- /dev/null
> +++ b/drivers/net/spnic/base/meson.build
> @@ -0,0 +1,26 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2021 Ramaxel Memory Technology, Ltd
> +
> +sources = [
> +]
> +
> +extra_flags = []
> +# The driver runs only on arch64 machine, remove 32bit warnings
> +if not dpdk_conf.get('RTE_ARCH_64')
> +        extra_flags += ['-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast']
> +endif

Why disabling compiler warning even without having any source file.
Please start with empty meson file, and develop it as needed.

> +
> +foreach flag: extra_flags
> +        if cc.has_argument(flag)
> +                cflags += flag
> +        endif
> +endforeach
> +
> +deps += ['hash']
> +cflags += ['-DHW_CONVERT_ENDIAN']
> +c_args = cflags

ditto

> +
> +base_lib = static_library('spnic_base', sources,
> +	dependencies: [static_rte_eal, static_rte_ethdev, static_rte_bus_pci, static_rte_hash],
> +	c_args: c_args)
> +base_objs = base_lib.extract_all_objects()
> diff --git a/drivers/net/spnic/base/spnic_compat.h b/drivers/net/spnic/base/spnic_compat.h
> new file mode 100644
> index 0000000000..97f817cba9
> --- /dev/null
> +++ b/drivers/net/spnic/base/spnic_compat.h
> @@ -0,0 +1,184 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2021 Ramaxel Memory Technology, Ltd
> + */
> +
> +#ifndef _SPNIC_COMPAT_H_
> +#define _SPNIC_COMPAT_H_
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <sys/time.h>
> +#include <unistd.h>
> +#include <pthread.h>
> +#include <rte_common.h>
> +#include <rte_byteorder.h>
> +#include <rte_memzone.h>
> +#include <rte_memcpy.h>
> +#include <rte_malloc.h>
> +#include <rte_atomic.h>
> +#include <rte_spinlock.h>
> +#include <rte_cycles.h>
> +#include <rte_log.h>
> +#include <rte_config.h>
> +#include <rte_io.h>
> +

Do you need to include all these headers at this stage?
Can you please add them as needed?

> +typedef uint8_t   u8;
> +typedef int8_t    s8;
> +typedef uint16_t  u16;
> +typedef uint32_t  u32;
> +typedef int32_t   s32;
> +typedef uint64_t  u64;
> +
> +#ifndef BIT
> +#define BIT(n) (1 << (n))
> +#endif
> +

There is already RTE_BIT64 / RTE_BIT32 in DPDK, those can be used.


> +#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
> +#define lower_32_bits(n) ((u32)(n))
> +
> +#define SPNIC_MEM_ALLOC_ALIGN_MIN	1
> +
> +#define SPNIC_DRIVER_NAME "spnic"
> +
> +extern int spnic_logtype;
> +
> +#define PMD_DRV_LOG(level, fmt, args...) \
> +	rte_log(RTE_LOG_ ## level, spnic_logtype, \
> +		SPNIC_DRIVER_NAME ": " fmt "\n", ##args)
> +
> +/* Bit order interface */
> +#define cpu_to_be16(o) rte_cpu_to_be_16(o)
> +#define cpu_to_be32(o) rte_cpu_to_be_32(o)
> +#define cpu_to_be64(o) rte_cpu_to_be_64(o)
> +#define cpu_to_le32(o) rte_cpu_to_le_32(o)
> +#define be16_to_cpu(o) rte_be_to_cpu_16(o)
> +#define be32_to_cpu(o) rte_be_to_cpu_32(o)
> +#define be64_to_cpu(o) rte_be_to_cpu_64(o)
> +#define le32_to_cpu(o) rte_le_to_cpu_32(o)
> +
> +#define ARRAY_LEN(arr) ((sizeof(arr) / sizeof((arr)[0])))
> +

There is DPDK 'RTE_DIM' for it.

> +#define SPNIC_MUTEX_TIMEOUT	10
> +#define SPNIC_S_TO_MS_UNIT	1000
> +#define SPNIC_S_TO_NS_UNIT	1000000
> +
> +static inline unsigned long clock_gettime_ms(void)
> +{
> +	struct timespec tv;
> +
> +	(void)clock_gettime(CLOCK_MONOTONIC_COARSE, &tv);
> +
> +	return (unsigned long)tv.tv_sec * SPNIC_S_TO_MS_UNIT +
> +	       (unsigned long)tv.tv_nsec / SPNIC_S_TO_NS_UNIT;
> +}
> +
> +#define jiffies	clock_gettime_ms()

Is 'jiffies' used at all?

<...>

> +
> +RTE_INIT(spnic_init_log)
> +{
> +	spnic_logtype = rte_log_register("pmd.net.spnic");
> +	if (spnic_logtype >= 0)
> +		rte_log_set_level(spnic_logtype, RTE_LOG_INFO);
> +}

Can you please use 'RTE_LOG_REGISTER_DEFAULT' macro instead?

<...>
  

Patch

diff --git a/drivers/net/meson.build b/drivers/net/meson.build
index 2355d1cde8..a5c715f59c 100644
--- a/drivers/net/meson.build
+++ b/drivers/net/meson.build
@@ -53,6 +53,7 @@  drivers = [
         'ring',
         'sfc',
         'softnic',
+	'spnic',
         'tap',
         'thunderx',
         'txgbe',
diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build
new file mode 100644
index 0000000000..e83a473881
--- /dev/null
+++ b/drivers/net/spnic/base/meson.build
@@ -0,0 +1,26 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+
+sources = [
+]
+
+extra_flags = []
+# The driver runs only on arch64 machine, remove 32bit warnings
+if not dpdk_conf.get('RTE_ARCH_64')
+        extra_flags += ['-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast']
+endif
+
+foreach flag: extra_flags
+        if cc.has_argument(flag)
+                cflags += flag
+        endif
+endforeach
+
+deps += ['hash']
+cflags += ['-DHW_CONVERT_ENDIAN']
+c_args = cflags
+
+base_lib = static_library('spnic_base', sources,
+	dependencies: [static_rte_eal, static_rte_ethdev, static_rte_bus_pci, static_rte_hash],
+	c_args: c_args)
+base_objs = base_lib.extract_all_objects()
diff --git a/drivers/net/spnic/base/spnic_compat.h b/drivers/net/spnic/base/spnic_compat.h
new file mode 100644
index 0000000000..97f817cba9
--- /dev/null
+++ b/drivers/net/spnic/base/spnic_compat.h
@@ -0,0 +1,184 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+ */
+
+#ifndef _SPNIC_COMPAT_H_
+#define _SPNIC_COMPAT_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_malloc.h>
+#include <rte_atomic.h>
+#include <rte_spinlock.h>
+#include <rte_cycles.h>
+#include <rte_log.h>
+#include <rte_config.h>
+#include <rte_io.h>
+
+typedef uint8_t   u8;
+typedef int8_t    s8;
+typedef uint16_t  u16;
+typedef uint32_t  u32;
+typedef int32_t   s32;
+typedef uint64_t  u64;
+
+#ifndef BIT
+#define BIT(n) (1 << (n))
+#endif
+
+#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
+#define lower_32_bits(n) ((u32)(n))
+
+#define SPNIC_MEM_ALLOC_ALIGN_MIN	1
+
+#define SPNIC_DRIVER_NAME "spnic"
+
+extern int spnic_logtype;
+
+#define PMD_DRV_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, spnic_logtype, \
+		SPNIC_DRIVER_NAME ": " fmt "\n", ##args)
+
+/* Bit order interface */
+#define cpu_to_be16(o) rte_cpu_to_be_16(o)
+#define cpu_to_be32(o) rte_cpu_to_be_32(o)
+#define cpu_to_be64(o) rte_cpu_to_be_64(o)
+#define cpu_to_le32(o) rte_cpu_to_le_32(o)
+#define be16_to_cpu(o) rte_be_to_cpu_16(o)
+#define be32_to_cpu(o) rte_be_to_cpu_32(o)
+#define be64_to_cpu(o) rte_be_to_cpu_64(o)
+#define le32_to_cpu(o) rte_le_to_cpu_32(o)
+
+#define ARRAY_LEN(arr) ((sizeof(arr) / sizeof((arr)[0])))
+
+#define SPNIC_MUTEX_TIMEOUT	10
+#define SPNIC_S_TO_MS_UNIT	1000
+#define SPNIC_S_TO_NS_UNIT	1000000
+
+static inline unsigned long clock_gettime_ms(void)
+{
+	struct timespec tv;
+
+	(void)clock_gettime(CLOCK_MONOTONIC_COARSE, &tv);
+
+	return (unsigned long)tv.tv_sec * SPNIC_S_TO_MS_UNIT +
+	       (unsigned long)tv.tv_nsec / SPNIC_S_TO_NS_UNIT;
+}
+
+#define jiffies	clock_gettime_ms()
+#define msecs_to_jiffies(ms)	(ms)
+
+#define time_after(a, b)	((long)((b) - (a)) < 0)
+#define time_before(a, b)	time_after(b, a)
+
+/**
+ * Convert data to big endian 32 bit format
+ *
+ * @param data
+ *   The data to convert
+ * @param len
+ *   Length of data to convert, must be Multiple of 4B
+ */
+static inline void spnic_cpu_to_be32(void *data, int len)
+{
+	int i, chunk_sz = sizeof(u32);
+	u32 *mem = data;
+
+	if (!data)
+		return;
+
+	len = len / chunk_sz;
+
+	for (i = 0; i < len; i++) {
+		*mem = cpu_to_be32(*mem);
+		mem++;
+	}
+}
+
+/**
+ * Convert data from big endian 32 bit format
+ *
+ * @param data
+ *   The data to convert
+ * @param len
+ *   Length of data to convert, must be Multiple of 4B
+ */
+static inline void spnic_be32_to_cpu(void *data, int len)
+{
+	int i, chunk_sz = sizeof(u32);
+	u32 *mem = data;
+
+	if (!data)
+		return;
+
+	len = len / chunk_sz;
+
+	for (i = 0; i < len; i++) {
+		*mem = be32_to_cpu(*mem);
+		mem++;
+	}
+}
+
+static inline u16 ilog2(u32 n)
+{
+	u16 res = 0;
+
+	while (n > 1) {
+		n >>= 1;
+		res++;
+	}
+
+	return res;
+}
+
+static inline int spnic_mutex_init(pthread_mutex_t *pthreadmutex,
+				   const pthread_mutexattr_t *mattr)
+{
+	int err;
+
+	err = pthread_mutex_init(pthreadmutex, mattr);
+	if (unlikely(err))
+		PMD_DRV_LOG(ERR, "Initialize mutex failed, error: %d", err);
+
+	return err;
+}
+
+static inline int spnic_mutex_destroy(pthread_mutex_t *pthreadmutex)
+{
+	int err;
+
+	err = pthread_mutex_destroy(pthreadmutex);
+	if (unlikely(err))
+		PMD_DRV_LOG(ERR, "Destroy mutex failed, error: %d", err);
+
+	return err;
+}
+
+static inline int spnic_mutex_lock(pthread_mutex_t *pthreadmutex)
+{
+	struct timespec tout;
+	int err;
+
+	(void)clock_gettime(CLOCK_MONOTONIC_COARSE, &tout);
+
+	tout.tv_sec += SPNIC_MUTEX_TIMEOUT;
+	err = pthread_mutex_timedlock(pthreadmutex, &tout);
+	if (err)
+		PMD_DRV_LOG(ERR, "Mutex lock failed, err: %d", err);
+
+	return err;
+}
+
+static inline int spnic_mutex_unlock(pthread_mutex_t *pthreadmutex)
+{
+	return pthread_mutex_unlock(pthreadmutex);
+}
+
+#endif /* _SPNIC_COMPAT_H_ */
diff --git a/drivers/net/spnic/meson.build b/drivers/net/spnic/meson.build
new file mode 100644
index 0000000000..c585aaf7f6
--- /dev/null
+++ b/drivers/net/spnic/meson.build
@@ -0,0 +1,17 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+
+if not (is_linux)
+    build = false
+    reason = 'only supported on Linux'
+    subdir_done()
+endif
+
+subdir('base')
+objs = [base_objs]
+
+sources = files(
+	'spnic_ethdev.c',
+	)
+
+includes += include_directories('base')
diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c
new file mode 100644
index 0000000000..b06492a8e9
--- /dev/null
+++ b/drivers/net/spnic/spnic_ethdev.c
@@ -0,0 +1,107 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+ */
+
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <ethdev_pci.h>
+#include <rte_errno.h>
+#include <rte_ether.h>
+
+#include "base/spnic_compat.h"
+#include "spnic_ethdev.h"
+
+/* Driver-specific log messages type */
+int spnic_logtype;
+
+static int spnic_func_init(struct rte_eth_dev *eth_dev)
+{
+	struct spnic_nic_dev *nic_dev = NULL;
+	struct rte_pci_device *pci_dev = NULL;
+
+	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+
+	/* EAL is secondary and eth_dev is already created */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+		PMD_DRV_LOG(INFO, "Initialize %s in secondary process",
+			    eth_dev->data->name);
+
+		return 0;
+	}
+
+	nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
+	snprintf(nic_dev->dev_name, sizeof(nic_dev->dev_name),
+		 "spnic-%.4x:%.2x:%.2x.%x",
+		 pci_dev->addr.domain, pci_dev->addr.bus,
+		 pci_dev->addr.devid, pci_dev->addr.function);
+
+	rte_bit_relaxed_set32(SPNIC_DEV_INIT, &nic_dev->dev_status);
+	PMD_DRV_LOG(INFO, "Initialize %s in primary succeed",
+		    eth_dev->data->name);
+
+	return 0;
+}
+
+static int spnic_dev_init(struct rte_eth_dev *eth_dev)
+{
+	struct rte_pci_device *pci_dev;
+
+	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+
+	PMD_DRV_LOG(INFO, "Initializing spnic-%.4x:%.2x:%.2x.%x in %s process",
+		    pci_dev->addr.domain, pci_dev->addr.bus,
+		    pci_dev->addr.devid, pci_dev->addr.function,
+		    (rte_eal_process_type() == RTE_PROC_PRIMARY) ?
+		    "primary" : "secondary");
+
+	return spnic_func_init(eth_dev);
+}
+
+static int spnic_dev_uninit(struct rte_eth_dev *dev)
+{
+	struct spnic_nic_dev *nic_dev;
+
+	nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+	rte_bit_relaxed_clear32(SPNIC_DEV_INIT, &nic_dev->dev_status);
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	return 0;
+}
+
+static struct rte_pci_id pci_id_spnic_map[] = {
+	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_RAMAXEL, SPNIC_DEV_ID_PF) },
+	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_RAMAXEL, SPNIC_DEV_ID_VF) },
+	{.vendor_id = 0},
+};
+
+static int spnic_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
+			   struct rte_pci_device *pci_dev)
+{
+	return rte_eth_dev_pci_generic_probe(pci_dev,
+					     sizeof(struct spnic_nic_dev),
+					     spnic_dev_init);
+}
+
+static int spnic_pci_remove(struct rte_pci_device *pci_dev)
+{
+	return rte_eth_dev_pci_generic_remove(pci_dev, spnic_dev_uninit);
+}
+
+static struct rte_pci_driver rte_spnic_pmd = {
+	.id_table = pci_id_spnic_map,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
+	.probe = spnic_pci_probe,
+	.remove = spnic_pci_remove,
+};
+
+RTE_PMD_REGISTER_PCI(net_spnic, rte_spnic_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(net_spnic, pci_id_spnic_map);
+
+RTE_INIT(spnic_init_log)
+{
+	spnic_logtype = rte_log_register("pmd.net.spnic");
+	if (spnic_logtype >= 0)
+		rte_log_set_level(spnic_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/net/spnic/spnic_ethdev.h b/drivers/net/spnic/spnic_ethdev.h
new file mode 100644
index 0000000000..d4ec641d83
--- /dev/null
+++ b/drivers/net/spnic/spnic_ethdev.h
@@ -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_ */
diff --git a/drivers/net/spnic/version.map b/drivers/net/spnic/version.map
new file mode 100644
index 0000000000..c2e0723b4c
--- /dev/null
+++ b/drivers/net/spnic/version.map
@@ -0,0 +1,3 @@ 
+DPDK_22 {
+	local: *;
+};