From c6c1ac5c4f4e89105d5c036f061c3f5941e134cf Mon Sep 17 00:00:00 2001 From: Akhil Goyal Date: Wed, 10 Jan 2018 16:16:41 +0530 Subject: [PATCH] bus/dpaa: support enqueue frames of multiple queues Signed-off-by: Akhil Goyal Signed-off-by: Nipun Gupta Acked-by: Hemant Agrawal --- drivers/bus/dpaa/base/qbman/qman.c | 66 +++++++++++++++++++++++ drivers/bus/dpaa/include/fsl_qman.h | 14 +++++ drivers/bus/dpaa/rte_bus_dpaa_version.map | 1 + 3 files changed, 81 insertions(+) diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c index 7e285a504d..e1713565ea 100644 --- a/drivers/bus/dpaa/base/qbman/qman.c +++ b/drivers/bus/dpaa/base/qbman/qman.c @@ -2158,6 +2158,72 @@ int qman_enqueue_multi(struct qman_fq *fq, return sent; } +int +qman_enqueue_multi_fq(struct qman_fq *fq[], const struct qm_fd *fd, + int frames_to_send) +{ + struct qman_portal *p = get_affine_portal(); + struct qm_portal *portal = &p->p; + + register struct qm_eqcr *eqcr = &portal->eqcr; + struct qm_eqcr_entry *eq = eqcr->cursor, *prev_eq; + + u8 i, diff, old_ci, sent = 0; + + /* Update the available entries if no entry is free */ + if (!eqcr->available) { + old_ci = eqcr->ci; + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1); + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci); + eqcr->available += diff; + if (!diff) + return 0; + } + + /* try to send as many frames as possible */ + while (eqcr->available && frames_to_send--) { + eq->fqid = fq[sent]->fqid_le; + eq->fd.opaque_addr = fd->opaque_addr; + eq->fd.addr = cpu_to_be40(fd->addr); + eq->fd.status = cpu_to_be32(fd->status); + eq->fd.opaque = cpu_to_be32(fd->opaque); + + eq = (void *)((unsigned long)(eq + 1) & + (~(unsigned long)(QM_EQCR_SIZE << 6))); + eqcr->available--; + sent++; + fd++; + } + lwsync(); + + /* In order for flushes to complete faster, all lines are recorded in + * 32 bit word. + */ + eq = eqcr->cursor; + for (i = 0; i < sent; i++) { + eq->__dont_write_directly__verb = + QM_EQCR_VERB_CMD_ENQUEUE | eqcr->vbit; + prev_eq = eq; + eq = (void *)((unsigned long)(eq + 1) & + (~(unsigned long)(QM_EQCR_SIZE << 6))); + if (unlikely((prev_eq + 1) != eq)) + eqcr->vbit ^= QM_EQCR_VERB_VBIT; + } + + /* We need to flush all the lines but without load/store operations + * between them + */ + eq = eqcr->cursor; + for (i = 0; i < sent; i++) { + dcbf(eq); + eq = (void *)((unsigned long)(eq + 1) & + (~(unsigned long)(QM_EQCR_SIZE << 6))); + } + /* Update cursor for the next call */ + eqcr->cursor = eq; + return sent; +} + int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags, struct qman_fq *orp, u16 orp_seqnum) { diff --git a/drivers/bus/dpaa/include/fsl_qman.h b/drivers/bus/dpaa/include/fsl_qman.h index 0b85109d41..927efb1d2a 100644 --- a/drivers/bus/dpaa/include/fsl_qman.h +++ b/drivers/bus/dpaa/include/fsl_qman.h @@ -1703,6 +1703,20 @@ int qman_enqueue_multi(struct qman_fq *fq, const struct qm_fd *fd, int frames_to_send); +/** + * qman_enqueue_multi_fq - Enqueue multiple frames to their respective frame + * queues. + * @fq[]: Array of frame queue objects to enqueue to + * @fd: pointer to first descriptor of frame to be enqueued + * @frames_to_send: number of frames to be sent. + * + * This API is similar to qman_enqueue_multi(), but it takes fd which needs + * to be processed by different frame queues. + */ +int +qman_enqueue_multi_fq(struct qman_fq *fq[], const struct qm_fd *fd, + int frames_to_send); + typedef int (*qman_cb_precommit) (void *arg); /** diff --git a/drivers/bus/dpaa/rte_bus_dpaa_version.map b/drivers/bus/dpaa/rte_bus_dpaa_version.map index ac455cdd5b..64068de961 100644 --- a/drivers/bus/dpaa/rte_bus_dpaa_version.map +++ b/drivers/bus/dpaa/rte_bus_dpaa_version.map @@ -73,6 +73,7 @@ DPDK_18.02 { qman_alloc_pool_range; qman_create_cgr; qman_delete_cgr; + qman_enqueue_multi_fq; qman_modify_cgr; qman_oos_fq; qman_portal_poll_rx; -- 2.20.1