[v2,1/9] crypto/ionic: introduce AMD Pensando ionic crypto driver

Message ID 20240430202144.49899-2-andrew.boyer@amd.com (mailing list archive)
State New
Delegated to: akhil goyal
Headers
Series crypto/ionic: introduce AMD Pensando ionic crypto driver |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Andrew Boyer April 30, 2024, 8:21 p.m. UTC
  Introduce a new crypto PMD for AMD Pensando hardware accelerators. It
allows applications running directly on the AMD Pensando DSC to offload
cryptographic operations to hardware cryptographic blocks.

Add support for the cryptodevs to the common ionic library.
Add the driver skeleton.
Add a skeleton features list and guide.
Hook the new PMD up to the build.
Update MAINTAINERS.

Signed-off-by: Andrew Boyer <andrew.boyer@amd.com>
---
 MAINTAINERS                              |   7 ++
 doc/guides/cryptodevs/features/ionic.ini |  32 +++++
 doc/guides/cryptodevs/index.rst          |   1 +
 doc/guides/cryptodevs/ionic.rst          |  28 +++++
 drivers/common/ionic/ionic_common.h      |   2 +
 drivers/common/ionic/ionic_common_uio.c  |  48 +++++++-
 drivers/common/ionic/version.map         |   1 +
 drivers/crypto/ionic/ionic_crypto.h      |  92 ++++++++++++++
 drivers/crypto/ionic/ionic_crypto_main.c | 148 +++++++++++++++++++++++
 drivers/crypto/ionic/ionic_crypto_vdev.c |  91 ++++++++++++++
 drivers/crypto/ionic/meson.build         |  13 ++
 drivers/crypto/meson.build               |   1 +
 12 files changed, 463 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/cryptodevs/features/ionic.ini
 create mode 100644 doc/guides/cryptodevs/ionic.rst
 create mode 100644 drivers/crypto/ionic/ionic_crypto.h
 create mode 100644 drivers/crypto/ionic/ionic_crypto_main.c
 create mode 100644 drivers/crypto/ionic/ionic_crypto_vdev.c
 create mode 100644 drivers/crypto/ionic/meson.build
  

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 7abb3aee49..7cf999371c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1075,6 +1075,13 @@  F: drivers/crypto/ccp/
 F: doc/guides/cryptodevs/ccp.rst
 F: doc/guides/cryptodevs/features/ccp.ini
 
+AMD Pensando ionic crypto
+M: Andrew Boyer <andrew.boyer@amd.com>
+F: drivers/crypto/ionic/
+F: drivers/common/ionic/
+F: doc/guides/cryptodevs/ionic.rst
+F: doc/guides/cryptodevs/features/ionic.ini
+
 ARMv8 Crypto
 M: Ruifeng Wang <ruifeng.wang@arm.com>
 F: drivers/crypto/armv8/
diff --git a/doc/guides/cryptodevs/features/ionic.ini b/doc/guides/cryptodevs/features/ionic.ini
new file mode 100644
index 0000000000..62b7e9e8f2
--- /dev/null
+++ b/doc/guides/cryptodevs/features/ionic.ini
@@ -0,0 +1,32 @@ 
+;
+; Supported features of the 'ionic' crypto driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+
+;
+; Supported crypto algorithms of 'ionic' crypto driver.
+;
+[Cipher]
+
+;
+; Supported authentication algorithms of 'ionic' crypto driver.
+;
+[Auth]
+
+;
+; Supported AEAD algorithms of 'ionic' crypto driver.
+;
+[AEAD]
+
+;
+; Supported Asymmetric algorithms of the 'ionic' crypto driver.
+;
+[Asymmetric]
+
+;
+; Supported Operating systems of the 'ionic' crypto driver.
+;
+[OS]
+Linux = Y
diff --git a/doc/guides/cryptodevs/index.rst b/doc/guides/cryptodevs/index.rst
index cb4ce227e9..1e57a9fe86 100644
--- a/doc/guides/cryptodevs/index.rst
+++ b/doc/guides/cryptodevs/index.rst
@@ -20,6 +20,7 @@  Crypto Device Drivers
     cnxk
     dpaa2_sec
     dpaa_sec
+    ionic
     kasumi
     octeontx
     openssl
