crypto/bcmfs: introduce BCMFS driver
authorVikas Gupta <vikas.gupta@broadcom.com>
Wed, 7 Oct 2020 17:18:53 +0000 (22:48 +0530)
committerAkhil Goyal <akhil.goyal@nxp.com>
Wed, 14 Oct 2020 19:42:57 +0000 (21:42 +0200)
Add Broadcom FlexSparc(FS) device creation driver which registers to a
vdev and create a device. Add APIs for logs, supportive documentation and
maintainers file.

Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
Signed-off-by: Raveendra Padasalagi <raveendra.padasalagi@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
MAINTAINERS
doc/guides/cryptodevs/bcmfs.rst [new file with mode: 0644]
doc/guides/cryptodevs/index.rst
doc/guides/rel_notes/release_20_11.rst
drivers/crypto/bcmfs/bcmfs_device.c [new file with mode: 0644]
drivers/crypto/bcmfs/bcmfs_device.h [new file with mode: 0644]
drivers/crypto/bcmfs/bcmfs_logs.c [new file with mode: 0644]
drivers/crypto/bcmfs/bcmfs_logs.h [new file with mode: 0644]
drivers/crypto/bcmfs/meson.build [new file with mode: 0644]
drivers/crypto/bcmfs/rte_pmd_bcmfs_version.map [new file with mode: 0644]
drivers/crypto/meson.build

index 3b96e8e..9d4b0ae 100644 (file)
@@ -967,6 +967,13 @@ F: drivers/crypto/armv8/
 F: doc/guides/cryptodevs/armv8.rst
 F: doc/guides/cryptodevs/features/armv8.ini
 
+Broadcom FlexSparc
+M: Ajit Khaparde <ajit.khaparde@broadcom.com>
+M: Raveendra Padasalagi <raveendra.padasalagi@broadcom.com>
+M: Vikas Gupta <vikas.gupta@broadcom.com>
+F: drivers/crypto/bcmfs/
+F: doc/guides/cryptodevs/bcmfs.rst
+
 Cavium OCTEON TX crypto
 M: Anoob Joseph <anoobj@marvell.com>
 F: drivers/common/cpt/
diff --git a/doc/guides/cryptodevs/bcmfs.rst b/doc/guides/cryptodevs/bcmfs.rst
new file mode 100644 (file)
index 0000000..0ed1a06
--- /dev/null
@@ -0,0 +1,51 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(C) 2020 Broadcom
+
+Broadcom FlexSparc Crypto Poll Mode Driver
+==========================================
+
+The FlexSparc crypto poll mode driver (BCMFS PMD) provides support for offloading
+cryptographic operations to the Broadcom SoCs having FlexSparc4/FlexSparc5 unit.
+Detailed information about SoCs can be found at `Broadcom Official Website
+<https://www.broadcom.com/products/ethernet-connectivity/network-adapters/smartnic>`__.
+
+Supported Broadcom SoCs
+-----------------------
+
+* Stingray
+* Stingray2
+
+Installation
+------------
+Information about kernel, rootfs and toolchain can be found at
+`Broadcom Official Website <https://www.broadcom.com/products/ethernet-connectivity
+/network-adapters/smartnic/stingray-software>`__.
+
+    .. Note::
+        To execute BCMFS PMD, it must be compiled with VFIO_PRESENT flag on the
+        compiling platform and same gets enabled in rte_vfio.h.
+
+The BCMFS crypto PMD may be compiled natively on a Stingray/Stingray2 platform or
+cross-compiled on an x86 platform. For example, below commands can be executed
+for cross compiling on x86 platform.
+
+.. code-block:: console
+
+    cd <DPDK-source-directory>
+    meson <dest-dir> --cross-file config/arm/arm64_stingray_linux_gcc
+    cd <dest-dir>
+    ninja
+
+Initialization
+--------------
+The supported platform devices should be present in the
+*/sys/bus/platform/devices/fs<version>/<dev_name>* path on the booted kernel.
+To get BCMFS PMD executing, device node must be owned by VFIO platform module only.
+For example, below commands can be run to get hold of a device node by VFIO.
+
+.. code-block:: console
+
+    SETUP_SYSFS_DEV_NAME=67000000.crypto_mbox
+    io_device_name="vfio-platform"
+    echo $io_device_name > /sys/bus/platform/devices/${SETUP_SYSFS_DEV_NAME}/driver_override
+    echo ${SETUP_SYSFS_DEV_NAME} > /sys/bus/platform/drivers_probe
index a67ed5a..279f56a 100644 (file)
@@ -13,6 +13,7 @@ Crypto Device Drivers
     aesni_mb
     aesni_gcm
     armv8
+    bcmfs
     caam_jr
     ccp
     dpaa2_sec
