From: Gage Eads <gage.eads@intel.com>
To: linux-kernel@vger.kernel.org, arnd@arndb.de, gregkh@linuxfoundation.org
Cc: magnus.karlsson@intel.com, bjorn.topel@intel.com
Subject: [PATCH 04/20] dlb2: add device ioctl layer and first 4 ioctls
Date: Sun, 12 Jul 2020 08:43:15 -0500 [thread overview]
Message-ID: <20200712134331.8169-5-gage.eads@intel.com> (raw)
In-Reply-To: <20200712134331.8169-1-gage.eads@intel.com>
This commit introduces the dlb2 device ioctl layer, and the first four
ioctls: query device version, driver version, and available resources; and
create a scheduling domain. This commit also introduces the user-space
interface file dlb2_user.h.
The PF hardware operation for scheduling domain creation will be added in a
subsequent commit.
Signed-off-by: Gage Eads <gage.eads@intel.com>
Reviewed-by: Magnus Karlsson <magnus.karlsson@intel.com>
---
drivers/misc/dlb2/Makefile | 1 +
drivers/misc/dlb2/dlb2_bitmap.h | 63 ++++++++++
drivers/misc/dlb2/dlb2_ioctl.c | 186 ++++++++++++++++++++++++++++++
drivers/misc/dlb2/dlb2_ioctl.h | 14 +++
drivers/misc/dlb2/dlb2_main.c | 33 +++++-
drivers/misc/dlb2/dlb2_main.h | 7 ++
drivers/misc/dlb2/dlb2_pf_ops.c | 21 ++++
drivers/misc/dlb2/dlb2_resource.c | 48 ++++++++
drivers/misc/dlb2/dlb2_resource.h | 22 ++++
include/uapi/linux/dlb2_user.h | 236 ++++++++++++++++++++++++++++++++++++++
10 files changed, 630 insertions(+), 1 deletion(-)
create mode 100644 drivers/misc/dlb2/dlb2_ioctl.c
create mode 100644 drivers/misc/dlb2/dlb2_ioctl.h
create mode 100644 include/uapi/linux/dlb2_user.h
diff --git a/drivers/misc/dlb2/Makefile b/drivers/misc/dlb2/Makefile
index 4fdf7ffc555b..18b5498b20e6 100644
--- a/drivers/misc/dlb2/Makefile
+++ b/drivers/misc/dlb2/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_INTEL_DLB2) := dlb2.o
dlb2-objs := \
dlb2_main.o \
+ dlb2_ioctl.o \
dlb2_pf_ops.o \
dlb2_resource.o \
diff --git a/drivers/misc/dlb2/dlb2_bitmap.h b/drivers/misc/dlb2/dlb2_bitmap.h
index c5bb4ba84d5c..2d2d2927b0ec 100644
--- a/drivers/misc/dlb2/dlb2_bitmap.h
+++ b/drivers/misc/dlb2/dlb2_bitmap.h
@@ -118,4 +118,67 @@ static inline int dlb2_bitmap_zero(struct dlb2_bitmap *bitmap)
return 0;
}
+/**
+ * dlb2_bitmap_count() - returns the number of set bits
+ * @bitmap: pointer to dlb2_bitmap structure.
+ *
+ * This function looks for a single set bit.
+ *
+ * Return:
+ * Returns the number of set bits upon success, <0 otherwise.
+ *
+ * Errors:
+ * EINVAL - bitmap is NULL or is uninitialized.
+ */
+static inline int dlb2_bitmap_count(struct dlb2_bitmap *bitmap)
+{
+ if (!bitmap || !bitmap->map)
+ return -EINVAL;
+
+ return bitmap_weight(bitmap->map, bitmap->len);
+}
+
+/**
+ * dlb2_bitmap_longest_set_range() - returns longest contiguous range of set
+ * bits
+ * @bitmap: pointer to dlb2_bitmap structure.
+ *
+ * Return:
+ * Returns the bitmap's longest contiguous range of of set bits upon success,
+ * <0 otherwise.
+ *
+ * Errors:
+ * EINVAL - bitmap is NULL or is uninitialized.
+ */
+static inline int dlb2_bitmap_longest_set_range(struct dlb2_bitmap *bitmap)
+{
+ unsigned int bits_per_long;
+ unsigned int i, j;
+ int max_len, len;
+
+ if (!bitmap || !bitmap->map)
+ return -EINVAL;
+
+ if (dlb2_bitmap_count(bitmap) == 0)
+ return 0;
+
+ max_len = 0;
+ len = 0;
+ bits_per_long = sizeof(unsigned long) * BITS_PER_BYTE;
+
+ for (i = 0; i < BITS_TO_LONGS(bitmap->len); i++) {
+ for (j = 0; j < bits_per_long; j++) {
+ if ((i * bits_per_long + j) >= bitmap->len)
+ break;
+
+ len = (test_bit(j, &bitmap->map[i])) ? len + 1 : 0;
+
+ if (len > max_len)
+ max_len = len;
+ }
+ }
+
+ return max_len;
+}
+
#endif /* __DLB2_OSDEP_BITMAP_H */
diff --git a/drivers/misc/dlb2/dlb2_ioctl.c b/drivers/misc/dlb2/dlb2_ioctl.c
new file mode 100644
index 000000000000..97a7220f0ea0
--- /dev/null
+++ b/drivers/misc/dlb2/dlb2_ioctl.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2017-2020 Intel Corporation */
+
+#include <linux/uaccess.h>
+
+#include <uapi/linux/dlb2_user.h>
+
+#include "dlb2_ioctl.h"
+#include "dlb2_main.h"
+
+/* Verify the ioctl argument size and copy the argument into kernel memory */
+static int dlb2_copy_from_user(struct dlb2_dev *dev,
+ unsigned long user_arg,
+ u16 user_size,
+ void *arg,
+ size_t size)
+{
+ if (user_size != size) {
+ dev_err(dev->dlb2_device,
+ "[%s()] Invalid ioctl size\n", __func__);
+ return -EINVAL;
+ }
+
+ if (copy_from_user(arg, (void __user *)user_arg, size)) {
+ dev_err(dev->dlb2_device,
+ "[%s()] Invalid ioctl argument pointer\n", __func__);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int dlb2_copy_resp_to_user(struct dlb2_dev *dev,
+ unsigned long user_resp,
+ struct dlb2_cmd_response *resp)
+{
+ if (copy_to_user((void __user *)user_resp, resp, sizeof(*resp))) {
+ dev_err(dev->dlb2_device,
+ "[%s()] Invalid ioctl response pointer\n", __func__);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+/* [7:0]: device revision, [15:8]: device version */
+#define DLB2_SET_DEVICE_VERSION(ver, rev) (((ver) << 8) | (rev))
+
+static int dlb2_ioctl_get_device_version(struct dlb2_dev *dev,
+ unsigned long user_arg,
+ u16 size)
+{
+ struct dlb2_get_device_version_args arg;
+ struct dlb2_cmd_response response;
+ int ret;
+
+ dev_dbg(dev->dlb2_device, "Entering %s()\n", __func__);
+
+ response.status = 0;
+ response.id = DLB2_SET_DEVICE_VERSION(2, DLB2_REV_A0);
+
+ ret = dlb2_copy_from_user(dev, user_arg, size, &arg, sizeof(arg));
+ if (ret)
+ return ret;
+
+ ret = dlb2_copy_resp_to_user(dev, arg.response, &response);
+ if (ret)
+ return ret;
+
+ dev_dbg(dev->dlb2_device, "Exiting %s()\n", __func__);
+
+ return 0;
+}
+
+static int dlb2_ioctl_create_sched_domain(struct dlb2_dev *dev,
+ unsigned long user_arg,
+ u16 size)
+{
+ struct dlb2_create_sched_domain_args arg;
+ struct dlb2_cmd_response response = {0};
+ int ret;
+
+ dev_dbg(dev->dlb2_device, "Entering %s()\n", __func__);
+
+ ret = dlb2_copy_from_user(dev, user_arg, size, &arg, sizeof(arg));
+ if (ret)
+ return ret;
+
+ /* Copy zeroes to verify the user-provided response pointer */
+ ret = dlb2_copy_resp_to_user(dev, arg.response, &response);
+ if (ret)
+ return ret;
+
+ mutex_lock(&dev->resource_mutex);
+
+ ret = dev->ops->create_sched_domain(&dev->hw, &arg, &response);
+
+ mutex_unlock(&dev->resource_mutex);
+
+ if (copy_to_user((void __user *)arg.response,
+ &response,
+ sizeof(response)))
+ return -EFAULT;
+
+ dev_dbg(dev->dlb2_device, "Exiting %s()\n", __func__);
+
+ return ret;
+}
+
+static int dlb2_ioctl_get_num_resources(struct dlb2_dev *dev,
+ unsigned long user_arg,
+ u16 size)
+{
+ struct dlb2_get_num_resources_args arg;
+ int ret;
+
+ dev_dbg(dev->dlb2_device, "Entering %s()\n", __func__);
+
+ mutex_lock(&dev->resource_mutex);
+
+ ret = dev->ops->get_num_resources(&dev->hw, &arg);
+
+ mutex_unlock(&dev->resource_mutex);
+
+ if (copy_to_user((void __user *)user_arg, &arg, sizeof(arg))) {
+ dev_err(dev->dlb2_device, "Invalid DLB resources pointer\n");
+ return -EFAULT;
+ }
+
+ dev_dbg(dev->dlb2_device, "Exiting %s()\n", __func__);
+
+ return ret;
+}
+
+static int dlb2_ioctl_get_driver_version(struct dlb2_dev *dev,
+ unsigned long user_arg,
+ u16 size)
+{
+ struct dlb2_get_driver_version_args arg;
+ struct dlb2_cmd_response response;
+ int ret;
+
+ dev_dbg(dev->dlb2_device, "Entering %s()\n", __func__);
+
+ response.status = 0;
+ response.id = DLB2_VERSION;
+
+ ret = dlb2_copy_from_user(dev, user_arg, size, &arg, sizeof(arg));
+ if (ret)
+ return ret;
+
+ ret = dlb2_copy_resp_to_user(dev, arg.response, &response);
+ if (ret)
+ return ret;
+
+ dev_dbg(dev->dlb2_device, "Exiting %s()\n", __func__);
+
+ return 0;
+}
+
+typedef int (*dlb2_ioctl_callback_fn_t)(struct dlb2_dev *dev,
+ unsigned long arg,
+ u16 size);
+
+static dlb2_ioctl_callback_fn_t dlb2_ioctl_callback_fns[NUM_DLB2_CMD] = {
+ dlb2_ioctl_get_device_version,
+ dlb2_ioctl_create_sched_domain,
+ dlb2_ioctl_get_num_resources,
+ dlb2_ioctl_get_driver_version,
+};
+
+int dlb2_ioctl_dispatcher(struct dlb2_dev *dev,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ u16 sz = _IOC_SIZE(cmd);
+
+ if (_IOC_NR(cmd) >= NUM_DLB2_CMD) {
+ dev_err(dev->dlb2_device,
+ "[%s()] Unexpected DLB command %d\n",
+ __func__, _IOC_NR(cmd));
+ return -1;
+ }
+
+ return dlb2_ioctl_callback_fns[_IOC_NR(cmd)](dev, arg, sz);
+}
diff --git a/drivers/misc/dlb2/dlb2_ioctl.h b/drivers/misc/dlb2/dlb2_ioctl.h
new file mode 100644
index 000000000000..476548cdd33c
--- /dev/null
+++ b/drivers/misc/dlb2/dlb2_ioctl.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ * Copyright(c) 2017-2020 Intel Corporation
+ */
+
+#ifndef __DLB2_IOCTL_H
+#define __DLB2_IOCTL_H
+
+#include "dlb2_main.h"
+
+int dlb2_ioctl_dispatcher(struct dlb2_dev *dev,
+ unsigned int cmd,
+ unsigned long arg);
+
+#endif /* __DLB2_IOCTL_H */
diff --git a/drivers/misc/dlb2/dlb2_main.c b/drivers/misc/dlb2/dlb2_main.c
index ae39dfea51e3..e3e32c6f3d63 100644
--- a/drivers/misc/dlb2/dlb2_main.c
+++ b/drivers/misc/dlb2/dlb2_main.c
@@ -11,15 +11,25 @@
#include <linux/pci.h>
#include <linux/uaccess.h>
+#include "dlb2_ioctl.h"
#include "dlb2_main.h"
#include "dlb2_resource.h"
static const char
dlb2_driver_copyright[] = "Copyright(c) 2018-2020 Intel Corporation";
+#define TO_STR2(s) #s
+#define TO_STR(s) TO_STR2(s)
+
+#define DRV_VERSION \
+ TO_STR(DLB2_VERSION_MAJOR_NUMBER) "." \
+ TO_STR(DLB2_VERSION_MINOR_NUMBER) "." \
+ TO_STR(DLB2_VERSION_REVISION_NUMBER)
+
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Copyright(c) 2018-2020 Intel Corporation");
MODULE_DESCRIPTION("Intel(R) Dynamic Load Balancer 2.0 Driver");
+MODULE_VERSION(DRV_VERSION);
/* The driver lock protects data structures that used by multiple devices. */
static DEFINE_MUTEX(dlb2_driver_lock);
@@ -59,10 +69,28 @@ static int dlb2_close(struct inode *i, struct file *f)
return 0;
}
+static long
+dlb2_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+{
+ struct dlb2_dev *dev;
+
+ dev = container_of(f->f_inode->i_cdev, struct dlb2_dev, cdev);
+
+ if (_IOC_TYPE(cmd) != DLB2_IOC_MAGIC) {
+ dev_err(dev->dlb2_device,
+ "[%s()] Bad magic number!\n", __func__);
+ return -EINVAL;
+ }
+
+ return dlb2_ioctl_dispatcher(dev, cmd, arg);
+}
+
static const struct file_operations dlb2_fops = {
.owner = THIS_MODULE,
.open = dlb2_open,
.release = dlb2_close,
+ .unlocked_ioctl = dlb2_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
};
/**********************************/
@@ -260,7 +288,10 @@ static int __init dlb2_init_module(void)
{
int err;
- pr_info("%s\n", dlb2_driver_name);
+ pr_info("%s - version %d.%d.%d\n", dlb2_driver_name,
+ DLB2_VERSION_MAJOR_NUMBER,
+ DLB2_VERSION_MINOR_NUMBER,
+ DLB2_VERSION_REVISION_NUMBER);
pr_info("%s\n", dlb2_driver_copyright);
dlb2_class = class_create(THIS_MODULE, dlb2_driver_name);
diff --git a/drivers/misc/dlb2/dlb2_main.h b/drivers/misc/dlb2/dlb2_main.h
index 0bb646b82e5c..9211a6d999d1 100644
--- a/drivers/misc/dlb2/dlb2_main.h
+++ b/drivers/misc/dlb2/dlb2_main.h
@@ -13,6 +13,8 @@
#include <linux/pci.h>
#include <linux/types.h>
+#include <uapi/linux/dlb2_user.h>
+
#include "dlb2_hw_types.h"
static const char dlb2_driver_name[] = KBUILD_MODNAME;
@@ -53,6 +55,11 @@ struct dlb2_device_ops {
void (*enable_pm)(struct dlb2_dev *dev);
int (*wait_for_device_ready)(struct dlb2_dev *dev,
struct pci_dev *pdev);
+ int (*create_sched_domain)(struct dlb2_hw *hw,
+ struct dlb2_create_sched_domain_args *args,
+ struct dlb2_cmd_response *resp);
+ int (*get_num_resources)(struct dlb2_hw *hw,
+ struct dlb2_get_num_resources_args *args);
void (*init_hardware)(struct dlb2_dev *dev);
};
diff --git a/drivers/misc/dlb2/dlb2_pf_ops.c b/drivers/misc/dlb2/dlb2_pf_ops.c
index 01664211d60a..8142b302ba95 100644
--- a/drivers/misc/dlb2/dlb2_pf_ops.c
+++ b/drivers/misc/dlb2/dlb2_pf_ops.c
@@ -194,6 +194,25 @@ dlb2_pf_init_hardware(struct dlb2_dev *dlb2_dev)
{
}
+/*****************************/
+/****** IOCTL callbacks ******/
+/*****************************/
+
+static int
+dlb2_pf_create_sched_domain(struct dlb2_hw *hw,
+ struct dlb2_create_sched_domain_args *args,
+ struct dlb2_cmd_response *resp)
+{
+ return 0;
+}
+
+static int
+dlb2_pf_get_num_resources(struct dlb2_hw *hw,
+ struct dlb2_get_num_resources_args *args)
+{
+ return dlb2_hw_get_num_resources(hw, args, false, 0);
+}
+
/********************************/
/****** DLB2 PF Device Ops ******/
/********************************/
@@ -209,5 +228,7 @@ struct dlb2_device_ops dlb2_pf_ops = {
.cdev_del = dlb2_pf_cdev_del,
.enable_pm = dlb2_pf_enable_pm,
.wait_for_device_ready = dlb2_pf_wait_for_device_ready,
+ .create_sched_domain = dlb2_pf_create_sched_domain,
+ .get_num_resources = dlb2_pf_get_num_resources,
.init_hardware = dlb2_pf_init_hardware,
};
diff --git a/drivers/misc/dlb2/dlb2_resource.c b/drivers/misc/dlb2/dlb2_resource.c
index 036ab10d7a98..44da2a3d3061 100644
--- a/drivers/misc/dlb2/dlb2_resource.c
+++ b/drivers/misc/dlb2/dlb2_resource.c
@@ -185,6 +185,54 @@ int dlb2_resource_init(struct dlb2_hw *hw)
return ret;
}
+int dlb2_hw_get_num_resources(struct dlb2_hw *hw,
+ struct dlb2_get_num_resources_args *arg,
+ bool vdev_req,
+ unsigned int vdev_id)
+{
+ struct dlb2_function_resources *rsrcs;
+ struct dlb2_bitmap *map;
+ int i;
+
+ if (vdev_req && vdev_id >= DLB2_MAX_NUM_VDEVS)
+ return -EINVAL;
+
+ if (vdev_req)
+ rsrcs = &hw->vdev[vdev_id];
+ else
+ rsrcs = &hw->pf;
+
+ arg->num_sched_domains = rsrcs->num_avail_domains;
+
+ arg->num_ldb_queues = rsrcs->num_avail_ldb_queues;
+
+ arg->num_ldb_ports = 0;
+ for (i = 0; i < DLB2_NUM_COS_DOMAINS; i++)
+ arg->num_ldb_ports += rsrcs->num_avail_ldb_ports[i];
+
+ arg->num_cos0_ldb_ports = rsrcs->num_avail_ldb_ports[0];
+ arg->num_cos1_ldb_ports = rsrcs->num_avail_ldb_ports[1];
+ arg->num_cos2_ldb_ports = rsrcs->num_avail_ldb_ports[2];
+ arg->num_cos3_ldb_ports = rsrcs->num_avail_ldb_ports[3];
+
+ arg->num_dir_ports = rsrcs->num_avail_dir_pq_pairs;
+
+ arg->num_atomic_inflights = rsrcs->num_avail_aqed_entries;
+
+ map = rsrcs->avail_hist_list_entries;
+
+ arg->num_hist_list_entries = dlb2_bitmap_count(map);
+
+ arg->max_contiguous_hist_list_entries =
+ dlb2_bitmap_longest_set_range(map);
+
+ arg->num_ldb_credits = rsrcs->num_avail_qed_entries;
+
+ arg->num_dir_credits = rsrcs->num_avail_dqed_entries;
+
+ return 0;
+}
+
void dlb2_clr_pmcsr_disable(struct dlb2_hw *hw)
{
union dlb2_cfg_mstr_cfg_pm_pmcsr_disable r0;
diff --git a/drivers/misc/dlb2/dlb2_resource.h b/drivers/misc/dlb2/dlb2_resource.h
index 73528943d36e..33c0b0ea6025 100644
--- a/drivers/misc/dlb2/dlb2_resource.h
+++ b/drivers/misc/dlb2/dlb2_resource.h
@@ -35,6 +35,28 @@ int dlb2_resource_init(struct dlb2_hw *hw);
void dlb2_resource_free(struct dlb2_hw *hw);
/**
+ * dlb2_hw_get_num_resources() - query the PCI function's available resources
+ * @hw: dlb2_hw handle for a particular device.
+ * @arg: pointer to resource counts.
+ * @vdev_request: indicates whether this request came from a vdev.
+ * @vdev_id: If vdev_request is true, this contains the vdev's ID.
+ *
+ * This function returns the number of available resources for the PF or for a
+ * VF.
+ *
+ * A vdev can be either an SR-IOV virtual function or a Scalable IOV virtual
+ * device.
+ *
+ * Return:
+ * Returns 0 upon success, -EINVAL if vdev_request is true and vdev_id is
+ * invalid.
+ */
+int dlb2_hw_get_num_resources(struct dlb2_hw *hw,
+ struct dlb2_get_num_resources_args *arg,
+ bool vdev_request,
+ unsigned int vdev_id);
+
+/**
* dlb2_clr_pmcsr_disable() - power on bulk of DLB 2.0 logic
* @hw: dlb2_hw handle for a particular device.
*
diff --git a/include/uapi/linux/dlb2_user.h b/include/uapi/linux/dlb2_user.h
new file mode 100644
index 000000000000..4742efae0b38
--- /dev/null
+++ b/include/uapi/linux/dlb2_user.h
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
+ * Copyright(c) 2016-2020 Intel Corporation
+ */
+
+#ifndef __DLB2_USER_H
+#define __DLB2_USER_H
+
+#include <linux/types.h>
+
+struct dlb2_cmd_response {
+ __u32 status; /* Interpret using enum dlb2_error */
+ __u32 id;
+};
+
+/********************************/
+/* 'dlb2' device file commands */
+/********************************/
+
+#define DLB2_DEVICE_VERSION(x) (((x) >> 8) & 0xFF)
+#define DLB2_DEVICE_REVISION(x) ((x) & 0xFF)
+
+enum dlb2_revisions {
+ DLB2_REV_A0 = 0,
+};
+
+/*
+ * DLB2_CMD_GET_DEVICE_VERSION: Query the DLB device version.
+ *
+ * This ioctl interface is the same in all driver versions and is always
+ * the first ioctl.
+ *
+ * Output parameters:
+ * - response: pointer to a struct dlb2_cmd_response.
+ * response.status: Detailed error code. In certain cases, such as if the
+ * response pointer is invalid, the driver won't set status.
+ * response.id[7:0]: Device revision.
+ * response.id[15:8]: Device version.
+ */
+
+struct dlb2_get_device_version_args {
+ /* Output parameters */
+ __u64 response;
+};
+
+#define DLB2_VERSION_MAJOR_NUMBER 1
+#define DLB2_VERSION_MINOR_NUMBER 0
+#define DLB2_VERSION_REVISION_NUMBER 0
+#define DLB2_VERSION (DLB2_VERSION_MAJOR_NUMBER << 24 | \
+ DLB2_VERSION_MINOR_NUMBER << 16 | \
+ DLB2_VERSION_REVISION_NUMBER)
+
+#define DLB2_VERSION_GET_MAJOR_NUMBER(x) (((x) >> 24) & 0xFF)
+#define DLB2_VERSION_GET_MINOR_NUMBER(x) (((x) >> 16) & 0xFF)
+#define DLB2_VERSION_GET_REVISION_NUMBER(x) ((x) & 0xFFFF)
+
+static inline __u8 dlb2_version_incompatible(__u32 version)
+{
+ __u8 inc;
+
+ inc = DLB2_VERSION_GET_MAJOR_NUMBER(version) !=
+ DLB2_VERSION_MAJOR_NUMBER;
+ inc |= (int)DLB2_VERSION_GET_MINOR_NUMBER(version) <
+ DLB2_VERSION_MINOR_NUMBER;
+
+ return inc;
+}
+
+/*
+ * DLB2_CMD_GET_DRIVER_VERSION: Query the DLB2 driver version. The major
+ * number is changed when there is an ABI-breaking change, the minor
+ * number is changed if the API is changed in a backwards-compatible way,
+ * and the revision number is changed for fixes that don't affect the API.
+ *
+ * If the kernel driver's API version major number and the header's
+ * DLB2_VERSION_MAJOR_NUMBER differ, the two are incompatible, or if the
+ * major numbers match but the kernel driver's minor number is less than
+ * the header file's, they are incompatible. The DLB2_VERSION_INCOMPATIBLE
+ * macro should be used to check for compatibility.
+ *
+ * This ioctl interface is the same in all driver versions. Applications
+ * should check the driver version before performing any other ioctl
+ * operations.
+ *
+ * Output parameters:
+ * - response: pointer to a struct dlb2_cmd_response.
+ * response.status: Detailed error code. In certain cases, such as if the
+ * response pointer is invalid, the driver won't set status.
+ * response.id: Driver API version. Use the DLB2_VERSION_GET_MAJOR_NUMBER,
+ * DLB2_VERSION_GET_MINOR_NUMBER, and
+ * DLB2_VERSION_GET_REVISION_NUMBER macros to interpret the field.
+ */
+
+struct dlb2_get_driver_version_args {
+ /* Output parameters */
+ __u64 response;
+};
+
+/*
+ * DLB2_CMD_CREATE_SCHED_DOMAIN: Create a DLB 2.0 scheduling domain and reserve
+ * its hardware resources. This command returns the newly created domain
+ * ID and a file descriptor for accessing the domain. Additional file
+ * descriptors can be opened using DLB2_CMD_GET_SCHED_DOMAIN_FD.
+ *
+ * Input parameters:
+ * - num_ldb_queues: Number of load-balanced queues.
+ * - num_ldb_ports: Number of load-balanced ports that can be allocated from
+ * from any class-of-service with available ports.
+ * - num_cos0_ldb_ports: Number of load-balanced ports from class-of-service 0.
+ * - num_cos1_ldb_ports: Number of load-balanced ports from class-of-service 1.
+ * - num_cos2_ldb_ports: Number of load-balanced ports from class-of-service 2.
+ * - num_cos3_ldb_ports: Number of load-balanced ports from class-of-service 3.
+ * - num_dir_ports: Number of directed ports. A directed port has one directed
+ * queue, so no num_dir_queues argument is necessary.
+ * - num_atomic_inflights: This specifies the amount of temporary atomic QE
+ * storage for the domain. This storage is divided among the domain's
+ * load-balanced queues that are configured for atomic scheduling.
+ * - num_hist_list_entries: Amount of history list storage. This is divided
+ * among the domain's CQs.
+ * - num_ldb_credits: Amount of load-balanced QE storage (QED). QEs occupy this
+ * space until they are scheduled to a load-balanced CQ. One credit
+ * represents the storage for one QE.
+ * - num_dir_credits: Amount of directed QE storage (DQED). QEs occupy this
+ * space until they are scheduled to a directed CQ. One credit represents
+ * the storage for one QE.
+ * - cos_strict: If set, return an error if there are insufficient ports in
+ * class-of-service N to satisfy the num_ldb_ports_cosN argument. If
+ * unset, attempt to fulfill num_ldb_ports_cosN arguments from other
+ * classes-of-service if class N does not contain enough free ports.
+ * - padding1: Reserved for future use.
+ *
+ * Output parameters:
+ * - response: pointer to a struct dlb2_cmd_response.
+ * response.status: Detailed error code. In certain cases, such as if the
+ * response pointer is invalid, the driver won't set status.
+ * response.id: domain ID.
+ * - domain_fd: file descriptor for performing the domain's ioctl operations
+ * - padding0: Reserved for future use.
+ */
+struct dlb2_create_sched_domain_args {
+ /* Output parameters */
+ __u64 response;
+ __u32 domain_fd;
+ __u32 padding0;
+ /* Input parameters */
+ __u32 num_ldb_queues;
+ __u32 num_ldb_ports;
+ __u32 num_cos0_ldb_ports;
+ __u32 num_cos1_ldb_ports;
+ __u32 num_cos2_ldb_ports;
+ __u32 num_cos3_ldb_ports;
+ __u32 num_dir_ports;
+ __u32 num_atomic_inflights;
+ __u32 num_hist_list_entries;
+ __u32 num_ldb_credits;
+ __u32 num_dir_credits;
+ __u8 cos_strict;
+ __u8 padding1[3];
+};
+
+/*
+ * DLB2_CMD_GET_NUM_RESOURCES: Return the number of available resources
+ * (queues, ports, etc.) that this device owns.
+ *
+ * Output parameters:
+ * - num_domains: Number of available scheduling domains.
+ * - num_ldb_queues: Number of available load-balanced queues.
+ * - num_ldb_ports: Total number of available load-balanced ports.
+ * - num_cos0_ldb_ports: Number of available load-balanced ports from
+ * class-of-service 0.
+ * - num_cos1_ldb_ports: Number of available load-balanced ports from
+ * class-of-service 1.
+ * - num_cos2_ldb_ports: Number of available load-balanced ports from
+ * class-of-service 2.
+ * - num_cos3_ldb_ports: Number of available load-balanced ports from
+ * class-of-service 3.
+ * - num_dir_ports: Number of available directed ports. There is one directed
+ * queue for every directed port.
+ * - num_atomic_inflights: Amount of available temporary atomic QE storage.
+ * - num_hist_list_entries: Amount of history list storage.
+ * - max_contiguous_hist_list_entries: History list storage is allocated in
+ * a contiguous chunk, and this return value is the longest available
+ * contiguous range of history list entries.
+ * - num_ldb_credits: Amount of available load-balanced QE storage.
+ * - num_dir_credits: Amount of available directed QE storage.
+ */
+struct dlb2_get_num_resources_args {
+ /* Output parameters */
+ __u32 num_sched_domains;
+ __u32 num_ldb_queues;
+ __u32 num_ldb_ports;
+ __u32 num_cos0_ldb_ports;
+ __u32 num_cos1_ldb_ports;
+ __u32 num_cos2_ldb_ports;
+ __u32 num_cos3_ldb_ports;
+ __u32 num_dir_ports;
+ __u32 num_atomic_inflights;
+ __u32 num_hist_list_entries;
+ __u32 max_contiguous_hist_list_entries;
+ __u32 num_ldb_credits;
+ __u32 num_dir_credits;
+};
+
+enum dlb2_user_interface_commands {
+ DLB2_CMD_GET_DEVICE_VERSION,
+ DLB2_CMD_CREATE_SCHED_DOMAIN,
+ DLB2_CMD_GET_NUM_RESOURCES,
+ DLB2_CMD_GET_DRIVER_VERSION,
+
+ /* NUM_DLB2_CMD must be last */
+ NUM_DLB2_CMD,
+};
+
+/********************/
+/* dlb2 ioctl codes */
+/********************/
+
+#define DLB2_IOC_MAGIC 'h'
+
+#define DLB2_IOC_GET_DEVICE_VERSION \
+ _IOWR(DLB2_IOC_MAGIC, \
+ DLB2_CMD_GET_DEVICE_VERSION, \
+ struct dlb2_get_device_version_args)
+#define DLB2_IOC_CREATE_SCHED_DOMAIN \
+ _IOWR(DLB2_IOC_MAGIC, \
+ DLB2_CMD_CREATE_SCHED_DOMAIN, \
+ struct dlb2_create_sched_domain_args)
+#define DLB2_IOC_GET_NUM_RESOURCES \
+ _IOWR(DLB2_IOC_MAGIC, \
+ DLB2_CMD_GET_NUM_RESOURCES, \
+ struct dlb2_get_num_resources_args)
+#define DLB2_IOC_GET_DRIVER_VERSION \
+ _IOWR(DLB2_IOC_MAGIC, \
+ DLB2_CMD_GET_DRIVER_VERSION, \
+ struct dlb2_get_driver_version_args)
+
+#endif /* __DLB2_USER_H */
--
2.13.6
next prev parent reply other threads:[~2020-07-12 13:51 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-12 13:43 [PATCH 00/20] dlb2: introduce DLB 2.0 device driver Gage Eads
2020-07-12 13:43 ` [PATCH 01/20] dlb2: add skeleton for DLB 2.0 driver Gage Eads
2020-07-12 15:56 ` Greg KH
2020-07-17 18:19 ` Eads, Gage
2020-07-18 6:46 ` Greg KH
2020-07-12 15:58 ` Greg KH
2020-07-17 18:18 ` Eads, Gage
2020-07-18 6:46 ` Greg KH
2020-07-20 19:02 ` Eads, Gage
2020-07-20 19:19 ` Greg KH
2020-07-24 21:00 ` Eads, Gage
2020-07-12 13:43 ` [PATCH 02/20] dlb2: initialize PF device Gage Eads
2020-07-12 13:43 ` [PATCH 03/20] dlb2: add resource and device initialization Gage Eads
2020-07-12 13:43 ` Gage Eads [this message]
2020-07-12 14:42 ` [PATCH 04/20] dlb2: add device ioctl layer and first 4 ioctls Randy Dunlap
2020-07-17 18:20 ` Eads, Gage
2020-07-12 14:53 ` Randy Dunlap
2020-07-17 18:20 ` Eads, Gage
2020-07-12 15:28 ` Arnd Bergmann
2020-07-17 18:19 ` Eads, Gage
2020-07-17 18:56 ` Arnd Bergmann
2020-07-17 20:05 ` Eads, Gage
2020-07-18 6:48 ` gregkh
2020-08-04 22:20 ` Eads, Gage
2020-08-05 6:46 ` gregkh
2020-08-05 15:07 ` Eads, Gage
2020-08-05 15:17 ` gregkh
2020-08-05 15:39 ` Eads, Gage
2020-07-12 13:43 ` [PATCH 05/20] dlb2: add sched domain config and reset support Gage Eads
2020-07-12 13:43 ` [PATCH 06/20] dlb2: add ioctl to get sched domain fd Gage Eads
2020-07-12 13:43 ` [PATCH 07/20] dlb2: add runtime power-management support Gage Eads
2020-07-12 13:43 ` [PATCH 08/20] dlb2: add queue create and queue-depth-get ioctls Gage Eads
2020-07-12 13:43 ` [PATCH 09/20] dlb2: add ioctl to configure ports, query poll mode Gage Eads
2020-07-12 15:34 ` Arnd Bergmann
2020-07-17 18:19 ` Eads, Gage
2020-07-12 13:43 ` [PATCH 10/20] dlb2: add port mmap support Gage Eads
2020-07-12 13:43 ` [PATCH 11/20] dlb2: add start domain ioctl Gage Eads
2020-07-12 13:43 ` [PATCH 12/20] dlb2: add queue map and unmap ioctls Gage Eads
2020-07-12 13:43 ` [PATCH 13/20] dlb2: add port enable/disable ioctls Gage Eads
2020-07-12 13:43 ` [PATCH 14/20] dlb2: add CQ interrupt support Gage Eads
2020-07-12 13:43 ` [PATCH 15/20] dlb2: add domain alert support Gage Eads
2020-07-12 13:43 ` [PATCH 16/20] dlb2: add sequence-number management ioctls Gage Eads
2020-07-12 13:43 ` [PATCH 17/20] dlb2: add cos bandwidth get/set ioctls Gage Eads
2020-07-12 13:43 ` [PATCH 18/20] dlb2: add device FLR support Gage Eads
2020-07-12 13:43 ` [PATCH 19/20] dlb2: add basic PF sysfs interfaces Gage Eads
2020-07-12 13:43 ` [PATCH 20/20] dlb2: add ingress error handling Gage Eads
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200712134331.8169-5-gage.eads@intel.com \
--to=gage.eads@intel.com \
--cc=arnd@arndb.de \
--cc=bjorn.topel@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=magnus.karlsson@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.