diff --git a/doc/guides/cryptodevs/ionic.rst b/doc/guides/cryptodevs/ionic.rst
new file mode 100644
index 0000000000..c9173deb2f
--- /dev/null
+++ b/doc/guides/cryptodevs/ionic.rst
@@ -0,0 +1,28 @@ 
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2021-2024 Advanced Micro Devices, Inc.
+
+IONIC Crypto Driver
+===================
+
+The ionic crypto driver provides support for offloading cryptographic operations
+to hardware cryptographic blocks on AMD Pensando server adapters.
+It currently supports the below models:
+
+- DSC-25 dual-port 25G Distributed Services Card `(pdf) <https://pensandoio.secure.force.com/DownloadFile?id=a0L4T000004IKurUAG>`__
+- DSC-100 dual-port 100G Distributed Services Card `(pdf) <https://pensandoio.secure.force.com/DownloadFile?id=a0L4T000004IKuwUAG>`__
+- DSC-200 dual-port 200G Distributed Services Card `(pdf) <https://www.amd.com/system/files/documents/pensando-dsc-200-product-brief.pdf>`__
+
+Please visit the AMD Pensando web site at https://www.amd.com/en/accelerators/pensando for more information.
+
+Device Support
+--------------
+
+The ionic crypto PMD currently supports running directly on the device's embedded
+processors. It does not yet support host-side access via PCI.
+For help running the PMD, please contact AMD Pensando support.
+
+Runtime Configuration
+---------------------
+
+None
+
diff --git a/drivers/common/ionic/ionic_common.h b/drivers/common/ionic/ionic_common.h
index eb4850e24c..c4a15fdf2b 100644
--- a/drivers/common/ionic/ionic_common.h
+++ b/drivers/common/ionic/ionic_common.h
@@ -32,6 +32,8 @@  struct ionic_dev_bar {
 
 __rte_internal
 void ionic_uio_scan_mnet_devices(void);
+__rte_internal
+void ionic_uio_scan_mcrypt_devices(void);
 
 __rte_internal
 void ionic_uio_get_rsrc(const char *name, int idx, struct ionic_dev_bar *bar);
diff --git a/drivers/common/ionic/ionic_common_uio.c b/drivers/common/ionic/ionic_common_uio.c
index e5c73faf96..c647b22eaf 100644
--- a/drivers/common/ionic/ionic_common_uio.c
+++ b/drivers/common/ionic/ionic_common_uio.c
@@ -23,10 +23,12 @@ 
 
 #define IONIC_MDEV_UNK      "mdev_unknown"
 #define IONIC_MNIC          "cpu_mnic"
+#define IONIC_MCRYPT        "cpu_mcrypt"
 
 #define IONIC_MAX_NAME_LEN  20
 #define IONIC_MAX_MNETS     5
-#define IONIC_MAX_DEVICES   (IONIC_MAX_MNETS)
+#define IONIC_MAX_MCPTS     1
+#define IONIC_MAX_DEVICES   (IONIC_MAX_MNETS + IONIC_MAX_MCPTS)
 #define IONIC_MAX_U16_IDX   0xFFFF
 #define IONIC_UIO_MAX_TRIES 32
 
@@ -49,6 +51,7 @@  struct ionic_map_tbl ionic_mdev_map[IONIC_MAX_DEVICES] = {
 	{ "net_ionic2", 2, IONIC_MAX_U16_IDX, IONIC_MDEV_UNK },
 	{ "net_ionic3", 3, IONIC_MAX_U16_IDX, IONIC_MDEV_UNK },
 	{ "net_ionic4", 4, IONIC_MAX_U16_IDX, IONIC_MDEV_UNK },
+	{ "crypto_ionic0", 5, IONIC_MAX_U16_IDX, IONIC_MDEV_UNK },
 };
 
 struct uio_name {
@@ -143,6 +146,49 @@  ionic_uio_scan_mnet_devices(void)
 	}
 }
 
