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?
<...>
@@ -53,6 +53,7 @@ drivers = [
'ring',
'sfc',
'softnic',
+ 'spnic',
'tap',
'thunderx',
'txgbe',
new file mode 100644
@@ -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()
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -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')
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -0,0 +1,3 @@
+DPDK_22 {
+ local: *;
+};