index d1e3758..5f1a01c 100644 (file)
@@ -159,6 +159,11 @@ New Features
   * Added support for SNOW3G-UEA2/UIA2 algorithms.
   * Added support for KASUMI-F8/F9 algorithms.
 
+* **Added Broadcom BCMFS symmetric crypto PMD.**
+
+  Added a symmetric crypto PMD for Broadcom FlexSparc crypto units.
+  See :doc:`../cryptodevs/bcmfs` guide for more details on this new PMD.
+
 * **Updated Marvell NITROX symmetric crypto PMD.**
 
   * Added AES-GCM support.
diff --git a/drivers/crypto/bcmfs/bcmfs_device.c b/drivers/crypto/bcmfs/bcmfs_device.c
new file mode 100644 (file)
index 0000000..f1050ff
--- /dev/null
@@ -0,0 +1,257 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Broadcom.
+ * All rights reserved.
+ */
+
+#include <dirent.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+
+#include "bcmfs_device.h"
+#include "bcmfs_logs.h"
+
+struct bcmfs_device_attr {
+       const char name[BCMFS_MAX_PATH_LEN];
+       const char suffix[BCMFS_DEV_NAME_LEN];
+       const enum bcmfs_device_type type;
+       const uint32_t offset;
+       const uint32_t version;
+};
+
+/* BCMFS supported devices */
+static struct bcmfs_device_attr dev_table[] = {
+       {
+               .name = "fs4",
+               .suffix = "crypto_mbox",
+               .type = BCMFS_SYM_FS4,
+               .offset = 0,
+               .version = BCMFS_SYM_FS4_VERSION
+       },
+       {
+               .name = "fs5",
+               .suffix = "mbox",
+               .type = BCMFS_SYM_FS5,
+               .offset = 0,
+               .version = BCMFS_SYM_FS5_VERSION
+       },
+       {
+               /* sentinel */
+       }
+};
+
+TAILQ_HEAD(fsdev_list, bcmfs_device);
+static struct fsdev_list fsdev_list = TAILQ_HEAD_INITIALIZER(fsdev_list);
+
+static struct bcmfs_device *
+fsdev_allocate_one_dev(struct rte_vdev_device *vdev,
+                      char *dirpath,
+                      char *devname,
+                      enum bcmfs_device_type dev_type __rte_unused)
+{
+       struct bcmfs_device *fsdev;
+
+       fsdev = rte_calloc(__func__, 1, sizeof(*fsdev), 0);
+       if (!fsdev)
+               return NULL;
+
+       if (strlen(dirpath) > sizeof(fsdev->dirname)) {
+               BCMFS_LOG(ERR, "dir path name is too long");
+               goto cleanup;
+       }
+
+       if (strlen(devname) > sizeof(fsdev->name)) {
+               BCMFS_LOG(ERR, "devname is too long");
+               goto cleanup;
+       }
+
+       strcpy(fsdev->dirname, dirpath);
+       strcpy(fsdev->name, devname);
+
+       fsdev->vdev = vdev;
+
+       TAILQ_INSERT_TAIL(&fsdev_list, fsdev, next);
+
+       return fsdev;
+
+cleanup:
+       free(fsdev);
+
+       return NULL;
+}
+
+static struct bcmfs_device *
+find_fsdev(struct rte_vdev_device *vdev)
+{
+       struct bcmfs_device *fsdev;
+
+       TAILQ_FOREACH(fsdev, &fsdev_list, next)
+               if (fsdev->vdev == vdev)
+                       return fsdev;
+
+       return NULL;
+}
+
+static void
+fsdev_release(struct bcmfs_device *fsdev)
+{
+       if (fsdev == NULL)
+               return;
+
+       TAILQ_REMOVE(&fsdev_list, fsdev, next);
+       free(fsdev);
+}
+
+static int
+cmprator(const void *a, const void *b)
+{
+       return (*(const unsigned int *)a - *(const unsigned int *)b);
+}
+
+static int
+fsdev_find_all_devs(const char *path, const char *search,
+                   uint32_t *devs)
+{
+       DIR *dir;
+       struct dirent *entry;
+       int count = 0;
+       char addr[BCMFS_MAX_NODES][BCMFS_MAX_PATH_LEN];
+       int i;
+
+       dir = opendir(path);
+       if (dir == NULL) {
+               BCMFS_LOG(ERR, "Unable to open directory");
+               return 0;
+       }
+
+       while ((entry = readdir(dir)) != NULL) {
+               if (strstr(entry->d_name, search)) {
+                       strlcpy(addr[count], entry->d_name,
+                               BCMFS_MAX_PATH_LEN);
+                       count++;
+               }
+       }
+
+       closedir(dir);
+
+       for (i = 0 ; i < count; i++)
+               devs[i] = (uint32_t)strtoul(addr[i], NULL, 16);
+       /* sort the devices based on IO addresses */
+       qsort(devs, count, sizeof(uint32_t), cmprator);
+
+       return count;
+}
+
+static bool
+fsdev_find_sub_dir(char *path, const char *search, char *output)
+{
+       DIR *dir;
+       struct dirent *entry;
+
+       dir = opendir(path);
+       if (dir == NULL) {
+               BCMFS_LOG(ERR, "Unable to open directory");
+               return -ENODEV;
+       }
+
+       while ((entry = readdir(dir)) != NULL) {
+               if (!strcmp(entry->d_name, search)) {
+                       strlcpy(output, entry->d_name, BCMFS_MAX_PATH_LEN);
+                       closedir(dir);
+                       return true;
+               }
+       }
+
+       closedir(dir);
+
+       return false;
+}
+
+
+static int
+bcmfs_vdev_probe(struct rte_vdev_device *vdev)
+{
+       struct bcmfs_device *fsdev;
+       char top_dirpath[BCMFS_MAX_PATH_LEN];
+       char sub_dirpath[BCMFS_MAX_PATH_LEN];
+       char out_dirpath[BCMFS_MAX_PATH_LEN];
+       char out_dirname[BCMFS_MAX_PATH_LEN];
+       uint32_t fsdev_dev[BCMFS_MAX_NODES];
+       enum bcmfs_device_type dtype;
+       int i = 0;
+       int dev_idx;
+       int count = 0;
+       bool found = false;
+
+       sprintf(top_dirpath, "%s", SYSFS_BCM_PLTFORM_DEVICES);
+       while (strlen(dev_table[i].name)) {
+               found = fsdev_find_sub_dir(top_dirpath,
+                                          dev_table[i].name,
+                                          sub_dirpath);
+               if (found)
+                       break;
+               i++;
+       }
+       if (!found) {
+               BCMFS_LOG(ERR, "No supported bcmfs dev found");
+               return -ENODEV;
+       }
+
+       dev_idx = i;
+       dtype = dev_table[i].type;
+
+       snprintf(out_dirpath, sizeof(out_dirpath), "%s/%s",
+                top_dirpath, sub_dirpath);
+       count = fsdev_find_all_devs(out_dirpath,
+                                   dev_table[dev_idx].suffix,
+                                   fsdev_dev);
+       if (!count) {
+               BCMFS_LOG(ERR, "No supported bcmfs dev found");
+               return -ENODEV;
+       }
+
+       i = 0;
+       while (count) {
+               /* format the device name present in the patch */
+               snprintf(out_dirname, sizeof(out_dirname), "%x.%s",
+                        fsdev_dev[i], dev_table[dev_idx].suffix);
+               fsdev = fsdev_allocate_one_dev(vdev, out_dirpath,
+                                              out_dirname, dtype);
+               if (!fsdev) {
+                       count--;
+                       i++;
+                       continue;
+               }
+               break;
+       }
+       if (fsdev == NULL) {
+               BCMFS_LOG(ERR, "All supported devs busy");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int
+bcmfs_vdev_remove(struct rte_vdev_device *vdev)
+{
+       struct bcmfs_device *fsdev;
+
+       fsdev = find_fsdev(vdev);
+       if (fsdev == NULL)
+               return -ENODEV;
+
+       fsdev_release(fsdev);
+       return 0;
+}
+
+/* Register with vdev */
+static struct rte_vdev_driver rte_bcmfs_pmd = {
+       .probe = bcmfs_vdev_probe,
+       .remove = bcmfs_vdev_remove
+};
+
+RTE_PMD_REGISTER_VDEV(bcmfs_pmd,
+                     rte_bcmfs_pmd);
diff --git a/drivers/crypto/bcmfs/bcmfs_device.h b/drivers/crypto/bcmfs/bcmfs_device.h
new file mode 100644 (file)
index 0000000..1a4d0cf
--- /dev/null
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Broadcom.
+ * All rights reserved.
+ */
+
+#ifndef _BCMFS_DEVICE_H_
+#define _BCMFS_DEVICE_H_
+
+#include <sys/queue.h>
+
+#include <rte_bus_vdev.h>
+
+#include "bcmfs_logs.h"
+
+/* max number of dev nodes */
+#define BCMFS_MAX_NODES                4
+#define BCMFS_MAX_PATH_LEN     512
+#define BCMFS_DEV_NAME_LEN     64
+
+/* Path for BCM-Platform device directory */
+#define SYSFS_BCM_PLTFORM_DEVICES    "/sys/bus/platform/devices"
+
+#define BCMFS_SYM_FS4_VERSION  0x76303031
+#define BCMFS_SYM_FS5_VERSION  0x76303032
+
+/* Supported devices */
+enum bcmfs_device_type {
+       BCMFS_SYM_FS4,
+       BCMFS_SYM_FS5,
+       BCMFS_UNKNOWN
+};
+
+struct bcmfs_device {
+       TAILQ_ENTRY(bcmfs_device) next;
+       /* Directory path for vfio */
+       char dirname[BCMFS_MAX_PATH_LEN];
+       /* BCMFS device name */
+       char name[BCMFS_DEV_NAME_LEN];
+       /* Parent vdev */
+       struct rte_vdev_device *vdev;
+};
+
+#endif /* _BCMFS_DEVICE_H_ */
diff --git a/drivers/crypto/bcmfs/bcmfs_logs.c b/drivers/crypto/bcmfs/bcmfs_logs.c
new file mode 100644 (file)
index 0000000..86f4ff3
--- /dev/null
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <rte_log.h>
+#include <rte_hexdump.h>
+
+#include "bcmfs_logs.h"
+
+int bcmfs_conf_logtype;
+int bcmfs_dp_logtype;
+
+int
+bcmfs_hexdump_log(uint32_t level, uint32_t logtype, const char *title,
+               const void *buf, unsigned int len)
+{
+       if (level > rte_log_get_global_level())
+               return 0;
+       if (level > (uint32_t)(rte_log_get_level(logtype)))
+               return 0;
+
+       rte_hexdump(rte_log_get_stream(), title, buf, len);
+       return 0;
+}
+
+RTE_INIT(bcmfs_device_init_log)
+{
+       /* Configuration and general logs */
+       bcmfs_conf_logtype = rte_log_register("pmd.bcmfs_config");
+       if (bcmfs_conf_logtype >= 0)
+               rte_log_set_level(bcmfs_conf_logtype, RTE_LOG_NOTICE);
+
+       /* data-path logs */
+       bcmfs_dp_logtype = rte_log_register("pmd.bcmfs_fp");
+       if (bcmfs_dp_logtype >= 0)
+               rte_log_set_level(bcmfs_dp_logtype, RTE_LOG_NOTICE);
+}
diff --git a/drivers/crypto/bcmfs/bcmfs_logs.h b/drivers/crypto/bcmfs/bcmfs_logs.h
new file mode 100644 (file)
index 0000000..c03a49b
--- /dev/null
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BCMFS_LOGS_H_
+#define _BCMFS_LOGS_H_
+
+#include <rte_log.h>
+
+extern int bcmfs_conf_logtype;
+extern int bcmfs_dp_logtype;
+
+#define BCMFS_LOG(level, fmt, args...)         \
+       rte_log(RTE_LOG_ ## level, bcmfs_conf_logtype,          \
+               "%s(): " fmt "\n", __func__, ## args)
+
+#define BCMFS_DP_LOG(level, fmt, args...)              \
+       rte_log(RTE_LOG_ ## level, bcmfs_dp_logtype,            \
+               "%s(): " fmt "\n", __func__, ## args)
+
+#define BCMFS_DP_HEXDUMP_LOG(level, title, buf, len)   \
+       bcmfs_hexdump_log(RTE_LOG_ ## level, bcmfs_dp_logtype, title, buf, len)
+
+/**
+ * bcmfs_hexdump_log Dump out memory in a special hex dump format.
+ *
+ * The message will be sent to the stream used by the rte_log infrastructure.
+ */
+int
+bcmfs_hexdump_log(uint32_t level, uint32_t logtype, const char *heading,
+                 const void *buf, unsigned int len);
+
+#endif /* _BCMFS_LOGS_H_ */
diff --git a/drivers/crypto/bcmfs/meson.build b/drivers/crypto/bcmfs/meson.build
new file mode 100644 (file)
index 0000000..a4bdd8e
--- /dev/null
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(C) 2020 Broadcom
+# All rights reserved.
+#
+
+deps += ['eal', 'bus_vdev']
+sources = files(
+               'bcmfs_logs.c',
+               'bcmfs_device.c'
+               )
diff --git a/drivers/crypto/bcmfs/rte_pmd_bcmfs_version.map b/drivers/crypto/bcmfs/rte_pmd_bcmfs_version.map
new file mode 100644 (file)
index 0000000..4a76d1d
--- /dev/null
@@ -0,0 +1,3 @@
+DPDK_21 {
+       local: *;
+};
index a242350..93c2968 100644 (file)
@@ -8,6 +8,7 @@ endif
 drivers = ['aesni_gcm',
           'aesni_mb',
           'armv8',
+          'bcmfs',
           'caam_jr',
           'ccp',
           'dpaa_sec',