blob: 3c76eefe710e99899543f39c6c309860874ea35c [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 1da6ba0350da068295d5bc5556193b21da38a388 Mon Sep 17 00:00:00 2001
2From: Youri Querry <youri.querry_1@nxp.com>
3Date: Mon, 4 Nov 2019 10:32:37 -0500
4Subject: [PATCH] soc: fsl: dpio: Adding QMAN multiple enqueue interface.
5
6Update of QMAN the interface to enqueue frame. We now support multiple
7enqueue (qbman_swp_enqueue_multiple) and multiple enqueue with
8a table of descriptor (qbman_swp_enqueue_multiple_desc).
9
10Signed-off-by: Youri Querry <youri.querry_1@nxp.com>
11---
12 drivers/soc/fsl/dpio/dpio-service.c | 69 ++++++++++++++++++++++++++++++++--
13 drivers/soc/fsl/dpio/qbman-portal.c | 75 +++++++++++++++++++++++++++++++------
14 drivers/soc/fsl/dpio/qbman-portal.h | 17 +++++++++
15 include/soc/fsl/dpaa2-io.h | 6 ++-
16 4 files changed, 152 insertions(+), 15 deletions(-)
17
18--- a/drivers/soc/fsl/dpio/dpio-service.c
19+++ b/drivers/soc/fsl/dpio/dpio-service.c
20@@ -1,7 +1,7 @@
21 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
22 /*
23 * Copyright 2014-2016 Freescale Semiconductor Inc.
24- * Copyright 2016 NXP
25+ * Copyright 2016-2019 NXP
26 *
27 */
28 #include <linux/types.h>
29@@ -437,6 +437,69 @@ int dpaa2_io_service_enqueue_fq(struct d
30 EXPORT_SYMBOL(dpaa2_io_service_enqueue_fq);
31
32 /**
33+ * dpaa2_io_service_enqueue_multiple_fq() - Enqueue multiple frames
34+ * to a frame queue using one fqid.
35+ * @d: the given DPIO service.
36+ * @fqid: the given frame queue id.
37+ * @fd: the frame descriptor which is enqueued.
38+ * @nb: number of frames to be enqueud
39+ *
40+ * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready,
41+ * or -ENODEV if there is no dpio service.
42+ */
43+int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d,
44+ u32 fqid,
45+ const struct dpaa2_fd *fd,
46+ int nb)
47+{
48+ struct qbman_eq_desc ed;
49+
50+ d = service_select(d);
51+ if (!d)
52+ return -ENODEV;
53+
54+ qbman_eq_desc_clear(&ed);
55+ qbman_eq_desc_set_no_orp(&ed, 0);
56+ qbman_eq_desc_set_fq(&ed, fqid);
57+
58+ return qbman_swp_enqueue_multiple(d->swp, &ed, fd, 0, nb);
59+}
60+EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_fq);
61+
62+/**
63+ * dpaa2_io_service_enqueue_multiple_desc_fq() - Enqueue multiple frames
64+ * to different frame queue using a list of fqids.
65+ * @d: the given DPIO service.
66+ * @fqid: the given list of frame queue ids.
67+ * @fd: the frame descriptor which is enqueued.
68+ * @nb: number of frames to be enqueud
69+ *
70+ * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready,
71+ * or -ENODEV if there is no dpio service.
72+ */
73+int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d,
74+ u32 *fqid,
75+ const struct dpaa2_fd *fd,
76+ int nb)
77+{
78+ int i;
79+ struct qbman_eq_desc ed[32];
80+
81+ d = service_select(d);
82+ if (!d)
83+ return -ENODEV;
84+
85+ for (i = 0; i < nb; i++) {
86+ qbman_eq_desc_clear(&ed[i]);
87+ qbman_eq_desc_set_no_orp(&ed[i], 0);
88+ qbman_eq_desc_set_fq(&ed[i], fqid[i]);
89+ }
90+
91+ return qbman_swp_enqueue_multiple_desc(d->swp, &ed[0], fd, nb);
92+}
93+EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_desc_fq);
94+
95+/**
96 * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD.
97 * @d: the given DPIO service.
98 * @qdid: the given queuing destination id.
99@@ -530,7 +593,7 @@ EXPORT_SYMBOL_GPL(dpaa2_io_service_acqui
100
101 /**
102 * dpaa2_io_store_create() - Create the dma memory storage for dequeue result.
103- * @max_frames: the maximum number of dequeued result for frames, must be <= 16.
104+ * @max_frames: the maximum number of dequeued result for frames, must be <= 32.
105 * @dev: the device to allow mapping/unmapping the DMAable region.
106 *
107 * The size of the storage is "max_frames*sizeof(struct dpaa2_dq)".
108@@ -545,7 +608,7 @@ struct dpaa2_io_store *dpaa2_io_store_cr
109 struct dpaa2_io_store *ret;
110 size_t size;
111
112- if (!max_frames || (max_frames > 16))
113+ if (!max_frames || (max_frames > 32))
114 return NULL;
115
116 ret = kmalloc(sizeof(*ret), GFP_KERNEL);
117--- a/drivers/soc/fsl/dpio/qbman-portal.c
118+++ b/drivers/soc/fsl/dpio/qbman-portal.c
119@@ -1,7 +1,7 @@
120 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
121 /*
122 * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
123- * Copyright 2016 NXP
124+ * Copyright 2016-2019 NXP
125 *
126 */
127
128@@ -86,7 +86,7 @@ enum qbman_sdqcr_fc {
129
130 #define dccvac(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
131 #define dcivac(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
132-static inline void qbman_inval_prefetch(struct qbman_swp *p, uint32_t offset)
133+static inline void qbman_inval_prefetch(struct qbman_swp *p, u32 offset)
134 {
135 dcivac(p->addr_cena + offset);
136 prefetch(p->addr_cena + offset);
137@@ -158,7 +158,7 @@ static inline u32 qbman_set_swp_cfg(u8 m
138 */
139 struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
140 {
141- struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
142+ struct qbman_swp *p = kzalloc(sizeof(*p), GFP_KERNEL);
143 u32 reg;
144
145 if (!p)
146@@ -380,7 +380,6 @@ enum qb_enqueue_commands {
147 };
148
149 #define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT 2
150-#define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3
151 #define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT 4
152
153 /**
154@@ -508,7 +507,7 @@ static inline void qbman_write_eqcr_am_r
155 int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
156 const struct dpaa2_fd *fd)
157 {
158- struct qbman_eq_desc *p;
159+ struct qbman_eq_desc_with_fd *p;
160 u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR);
161
162 if (!EQAR_SUCCESS(eqar))
163@@ -522,19 +521,19 @@ int qbman_swp_enqueue(struct qbman_swp *
164 * desc.orpid address alignment = 4
165 * desc.tgtid address alignment = 8
166 */
167- p->dca = d->dca;
168- p->seqnum = d->seqnum;
169- p->orpid = d->orpid;
170- memcpy(&p->tgtid, &d->tgtid, 24);
171+ p->desc.dca = d->dca;
172+ p->desc.seqnum = d->seqnum;
173+ p->desc.orpid = d->orpid;
174+ memcpy(&p->desc.tgtid, &d->tgtid, 24);
175 memcpy(&p->fd, fd, sizeof(*fd));
176
177 if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
178 /* Set the verb byte, have to substitute in the valid-bit */
179 dma_wmb();
180- p->verb = d->verb | EQAR_VB(eqar);
181+ p->desc.verb = d->verb | EQAR_VB(eqar);
182 dccvac(p);
183 } else {
184- p->verb = d->verb | EQAR_VB(eqar);
185+ p->desc.verb = d->verb | EQAR_VB(eqar);
186 dma_wmb();
187 qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar));
188 }
189@@ -542,6 +541,60 @@ int qbman_swp_enqueue(struct qbman_swp *
190 return 0;
191 }
192
193+/**
194+ * qbman_swp_enqueue_multiple() - Issue a multi enqueue command
195+ * using one enqueue descriptor
196+ * @s: the software portal used for enqueue
197+ * @d: the enqueue descriptor
198+ * @fd: table pointer of frame descriptor table to be enqueued
199+ * @flags: table pointer of flags, not used for the moment
200+ * @num_frames: number of fd to be enqueued
201+ *
202+ * Return the number of fd enqueued, or a negative error number.
203+ */
204+int qbman_swp_enqueue_multiple(struct qbman_swp *s,
205+ const struct qbman_eq_desc *d,
206+ const struct dpaa2_fd *fd,
207+ uint32_t *flags,
208+ int num_frames)
209+{
210+ int count = 0;
211+
212+ while (count < num_frames) {
213+ if (qbman_swp_enqueue(s, d, fd) != 0)
214+ break;
215+ count++;
216+ }
217+
218+ return count;
219+}
220+
221+/**
222+ * qbman_swp_enqueue_multiple_desc() - Issue a multi enqueue command
223+ * using multiple enqueue descriptor
224+ * @s: the software portal used for enqueue
225+ * @d: table of minimal enqueue descriptor
226+ * @fd: table pointer of frame descriptor table to be enqueued
227+ * @num_frames: number of fd to be enqueued
228+ *
229+ * Return the number of fd enqueued, or a negative error number.
230+ */
231+int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,
232+ const struct qbman_eq_desc *d,
233+ const struct dpaa2_fd *fd,
234+ int num_frames)
235+{
236+ int count = 0;
237+
238+ while (count < num_frames) {
239+ if (qbman_swp_enqueue(s, &(d[count]), fd) != 0)
240+ break;
241+ count++;
242+ }
243+
244+ return count;
245+}
246+
247 /* Static (push) dequeue */
248
249 /**
250--- a/drivers/soc/fsl/dpio/qbman-portal.h
251+++ b/drivers/soc/fsl/dpio/qbman-portal.h
252@@ -88,6 +88,10 @@ struct qbman_eq_desc {
253 u8 wae;
254 u8 rspid;
255 __le64 rsp_addr;
256+};
257+
258+struct qbman_eq_desc_with_fd {
259+ struct qbman_eq_desc desc;
260 u8 fd[32];
261 };
262
263@@ -205,6 +209,19 @@ void *qbman_swp_mc_start(struct qbman_sw
264 void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb);
265 void *qbman_swp_mc_result(struct qbman_swp *p);
266
267+int
268+qbman_swp_enqueue_multiple(struct qbman_swp *s,
269+ const struct qbman_eq_desc *d,
270+ const struct dpaa2_fd *fd,
271+ uint32_t *flags,
272+ int num_frames);
273+
274+int
275+qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,
276+ const struct qbman_eq_desc *d,
277+ const struct dpaa2_fd *fd,
278+ int num_frames);
279+
280 /**
281 * qbman_result_is_DQ() - check if the dequeue result is a dequeue response
282 * @dq: the dequeue result to be checked
283--- a/include/soc/fsl/dpaa2-io.h
284+++ b/include/soc/fsl/dpaa2-io.h
285@@ -1,7 +1,7 @@
286 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
287 /*
288 * Copyright 2014-2016 Freescale Semiconductor Inc.
289- * Copyright 2017 NXP
290+ * Copyright 2017-2019 NXP
291 *
292 */
293 #ifndef __FSL_DPAA2_IO_H
294@@ -109,6 +109,10 @@ int dpaa2_io_service_pull_channel(struct
295
296 int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d, u32 fqid,
297 const struct dpaa2_fd *fd);
298+int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d, u32 fqid,
299+ const struct dpaa2_fd *fd, int number_of_frame);
300+int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, u32 *fqid,
301+ const struct dpaa2_fd *fd, int number_of_frame);
302 int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio,
303 u16 qdbin, const struct dpaa2_fd *fd);
304 int dpaa2_io_service_release(struct dpaa2_io *d, u16 bpid,