From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nipun Gupta Subject: [PATCH 14/21 v4] bus/fslmc: support enqueue with multiple enqueue descriptors Date: Thu, 29 Jun 2017 15:57:58 +0530 Message-ID: <1498732085-18449-15-git-send-email-nipun.gupta@nxp.com> References: <1495735361-4840-1-git-send-email-nipun.gupta@nxp.com> <1498732085-18449-1-git-send-email-nipun.gupta@nxp.com> Mime-Version: 1.0 Content-Type: text/plain Cc: , , , , , , Nipun Gupta To: Return-path: Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1nam02on0080.outbound.protection.outlook.com [104.47.36.80]) by dpdk.org (Postfix) with ESMTP id 012BB7CD8 for ; Thu, 29 Jun 2017 12:29:18 +0200 (CEST) In-Reply-To: <1498732085-18449-1-git-send-email-nipun.gupta@nxp.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch adds the QBMAN API which support multiple enqueue descriptors. Signed-off-by: Nipun Gupta --- drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h | 14 +++++ drivers/bus/fslmc/qbman/qbman_portal.c | 70 ++++++++++++++++++++++ drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 + 3 files changed, 85 insertions(+) diff --git a/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h b/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h index 7731772..39407c8 100644 --- a/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h +++ b/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h @@ -883,6 +883,20 @@ void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable, */ int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct qbman_fd *fd); +/** + * qbman_swp_enqueue_multiple_eqdesc() - Enqueue multiple frames with separte + * enqueue descriptors. + * @s: the software portal used for enqueue. + * @d: the enqueue descriptors + * @fd: the frame descriptor to be enqueued. + * @num_frames: the number of the frames to be enqueued. + * + * Return the number of enqueued frames, -EBUSY if the EQCR is not ready. + */ +int qbman_swp_enqueue_multiple_eqdesc(struct qbman_swp *s, + const struct qbman_eq_desc *d, + const struct qbman_fd *fd, + int num_frames); /* TODO: * qbman_swp_enqueue_thresh() - Set threshold for EQRI interrupt. diff --git a/drivers/bus/fslmc/qbman/qbman_portal.c b/drivers/bus/fslmc/qbman/qbman_portal.c index be4e2e5..137b55d 100644 --- a/drivers/bus/fslmc/qbman/qbman_portal.c +++ b/drivers/bus/fslmc/qbman/qbman_portal.c @@ -574,6 +574,76 @@ int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, return qbman_swp_enqueue_ring_mode(s, d, fd); } +int qbman_swp_enqueue_multiple_eqdesc(struct qbman_swp *s, + const struct qbman_eq_desc *d, + const struct qbman_fd *fd, + int num_frames) +{ + uint32_t *p; + const uint32_t *cl = qb_cl(d); + uint32_t eqcr_ci, eqcr_pi; + uint8_t diff; + int i, num_enqueued = 0; + uint64_t addr_cena; + + if (!s->eqcr.available) { + eqcr_ci = s->eqcr.ci; + s->eqcr.ci = qbman_cena_read_reg(&s->sys, + QBMAN_CENA_SWP_EQCR_CI) & 0xF; + diff = qm_cyc_diff(QBMAN_EQCR_SIZE, + eqcr_ci, s->eqcr.ci); + s->eqcr.available += diff; + if (!diff) + return 0; + } + + eqcr_pi = s->eqcr.pi; + num_enqueued = (s->eqcr.available < num_frames) ? + s->eqcr.available : num_frames; + s->eqcr.available -= num_enqueued; + /* Fill in the EQCR ring */ + for (i = 0; i < num_enqueued; i++) { + p = qbman_cena_write_start_wo_shadow(&s->sys, + QBMAN_CENA_SWP_EQCR(eqcr_pi & 7)); + memcpy(&p[1], &cl[1], 28); + memcpy(&p[8], &fd[i], sizeof(*fd)); + eqcr_pi++; + eqcr_pi &= 0xF; + /*Pointing to the next enqueue descriptor*/ + cl += (sizeof(struct qbman_eq_desc) / sizeof(uint32_t)); + } + + lwsync(); + + /* Set the verb byte, have to substitute in the valid-bit */ + eqcr_pi = s->eqcr.pi; + cl = qb_cl(d); + for (i = 0; i < num_enqueued; i++) { + p = qbman_cena_write_start_wo_shadow(&s->sys, + QBMAN_CENA_SWP_EQCR(eqcr_pi & 7)); + p[0] = cl[0] | s->eqcr.pi_vb; + eqcr_pi++; + eqcr_pi &= 0xF; + if (!(eqcr_pi & 7)) + s->eqcr.pi_vb ^= QB_VALID_BIT; + /*Pointing to the next enqueue descriptor*/ + cl += (sizeof(struct qbman_eq_desc) / sizeof(uint32_t)); + } + + /* Flush all the cacheline without load/store in between */ + eqcr_pi = s->eqcr.pi; + addr_cena = (uint64_t)s->sys.addr_cena; + for (i = 0; i < num_enqueued; i++) { + dcbf((uint64_t *)(addr_cena + + QBMAN_CENA_SWP_EQCR(eqcr_pi & 7))); + eqcr_pi++; + eqcr_pi &= 0xF; + } + s->eqcr.pi = eqcr_pi; + + return num_enqueued; +} + /*************************/ /* Static (push) dequeue */ /*************************/ diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map index c879e2f..9950557 100644 --- a/drivers/bus/fslmc/rte_bus_fslmc_version.map +++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map @@ -69,6 +69,7 @@ DPDK_17.08 { qbman_result_SCN_state_in_mem; qbman_swp_dqrr_consume; qbman_swp_dqrr_next; + qbman_swp_enqueue_multiple_eqdesc; qbman_swp_push_set; rte_dpaa2_alloc_dpci_dev; rte_fslmc_object_register; -- 1.9.1