[dpdk-dev] [PATCH v2 09/27] event/dlb2: add v2.5 create dir queue
Jerin Jacob
jerinjacobk at gmail.com
Sat Apr 3 12:26:15 CEST 2021
On Wed, Mar 31, 2021 at 1:08 AM Timothy McDaniel
<timothy.mcdaniel at intel.com> wrote:
>
> Updated low level hardware functions to account for new
> register map and hardware access macros.
>
> Signed-off-by: Timothy McDaniel <timothy.mcdaniel at intel.com>
> ---
> drivers/event/dlb2/pf/base/dlb2_resource.c | 213 ------------------
> .../event/dlb2/pf/base/dlb2_resource_new.c | 201 +++++++++++++++++
All changes to this file, please take the git rename path to reduce the diff.
> 2 files changed, 201 insertions(+), 213 deletions(-)
>
> diff --git a/drivers/event/dlb2/pf/base/dlb2_resource.c b/drivers/event/dlb2/pf/base/dlb2_resource.c
> index 70c52e908..362deadfe 100644
> --- a/drivers/event/dlb2/pf/base/dlb2_resource.c
> +++ b/drivers/event/dlb2/pf/base/dlb2_resource.c
> @@ -1225,219 +1225,6 @@ dlb2_get_domain_used_dir_pq(struct dlb2_hw *hw,
> return NULL;
> }
>
> -static void dlb2_configure_dir_queue(struct dlb2_hw *hw,
> - struct dlb2_hw_domain *domain,
> - struct dlb2_dir_pq_pair *queue,
> - struct dlb2_create_dir_queue_args *args,
> - bool vdev_req,
> - unsigned int vdev_id)
> -{
> - union dlb2_sys_dir_vasqid_v r0 = { {0} };
> - union dlb2_sys_dir_qid_its r1 = { {0} };
> - union dlb2_lsp_qid_dir_depth_thrsh r2 = { {0} };
> - union dlb2_sys_dir_qid_v r5 = { {0} };
> -
> - unsigned int offs;
> -
> - /* QID write permissions are turned on when the domain is started */
> - r0.field.vasqid_v = 0;
> -
> - offs = domain->id.phys_id * DLB2_MAX_NUM_DIR_QUEUES(hw->ver) +
> - queue->id.phys_id;
> -
> - DLB2_CSR_WR(hw, DLB2_SYS_DIR_VASQID_V(offs), r0.val);
> -
> - /* Don't timestamp QEs that pass through this queue */
> - r1.field.qid_its = 0;
> -
> - DLB2_CSR_WR(hw,
> - DLB2_SYS_DIR_QID_ITS(queue->id.phys_id),
> - r1.val);
> -
> - r2.field.thresh = args->depth_threshold;
> -
> - DLB2_CSR_WR(hw,
> - DLB2_LSP_QID_DIR_DEPTH_THRSH(queue->id.phys_id),
> - r2.val);
> -
> - if (vdev_req) {
> - union dlb2_sys_vf_dir_vqid_v r3 = { {0} };
> - union dlb2_sys_vf_dir_vqid2qid r4 = { {0} };
> -
> - offs = vdev_id * DLB2_MAX_NUM_DIR_QUEUES(hw->ver)
> - + queue->id.virt_id;
> -
> - r3.field.vqid_v = 1;
> -
> - DLB2_CSR_WR(hw, DLB2_SYS_VF_DIR_VQID_V(offs), r3.val);
> -
> - r4.field.qid = queue->id.phys_id;
> -
> - DLB2_CSR_WR(hw, DLB2_SYS_VF_DIR_VQID2QID(offs), r4.val);
> - }
> -
> - r5.field.qid_v = 1;
> -
> - DLB2_CSR_WR(hw, DLB2_SYS_DIR_QID_V(queue->id.phys_id), r5.val);
> -
> - queue->queue_configured = true;
> -}
> -
> -static void
> -dlb2_log_create_dir_queue_args(struct dlb2_hw *hw,
> - u32 domain_id,
> - struct dlb2_create_dir_queue_args *args,
> - bool vdev_req,
> - unsigned int vdev_id)
> -{
> - DLB2_HW_DBG(hw, "DLB2 create directed queue arguments:\n");
> - if (vdev_req)
> - DLB2_HW_DBG(hw, "(Request from vdev %d)\n", vdev_id);
> - DLB2_HW_DBG(hw, "\tDomain ID: %d\n", domain_id);
> - DLB2_HW_DBG(hw, "\tPort ID: %d\n", args->port_id);
> -}
> -
> -static int
> -dlb2_verify_create_dir_queue_args(struct dlb2_hw *hw,
> - u32 domain_id,
> - struct dlb2_create_dir_queue_args *args,
> - struct dlb2_cmd_response *resp,
> - bool vdev_req,
> - unsigned int vdev_id)
> -{
> - struct dlb2_hw_domain *domain;
> -
> - domain = dlb2_get_domain_from_id(hw, domain_id, vdev_req, vdev_id);
> -
> - if (domain == NULL) {
> - resp->status = DLB2_ST_INVALID_DOMAIN_ID;
> - return -EINVAL;
> - }
> -
> - if (!domain->configured) {
> - resp->status = DLB2_ST_DOMAIN_NOT_CONFIGURED;
> - return -EINVAL;
> - }
> -
> - if (domain->started) {
> - resp->status = DLB2_ST_DOMAIN_STARTED;
> - return -EINVAL;
> - }
> -
> - /*
> - * If the user claims the port is already configured, validate the port
> - * ID, its domain, and whether the port is configured.
> - */
> - if (args->port_id != -1) {
> - struct dlb2_dir_pq_pair *port;
> -
> - port = dlb2_get_domain_used_dir_pq(hw,
> - args->port_id,
> - vdev_req,
> - domain);
> -
> - if (port == NULL || port->domain_id.phys_id !=
> - domain->id.phys_id || !port->port_configured) {
> - resp->status = DLB2_ST_INVALID_PORT_ID;
> - return -EINVAL;
> - }
> - }
> -
> - /*
> - * If the queue's port is not configured, validate that a free
> - * port-queue pair is available.
> - */
> - if (args->port_id == -1 &&
> - dlb2_list_empty(&domain->avail_dir_pq_pairs)) {
> - resp->status = DLB2_ST_DIR_QUEUES_UNAVAILABLE;
> - return -EINVAL;
> - }
> -
> - return 0;
> -}
> -
> -/**
> - * dlb2_hw_create_dir_queue() - Allocate and initialize a DLB DIR queue.
> - * @hw: Contains the current state of the DLB2 hardware.
> - * @domain_id: Domain ID
> - * @args: User-provided arguments.
> - * @resp: Response to user.
> - * @vdev_req: Request came from a virtual device.
> - * @vdev_id: If vdev_req is true, this contains the virtual device's ID.
> - *
> - * Return: returns < 0 on error, 0 otherwise. If the driver is unable to
> - * satisfy a request, resp->status will be set accordingly.
> - */
> -int dlb2_hw_create_dir_queue(struct dlb2_hw *hw,
> - u32 domain_id,
> - struct dlb2_create_dir_queue_args *args,
> - struct dlb2_cmd_response *resp,
> - bool vdev_req,
> - unsigned int vdev_id)
> -{
> - struct dlb2_dir_pq_pair *queue;
> - struct dlb2_hw_domain *domain;
> - int ret;
> -
> - dlb2_log_create_dir_queue_args(hw, domain_id, args, vdev_req, vdev_id);
> -
> - /*
> - * Verify that hardware resources are available before attempting to
> - * satisfy the request. This simplifies the error unwinding code.
> - */
> - ret = dlb2_verify_create_dir_queue_args(hw,
> - domain_id,
> - args,
> - resp,
> - vdev_req,
> - vdev_id);
> - if (ret)
> - return ret;
> -
> - domain = dlb2_get_domain_from_id(hw, domain_id, vdev_req, vdev_id);
> - if (domain == NULL) {
> - DLB2_HW_ERR(hw,
> - "[%s():%d] Internal error: domain not found\n",
> - __func__, __LINE__);
> - return -EFAULT;
> - }
> -
> - if (args->port_id != -1)
> - queue = dlb2_get_domain_used_dir_pq(hw,
> - args->port_id,
> - vdev_req,
> - domain);
> - else
> - queue = DLB2_DOM_LIST_HEAD(domain->avail_dir_pq_pairs,
> - typeof(*queue));
> - if (queue == NULL) {
> - DLB2_HW_ERR(hw,
> - "[%s():%d] Internal error: no available dir queues\n",
> - __func__, __LINE__);
> - return -EFAULT;
> - }
> -
> - dlb2_configure_dir_queue(hw, domain, queue, args, vdev_req, vdev_id);
> -
> - /*
> - * Configuration succeeded, so move the resource from the 'avail' to
> - * the 'used' list (if it's not already there).
> - */
> - if (args->port_id == -1) {
> - dlb2_list_del(&domain->avail_dir_pq_pairs,
> - &queue->domain_list);
> -
> - dlb2_list_add(&domain->used_dir_pq_pairs,
> - &queue->domain_list);
> - }
> -
> - resp->status = 0;
> -
> - resp->id = (vdev_req) ? queue->id.virt_id : queue->id.phys_id;
> -
> - return 0;
> -}
> -
> static bool
> dlb2_port_find_slot_with_pending_map_queue(struct dlb2_ldb_port *port,
> struct dlb2_ldb_queue *queue,
> diff --git a/drivers/event/dlb2/pf/base/dlb2_resource_new.c b/drivers/event/dlb2/pf/base/dlb2_resource_new.c
> index 4e4b390dd..d4b401250 100644
> --- a/drivers/event/dlb2/pf/base/dlb2_resource_new.c
> +++ b/drivers/event/dlb2/pf/base/dlb2_resource_new.c
> @@ -4857,3 +4857,204 @@ int dlb2_hw_create_dir_port(struct dlb2_hw *hw,
>
> return 0;
> }
> +
> +static void dlb2_configure_dir_queue(struct dlb2_hw *hw,
> + struct dlb2_hw_domain *domain,
> + struct dlb2_dir_pq_pair *queue,
> + struct dlb2_create_dir_queue_args *args,
> + bool vdev_req,
> + unsigned int vdev_id)
> +{
> + unsigned int offs;
> + u32 reg = 0;
> +
> + /* QID write permissions are turned on when the domain is started */
> + offs = domain->id.phys_id * DLB2_MAX_NUM_DIR_QUEUES(hw->ver) +
> + queue->id.phys_id;
> +
> + DLB2_CSR_WR(hw, DLB2_SYS_DIR_VASQID_V(offs), reg);
> +
> + /* Don't timestamp QEs that pass through this queue */
> + DLB2_CSR_WR(hw, DLB2_SYS_DIR_QID_ITS(queue->id.phys_id), reg);
> +
> + reg = 0;
> + DLB2_BITS_SET(reg, args->depth_threshold,
> + DLB2_LSP_QID_DIR_DEPTH_THRSH_THRESH);
> + DLB2_CSR_WR(hw,
> + DLB2_LSP_QID_DIR_DEPTH_THRSH(hw->ver, queue->id.phys_id),
> + reg);
> +
> + if (vdev_req) {
> + offs = vdev_id * DLB2_MAX_NUM_DIR_QUEUES(hw->ver) +
> + queue->id.virt_id;
> +
> + reg = 0;
> + DLB2_BIT_SET(reg, DLB2_SYS_VF_DIR_VQID_V_VQID_V);
> + DLB2_CSR_WR(hw, DLB2_SYS_VF_DIR_VQID_V(offs), reg);
> +
> + reg = 0;
> + DLB2_BITS_SET(reg, queue->id.phys_id,
> + DLB2_SYS_VF_DIR_VQID2QID_QID);
> + DLB2_CSR_WR(hw, DLB2_SYS_VF_DIR_VQID2QID(offs), reg);
> + }
> +
> + reg = 0;
> + DLB2_BIT_SET(reg, DLB2_SYS_DIR_QID_V_QID_V);
> + DLB2_CSR_WR(hw, DLB2_SYS_DIR_QID_V(queue->id.phys_id), reg);
> +
> + queue->queue_configured = true;
> +}
> +
> +static void
> +dlb2_log_create_dir_queue_args(struct dlb2_hw *hw,
> + u32 domain_id,
> + struct dlb2_create_dir_queue_args *args,
> + bool vdev_req,
> + unsigned int vdev_id)
> +{
> + DLB2_HW_DBG(hw, "DLB2 create directed queue arguments:\n");
> + if (vdev_req)
> + DLB2_HW_DBG(hw, "(Request from vdev %d)\n", vdev_id);
> + DLB2_HW_DBG(hw, "\tDomain ID: %d\n", domain_id);
> + DLB2_HW_DBG(hw, "\tPort ID: %d\n", args->port_id);
> +}
> +
> +static int
> +dlb2_verify_create_dir_queue_args(struct dlb2_hw *hw,
> + u32 domain_id,
> + struct dlb2_create_dir_queue_args *args,
> + struct dlb2_cmd_response *resp,
> + bool vdev_req,
> + unsigned int vdev_id,
> + struct dlb2_hw_domain **out_domain,
> + struct dlb2_dir_pq_pair **out_queue)
> +{
> + struct dlb2_hw_domain *domain;
> + struct dlb2_dir_pq_pair *pq;
> +
> + domain = dlb2_get_domain_from_id(hw, domain_id, vdev_req, vdev_id);
> +
> + if (!domain) {
> + resp->status = DLB2_ST_INVALID_DOMAIN_ID;
> + return -EINVAL;
> + }
> +
> + if (!domain->configured) {
> + resp->status = DLB2_ST_DOMAIN_NOT_CONFIGURED;
> + return -EINVAL;
> + }
> +
> + if (domain->started) {
> + resp->status = DLB2_ST_DOMAIN_STARTED;
> + return -EINVAL;
> + }
> +
> + /*
> + * If the user claims the port is already configured, validate the port
> + * ID, its domain, and whether the port is configured.
> + */
> + if (args->port_id != -1) {
> + pq = dlb2_get_domain_used_dir_pq(hw,
> + args->port_id,
> + vdev_req,
> + domain);
> +
> + if (!pq || pq->domain_id.phys_id != domain->id.phys_id ||
> + !pq->port_configured) {
> + resp->status = DLB2_ST_INVALID_PORT_ID;
> + return -EINVAL;
> + }
> + } else {
> + /*
> + * If the queue's port is not configured, validate that a free
> + * port-queue pair is available.
> + */
> + pq = DLB2_DOM_LIST_HEAD(domain->avail_dir_pq_pairs,
> + typeof(*pq));
> + if (!pq) {
> + resp->status = DLB2_ST_DIR_QUEUES_UNAVAILABLE;
> + return -EINVAL;
> + }
> + }
> +
> + *out_domain = domain;
> + *out_queue = pq;
> +
> + return 0;
> +}
> +
> +/**
> + * dlb2_hw_create_dir_queue() - create a directed queue
> + * @hw: dlb2_hw handle for a particular device.
> + * @domain_id: domain ID.
> + * @args: queue creation arguments.
> + * @resp: response structure.
> + * @vdev_req: indicates whether this request came from a vdev.
> + * @vdev_id: If vdev_req is true, this contains the vdev's ID.
> + *
> + * This function creates a directed queue.
> + *
> + * A vdev can be either an SR-IOV virtual function or a Scalable IOV virtual
> + * device.
> + *
> + * Return:
> + * Returns 0 upon success, < 0 otherwise. If an error occurs, resp->status is
> + * assigned a detailed error code from enum dlb2_error. If successful, resp->id
> + * contains the queue ID.
> + *
> + * resp->id contains a virtual ID if vdev_req is true.
> + *
> + * Errors:
> + * EINVAL - A requested resource is unavailable, the domain is not configured,
> + * or the domain has already been started.
> + * EFAULT - Internal error (resp->status not set).
> + */
> +int dlb2_hw_create_dir_queue(struct dlb2_hw *hw,
> + u32 domain_id,
> + struct dlb2_create_dir_queue_args *args,
> + struct dlb2_cmd_response *resp,
> + bool vdev_req,
> + unsigned int vdev_id)
> +{
> + struct dlb2_dir_pq_pair *queue;
> + struct dlb2_hw_domain *domain;
> + int ret;
> +
> + dlb2_log_create_dir_queue_args(hw, domain_id, args, vdev_req, vdev_id);
> +
> + /*
> + * Verify that hardware resources are available before attempting to
> + * satisfy the request. This simplifies the error unwinding code.
> + */
> + ret = dlb2_verify_create_dir_queue_args(hw,
> + domain_id,
> + args,
> + resp,
> + vdev_req,
> + vdev_id,
> + &domain,
> + &queue);
> + if (ret)
> + return ret;
> +
> + dlb2_configure_dir_queue(hw, domain, queue, args, vdev_req, vdev_id);
> +
> + /*
> + * Configuration succeeded, so move the resource from the 'avail' to
> + * the 'used' list (if it's not already there).
> + */
> + if (args->port_id == -1) {
> + dlb2_list_del(&domain->avail_dir_pq_pairs,
> + &queue->domain_list);
> +
> + dlb2_list_add(&domain->used_dir_pq_pairs,
> + &queue->domain_list);
> + }
> +
> + resp->status = 0;
> +
> + resp->id = (vdev_req) ? queue->id.virt_id : queue->id.phys_id;
> +
> + return 0;
> +}
> +
> --
> 2.23.0
>
More information about the dev
mailing list