+void
+ionic_uio_scan_mcrypt_devices(void)
+{
+	struct ionic_map_tbl *map;
+	char devname[IONIC_MAX_NAME_LEN];
+	struct uio_name name_cache[IONIC_MAX_DEVICES];
+	bool done;
+	int mdev_idx = 0;
+	int uio_idx;
+	int i;
+	static bool scan_done;
+
+	if (scan_done)
+		return;
+
+	scan_done = true;
+
+	uio_fill_name_cache(name_cache, IONIC_MCRYPT);
+
+	for (i = IONIC_MAX_MNETS; i < IONIC_MAX_DEVICES; i++) {
+		done = false;
+
+		while (!done) {
+			if (mdev_idx > IONIC_MAX_MDEV_SCAN)
+				break;
+
+			/* Look for a matching mcrypt */
+			snprintf(devname, IONIC_MAX_NAME_LEN,
+				IONIC_MCRYPT "%d", mdev_idx);
+			uio_idx = uio_get_idx_for_devname(name_cache, devname);
+			if (uio_idx >= 0) {
+				map = &ionic_mdev_map[i];
+				map->uio_idx = (uint16_t)uio_idx;
+				strlcpy(map->mdev_name, devname,
+					IONIC_MAX_NAME_LEN);
+				done = true;
+			}
+
+			mdev_idx++;
+		}
+	}
+}
+
 static int
 uio_get_multi_dev_uionum(const char *name)
 {
diff --git a/drivers/common/ionic/version.map b/drivers/common/ionic/version.map
index 484330c437..db532d4ffc 100644
--- a/drivers/common/ionic/version.map
+++ b/drivers/common/ionic/version.map
@@ -2,6 +2,7 @@  INTERNAL {
 	global:
 
 	ionic_uio_scan_mnet_devices;
+	ionic_uio_scan_mcrypt_devices;
 	ionic_uio_get_rsrc;
 	ionic_uio_rel_rsrc;
 
diff --git a/drivers/crypto/ionic/ionic_crypto.h b/drivers/crypto/ionic/ionic_crypto.h
new file mode 100644
index 0000000000..86750f0cbd
--- /dev/null
+++ b/drivers/crypto/ionic/ionic_crypto.h
@@ -0,0 +1,92 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021-2024 Advanced Micro Devices, Inc.
+ */
+
+#ifndef _IONIC_CRYPTO_H_
+#define _IONIC_CRYPTO_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include <rte_common.h>
+#include <rte_dev.h>
+#include <rte_cryptodev.h>
+#include <cryptodev_pmd.h>
+#include <rte_log.h>
+
+#include "ionic_common.h"
+#include "ionic_regs.h"
+
+/* Devargs */
+/* NONE */
+
+extern int iocpt_logtype;
+#define RTE_LOGTYPE_IOCPT iocpt_logtype
+
+#define IOCPT_PRINT(level, ...)						\
+	RTE_LOG_LINE_PREFIX(level, IOCPT, "%s(): ", __func__, __VA_ARGS__)
+
+#define IOCPT_PRINT_CALL() IOCPT_PRINT(DEBUG, " >>")
+
+struct iocpt_dev_bars {
+	struct ionic_dev_bar bar[IONIC_BARS_MAX];
+	uint32_t num_bars;
+};
+
+#define IOCPT_DEV_F_INITED		BIT(0)
+#define IOCPT_DEV_F_UP			BIT(1)
+#define IOCPT_DEV_F_FW_RESET		BIT(2)
+
+/* Combined dev / LIF object */
+struct iocpt_dev {
+	const char *name;
+	struct iocpt_dev_bars bars;
+
+	const struct iocpt_dev_intf *intf;
+	void *bus_dev;
+	struct rte_cryptodev *crypto_dev;
+
+	uint32_t max_qps;
+	uint32_t max_sessions;
+	uint16_t state;
+	uint8_t driver_id;
+	uint8_t socket_id;
+
+	uint64_t features;
+	uint32_t hw_features;
+};
+
+struct iocpt_dev_intf {
+	int  (*setup_bars)(struct iocpt_dev *dev);
+	void (*unmap_bars)(struct iocpt_dev *dev);
+};
+
+static inline int
+iocpt_setup_bars(struct iocpt_dev *dev)
+{
+	if (dev->intf->setup_bars == NULL)
+		return -EINVAL;
+
+	return (*dev->intf->setup_bars)(dev);
+}
+
+int iocpt_probe(void *bus_dev, struct rte_device *rte_dev,
+	struct iocpt_dev_bars *bars, const struct iocpt_dev_intf *intf,
+	uint8_t driver_id, uint8_t socket_id);
+int iocpt_remove(struct rte_device *rte_dev);
+
+void iocpt_configure(struct iocpt_dev *dev);
+void iocpt_deinit(struct iocpt_dev *dev);
+
+static inline bool
+iocpt_is_embedded(void)
+{
+#if defined(RTE_LIBRTE_IONIC_PMD_EMBEDDED)
+	return true;
+#else
+	return false;
+#endif
+}
+
+#endif /* _IONIC_CRYPTO_H_ */
diff --git a/drivers/crypto/ionic/ionic_crypto_main.c b/drivers/crypto/ionic/ionic_crypto_main.c
new file mode 100644
index 0000000000..ecbb1cb161
--- /dev/null
+++ b/drivers/crypto/ionic/ionic_crypto_main.c
@@ -0,0 +1,148 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021-2024 Advanced Micro Devices, Inc.
+ */
+
+#include <inttypes.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_bitops.h>
+
+#include "ionic_crypto.h"
+
+static int
+iocpt_init(struct iocpt_dev *dev)
+{
+	dev->state |= IOCPT_DEV_F_INITED;
+
+	return 0;
+}
+
+void
+iocpt_configure(struct iocpt_dev *dev)
+{
+	RTE_SET_USED(dev);
+}
+
+void
+iocpt_deinit(struct iocpt_dev *dev)
+{
+	IOCPT_PRINT_CALL();
+
+	if (!(dev->state & IOCPT_DEV_F_INITED))
+		return;
+
+	dev->state &= ~IOCPT_DEV_F_INITED;
+}
+
+static int
+iocpt_devargs(struct rte_devargs *devargs, struct iocpt_dev *dev)
+{
+	RTE_SET_USED(devargs);
+	RTE_SET_USED(dev);
+
+	return 0;
+}
+
+int
+iocpt_probe(void *bus_dev, struct rte_device *rte_dev,
+	struct iocpt_dev_bars *bars, const struct iocpt_dev_intf *intf,
+	uint8_t driver_id, uint8_t socket_id)
+{
+	struct rte_cryptodev_pmd_init_params init_params = {
+		"iocpt",
+		sizeof(struct iocpt_dev),
+		socket_id,
+		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
+	};
+	struct rte_cryptodev *cdev;
+	struct iocpt_dev *dev;
+	uint32_t i;
+	int err;
+
+	/* Multi-process not supported */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+		err = -EPERM;
+		goto err;
+	}
+
+	cdev = rte_cryptodev_pmd_create(rte_dev->name, rte_dev, &init_params);
+	if (cdev == NULL) {
+		IOCPT_PRINT(ERR, "OOM");
+		err = -ENOMEM;
+		goto err;
+	}
+
+	dev = cdev->data->dev_private;
+	dev->crypto_dev = cdev;
+	dev->bus_dev = bus_dev;
+	dev->intf = intf;
+	dev->driver_id = driver_id;
+	dev->socket_id = socket_id;
+
+	for (i = 0; i < bars->num_bars; i++) {
+		struct ionic_dev_bar *bar = &bars->bar[i];
+
+		IOCPT_PRINT(DEBUG,
+			"bar[%u] = { .va = %p, .pa = %#jx, .len = %lu }",
+			i, bar->vaddr, bar->bus_addr, bar->len);
+		if (bar->vaddr == NULL) {
+			IOCPT_PRINT(ERR, "Null bar found, aborting");
+			err = -EFAULT;
+			goto err_destroy_crypto_dev;
+		}
+
+		dev->bars.bar[i].vaddr = bar->vaddr;
+		dev->bars.bar[i].bus_addr = bar->bus_addr;
+		dev->bars.bar[i].len = bar->len;
+	}
+	dev->bars.num_bars = bars->num_bars;
+
+	err = iocpt_devargs(rte_dev->devargs, dev);
+	if (err != 0) {
+		IOCPT_PRINT(ERR, "Cannot parse device arguments");
+		goto err_destroy_crypto_dev;
+	}
+
+	err = iocpt_setup_bars(dev);
+	if (err != 0) {
+		IOCPT_PRINT(ERR, "Cannot setup BARs: %d, aborting", err);
+		goto err_destroy_crypto_dev;
+	}
+
+	err = iocpt_init(dev);
+	if (err != 0) {
+		IOCPT_PRINT(ERR, "Cannot init device: %d, aborting", err);
+		goto err_destroy_crypto_dev;
+	}
+
+	return 0;
+
+err_destroy_crypto_dev:
+	rte_cryptodev_pmd_destroy(cdev);
+err:
+	return err;
+}
+
+int
+iocpt_remove(struct rte_device *rte_dev)
+{
+	struct rte_cryptodev *cdev;
+	struct iocpt_dev *dev;
+
+	cdev = rte_cryptodev_pmd_get_named_dev(rte_dev->name);
+	if (cdev == NULL) {
+		IOCPT_PRINT(DEBUG, "Cannot find device %s", rte_dev->name);
+		return -ENODEV;
+	}
+
+	dev = cdev->data->dev_private;
+
+	iocpt_deinit(dev);
+
+	rte_cryptodev_pmd_destroy(cdev);
+
+	return 0;
+}
+
+RTE_LOG_REGISTER_DEFAULT(iocpt_logtype, NOTICE);
diff --git a/drivers/crypto/ionic/ionic_crypto_vdev.c b/drivers/crypto/ionic/ionic_crypto_vdev.c
new file mode 100644
index 0000000000..a915aa06aa
--- /dev/null
+++ b/drivers/crypto/ionic/ionic_crypto_vdev.c
@@ -0,0 +1,91 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021-2024 Advanced Micro Devices, Inc.
+ */
+
+#include <stdint.h>
+#include <errno.h>
+
+#include <rte_errno.h>
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_eal.h>
+#include <bus_vdev_driver.h>
+#include <rte_dev.h>
+#include <rte_string_fns.h>
+
+#include "ionic_crypto.h"
+
+#define IOCPT_VDEV_DEV_BAR          0
+#define IOCPT_VDEV_INTR_CTL_BAR     1
+#define IOCPT_VDEV_INTR_CFG_BAR     2
+#define IOCPT_VDEV_DB_BAR           3
+#define IOCPT_VDEV_BARS_MAX         4
+
+#define IOCPT_VDEV_DEV_INFO_REGS_OFFSET      0x0000
+#define IOCPT_VDEV_DEV_CMD_REGS_OFFSET       0x0800
+
+static int
+iocpt_vdev_setup_bars(struct iocpt_dev *dev)
+{
+	IOCPT_PRINT_CALL();
+
+	dev->name = rte_vdev_device_name(dev->bus_dev);
+
+	return 0;
+}
+
+static void
+iocpt_vdev_unmap_bars(struct iocpt_dev *dev)
+{
+	struct iocpt_dev_bars *bars = &dev->bars;
+	uint32_t i;
+
+	for (i = 0; i < IOCPT_VDEV_BARS_MAX; i++)
+		ionic_uio_rel_rsrc(dev->name, i, &bars->bar[i]);
+}
+
+static uint8_t iocpt_vdev_driver_id;
+static const struct iocpt_dev_intf iocpt_vdev_intf = {
+	.setup_bars = iocpt_vdev_setup_bars,
+	.unmap_bars = iocpt_vdev_unmap_bars,
+};
+
+static int
+iocpt_vdev_probe(struct rte_vdev_device *vdev)
+{
+	struct iocpt_dev_bars bars = {};
+	const char *name = rte_vdev_device_name(vdev);
+	unsigned int i;
+
+	IOCPT_PRINT(NOTICE, "Initializing device %s%s", name,
+		rte_eal_process_type() == RTE_PROC_SECONDARY ?
+			" [SECONDARY]" : "");
+
+	ionic_uio_scan_mcrypt_devices();
+
+	for (i = 0; i < IOCPT_VDEV_BARS_MAX; i++)
+		ionic_uio_get_rsrc(name, i, &bars.bar[i]);
+
+	bars.num_bars = IOCPT_VDEV_BARS_MAX;
+
+	return iocpt_probe((void *)vdev, &vdev->device,
+			&bars, &iocpt_vdev_intf,
+			iocpt_vdev_driver_id, rte_socket_id());
+}
+
+static int
+iocpt_vdev_remove(struct rte_vdev_device *vdev)
+{
+	return iocpt_remove(&vdev->device);
+}
+
+static struct rte_vdev_driver rte_vdev_iocpt_pmd = {
+	.probe = iocpt_vdev_probe,
+	.remove = iocpt_vdev_remove,
+};
+
+static struct cryptodev_driver rte_vdev_iocpt_drv;
+
+RTE_PMD_REGISTER_VDEV(crypto_ionic, rte_vdev_iocpt_pmd);
+RTE_PMD_REGISTER_CRYPTO_DRIVER(rte_vdev_iocpt_drv, rte_vdev_iocpt_pmd.driver,
+		iocpt_vdev_driver_id);
diff --git a/drivers/crypto/ionic/meson.build b/drivers/crypto/ionic/meson.build
new file mode 100644
index 0000000000..4114e13e53
--- /dev/null
+++ b/drivers/crypto/ionic/meson.build
@@ -0,0 +1,13 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2021-2024 Advanced Micro Devices, Inc.
+
+deps += ['bus_vdev']
+deps += ['common_ionic']
+
+sources = files(
+        'ionic_crypto_main.c',
+        'ionic_crypto_vdev.c',
+)
+name = 'ionic_crypto'
+
+includes += include_directories('../../common/ionic')
diff --git a/drivers/crypto/meson.build b/drivers/crypto/meson.build
index ee5377deff..e799861bb6 100644
--- a/drivers/crypto/meson.build
+++ b/drivers/crypto/meson.build
@@ -10,6 +10,7 @@  drivers = [
         'cnxk',
         'dpaa_sec',
         'dpaa2_sec',
+        'ionic',
         'ipsec_mb',
         'mlx5',
         'mvsam',