From 830b61ba4ee2b7a33cac160d55275513b1ba4eea Mon Sep 17 00:00:00 2001 From: Madalin Bucur Date: Wed, 21 Nov 2018 13:41:07 +0200 Subject: soc: fsl: qbman: read ithresh from HW Read the DQRR interrupt threshold directly from the hardware. Signed-off-by: Madalin Bucur Signed-off-by: Roy Pledge Signed-off-by: David S. Miller --- drivers/soc/fsl/qbman/qman.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 5ce24718c2fd..ce7c03052e33 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -1025,7 +1025,7 @@ EXPORT_SYMBOL(qman_dqrr_set_ithresh); void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh) { if (portal && ithresh) - *ithresh = portal->p.dqrr.ithresh; + *ithresh = qm_in(&portal->p, QM_REG_DQRR_ITR); } EXPORT_SYMBOL(qman_dqrr_get_ithresh); -- cgit v1.2.3 From 5c664ace8cdfd947d293b97871a4f1e4bedca5b9 Mon Sep 17 00:00:00 2001 From: Madalin Bucur Date: Wed, 21 Nov 2018 13:41:08 +0200 Subject: soc/qman: add return value to interrupt coalesce changing APIs Check that the values received by the portal interrupt coalesce change APIs are in range. Signed-off-by: Madalin Bucur Signed-off-by: Roy Pledge Signed-off-by: David S. Miller --- drivers/soc/fsl/qbman/qman.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index ce7c03052e33..52c153cd795a 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -36,6 +36,8 @@ #define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */ #define QMAN_POLL_LIMIT 32 #define QMAN_PIRQ_DQRR_ITHRESH 12 +#define QMAN_DQRR_IT_MAX 15 +#define QMAN_ITP_MAX 0xFFF #define QMAN_PIRQ_MR_ITHRESH 4 #define QMAN_PIRQ_IPERIOD 100 @@ -727,9 +729,15 @@ static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr) qm_out(portal, QM_REG_DQRR_VDQCR, vdqcr); } -static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh) +static inline int qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh) { + + if (ithresh > QMAN_DQRR_IT_MAX) + return -EINVAL; + qm_out(portal, QM_REG_DQRR_ITR, ithresh); + + return 0; } /* --- MR API --- */ @@ -1012,13 +1020,20 @@ static inline void put_affine_portal(void) static struct workqueue_struct *qm_portal_wq; -void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh) +int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh) { + int res; + if (!portal) - return; + return -EINVAL; + + res = qm_dqrr_set_ithresh(&portal->p, ithresh); + if (res) + return res; - qm_dqrr_set_ithresh(&portal->p, ithresh); portal->p.dqrr.ithresh = ithresh; + + return 0; } EXPORT_SYMBOL(qman_dqrr_set_ithresh); @@ -1036,10 +1051,14 @@ void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod) } EXPORT_SYMBOL(qman_portal_get_iperiod); -void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod) +int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod) { - if (portal) - qm_out(&portal->p, QM_REG_ITPR, iperiod); + if (!portal || iperiod > QMAN_ITP_MAX) + return -EINVAL; + + qm_out(&portal->p, QM_REG_ITPR, iperiod); + + return 0; } EXPORT_SYMBOL(qman_portal_set_iperiod); -- cgit v1.2.3 From e80081c34b03587cf6e89c0a1ea16c71b40bccca Mon Sep 17 00:00:00 2001 From: Roy Pledge Date: Tue, 18 Dec 2018 15:23:01 +0000 Subject: soc: fsl: dpio: Add BP and FQ query APIs Add FQ (Frame Queue) and BP (Buffer Pool) query APIs that users of QBMan can invoke to see the status of the queues and pools that they are using. Signed-off-by: Roy Pledge Signed-off-by: Ioana Radulescu Signed-off-by: Ioana Ciornei Signed-off-by: David S. Miller --- drivers/soc/fsl/dpio/dpio-service.c | 68 ++++++++++++++++++++++++++ drivers/soc/fsl/dpio/qbman-portal.c | 96 +++++++++++++++++++++++++++++++++++++ drivers/soc/fsl/dpio/qbman-portal.h | 58 ++++++++++++++++++++++ 3 files changed, 222 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/dpio/dpio-service.c b/drivers/soc/fsl/dpio/dpio-service.c index 321a92613a7e..ec0837ff039a 100644 --- a/drivers/soc/fsl/dpio/dpio-service.c +++ b/drivers/soc/fsl/dpio/dpio-service.c @@ -601,3 +601,71 @@ struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last) return ret; } EXPORT_SYMBOL_GPL(dpaa2_io_store_next); + +/** + * dpaa2_io_query_fq_count() - Get the frame and byte count for a given fq. + * @d: the given DPIO object. + * @fqid: the id of frame queue to be queried. + * @fcnt: the queried frame count. + * @bcnt: the queried byte count. + * + * Knowing the FQ count at run-time can be useful in debugging situations. + * The instantaneous frame- and byte-count are hereby returned. + * + * Return 0 for a successful query, and negative error code if query fails. + */ +int dpaa2_io_query_fq_count(struct dpaa2_io *d, u32 fqid, + u32 *fcnt, u32 *bcnt) +{ + struct qbman_fq_query_np_rslt state; + struct qbman_swp *swp; + unsigned long irqflags; + int ret; + + d = service_select(d); + if (!d) + return -ENODEV; + + swp = d->swp; + spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags); + ret = qbman_fq_query_state(swp, fqid, &state); + spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags); + if (ret) + return ret; + *fcnt = qbman_fq_state_frame_count(&state); + *bcnt = qbman_fq_state_byte_count(&state); + + return 0; +} +EXPORT_SYMBOL_GPL(dpaa2_io_query_fq_count); + +/** + * dpaa2_io_query_bp_count() - Query the number of buffers currently in a + * buffer pool. + * @d: the given DPIO object. + * @bpid: the index of buffer pool to be queried. + * @num: the queried number of buffers in the buffer pool. + * + * Return 0 for a successful query, and negative error code if query fails. + */ +int dpaa2_io_query_bp_count(struct dpaa2_io *d, u16 bpid, u32 *num) +{ + struct qbman_bp_query_rslt state; + struct qbman_swp *swp; + unsigned long irqflags; + int ret; + + d = service_select(d); + if (!d) + return -ENODEV; + + swp = d->swp; + spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags); + ret = qbman_bp_query(swp, bpid, &state); + spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags); + if (ret) + return ret; + *num = qbman_bp_info_num_free_bufs(&state); + return 0; +} +EXPORT_SYMBOL_GPL(dpaa2_io_query_bp_count); diff --git a/drivers/soc/fsl/dpio/qbman-portal.c b/drivers/soc/fsl/dpio/qbman-portal.c index cf1d448ea468..0bddb85c0ae5 100644 --- a/drivers/soc/fsl/dpio/qbman-portal.c +++ b/drivers/soc/fsl/dpio/qbman-portal.c @@ -1003,3 +1003,99 @@ int qbman_swp_CDAN_set(struct qbman_swp *s, u16 channelid, return 0; } + +#define QBMAN_RESPONSE_VERB_MASK 0x7f +#define QBMAN_FQ_QUERY_NP 0x45 +#define QBMAN_BP_QUERY 0x32 + +struct qbman_fq_query_desc { + u8 verb; + u8 reserved[3]; + __le32 fqid; + u8 reserved2[56]; +}; + +int qbman_fq_query_state(struct qbman_swp *s, u32 fqid, + struct qbman_fq_query_np_rslt *r) +{ + struct qbman_fq_query_desc *p; + void *resp; + + p = (struct qbman_fq_query_desc *)qbman_swp_mc_start(s); + if (!p) + return -EBUSY; + + /* FQID is a 24 bit value */ + p->fqid = cpu_to_le32(fqid & 0x00FFFFFF); + resp = qbman_swp_mc_complete(s, p, QBMAN_FQ_QUERY_NP); + if (!resp) { + pr_err("qbman: Query FQID %d NP fields failed, no response\n", + fqid); + return -EIO; + } + *r = *(struct qbman_fq_query_np_rslt *)resp; + /* Decode the outcome */ + WARN_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_FQ_QUERY_NP); + + /* Determine success or failure */ + if (r->rslt != QBMAN_MC_RSLT_OK) { + pr_err("Query NP fields of FQID 0x%x failed, code=0x%02x\n", + p->fqid, r->rslt); + return -EIO; + } + + return 0; +} + +u32 qbman_fq_state_frame_count(const struct qbman_fq_query_np_rslt *r) +{ + return (le32_to_cpu(r->frm_cnt) & 0x00FFFFFF); +} + +u32 qbman_fq_state_byte_count(const struct qbman_fq_query_np_rslt *r) +{ + return le32_to_cpu(r->byte_cnt); +} + +struct qbman_bp_query_desc { + u8 verb; + u8 reserved; + __le16 bpid; + u8 reserved2[60]; +}; + +int qbman_bp_query(struct qbman_swp *s, u16 bpid, + struct qbman_bp_query_rslt *r) +{ + struct qbman_bp_query_desc *p; + void *resp; + + p = (struct qbman_bp_query_desc *)qbman_swp_mc_start(s); + if (!p) + return -EBUSY; + + p->bpid = cpu_to_le16(bpid); + resp = qbman_swp_mc_complete(s, p, QBMAN_BP_QUERY); + if (!resp) { + pr_err("qbman: Query BPID %d fields failed, no response\n", + bpid); + return -EIO; + } + *r = *(struct qbman_bp_query_rslt *)resp; + /* Decode the outcome */ + WARN_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_BP_QUERY); + + /* Determine success or failure */ + if (r->rslt != QBMAN_MC_RSLT_OK) { + pr_err("Query fields of BPID 0x%x failed, code=0x%02x\n", + bpid, r->rslt); + return -EIO; + } + + return 0; +} + +u32 qbman_bp_info_num_free_bufs(struct qbman_bp_query_rslt *a) +{ + return le32_to_cpu(a->fill); +} diff --git a/drivers/soc/fsl/dpio/qbman-portal.h b/drivers/soc/fsl/dpio/qbman-portal.h index 89d1dd9969b6..fa35fc1afeaa 100644 --- a/drivers/soc/fsl/dpio/qbman-portal.h +++ b/drivers/soc/fsl/dpio/qbman-portal.h @@ -441,4 +441,62 @@ static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd, return cmd; } +/* Query APIs */ +struct qbman_fq_query_np_rslt { + u8 verb; + u8 rslt; + u8 st1; + u8 st2; + u8 reserved[2]; + __le16 od1_sfdr; + __le16 od2_sfdr; + __le16 od3_sfdr; + __le16 ra1_sfdr; + __le16 ra2_sfdr; + __le32 pfdr_hptr; + __le32 pfdr_tptr; + __le32 frm_cnt; + __le32 byte_cnt; + __le16 ics_surp; + u8 is; + u8 reserved2[29]; +}; + +int qbman_fq_query_state(struct qbman_swp *s, u32 fqid, + struct qbman_fq_query_np_rslt *r); +u32 qbman_fq_state_frame_count(const struct qbman_fq_query_np_rslt *r); +u32 qbman_fq_state_byte_count(const struct qbman_fq_query_np_rslt *r); + +struct qbman_bp_query_rslt { + u8 verb; + u8 rslt; + u8 reserved[4]; + u8 bdi; + u8 state; + __le32 fill; + __le32 hdotr; + __le16 swdet; + __le16 swdxt; + __le16 hwdet; + __le16 hwdxt; + __le16 swset; + __le16 swsxt; + __le16 vbpid; + __le16 icid; + __le64 bpscn_addr; + __le64 bpscn_ctx; + __le16 hw_targ; + u8 dbe; + u8 reserved2; + u8 sdcnt; + u8 hdcnt; + u8 sscnt; + u8 reserved3[9]; +}; + +int qbman_bp_query(struct qbman_swp *s, u16 bpid, + struct qbman_bp_query_rslt *r); + +u32 qbman_bp_info_num_free_bufs(struct qbman_bp_query_rslt *a); + #endif /* __FSL_QBMAN_PORTAL_H */ -- cgit v1.2.3