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',
