lkml.org 
[lkml]   [2019]   [Dec]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/3] soc: fsl: dpio: Adding QMAN multiple enqueue interface.
    Date
    Update of QMAN the interface to enqueue frame. We now support multiple
    enqueue (qbman_swp_enqueue_multiple) and multiple enqueue with
    a table of descriptor (qbman_swp_enqueue_multiple_desc).

    Signed-off-by: Youri Querry <youri.querry_1@nxp.com>
    ---
    drivers/soc/fsl/dpio/dpio-service.c | 69 ++++++++++++++++++++++++++++--
    drivers/soc/fsl/dpio/qbman-portal.c | 83 +++++++++++++++++++++++++++++++------
    drivers/soc/fsl/dpio/qbman-portal.h | 24 +++++++++++
    include/soc/fsl/dpaa2-io.h | 6 ++-
    4 files changed, 165 insertions(+), 17 deletions(-)

    diff --git a/drivers/soc/fsl/dpio/dpio-service.c b/drivers/soc/fsl/dpio/dpio-service.c
    index 518a8e0..cd4f641 100644
    --- a/drivers/soc/fsl/dpio/dpio-service.c
    +++ b/drivers/soc/fsl/dpio/dpio-service.c
    @@ -1,7 +1,7 @@
    // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
    /*
    * Copyright 2014-2016 Freescale Semiconductor Inc.
    - * Copyright 2016 NXP
    + * Copyright 2016-2019 NXP
    *
    */
    #include <linux/types.h>
    @@ -433,6 +433,69 @@ int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d,
    EXPORT_SYMBOL(dpaa2_io_service_enqueue_fq);

    /**
    + * dpaa2_io_service_enqueue_multiple_fq() - Enqueue multiple frames
    + * to a frame queue using one fqid.
    + * @d: the given DPIO service.
    + * @fqid: the given frame queue id.
    + * @fd: the frame descriptor which is enqueued.
    + * @nb: number of frames to be enqueud
    + *
    + * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready,
    + * or -ENODEV if there is no dpio service.
    + */
    +int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d,
    + u32 fqid,
    + const struct dpaa2_fd *fd,
    + int nb)
    +{
    + struct qbman_eq_desc ed;
    +
    + d = service_select(d);
    + if (!d)
    + return -ENODEV;
    +
    + qbman_eq_desc_clear(&ed);
    + qbman_eq_desc_set_no_orp(&ed, 0);
    + qbman_eq_desc_set_fq(&ed, fqid);
    +
    + return qbman_swp_enqueue_multiple(d->swp, &ed, fd, 0, nb);
    +}
    +EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_fq);
    +
    +/**
    + * dpaa2_io_service_enqueue_multiple_desc_fq() - Enqueue multiple frames
    + * to different frame queue using a list of fqids.
    + * @d: the given DPIO service.
    + * @fqid: the given list of frame queue ids.
    + * @fd: the frame descriptor which is enqueued.
    + * @nb: number of frames to be enqueud
    + *
    + * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready,
    + * or -ENODEV if there is no dpio service.
    + */
    +int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d,
    + u32 *fqid,
    + const struct dpaa2_fd *fd,
    + int nb)
    +{
    + int i;
    + struct qbman_eq_desc ed[32];
    +
    + d = service_select(d);
    + if (!d)
    + return -ENODEV;
    +
    + for (i = 0; i < nb; i++) {
    + qbman_eq_desc_clear(&ed[i]);
    + qbman_eq_desc_set_no_orp(&ed[i], 0);
    + qbman_eq_desc_set_fq(&ed[i], fqid[i]);
    + }
    +
    + return qbman_swp_enqueue_multiple_desc(d->swp, &ed[0], fd, nb);
    +}
    +EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_desc_fq);
    +
    +/**
    * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD.
    * @d: the given DPIO service.
    * @qdid: the given queuing destination id.
    @@ -526,7 +589,7 @@ EXPORT_SYMBOL_GPL(dpaa2_io_service_acquire);

    /**
    * dpaa2_io_store_create() - Create the dma memory storage for dequeue result.
    - * @max_frames: the maximum number of dequeued result for frames, must be <= 16.
    + * @max_frames: the maximum number of dequeued result for frames, must be <= 32.
    * @dev: the device to allow mapping/unmapping the DMAable region.
    *
    * The size of the storage is "max_frames*sizeof(struct dpaa2_dq)".
    @@ -541,7 +604,7 @@ struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
    struct dpaa2_io_store *ret;
    size_t size;

    - if (!max_frames || (max_frames > 16))
    + if (!max_frames || (max_frames > 32))
    return NULL;

    ret = kmalloc(sizeof(*ret), GFP_KERNEL);
    diff --git a/drivers/soc/fsl/dpio/qbman-portal.c b/drivers/soc/fsl/dpio/qbman-portal.c
    index c66f5b7..5a37ac8 100644
    --- a/drivers/soc/fsl/dpio/qbman-portal.c
    +++ b/drivers/soc/fsl/dpio/qbman-portal.c
    @@ -1,7 +1,7 @@
    // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
    /*
    * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
    - * Copyright 2016 NXP
    + * Copyright 2016-2019 NXP
    *
    */

    @@ -12,13 +12,6 @@

    #include "qbman-portal.h"

    -#define QMAN_REV_4000 0x04000000
    -#define QMAN_REV_4100 0x04010000
    -#define QMAN_REV_4101 0x04010001
    -#define QMAN_REV_5000 0x05000000
    -
    -#define QMAN_REV_MASK 0xffff0000
    -
    /* All QBMan command and result structures use this "valid bit" encoding */
    #define QB_VALID_BIT ((u32)0x80)

    @@ -156,7 +149,7 @@ static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn, u8 est, u8 rpm, u8 dcm,
    */
    struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
    {
    - struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
    + struct qbman_swp *p = kzalloc(sizeof(*p), GFP_KERNEL);
    u32 reg;

    if (!p)
    @@ -467,22 +460,32 @@ static inline void qbman_write_eqcr_am_rt_register(struct qbman_swp *p,
    int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
    const struct dpaa2_fd *fd)
    {
    - struct qbman_eq_desc *p;
    + struct qbman_eq_desc_with_fd *p;
    u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR);

    if (!EQAR_SUCCESS(eqar))
    return -EBUSY;

    p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
    - memcpy(&p->dca, &d->dca, 31);
    + /* This is mapped as DEVICE type memory, writes are
    + * with address alignment:
    + * desc.dca address alignment = 1
    + * desc.seqnum address alignment = 2
    + * desc.orpid address alignment = 4
    + * desc.tgtid address alignment = 8
    + */
    + p->desc.dca = d->dca;
    + p->desc.seqnum = d->seqnum;
    + p->desc.orpid = d->orpid;
    + memcpy(&p->desc.tgtid, &d->tgtid, 24);
    memcpy(&p->fd, fd, sizeof(*fd));

    if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
    /* Set the verb byte, have to substitute in the valid-bit */
    dma_wmb();
    - p->verb = d->verb | EQAR_VB(eqar);
    + p->desc.verb = d->verb | EQAR_VB(eqar);
    } else {
    - p->verb = d->verb | EQAR_VB(eqar);
    + p->desc.verb = d->verb | EQAR_VB(eqar);
    dma_wmb();
    qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar));
    }
    @@ -490,6 +493,60 @@ int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
    return 0;
    }

    +/**
    + * qbman_swp_enqueue_multiple() - Issue a multi enqueue command
    + * using one enqueue descriptor
    + * @s: the software portal used for enqueue
    + * @d: the enqueue descriptor
    + * @fd: table pointer of frame descriptor table to be enqueued
    + * @flags: table pointer of flags, not used for the moment
    + * @num_frames: number of fd to be enqueued
    + *
    + * Return the number of fd enqueued, or a negative error number.
    + */
    +int qbman_swp_enqueue_multiple(struct qbman_swp *s,
    + const struct qbman_eq_desc *d,
    + const struct dpaa2_fd *fd,
    + uint32_t *flags,
    + int num_frames)
    +{
    + int count = 0;
    +
    + while (count < num_frames) {
    + if (qbman_swp_enqueue(s, d, fd) != 0)
    + break;
    + count++;
    + }
    +
    + return count;
    +}
    +
    +/**
    + * qbman_swp_enqueue_multiple_desc() - Issue a multi enqueue command
    + * using multiple enqueue descriptor
    + * @s: the software portal used for enqueue
    + * @d: table of minimal enqueue descriptor
    + * @fd: table pointer of frame descriptor table to be enqueued
    + * @num_frames: number of fd to be enqueued
    + *
    + * Return the number of fd enqueued, or a negative error number.
    + */
    +int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,
    + const struct qbman_eq_desc *d,
    + const struct dpaa2_fd *fd,
    + int num_frames)
    +{
    + int count = 0;
    +
    + while (count < num_frames) {
    + if (qbman_swp_enqueue(s, &(d[count]), fd) != 0)
    + break;
    + count++;
    + }
    +
    + return count;
    +}
    +
    /* Static (push) dequeue */

    /**
    diff --git a/drivers/soc/fsl/dpio/qbman-portal.h b/drivers/soc/fsl/dpio/qbman-portal.h
    index f3ec5d2..ac58a97 100644
    --- a/drivers/soc/fsl/dpio/qbman-portal.h
    +++ b/drivers/soc/fsl/dpio/qbman-portal.h
    @@ -9,6 +9,13 @@

    #include <soc/fsl/dpaa2-fd.h>

    +#define QMAN_REV_4000 0x04000000
    +#define QMAN_REV_4100 0x04010000
    +#define QMAN_REV_4101 0x04010001
    +#define QMAN_REV_5000 0x05000000
    +
    +#define QMAN_REV_MASK 0xffff0000
    +
    struct dpaa2_dq;
    struct qbman_swp;

    @@ -81,6 +88,10 @@ struct qbman_eq_desc {
    u8 wae;
    u8 rspid;
    __le64 rsp_addr;
    +};
    +
    +struct qbman_eq_desc_with_fd {
    + struct qbman_eq_desc desc;
    u8 fd[32];
    };

    @@ -193,6 +204,19 @@ void *qbman_swp_mc_start(struct qbman_swp *p);
    void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb);
    void *qbman_swp_mc_result(struct qbman_swp *p);

    +int
    +qbman_swp_enqueue_multiple(struct qbman_swp *s,
    + const struct qbman_eq_desc *d,
    + const struct dpaa2_fd *fd,
    + uint32_t *flags,
    + int num_frames);
    +
    +int
    +qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,
    + const struct qbman_eq_desc *d,
    + const struct dpaa2_fd *fd,
    + int num_frames);
    +
    /**
    * qbman_result_is_DQ() - check if the dequeue result is a dequeue response
    * @dq: the dequeue result to be checked
    diff --git a/include/soc/fsl/dpaa2-io.h b/include/soc/fsl/dpaa2-io.h
    index 672cfb5..c9d8499 100644
    --- a/include/soc/fsl/dpaa2-io.h
    +++ b/include/soc/fsl/dpaa2-io.h
    @@ -1,7 +1,7 @@
    /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
    /*
    * Copyright 2014-2016 Freescale Semiconductor Inc.
    - * Copyright NXP
    + * Copyright 2017-2019 NXP
    *
    */
    #ifndef __FSL_DPAA2_IO_H
    @@ -109,6 +109,10 @@ int dpaa2_io_service_pull_channel(struct dpaa2_io *d, u32 channelid,

    int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d, u32 fqid,
    const struct dpaa2_fd *fd);
    +int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d, u32 fqid,
    + const struct dpaa2_fd *fd, int number_of_frame);
    +int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, u32 *fqid,
    + const struct dpaa2_fd *fd, int number_of_frame);
    int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio,
    u16 qdbin, const struct dpaa2_fd *fd);
    int dpaa2_io_service_release(struct dpaa2_io *d, u16 bpid,
    --
    2.7.4
    \
     
     \ /
      Last update: 2019-12-12 18:02    [W:3.221 / U:0.864 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site