From patchwork Tue Mar 30 19:35:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timothy McDaniel X-Patchwork-Id: 90125 X-Patchwork-Delegate: jerinj@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7B3FDA034F; Tue, 30 Mar 2021 21:38:02 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CBAD6140EED; Tue, 30 Mar 2021 21:37:00 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mails.dpdk.org (Postfix) with ESMTP id 204F7140E80 for ; Tue, 30 Mar 2021 21:36:41 +0200 (CEST) IronPort-SDR: WPn57zCE1dpNXqYJqhCgTSxw5RwshfBeHQ1/ZOEq1vmmLanQH8Xgj5j06jVeGV/o8xGpUXyheQ nD5cf2fvFyUA== X-IronPort-AV: E=McAfee;i="6000,8403,9939"; a="189601145" X-IronPort-AV: E=Sophos;i="5.81,291,1610438400"; d="scan'208";a="189601145" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Mar 2021 12:36:41 -0700 IronPort-SDR: 3g4SkOsitk7xhjfzm1/TH7ix5v9VCZSMGnaGsdmLnmYVpE1vkVmmQhdIJ+Y6x+RYehyG0wM03Y FJ7wr+yrA8zw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,291,1610438400"; d="scan'208";a="418309708" Received: from txasoft-yocto.an.intel.com ([10.123.72.192]) by orsmga008.jf.intel.com with ESMTP; 30 Mar 2021 12:36:41 -0700 From: Timothy McDaniel To: Cc: dev@dpdk.org, erik.g.carrillo@intel.com, gage.eads@intel.com, harry.van.haaren@intel.com, jerinj@marvell.com, thomas@monjalon.net Date: Tue, 30 Mar 2021 14:35:22 -0500 Message-Id: <1617132940-24800-10-git-send-email-timothy.mcdaniel@intel.com> X-Mailer: git-send-email 1.7.10 In-Reply-To: <1617132940-24800-1-git-send-email-timothy.mcdaniel@intel.com> References: <20210316221857.2254-2-timothy.mcdaniel@intel.com> <1617132940-24800-1-git-send-email-timothy.mcdaniel@intel.com> Subject: [dpdk-dev] [PATCH v2 09/27] event/dlb2: add v2.5 create dir queue X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Updated low level hardware functions to account for new register map and hardware access macros. Signed-off-by: Timothy McDaniel --- drivers/event/dlb2/pf/base/dlb2_resource.c | 213 ------------------ .../event/dlb2/pf/base/dlb2_resource_new.c | 201 +++++++++++++++++ 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; +} +