soc: fsl: dpio: Add BP and FQ query APIs
authorRoy Pledge <roy.pledge@nxp.com>
Tue, 18 Dec 2018 15:23:01 +0000 (15:23 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 19 Dec 2018 18:37:22 +0000 (10:37 -0800)
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 <roy.pledge@nxp.com>
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/soc/fsl/dpio/dpio-service.c
drivers/soc/fsl/dpio/qbman-portal.c
drivers/soc/fsl/dpio/qbman-portal.h
include/soc/fsl/dpaa2-io.h

index 321a92613a7eb4df1dd48b7cfafc64f659a1ed88..ec0837ff039a0a334d11df97bde68d6316bbaaee 100644 (file)
@@ -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);
index cf1d448ea4688ce94555992d79a950feb5cc9857..0bddb85c0ae54c37c3d37dee7787e0f39efeb1e8 100644 (file)
@@ -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);
+}
index 89d1dd9969b6239712f7ecc407bd70517c5ad2a9..fa35fc1afeaa281432eed5ac686447a3fee17ac8 100644 (file)
@@ -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 */
index 70997ab2146cb34c6fbd0a4d409d6c723a27f72b..3fbd71c27ba30f6e5c1b5adc6e1d64ac75707128 100644 (file)
@@ -116,4 +116,8 @@ struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
 void dpaa2_io_store_destroy(struct dpaa2_io_store *s);
 struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last);
 
+int dpaa2_io_query_fq_count(struct dpaa2_io *d, u32 fqid,
+                           u32 *fcnt, u32 *bcnt);
+int dpaa2_io_query_bp_count(struct dpaa2_io *d, u16 bpid,
+                           u32 *num);
 #endif /* __FSL_DPAA2_IO_H */