1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
4  * Copyright 2018-2020 NXP
5  *
6  */
7 
8 #include "qbman_sys.h"
9 #include "qbman_portal.h"
10 
11 /* QBMan portal management command codes */
12 #define QBMAN_MC_ACQUIRE       0x30
13 #define QBMAN_WQCHAN_CONFIGURE 0x46
14 
15 /* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
16 #define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6)
17 
18 /* QBMan FQ management command codes */
19 #define QBMAN_FQ_SCHEDULE	0x48
20 #define QBMAN_FQ_FORCE		0x49
21 #define QBMAN_FQ_XON		0x4d
22 #define QBMAN_FQ_XOFF		0x4e
23 
24 /*******************************/
25 /* Pre-defined attribute codes */
26 /*******************************/
27 
28 #define QBMAN_RESPONSE_VERB_MASK   0x7f
29 
30 /*************************/
31 /* SDQCR attribute codes */
32 /*************************/
33 #define QB_SDQCR_FC_SHIFT   29
34 #define QB_SDQCR_FC_MASK    0x1
35 #define QB_SDQCR_DCT_SHIFT  24
36 #define QB_SDQCR_DCT_MASK   0x3
37 #define QB_SDQCR_TOK_SHIFT  16
38 #define QB_SDQCR_TOK_MASK   0xff
39 #define QB_SDQCR_SRC_SHIFT  0
40 #define QB_SDQCR_SRC_MASK   0xffff
41 
42 /* opaque token for static dequeues */
43 #define QMAN_SDQCR_TOKEN    0xbb
44 
45 enum qbman_sdqcr_dct {
46 	qbman_sdqcr_dct_null = 0,
47 	qbman_sdqcr_dct_prio_ics,
48 	qbman_sdqcr_dct_active_ics,
49 	qbman_sdqcr_dct_active
50 };
51 
52 enum qbman_sdqcr_fc {
53 	qbman_sdqcr_fc_one = 0,
54 	qbman_sdqcr_fc_up_to_3 = 1
55 };
56 
57 /* We need to keep track of which SWP triggered a pull command
58  * so keep an array of portal IDs and use the token field to
59  * be able to find the proper portal
60  */
61 #define MAX_QBMAN_PORTALS  64
62 static struct qbman_swp *portal_idx_map[MAX_QBMAN_PORTALS];
63 
64 uint32_t qman_version;
65 
66 /* Internal Function declaration */
67 static int
68 qbman_swp_enqueue_array_mode_direct(struct qbman_swp *s,
69 		const struct qbman_eq_desc *d,
70 		const struct qbman_fd *fd);
71 static int
72 qbman_swp_enqueue_array_mode_mem_back(struct qbman_swp *s,
73 		const struct qbman_eq_desc *d,
74 		const struct qbman_fd *fd);
75 
76 static int
77 qbman_swp_enqueue_ring_mode_direct(struct qbman_swp *s,
78 		const struct qbman_eq_desc *d,
79 		const struct qbman_fd *fd);
80 static int
81 qbman_swp_enqueue_ring_mode_cinh_read_direct(struct qbman_swp *s,
82 		const struct qbman_eq_desc *d,
83 		const struct qbman_fd *fd);
84 static int
85 qbman_swp_enqueue_ring_mode_cinh_direct(struct qbman_swp *s,
86 		const struct qbman_eq_desc *d,
87 		const struct qbman_fd *fd);
88 static int
89 qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp *s,
90 		const struct qbman_eq_desc *d,
91 		const struct qbman_fd *fd);
92 
93 static int
94 qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
95 		const struct qbman_eq_desc *d,
96 		const struct qbman_fd *fd,
97 		uint32_t *flags,
98 		int num_frames);
99 static int
100 qbman_swp_enqueue_multiple_cinh_read_direct(struct qbman_swp *s,
101 		const struct qbman_eq_desc *d,
102 		const struct qbman_fd *fd,
103 		uint32_t *flags,
104 		int num_frames);
105 static int
106 qbman_swp_enqueue_multiple_cinh_direct(struct qbman_swp *s,
107 		const struct qbman_eq_desc *d,
108 		const struct qbman_fd *fd,
109 		uint32_t *flags,
110 		int num_frames);
111 static int
112 qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,
113 		const struct qbman_eq_desc *d,
114 		const struct qbman_fd *fd,
115 		uint32_t *flags,
116 		int num_frames);
117 
118 static int
119 qbman_swp_enqueue_multiple_fd_direct(struct qbman_swp *s,
120 		const struct qbman_eq_desc *d,
121 		struct qbman_fd **fd,
122 		uint32_t *flags,
123 		int num_frames);
124 static int
125 qbman_swp_enqueue_multiple_fd_cinh_read_direct(struct qbman_swp *s,
126 		const struct qbman_eq_desc *d,
127 		struct qbman_fd **fd,
128 		uint32_t *flags,
129 		int num_frames);
130 static int
131 qbman_swp_enqueue_multiple_fd_cinh_direct(struct qbman_swp *s,
132 		const struct qbman_eq_desc *d,
133 		struct qbman_fd **fd,
134 		uint32_t *flags,
135 		int num_frames);
136 static int
137 qbman_swp_enqueue_multiple_fd_mem_back(struct qbman_swp *s,
138 		const struct qbman_eq_desc *d,
139 		struct qbman_fd **fd,
140 		uint32_t *flags,
141 		int num_frames);
142 
143 static int
144 qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
145 		const struct qbman_eq_desc *d,
146 		const struct qbman_fd *fd,
147 		int num_frames);
148 static int
149 qbman_swp_enqueue_multiple_desc_cinh_read_direct(struct qbman_swp *s,
150 		const struct qbman_eq_desc *d,
151 		const struct qbman_fd *fd,
152 		int num_frames);
153 static int
154 qbman_swp_enqueue_multiple_desc_cinh_direct(struct qbman_swp *s,
155 		const struct qbman_eq_desc *d,
156 		const struct qbman_fd *fd,
157 		int num_frames);
158 static int
159 qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,
160 		const struct qbman_eq_desc *d,
161 		const struct qbman_fd *fd,
162 		int num_frames);
163 
164 static int
165 qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d);
166 static int
167 qbman_swp_pull_cinh_direct(struct qbman_swp *s, struct qbman_pull_desc *d);
168 static int
169 qbman_swp_pull_mem_back(struct qbman_swp *s, struct qbman_pull_desc *d);
170 
171 const struct qbman_result *qbman_swp_dqrr_next_direct(struct qbman_swp *s);
172 const struct qbman_result *qbman_swp_dqrr_next_cinh_direct(struct qbman_swp *s);
173 const struct qbman_result *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s);
174 
175 static int
176 qbman_swp_release_direct(struct qbman_swp *s,
177 		const struct qbman_release_desc *d,
178 		const uint64_t *buffers, unsigned int num_buffers);
179 static int
180 qbman_swp_release_cinh_direct(struct qbman_swp *s,
181 		const struct qbman_release_desc *d,
182 		const uint64_t *buffers, unsigned int num_buffers);
183 static int
184 qbman_swp_release_mem_back(struct qbman_swp *s,
185 		const struct qbman_release_desc *d,
186 		const uint64_t *buffers, unsigned int num_buffers);
187 
188 /* Function pointers */
189 static int (*qbman_swp_enqueue_array_mode_ptr)(struct qbman_swp *s,
190 		const struct qbman_eq_desc *d,
191 		const struct qbman_fd *fd)
192 	= qbman_swp_enqueue_array_mode_direct;
193 
194 static int (*qbman_swp_enqueue_ring_mode_ptr)(struct qbman_swp *s,
195 		const struct qbman_eq_desc *d,
196 		const struct qbman_fd *fd)
197 	= qbman_swp_enqueue_ring_mode_direct;
198 
199 static int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s,
200 		const struct qbman_eq_desc *d,
201 		const struct qbman_fd *fd,
202 		uint32_t *flags,
203 		int num_frames)
204 	= qbman_swp_enqueue_multiple_direct;
205 
206 static int (*qbman_swp_enqueue_multiple_fd_ptr)(struct qbman_swp *s,
207 		const struct qbman_eq_desc *d,
208 		struct qbman_fd **fd,
209 		uint32_t *flags,
210 		int num_frames)
211 	= qbman_swp_enqueue_multiple_fd_direct;
212 
213 static int (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s,
214 		const struct qbman_eq_desc *d,
215 		const struct qbman_fd *fd,
216 		int num_frames)
217 	= qbman_swp_enqueue_multiple_desc_direct;
218 
219 static int (*qbman_swp_pull_ptr)(struct qbman_swp *s,
220 		struct qbman_pull_desc *d)
221 	= qbman_swp_pull_direct;
222 
223 const struct qbman_result *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s)
224 		= qbman_swp_dqrr_next_direct;
225 
226 static int (*qbman_swp_release_ptr)(struct qbman_swp *s,
227 			const struct qbman_release_desc *d,
228 			const uint64_t *buffers, unsigned int num_buffers)
229 			= qbman_swp_release_direct;
230 
231 /*********************************/
232 /* Portal constructor/destructor */
233 /*********************************/
234 
235 /* Software portals should always be in the power-on state when we initialise,
236  * due to the CCSR-based portal reset functionality that MC has.
237  *
238  * Erk! Turns out that QMan versions prior to 4.1 do not correctly reset DQRR
239  * valid-bits, so we need to support a workaround where we don't trust
240  * valid-bits when detecting new entries until any stale ring entries have been
241  * overwritten at least once. The idea is that we read PI for the first few
242  * entries, then switch to valid-bit after that. The trick is to clear the
243  * bug-work-around boolean once the PI wraps around the ring for the first time.
244  *
245  * Note: this still carries a slight additional cost once the decrementer hits
246  * zero.
247  */
qbman_swp_init(const struct qbman_swp_desc * d)248 struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
249 {
250 	int ret;
251 	uint32_t eqcr_pi;
252 	uint32_t mask_size;
253 	struct qbman_swp *p = malloc(sizeof(*p));
254 
255 	if (!p)
256 		return NULL;
257 
258 	memset(p, 0, sizeof(struct qbman_swp));
259 
260 	p->desc = *d;
261 #ifdef QBMAN_CHECKING
262 	p->mc.check = swp_mc_can_start;
263 #endif
264 	p->mc.valid_bit = QB_VALID_BIT;
265 	p->sdq |= qbman_sdqcr_dct_prio_ics << QB_SDQCR_DCT_SHIFT;
266 	p->sdq |= qbman_sdqcr_fc_up_to_3 << QB_SDQCR_FC_SHIFT;
267 	p->sdq |= QMAN_SDQCR_TOKEN << QB_SDQCR_TOK_SHIFT;
268 	if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
269 			&& (d->cena_access_mode == qman_cena_fastest_access))
270 		p->mr.valid_bit = QB_VALID_BIT;
271 
272 	atomic_set(&p->vdq.busy, 1);
273 	p->vdq.valid_bit = QB_VALID_BIT;
274 	p->dqrr.valid_bit = QB_VALID_BIT;
275 	qman_version = p->desc.qman_version;
276 	if ((qman_version & QMAN_REV_MASK) < QMAN_REV_4100) {
277 		p->dqrr.dqrr_size = 4;
278 		p->dqrr.reset_bug = 1;
279 	} else {
280 		p->dqrr.dqrr_size = 8;
281 		p->dqrr.reset_bug = 0;
282 	}
283 
284 	ret = qbman_swp_sys_init(&p->sys, d, p->dqrr.dqrr_size);
285 	if (ret) {
286 		free(p);
287 		pr_err("qbman_swp_sys_init() failed %d\n", ret);
288 		return NULL;
289 	}
290 
291 	/* Verify that the DQRRPI is 0 - if it is not the portal isn't
292 	 * in default state which is an error
293 	 */
294 	if (qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_DQPI) & 0xF) {
295 		pr_err("qbman DQRR PI is not zero, portal is not clean\n");
296 		free(p);
297 		return NULL;
298 	}
299 
300 	/* SDQCR needs to be initialized to 0 when no channels are
301 	 * being dequeued from or else the QMan HW will indicate an
302 	 * error.  The values that were calculated above will be
303 	 * applied when dequeues from a specific channel are enabled.
304 	 */
305 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, 0);
306 
307 	p->eqcr.pi_ring_size = 8;
308 	if ((qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
309 			&& (d->cena_access_mode == qman_cena_fastest_access)) {
310 		p->eqcr.pi_ring_size = 32;
311 		qbman_swp_enqueue_array_mode_ptr =
312 			qbman_swp_enqueue_array_mode_mem_back;
313 		qbman_swp_enqueue_ring_mode_ptr =
314 			qbman_swp_enqueue_ring_mode_mem_back;
315 		qbman_swp_enqueue_multiple_ptr =
316 			qbman_swp_enqueue_multiple_mem_back;
317 		qbman_swp_enqueue_multiple_fd_ptr =
318 			qbman_swp_enqueue_multiple_fd_mem_back;
319 		qbman_swp_enqueue_multiple_desc_ptr =
320 			qbman_swp_enqueue_multiple_desc_mem_back;
321 		qbman_swp_pull_ptr = qbman_swp_pull_mem_back;
322 		qbman_swp_dqrr_next_ptr = qbman_swp_dqrr_next_mem_back;
323 		qbman_swp_release_ptr = qbman_swp_release_mem_back;
324 	}
325 
326 	if (dpaa2_svr_family == SVR_LS1080A) {
327 		qbman_swp_enqueue_ring_mode_ptr =
328 			qbman_swp_enqueue_ring_mode_cinh_read_direct;
329 		qbman_swp_enqueue_multiple_ptr =
330 			qbman_swp_enqueue_multiple_cinh_read_direct;
331 		qbman_swp_enqueue_multiple_fd_ptr =
332 			qbman_swp_enqueue_multiple_fd_cinh_read_direct;
333 		qbman_swp_enqueue_multiple_desc_ptr =
334 			qbman_swp_enqueue_multiple_desc_cinh_read_direct;
335 	}
336 
337 	for (mask_size = p->eqcr.pi_ring_size; mask_size > 0; mask_size >>= 1)
338 		p->eqcr.pi_ci_mask = (p->eqcr.pi_ci_mask<<1) + 1;
339 	eqcr_pi = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI);
340 	p->eqcr.pi = eqcr_pi & p->eqcr.pi_ci_mask;
341 	p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT;
342 	if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
343 			&& (d->cena_access_mode == qman_cena_fastest_access))
344 		p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI)
345 					     & p->eqcr.pi_ci_mask;
346 	else
347 		p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI)
348 					     & p->eqcr.pi_ci_mask;
349 	p->eqcr.available = p->eqcr.pi_ring_size -
350 				qm_cyc_diff(p->eqcr.pi_ring_size,
351 				p->eqcr.ci & (p->eqcr.pi_ci_mask<<1),
352 				p->eqcr.pi & (p->eqcr.pi_ci_mask<<1));
353 
354 	portal_idx_map[p->desc.idx] = p;
355 	return p;
356 }
357 
qbman_swp_update(struct qbman_swp * p,int stash_off)358 int qbman_swp_update(struct qbman_swp *p, int stash_off)
359 {
360 	const struct qbman_swp_desc *d = &p->desc;
361 	struct qbman_swp_sys *s = &p->sys;
362 	int ret;
363 
364 	/* Nothing needs to be done for QBMAN rev > 5000 with fast access */
365 	if ((qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
366 			&& (d->cena_access_mode == qman_cena_fastest_access))
367 		return 0;
368 
369 	ret = qbman_swp_sys_update(s, d, p->dqrr.dqrr_size, stash_off);
370 	if (ret) {
371 		pr_err("qbman_swp_sys_init() failed %d\n", ret);
372 		return ret;
373 	}
374 
375 	p->stash_off = stash_off;
376 
377 	return 0;
378 }
379 
qbman_swp_finish(struct qbman_swp * p)380 void qbman_swp_finish(struct qbman_swp *p)
381 {
382 #ifdef QBMAN_CHECKING
383 	QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
384 #endif
385 	qbman_swp_sys_finish(&p->sys);
386 	portal_idx_map[p->desc.idx] = NULL;
387 	free(p);
388 }
389 
qbman_swp_get_desc(struct qbman_swp * p)390 const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p)
391 {
392 	return &p->desc;
393 }
394 
395 /**************/
396 /* Interrupts */
397 /**************/
398 
qbman_swp_interrupt_get_vanish(struct qbman_swp * p)399 uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p)
400 {
401 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISDR);
402 }
403 
qbman_swp_interrupt_set_vanish(struct qbman_swp * p,uint32_t mask)404 void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask)
405 {
406 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISDR, mask);
407 }
408 
qbman_swp_interrupt_read_status(struct qbman_swp * p)409 uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p)
410 {
411 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISR);
412 }
413 
qbman_swp_interrupt_clear_status(struct qbman_swp * p,uint32_t mask)414 void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask)
415 {
416 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISR, mask);
417 }
418 
qbman_swp_dqrr_thrshld_read_status(struct qbman_swp * p)419 uint32_t qbman_swp_dqrr_thrshld_read_status(struct qbman_swp *p)
420 {
421 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_DQRR_ITR);
422 }
423 
qbman_swp_dqrr_thrshld_write(struct qbman_swp * p,uint32_t mask)424 void qbman_swp_dqrr_thrshld_write(struct qbman_swp *p, uint32_t mask)
425 {
426 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_DQRR_ITR, mask);
427 }
428 
qbman_swp_intr_timeout_read_status(struct qbman_swp * p)429 uint32_t qbman_swp_intr_timeout_read_status(struct qbman_swp *p)
430 {
431 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ITPR);
432 }
433 
qbman_swp_intr_timeout_write(struct qbman_swp * p,uint32_t mask)434 void qbman_swp_intr_timeout_write(struct qbman_swp *p, uint32_t mask)
435 {
436 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ITPR, mask);
437 }
438 
qbman_swp_interrupt_get_trigger(struct qbman_swp * p)439 uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p)
440 {
441 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IER);
442 }
443 
qbman_swp_interrupt_set_trigger(struct qbman_swp * p,uint32_t mask)444 void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask)
445 {
446 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IER, mask);
447 }
448 
qbman_swp_interrupt_get_inhibit(struct qbman_swp * p)449 int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)
450 {
451 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IIR);
452 }
453 
qbman_swp_interrupt_set_inhibit(struct qbman_swp * p,int inhibit)454 void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)
455 {
456 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IIR,
457 			 inhibit ? 0xffffffff : 0);
458 }
459 
460 /***********************/
461 /* Management commands */
462 /***********************/
463 
464 /*
465  * Internal code common to all types of management commands.
466  */
467 
qbman_swp_mc_start(struct qbman_swp * p)468 void *qbman_swp_mc_start(struct qbman_swp *p)
469 {
470 	void *ret;
471 #ifdef QBMAN_CHECKING
472 	QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
473 #endif
474 	if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
475 		    && (p->desc.cena_access_mode == qman_cena_fastest_access))
476 		ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR_MEM);
477 	else
478 		ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
479 #ifdef QBMAN_CHECKING
480 	if (!ret)
481 		p->mc.check = swp_mc_can_submit;
482 #endif
483 	return ret;
484 }
485 
qbman_swp_mc_submit(struct qbman_swp * p,void * cmd,uint8_t cmd_verb)486 void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint8_t cmd_verb)
487 {
488 	uint8_t *v = cmd;
489 #ifdef QBMAN_CHECKING
490 	QBMAN_BUG_ON(!(p->mc.check != swp_mc_can_submit));
491 #endif
492 	/* TBD: "|=" is going to hurt performance. Need to move as many fields
493 	 * out of word zero, and for those that remain, the "OR" needs to occur
494 	 * at the caller side. This debug check helps to catch cases where the
495 	 * caller wants to OR but has forgotten to do so.
496 	 */
497 	QBMAN_BUG_ON((*v & cmd_verb) != *v);
498 	if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
499 		    && (p->desc.cena_access_mode == qman_cena_fastest_access)) {
500 		*v = cmd_verb | p->mr.valid_bit;
501 		qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR_MEM, cmd);
502 		dma_wmb();
503 		qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_CR_RT, QMAN_RT_MODE);
504 	} else {
505 		dma_wmb();
506 		*v = cmd_verb | p->mc.valid_bit;
507 		qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
508 		clean(cmd);
509 	}
510 #ifdef QBMAN_CHECKING
511 	p->mc.check = swp_mc_can_poll;
512 #endif
513 }
514 
qbman_swp_mc_submit_cinh(struct qbman_swp * p,void * cmd,uint8_t cmd_verb)515 void qbman_swp_mc_submit_cinh(struct qbman_swp *p, void *cmd, uint8_t cmd_verb)
516 {
517 	uint8_t *v = cmd;
518 #ifdef QBMAN_CHECKING
519 	QBMAN_BUG_ON(!(p->mc.check != swp_mc_can_submit));
520 #endif
521 	/* TBD: "|=" is going to hurt performance. Need to move as many fields
522 	 * out of word zero, and for those that remain, the "OR" needs to occur
523 	 * at the caller side. This debug check helps to catch cases where the
524 	 * caller wants to OR but has forgotten to do so.
525 	 */
526 	QBMAN_BUG_ON((*v & cmd_verb) != *v);
527 	dma_wmb();
528 	*v = cmd_verb | p->mc.valid_bit;
529 	qbman_cinh_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
530 	clean(cmd);
531 #ifdef QBMAN_CHECKING
532 	p->mc.check = swp_mc_can_poll;
533 #endif
534 }
535 
qbman_swp_mc_result(struct qbman_swp * p)536 void *qbman_swp_mc_result(struct qbman_swp *p)
537 {
538 	uint32_t *ret, verb;
539 #ifdef QBMAN_CHECKING
540 	QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll);
541 #endif
542 	if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
543 		&& (p->desc.cena_access_mode == qman_cena_fastest_access)) {
544 		ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR_MEM);
545 		/* Command completed if the valid bit is toggled */
546 		if (p->mr.valid_bit != (ret[0] & QB_VALID_BIT))
547 			return NULL;
548 		/* Remove the valid-bit -
549 		 * command completed iff the rest is non-zero
550 		 */
551 		verb = ret[0] & ~QB_VALID_BIT;
552 		if (!verb)
553 			return NULL;
554 		p->mr.valid_bit ^= QB_VALID_BIT;
555 	} else {
556 		qbman_cena_invalidate_prefetch(&p->sys,
557 			QBMAN_CENA_SWP_RR(p->mc.valid_bit));
558 		ret = qbman_cena_read(&p->sys,
559 				      QBMAN_CENA_SWP_RR(p->mc.valid_bit));
560 		/* Remove the valid-bit -
561 		 * command completed iff the rest is non-zero
562 		 */
563 		verb = ret[0] & ~QB_VALID_BIT;
564 		if (!verb)
565 			return NULL;
566 		p->mc.valid_bit ^= QB_VALID_BIT;
567 	}
568 #ifdef QBMAN_CHECKING
569 	p->mc.check = swp_mc_can_start;
570 #endif
571 	return ret;
572 }
573 
qbman_swp_mc_result_cinh(struct qbman_swp * p)574 void *qbman_swp_mc_result_cinh(struct qbman_swp *p)
575 {
576 	uint32_t *ret, verb;
577 #ifdef QBMAN_CHECKING
578 	QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll);
579 #endif
580 	ret = qbman_cinh_read_shadow(&p->sys,
581 			      QBMAN_CENA_SWP_RR(p->mc.valid_bit));
582 	/* Remove the valid-bit -
583 	 * command completed iff the rest is non-zero
584 	 */
585 	verb = ret[0] & ~QB_VALID_BIT;
586 	if (!verb)
587 		return NULL;
588 	p->mc.valid_bit ^= QB_VALID_BIT;
589 #ifdef QBMAN_CHECKING
590 	p->mc.check = swp_mc_can_start;
591 #endif
592 	return ret;
593 }
594 
595 /***********/
596 /* Enqueue */
597 /***********/
598 
599 #define QB_ENQUEUE_CMD_OPTIONS_SHIFT    0
600 enum qb_enqueue_commands {
601 	enqueue_empty = 0,
602 	enqueue_response_always = 1,
603 	enqueue_rejects_to_fq = 2
604 };
605 
606 #define QB_ENQUEUE_CMD_EC_OPTION_MASK        0x3
607 #define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT      2
608 #define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3
609 #define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT     4
610 #define QB_ENQUEUE_CMD_DCA_PK_SHIFT          6
611 #define QB_ENQUEUE_CMD_DCA_EN_SHIFT          7
612 #define QB_ENQUEUE_CMD_NLIS_SHIFT            14
613 #define QB_ENQUEUE_CMD_IS_NESN_SHIFT         15
614 
qbman_eq_desc_clear(struct qbman_eq_desc * d)615 void qbman_eq_desc_clear(struct qbman_eq_desc *d)
616 {
617 	memset(d, 0, sizeof(*d));
618 }
619 
qbman_eq_desc_set_no_orp(struct qbman_eq_desc * d,int respond_success)620 void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
621 {
622 	d->eq.verb &= ~(1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT);
623 	if (respond_success)
624 		d->eq.verb |= enqueue_response_always;
625 	else
626 		d->eq.verb |= enqueue_rejects_to_fq;
627 }
628 
qbman_eq_desc_set_orp(struct qbman_eq_desc * d,int respond_success,uint16_t opr_id,uint16_t seqnum,int incomplete)629 void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
630 			   uint16_t opr_id, uint16_t seqnum, int incomplete)
631 {
632 	d->eq.verb |= 1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT;
633 	if (respond_success)
634 		d->eq.verb |= enqueue_response_always;
635 	else
636 		d->eq.verb |= enqueue_rejects_to_fq;
637 
638 	d->eq.orpid = opr_id;
639 	d->eq.seqnum = seqnum;
640 	if (incomplete)
641 		d->eq.seqnum |= 1 << QB_ENQUEUE_CMD_NLIS_SHIFT;
642 	else
643 		d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_NLIS_SHIFT);
644 }
645 
qbman_eq_desc_set_orp_hole(struct qbman_eq_desc * d,uint16_t opr_id,uint16_t seqnum)646 void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint16_t opr_id,
647 				uint16_t seqnum)
648 {
649 	d->eq.verb |= 1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT;
650 	d->eq.verb &= ~QB_ENQUEUE_CMD_EC_OPTION_MASK;
651 	d->eq.orpid = opr_id;
652 	d->eq.seqnum = seqnum;
653 	d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_NLIS_SHIFT);
654 	d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_IS_NESN_SHIFT);
655 }
656 
qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc * d,uint16_t opr_id,uint16_t seqnum)657 void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint16_t opr_id,
658 				uint16_t seqnum)
659 {
660 	d->eq.verb |= 1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT;
661 	d->eq.verb &= ~QB_ENQUEUE_CMD_EC_OPTION_MASK;
662 	d->eq.orpid = opr_id;
663 	d->eq.seqnum = seqnum;
664 	d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_NLIS_SHIFT);
665 	d->eq.seqnum |= 1 << QB_ENQUEUE_CMD_IS_NESN_SHIFT;
666 }
667 
qbman_eq_desc_set_response(struct qbman_eq_desc * d,dma_addr_t storage_phys,int stash)668 void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
669 				dma_addr_t storage_phys,
670 				int stash)
671 {
672 	d->eq.rsp_addr = storage_phys;
673 	d->eq.wae = stash;
674 }
675 
qbman_eq_desc_set_token(struct qbman_eq_desc * d,uint8_t token)676 void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token)
677 {
678 	d->eq.rspid = token;
679 }
680 
qbman_eq_desc_set_fq(struct qbman_eq_desc * d,uint32_t fqid)681 void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid)
682 {
683 	d->eq.verb &= ~(1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT);
684 	d->eq.tgtid = fqid;
685 }
686 
qbman_eq_desc_set_qd(struct qbman_eq_desc * d,uint32_t qdid,uint16_t qd_bin,uint8_t qd_prio)687 void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
688 			  uint16_t qd_bin, uint8_t qd_prio)
689 {
690 	d->eq.verb |= 1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT;
691 	d->eq.tgtid = qdid;
692 	d->eq.qdbin = qd_bin;
693 	d->eq.qpri = qd_prio;
694 }
695 
qbman_eq_desc_set_eqdi(struct qbman_eq_desc * d,int enable)696 void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable)
697 {
698 	if (enable)
699 		d->eq.verb |= 1 << QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT;
700 	else
701 		d->eq.verb &= ~(1 << QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT);
702 }
703 
qbman_eq_desc_set_dca(struct qbman_eq_desc * d,int enable,uint8_t dqrr_idx,int park)704 void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
705 			   uint8_t dqrr_idx, int park)
706 {
707 	if (enable) {
708 		d->eq.dca = dqrr_idx;
709 		if (park)
710 			d->eq.dca |= 1 << QB_ENQUEUE_CMD_DCA_PK_SHIFT;
711 		else
712 			d->eq.dca &= ~(1 << QB_ENQUEUE_CMD_DCA_PK_SHIFT);
713 		d->eq.dca |= 1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT;
714 	} else {
715 		d->eq.dca &= ~(1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT);
716 	}
717 }
718 
719 #define EQAR_IDX(eqar)     ((eqar) & 0x1f)
720 #define EQAR_VB(eqar)      ((eqar) & 0x80)
721 #define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
722 
qbman_write_eqcr_am_rt_register(struct qbman_swp * p,uint8_t idx)723 static inline void qbman_write_eqcr_am_rt_register(struct qbman_swp *p,
724 						   uint8_t idx)
725 {
726 	if (idx < 16)
727 		qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_EQCR_AM_RT + idx * 4,
728 				     QMAN_RT_MODE);
729 	else
730 		qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_EQCR_AM_RT2 +
731 				     (idx - 16) * 4,
732 				     QMAN_RT_MODE);
733 }
734 
memcpy_byte_by_byte(void * to,const void * from,size_t n)735 static void memcpy_byte_by_byte(void *to, const void *from, size_t n)
736 {
737 	const uint8_t *src = from;
738 	volatile uint8_t *dest = to;
739 	size_t i;
740 
741 	for (i = 0; i < n; i++)
742 		dest[i] = src[i];
743 }
744 
745 
qbman_swp_enqueue_array_mode_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd)746 static int qbman_swp_enqueue_array_mode_direct(struct qbman_swp *s,
747 					       const struct qbman_eq_desc *d,
748 					       const struct qbman_fd *fd)
749 {
750 	uint32_t *p;
751 	const uint32_t *cl = qb_cl(d);
752 	uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
753 
754 	pr_debug("EQAR=%08x\n", eqar);
755 	if (!EQAR_SUCCESS(eqar))
756 		return -EBUSY;
757 	p = qbman_cena_write_start_wo_shadow(&s->sys,
758 			QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
759 	memcpy(&p[1], &cl[1], 28);
760 	memcpy(&p[8], fd, sizeof(*fd));
761 
762 	/* Set the verb byte, have to substitute in the valid-bit */
763 	dma_wmb();
764 	p[0] = cl[0] | EQAR_VB(eqar);
765 	qbman_cena_write_complete_wo_shadow(&s->sys,
766 				QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
767 	return 0;
768 }
qbman_swp_enqueue_array_mode_mem_back(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd)769 static int qbman_swp_enqueue_array_mode_mem_back(struct qbman_swp *s,
770 						 const struct qbman_eq_desc *d,
771 						 const struct qbman_fd *fd)
772 {
773 	uint32_t *p;
774 	const uint32_t *cl = qb_cl(d);
775 	uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
776 
777 	pr_debug("EQAR=%08x\n", eqar);
778 	if (!EQAR_SUCCESS(eqar))
779 		return -EBUSY;
780 	p = qbman_cena_write_start_wo_shadow(&s->sys,
781 			QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
782 	memcpy(&p[1], &cl[1], 28);
783 	memcpy(&p[8], fd, sizeof(*fd));
784 
785 	/* Set the verb byte, have to substitute in the valid-bit */
786 	p[0] = cl[0] | EQAR_VB(eqar);
787 	dma_wmb();
788 	qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar));
789 	return 0;
790 }
791 
qbman_swp_enqueue_array_mode(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd)792 static inline int qbman_swp_enqueue_array_mode(struct qbman_swp *s,
793 					       const struct qbman_eq_desc *d,
794 					       const struct qbman_fd *fd)
795 {
796 	return qbman_swp_enqueue_array_mode_ptr(s, d, fd);
797 }
798 
qbman_swp_enqueue_ring_mode_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd)799 static int qbman_swp_enqueue_ring_mode_direct(struct qbman_swp *s,
800 					      const struct qbman_eq_desc *d,
801 					      const struct qbman_fd *fd)
802 {
803 	uint32_t *p;
804 	const uint32_t *cl = qb_cl(d);
805 	uint32_t eqcr_ci, full_mask, half_mask;
806 
807 	half_mask = (s->eqcr.pi_ci_mask>>1);
808 	full_mask = s->eqcr.pi_ci_mask;
809 	if (!s->eqcr.available) {
810 		eqcr_ci = s->eqcr.ci;
811 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
812 				QBMAN_CENA_SWP_EQCR_CI) & full_mask;
813 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
814 				eqcr_ci, s->eqcr.ci);
815 		if (!s->eqcr.available)
816 			return -EBUSY;
817 	}
818 
819 	p = qbman_cena_write_start_wo_shadow(&s->sys,
820 			QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));
821 	memcpy(&p[1], &cl[1], 28);
822 	memcpy(&p[8], fd, sizeof(*fd));
823 	lwsync();
824 
825 	/* Set the verb byte, have to substitute in the valid-bit */
826 	p[0] = cl[0] | s->eqcr.pi_vb;
827 	qbman_cena_write_complete_wo_shadow(&s->sys,
828 			QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));
829 	s->eqcr.pi++;
830 	s->eqcr.pi &= full_mask;
831 	s->eqcr.available--;
832 	if (!(s->eqcr.pi & half_mask))
833 		s->eqcr.pi_vb ^= QB_VALID_BIT;
834 
835 	return 0;
836 }
837 
qbman_swp_enqueue_ring_mode_cinh_read_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd)838 static int qbman_swp_enqueue_ring_mode_cinh_read_direct(
839 		struct qbman_swp *s,
840 		const struct qbman_eq_desc *d,
841 		const struct qbman_fd *fd)
842 {
843 	uint32_t *p;
844 	const uint32_t *cl = qb_cl(d);
845 	uint32_t eqcr_ci, full_mask, half_mask;
846 
847 	half_mask = (s->eqcr.pi_ci_mask>>1);
848 	full_mask = s->eqcr.pi_ci_mask;
849 	if (!s->eqcr.available) {
850 		eqcr_ci = s->eqcr.ci;
851 		s->eqcr.ci = qbman_cinh_read(&s->sys,
852 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
853 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
854 				eqcr_ci, s->eqcr.ci);
855 		if (!s->eqcr.available)
856 			return -EBUSY;
857 	}
858 
859 	p = qbman_cinh_write_start_wo_shadow(&s->sys,
860 			QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));
861 	memcpy(&p[1], &cl[1], 28);
862 	memcpy(&p[8], fd, sizeof(*fd));
863 	lwsync();
864 
865 	/* Set the verb byte, have to substitute in the valid-bit */
866 	p[0] = cl[0] | s->eqcr.pi_vb;
867 	s->eqcr.pi++;
868 	s->eqcr.pi &= full_mask;
869 	s->eqcr.available--;
870 	if (!(s->eqcr.pi & half_mask))
871 		s->eqcr.pi_vb ^= QB_VALID_BIT;
872 
873 	return 0;
874 }
875 
qbman_swp_enqueue_ring_mode_cinh_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd)876 static int qbman_swp_enqueue_ring_mode_cinh_direct(
877 		struct qbman_swp *s,
878 		const struct qbman_eq_desc *d,
879 		const struct qbman_fd *fd)
880 {
881 	uint32_t *p;
882 	const uint32_t *cl = qb_cl(d);
883 	uint32_t eqcr_ci, full_mask, half_mask;
884 
885 	half_mask = (s->eqcr.pi_ci_mask>>1);
886 	full_mask = s->eqcr.pi_ci_mask;
887 	if (!s->eqcr.available) {
888 		eqcr_ci = s->eqcr.ci;
889 		s->eqcr.ci = qbman_cinh_read(&s->sys,
890 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
891 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
892 				eqcr_ci, s->eqcr.ci);
893 		if (!s->eqcr.available)
894 			return -EBUSY;
895 	}
896 
897 	p = qbman_cinh_write_start_wo_shadow(&s->sys,
898 			QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));
899 	memcpy_byte_by_byte(&p[1], &cl[1], 28);
900 	memcpy_byte_by_byte(&p[8], fd, sizeof(*fd));
901 	lwsync();
902 
903 	/* Set the verb byte, have to substitute in the valid-bit */
904 	p[0] = cl[0] | s->eqcr.pi_vb;
905 	s->eqcr.pi++;
906 	s->eqcr.pi &= full_mask;
907 	s->eqcr.available--;
908 	if (!(s->eqcr.pi & half_mask))
909 		s->eqcr.pi_vb ^= QB_VALID_BIT;
910 
911 	return 0;
912 }
913 
qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd)914 static int qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp *s,
915 						const struct qbman_eq_desc *d,
916 						const struct qbman_fd *fd)
917 {
918 	uint32_t *p;
919 	const uint32_t *cl = qb_cl(d);
920 	uint32_t eqcr_ci, full_mask, half_mask;
921 
922 	half_mask = (s->eqcr.pi_ci_mask>>1);
923 	full_mask = s->eqcr.pi_ci_mask;
924 	if (!s->eqcr.available) {
925 		eqcr_ci = s->eqcr.ci;
926 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
927 				QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask;
928 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
929 				eqcr_ci, s->eqcr.ci);
930 		if (!s->eqcr.available)
931 			return -EBUSY;
932 	}
933 
934 	p = qbman_cena_write_start_wo_shadow(&s->sys,
935 			QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));
936 	memcpy(&p[1], &cl[1], 28);
937 	memcpy(&p[8], fd, sizeof(*fd));
938 
939 	/* Set the verb byte, have to substitute in the valid-bit */
940 	p[0] = cl[0] | s->eqcr.pi_vb;
941 	s->eqcr.pi++;
942 	s->eqcr.pi &= full_mask;
943 	s->eqcr.available--;
944 	if (!(s->eqcr.pi & half_mask))
945 		s->eqcr.pi_vb ^= QB_VALID_BIT;
946 	dma_wmb();
947 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,
948 				(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
949 	return 0;
950 }
951 
qbman_swp_enqueue_ring_mode(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd)952 static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s,
953 				       const struct qbman_eq_desc *d,
954 				       const struct qbman_fd *fd)
955 {
956 	if (!s->stash_off)
957 		return qbman_swp_enqueue_ring_mode_ptr(s, d, fd);
958 	else
959 		return qbman_swp_enqueue_ring_mode_cinh_direct(s, d, fd);
960 }
961 
qbman_swp_enqueue(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd)962 int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
963 		      const struct qbman_fd *fd)
964 {
965 	if (s->sys.eqcr_mode == qman_eqcr_vb_array)
966 		return qbman_swp_enqueue_array_mode(s, d, fd);
967 	else    /* Use ring mode by default */
968 		return qbman_swp_enqueue_ring_mode(s, d, fd);
969 }
970 
qbman_swp_enqueue_multiple_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd,uint32_t * flags,int num_frames)971 static int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
972 					     const struct qbman_eq_desc *d,
973 					     const struct qbman_fd *fd,
974 					     uint32_t *flags,
975 					     int num_frames)
976 {
977 	uint32_t *p = NULL;
978 	const uint32_t *cl = qb_cl(d);
979 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
980 	int i, num_enqueued = 0;
981 	uint64_t addr_cena;
982 
983 	half_mask = (s->eqcr.pi_ci_mask>>1);
984 	full_mask = s->eqcr.pi_ci_mask;
985 	if (!s->eqcr.available) {
986 		eqcr_ci = s->eqcr.ci;
987 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
988 				QBMAN_CENA_SWP_EQCR_CI) & full_mask;
989 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
990 				eqcr_ci, s->eqcr.ci);
991 		if (!s->eqcr.available)
992 			return 0;
993 	}
994 
995 	eqcr_pi = s->eqcr.pi;
996 	num_enqueued = (s->eqcr.available < num_frames) ?
997 			s->eqcr.available : num_frames;
998 	s->eqcr.available -= num_enqueued;
999 	/* Fill in the EQCR ring */
1000 	for (i = 0; i < num_enqueued; i++) {
1001 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1002 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1003 		memcpy(&p[1], &cl[1], 28);
1004 		memcpy(&p[8], &fd[i], sizeof(*fd));
1005 		eqcr_pi++;
1006 	}
1007 
1008 	lwsync();
1009 
1010 	/* Set the verb byte, have to substitute in the valid-bit */
1011 	eqcr_pi = s->eqcr.pi;
1012 	for (i = 0; i < num_enqueued; i++) {
1013 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1014 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1015 		p[0] = cl[0] | s->eqcr.pi_vb;
1016 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1017 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1018 
1019 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1020 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1021 		}
1022 		eqcr_pi++;
1023 		if (!(eqcr_pi & half_mask))
1024 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1025 	}
1026 
1027 	/* Flush all the cacheline without load/store in between */
1028 	eqcr_pi = s->eqcr.pi;
1029 	addr_cena = (size_t)s->sys.addr_cena;
1030 	for (i = 0; i < num_enqueued; i++) {
1031 		dcbf((uintptr_t)(addr_cena +
1032 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)));
1033 		eqcr_pi++;
1034 	}
1035 	s->eqcr.pi = eqcr_pi & full_mask;
1036 
1037 	return num_enqueued;
1038 }
1039 
qbman_swp_enqueue_multiple_cinh_read_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd,uint32_t * flags,int num_frames)1040 static int qbman_swp_enqueue_multiple_cinh_read_direct(
1041 		struct qbman_swp *s,
1042 		const struct qbman_eq_desc *d,
1043 		const struct qbman_fd *fd,
1044 		uint32_t *flags,
1045 		int num_frames)
1046 {
1047 	uint32_t *p = NULL;
1048 	const uint32_t *cl = qb_cl(d);
1049 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1050 	int i, num_enqueued = 0;
1051 	uint64_t addr_cena;
1052 
1053 	half_mask = (s->eqcr.pi_ci_mask>>1);
1054 	full_mask = s->eqcr.pi_ci_mask;
1055 	if (!s->eqcr.available) {
1056 		eqcr_ci = s->eqcr.ci;
1057 		s->eqcr.ci = qbman_cinh_read(&s->sys,
1058 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
1059 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1060 				eqcr_ci, s->eqcr.ci);
1061 		if (!s->eqcr.available)
1062 			return 0;
1063 	}
1064 
1065 	eqcr_pi = s->eqcr.pi;
1066 	num_enqueued = (s->eqcr.available < num_frames) ?
1067 			s->eqcr.available : num_frames;
1068 	s->eqcr.available -= num_enqueued;
1069 	/* Fill in the EQCR ring */
1070 	for (i = 0; i < num_enqueued; i++) {
1071 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1072 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1073 		memcpy(&p[1], &cl[1], 28);
1074 		memcpy(&p[8], &fd[i], sizeof(*fd));
1075 		eqcr_pi++;
1076 	}
1077 
1078 	lwsync();
1079 
1080 	/* Set the verb byte, have to substitute in the valid-bit */
1081 	eqcr_pi = s->eqcr.pi;
1082 	for (i = 0; i < num_enqueued; i++) {
1083 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1084 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1085 		p[0] = cl[0] | s->eqcr.pi_vb;
1086 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1087 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1088 
1089 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1090 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1091 		}
1092 		eqcr_pi++;
1093 		if (!(eqcr_pi & half_mask))
1094 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1095 	}
1096 
1097 	/* Flush all the cacheline without load/store in between */
1098 	eqcr_pi = s->eqcr.pi;
1099 	addr_cena = (size_t)s->sys.addr_cena;
1100 	for (i = 0; i < num_enqueued; i++) {
1101 		dcbf(addr_cena +
1102 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1103 		eqcr_pi++;
1104 	}
1105 	s->eqcr.pi = eqcr_pi & full_mask;
1106 
1107 	return num_enqueued;
1108 }
1109 
qbman_swp_enqueue_multiple_cinh_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd,uint32_t * flags,int num_frames)1110 static int qbman_swp_enqueue_multiple_cinh_direct(
1111 		struct qbman_swp *s,
1112 		const struct qbman_eq_desc *d,
1113 		const struct qbman_fd *fd,
1114 		uint32_t *flags,
1115 		int num_frames)
1116 {
1117 	uint32_t *p = NULL;
1118 	const uint32_t *cl = qb_cl(d);
1119 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1120 	int i, num_enqueued = 0;
1121 
1122 	half_mask = (s->eqcr.pi_ci_mask>>1);
1123 	full_mask = s->eqcr.pi_ci_mask;
1124 	if (!s->eqcr.available) {
1125 		eqcr_ci = s->eqcr.ci;
1126 		s->eqcr.ci = qbman_cinh_read(&s->sys,
1127 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
1128 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1129 				eqcr_ci, s->eqcr.ci);
1130 		if (!s->eqcr.available)
1131 			return 0;
1132 	}
1133 
1134 	eqcr_pi = s->eqcr.pi;
1135 	num_enqueued = (s->eqcr.available < num_frames) ?
1136 			s->eqcr.available : num_frames;
1137 	s->eqcr.available -= num_enqueued;
1138 	/* Fill in the EQCR ring */
1139 	for (i = 0; i < num_enqueued; i++) {
1140 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
1141 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1142 		memcpy_byte_by_byte(&p[1], &cl[1], 28);
1143 		memcpy_byte_by_byte(&p[8], &fd[i], sizeof(*fd));
1144 		eqcr_pi++;
1145 	}
1146 
1147 	lwsync();
1148 
1149 	/* Set the verb byte, have to substitute in the valid-bit */
1150 	eqcr_pi = s->eqcr.pi;
1151 	for (i = 0; i < num_enqueued; i++) {
1152 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
1153 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1154 		p[0] = cl[0] | s->eqcr.pi_vb;
1155 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1156 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1157 
1158 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1159 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1160 		}
1161 		eqcr_pi++;
1162 		if (!(eqcr_pi & half_mask))
1163 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1164 	}
1165 
1166 	s->eqcr.pi = eqcr_pi & full_mask;
1167 
1168 	return num_enqueued;
1169 }
1170 
qbman_swp_enqueue_multiple_mem_back(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd,uint32_t * flags,int num_frames)1171 static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,
1172 					       const struct qbman_eq_desc *d,
1173 					       const struct qbman_fd *fd,
1174 					       uint32_t *flags,
1175 					       int num_frames)
1176 {
1177 	uint32_t *p = NULL;
1178 	const uint32_t *cl = qb_cl(d);
1179 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1180 	int i, num_enqueued = 0;
1181 
1182 	half_mask = (s->eqcr.pi_ci_mask>>1);
1183 	full_mask = s->eqcr.pi_ci_mask;
1184 	if (!s->eqcr.available) {
1185 		eqcr_ci = s->eqcr.ci;
1186 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
1187 				QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask;
1188 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1189 					eqcr_ci, s->eqcr.ci);
1190 		if (!s->eqcr.available)
1191 			return 0;
1192 	}
1193 
1194 	eqcr_pi = s->eqcr.pi;
1195 	num_enqueued = (s->eqcr.available < num_frames) ?
1196 			s->eqcr.available : num_frames;
1197 	s->eqcr.available -= num_enqueued;
1198 	/* Fill in the EQCR ring */
1199 	for (i = 0; i < num_enqueued; i++) {
1200 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1201 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1202 		memcpy(&p[1], &cl[1], 28);
1203 		memcpy(&p[8], &fd[i], sizeof(*fd));
1204 		p[0] = cl[0] | s->eqcr.pi_vb;
1205 
1206 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1207 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1208 
1209 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1210 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1211 		}
1212 		eqcr_pi++;
1213 
1214 		if (!(eqcr_pi & half_mask))
1215 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1216 	}
1217 	s->eqcr.pi = eqcr_pi & full_mask;
1218 
1219 	dma_wmb();
1220 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,
1221 				(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
1222 	return num_enqueued;
1223 }
1224 
qbman_swp_enqueue_multiple(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd,uint32_t * flags,int num_frames)1225 int qbman_swp_enqueue_multiple(struct qbman_swp *s,
1226 				      const struct qbman_eq_desc *d,
1227 				      const struct qbman_fd *fd,
1228 				      uint32_t *flags,
1229 				      int num_frames)
1230 {
1231 	if (!s->stash_off)
1232 		return qbman_swp_enqueue_multiple_ptr(s, d, fd, flags,
1233 						num_frames);
1234 	else
1235 		return qbman_swp_enqueue_multiple_cinh_direct(s, d, fd, flags,
1236 						num_frames);
1237 }
1238 
qbman_swp_enqueue_multiple_fd_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,struct qbman_fd ** fd,uint32_t * flags,int num_frames)1239 static int qbman_swp_enqueue_multiple_fd_direct(struct qbman_swp *s,
1240 						const struct qbman_eq_desc *d,
1241 						struct qbman_fd **fd,
1242 						uint32_t *flags,
1243 						int num_frames)
1244 {
1245 	uint32_t *p = NULL;
1246 	const uint32_t *cl = qb_cl(d);
1247 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1248 	int i, num_enqueued = 0;
1249 	uint64_t addr_cena;
1250 
1251 	half_mask = (s->eqcr.pi_ci_mask>>1);
1252 	full_mask = s->eqcr.pi_ci_mask;
1253 	if (!s->eqcr.available) {
1254 		eqcr_ci = s->eqcr.ci;
1255 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
1256 				QBMAN_CENA_SWP_EQCR_CI) & full_mask;
1257 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1258 				eqcr_ci, s->eqcr.ci);
1259 		if (!s->eqcr.available)
1260 			return 0;
1261 	}
1262 
1263 	eqcr_pi = s->eqcr.pi;
1264 	num_enqueued = (s->eqcr.available < num_frames) ?
1265 			s->eqcr.available : num_frames;
1266 	s->eqcr.available -= num_enqueued;
1267 	/* Fill in the EQCR ring */
1268 	for (i = 0; i < num_enqueued; i++) {
1269 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1270 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1271 		memcpy(&p[1], &cl[1], 28);
1272 		memcpy(&p[8], fd[i], sizeof(struct qbman_fd));
1273 		eqcr_pi++;
1274 	}
1275 
1276 	lwsync();
1277 
1278 	/* Set the verb byte, have to substitute in the valid-bit */
1279 	eqcr_pi = s->eqcr.pi;
1280 	for (i = 0; i < num_enqueued; i++) {
1281 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1282 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1283 		p[0] = cl[0] | s->eqcr.pi_vb;
1284 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1285 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1286 
1287 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1288 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1289 		}
1290 		eqcr_pi++;
1291 		if (!(eqcr_pi & half_mask))
1292 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1293 	}
1294 
1295 	/* Flush all the cacheline without load/store in between */
1296 	eqcr_pi = s->eqcr.pi;
1297 	addr_cena = (size_t)s->sys.addr_cena;
1298 	for (i = 0; i < num_enqueued; i++) {
1299 		dcbf(addr_cena +
1300 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1301 		eqcr_pi++;
1302 	}
1303 	s->eqcr.pi = eqcr_pi & full_mask;
1304 
1305 	return num_enqueued;
1306 }
1307 
qbman_swp_enqueue_multiple_fd_cinh_read_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,struct qbman_fd ** fd,uint32_t * flags,int num_frames)1308 static int qbman_swp_enqueue_multiple_fd_cinh_read_direct(
1309 		struct qbman_swp *s,
1310 		const struct qbman_eq_desc *d,
1311 		struct qbman_fd **fd,
1312 		uint32_t *flags,
1313 		int num_frames)
1314 {
1315 	uint32_t *p = NULL;
1316 	const uint32_t *cl = qb_cl(d);
1317 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1318 	int i, num_enqueued = 0;
1319 	uint64_t addr_cena;
1320 
1321 	half_mask = (s->eqcr.pi_ci_mask>>1);
1322 	full_mask = s->eqcr.pi_ci_mask;
1323 	if (!s->eqcr.available) {
1324 		eqcr_ci = s->eqcr.ci;
1325 		s->eqcr.ci = qbman_cinh_read(&s->sys,
1326 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
1327 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1328 				eqcr_ci, s->eqcr.ci);
1329 		if (!s->eqcr.available)
1330 			return 0;
1331 	}
1332 
1333 	eqcr_pi = s->eqcr.pi;
1334 	num_enqueued = (s->eqcr.available < num_frames) ?
1335 			s->eqcr.available : num_frames;
1336 	s->eqcr.available -= num_enqueued;
1337 	/* Fill in the EQCR ring */
1338 	for (i = 0; i < num_enqueued; i++) {
1339 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1340 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1341 		memcpy(&p[1], &cl[1], 28);
1342 		memcpy(&p[8], fd[i], sizeof(struct qbman_fd));
1343 		eqcr_pi++;
1344 	}
1345 
1346 	lwsync();
1347 
1348 	/* Set the verb byte, have to substitute in the valid-bit */
1349 	eqcr_pi = s->eqcr.pi;
1350 	for (i = 0; i < num_enqueued; i++) {
1351 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1352 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1353 		p[0] = cl[0] | s->eqcr.pi_vb;
1354 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1355 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1356 
1357 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1358 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1359 		}
1360 		eqcr_pi++;
1361 		if (!(eqcr_pi & half_mask))
1362 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1363 	}
1364 
1365 	/* Flush all the cacheline without load/store in between */
1366 	eqcr_pi = s->eqcr.pi;
1367 	addr_cena = (size_t)s->sys.addr_cena;
1368 	for (i = 0; i < num_enqueued; i++) {
1369 		dcbf(addr_cena +
1370 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1371 		eqcr_pi++;
1372 	}
1373 	s->eqcr.pi = eqcr_pi & full_mask;
1374 
1375 	return num_enqueued;
1376 }
1377 
qbman_swp_enqueue_multiple_fd_cinh_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,struct qbman_fd ** fd,uint32_t * flags,int num_frames)1378 static int qbman_swp_enqueue_multiple_fd_cinh_direct(
1379 		struct qbman_swp *s,
1380 		const struct qbman_eq_desc *d,
1381 		struct qbman_fd **fd,
1382 		uint32_t *flags,
1383 		int num_frames)
1384 {
1385 	uint32_t *p = NULL;
1386 	const uint32_t *cl = qb_cl(d);
1387 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1388 	int i, num_enqueued = 0;
1389 
1390 	half_mask = (s->eqcr.pi_ci_mask>>1);
1391 	full_mask = s->eqcr.pi_ci_mask;
1392 	if (!s->eqcr.available) {
1393 		eqcr_ci = s->eqcr.ci;
1394 		s->eqcr.ci = qbman_cinh_read(&s->sys,
1395 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
1396 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1397 				eqcr_ci, s->eqcr.ci);
1398 		if (!s->eqcr.available)
1399 			return 0;
1400 	}
1401 
1402 	eqcr_pi = s->eqcr.pi;
1403 	num_enqueued = (s->eqcr.available < num_frames) ?
1404 			s->eqcr.available : num_frames;
1405 	s->eqcr.available -= num_enqueued;
1406 	/* Fill in the EQCR ring */
1407 	for (i = 0; i < num_enqueued; i++) {
1408 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
1409 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1410 		memcpy_byte_by_byte(&p[1], &cl[1], 28);
1411 		memcpy_byte_by_byte(&p[8], fd[i], sizeof(struct qbman_fd));
1412 		eqcr_pi++;
1413 	}
1414 
1415 	lwsync();
1416 
1417 	/* Set the verb byte, have to substitute in the valid-bit */
1418 	eqcr_pi = s->eqcr.pi;
1419 	for (i = 0; i < num_enqueued; i++) {
1420 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
1421 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1422 		p[0] = cl[0] | s->eqcr.pi_vb;
1423 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1424 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1425 
1426 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1427 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1428 		}
1429 		eqcr_pi++;
1430 		if (!(eqcr_pi & half_mask))
1431 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1432 	}
1433 
1434 	s->eqcr.pi = eqcr_pi & full_mask;
1435 
1436 	return num_enqueued;
1437 }
1438 
qbman_swp_enqueue_multiple_fd_mem_back(struct qbman_swp * s,const struct qbman_eq_desc * d,struct qbman_fd ** fd,uint32_t * flags,int num_frames)1439 static int qbman_swp_enqueue_multiple_fd_mem_back(struct qbman_swp *s,
1440 						  const struct qbman_eq_desc *d,
1441 						  struct qbman_fd **fd,
1442 						  uint32_t *flags,
1443 						  int num_frames)
1444 {
1445 	uint32_t *p = NULL;
1446 	const uint32_t *cl = qb_cl(d);
1447 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1448 	int i, num_enqueued = 0;
1449 
1450 	half_mask = (s->eqcr.pi_ci_mask>>1);
1451 	full_mask = s->eqcr.pi_ci_mask;
1452 	if (!s->eqcr.available) {
1453 		eqcr_ci = s->eqcr.ci;
1454 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
1455 				QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask;
1456 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1457 					eqcr_ci, s->eqcr.ci);
1458 		if (!s->eqcr.available)
1459 			return 0;
1460 	}
1461 
1462 	eqcr_pi = s->eqcr.pi;
1463 	num_enqueued = (s->eqcr.available < num_frames) ?
1464 			s->eqcr.available : num_frames;
1465 	s->eqcr.available -= num_enqueued;
1466 	/* Fill in the EQCR ring */
1467 	for (i = 0; i < num_enqueued; i++) {
1468 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1469 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1470 		memcpy(&p[1], &cl[1], 28);
1471 		memcpy(&p[8], fd[i], sizeof(struct qbman_fd));
1472 		eqcr_pi++;
1473 	}
1474 
1475 	/* Set the verb byte, have to substitute in the valid-bit */
1476 	eqcr_pi = s->eqcr.pi;
1477 	for (i = 0; i < num_enqueued; i++) {
1478 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1479 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1480 		p[0] = cl[0] | s->eqcr.pi_vb;
1481 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1482 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1483 
1484 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1485 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1486 		}
1487 		eqcr_pi++;
1488 		if (!(eqcr_pi & half_mask))
1489 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1490 	}
1491 	s->eqcr.pi = eqcr_pi & full_mask;
1492 
1493 	dma_wmb();
1494 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,
1495 				(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
1496 	return num_enqueued;
1497 }
1498 
qbman_swp_enqueue_multiple_fd(struct qbman_swp * s,const struct qbman_eq_desc * d,struct qbman_fd ** fd,uint32_t * flags,int num_frames)1499 int qbman_swp_enqueue_multiple_fd(struct qbman_swp *s,
1500 					 const struct qbman_eq_desc *d,
1501 					 struct qbman_fd **fd,
1502 					 uint32_t *flags,
1503 					 int num_frames)
1504 {
1505 	if (!s->stash_off)
1506 		return qbman_swp_enqueue_multiple_fd_ptr(s, d, fd, flags,
1507 					num_frames);
1508 	else
1509 		return qbman_swp_enqueue_multiple_fd_cinh_direct(s, d, fd,
1510 					flags, num_frames);
1511 }
1512 
qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd,int num_frames)1513 static int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
1514 					const struct qbman_eq_desc *d,
1515 					const struct qbman_fd *fd,
1516 					int num_frames)
1517 {
1518 	uint32_t *p;
1519 	const uint32_t *cl;
1520 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1521 	int i, num_enqueued = 0;
1522 	uint64_t addr_cena;
1523 
1524 	half_mask = (s->eqcr.pi_ci_mask>>1);
1525 	full_mask = s->eqcr.pi_ci_mask;
1526 	if (!s->eqcr.available) {
1527 		eqcr_ci = s->eqcr.ci;
1528 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
1529 				QBMAN_CENA_SWP_EQCR_CI) & full_mask;
1530 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1531 					eqcr_ci, s->eqcr.ci);
1532 		if (!s->eqcr.available)
1533 			return 0;
1534 	}
1535 
1536 	eqcr_pi = s->eqcr.pi;
1537 	num_enqueued = (s->eqcr.available < num_frames) ?
1538 			s->eqcr.available : num_frames;
1539 	s->eqcr.available -= num_enqueued;
1540 	/* Fill in the EQCR ring */
1541 	for (i = 0; i < num_enqueued; i++) {
1542 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1543 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1544 		cl = qb_cl(&d[i]);
1545 		memcpy(&p[1], &cl[1], 28);
1546 		memcpy(&p[8], &fd[i], sizeof(*fd));
1547 		eqcr_pi++;
1548 	}
1549 
1550 	lwsync();
1551 
1552 	/* Set the verb byte, have to substitute in the valid-bit */
1553 	eqcr_pi = s->eqcr.pi;
1554 	for (i = 0; i < num_enqueued; i++) {
1555 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1556 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1557 		cl = qb_cl(&d[i]);
1558 		p[0] = cl[0] | s->eqcr.pi_vb;
1559 		eqcr_pi++;
1560 		if (!(eqcr_pi & half_mask))
1561 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1562 	}
1563 
1564 	/* Flush all the cacheline without load/store in between */
1565 	eqcr_pi = s->eqcr.pi;
1566 	addr_cena = (size_t)s->sys.addr_cena;
1567 	for (i = 0; i < num_enqueued; i++) {
1568 		dcbf((uintptr_t)(addr_cena +
1569 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)));
1570 		eqcr_pi++;
1571 	}
1572 	s->eqcr.pi = eqcr_pi & full_mask;
1573 
1574 	return num_enqueued;
1575 }
1576 
qbman_swp_enqueue_multiple_desc_cinh_read_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd,int num_frames)1577 static int qbman_swp_enqueue_multiple_desc_cinh_read_direct(
1578 		struct qbman_swp *s,
1579 		const struct qbman_eq_desc *d,
1580 		const struct qbman_fd *fd,
1581 		int num_frames)
1582 {
1583 	uint32_t *p;
1584 	const uint32_t *cl;
1585 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1586 	int i, num_enqueued = 0;
1587 	uint64_t addr_cena;
1588 
1589 	half_mask = (s->eqcr.pi_ci_mask>>1);
1590 	full_mask = s->eqcr.pi_ci_mask;
1591 	if (!s->eqcr.available) {
1592 		eqcr_ci = s->eqcr.ci;
1593 		s->eqcr.ci = qbman_cinh_read(&s->sys,
1594 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
1595 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1596 					eqcr_ci, s->eqcr.ci);
1597 		if (!s->eqcr.available)
1598 			return 0;
1599 	}
1600 
1601 	eqcr_pi = s->eqcr.pi;
1602 	num_enqueued = (s->eqcr.available < num_frames) ?
1603 			s->eqcr.available : num_frames;
1604 	s->eqcr.available -= num_enqueued;
1605 	/* Fill in the EQCR ring */
1606 	for (i = 0; i < num_enqueued; i++) {
1607 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1608 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1609 		cl = qb_cl(&d[i]);
1610 		memcpy(&p[1], &cl[1], 28);
1611 		memcpy(&p[8], &fd[i], sizeof(*fd));
1612 		eqcr_pi++;
1613 	}
1614 
1615 	lwsync();
1616 
1617 	/* Set the verb byte, have to substitute in the valid-bit */
1618 	eqcr_pi = s->eqcr.pi;
1619 	for (i = 0; i < num_enqueued; i++) {
1620 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1621 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1622 		cl = qb_cl(&d[i]);
1623 		p[0] = cl[0] | s->eqcr.pi_vb;
1624 		eqcr_pi++;
1625 		if (!(eqcr_pi & half_mask))
1626 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1627 	}
1628 
1629 	/* Flush all the cacheline without load/store in between */
1630 	eqcr_pi = s->eqcr.pi;
1631 	addr_cena = (size_t)s->sys.addr_cena;
1632 	for (i = 0; i < num_enqueued; i++) {
1633 		dcbf(addr_cena +
1634 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1635 		eqcr_pi++;
1636 	}
1637 	s->eqcr.pi = eqcr_pi & full_mask;
1638 
1639 	return num_enqueued;
1640 }
1641 
qbman_swp_enqueue_multiple_desc_cinh_direct(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd,int num_frames)1642 static int qbman_swp_enqueue_multiple_desc_cinh_direct(
1643 		struct qbman_swp *s,
1644 		const struct qbman_eq_desc *d,
1645 		const struct qbman_fd *fd,
1646 		int num_frames)
1647 {
1648 	uint32_t *p;
1649 	const uint32_t *cl;
1650 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1651 	int i, num_enqueued = 0;
1652 
1653 	half_mask = (s->eqcr.pi_ci_mask>>1);
1654 	full_mask = s->eqcr.pi_ci_mask;
1655 	if (!s->eqcr.available) {
1656 		eqcr_ci = s->eqcr.ci;
1657 		s->eqcr.ci = qbman_cinh_read(&s->sys,
1658 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
1659 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1660 					eqcr_ci, s->eqcr.ci);
1661 		if (!s->eqcr.available)
1662 			return 0;
1663 	}
1664 
1665 	eqcr_pi = s->eqcr.pi;
1666 	num_enqueued = (s->eqcr.available < num_frames) ?
1667 			s->eqcr.available : num_frames;
1668 	s->eqcr.available -= num_enqueued;
1669 	/* Fill in the EQCR ring */
1670 	for (i = 0; i < num_enqueued; i++) {
1671 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
1672 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1673 		cl = qb_cl(&d[i]);
1674 		memcpy_byte_by_byte(&p[1], &cl[1], 28);
1675 		memcpy_byte_by_byte(&p[8], &fd[i], sizeof(*fd));
1676 		eqcr_pi++;
1677 	}
1678 
1679 	lwsync();
1680 
1681 	/* Set the verb byte, have to substitute in the valid-bit */
1682 	eqcr_pi = s->eqcr.pi;
1683 	for (i = 0; i < num_enqueued; i++) {
1684 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
1685 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1686 		cl = qb_cl(&d[i]);
1687 		p[0] = cl[0] | s->eqcr.pi_vb;
1688 		eqcr_pi++;
1689 		if (!(eqcr_pi & half_mask))
1690 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1691 	}
1692 
1693 	s->eqcr.pi = eqcr_pi & full_mask;
1694 
1695 	return num_enqueued;
1696 }
1697 
qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd,int num_frames)1698 static int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,
1699 					const struct qbman_eq_desc *d,
1700 					const struct qbman_fd *fd,
1701 					int num_frames)
1702 {
1703 	uint32_t *p;
1704 	const uint32_t *cl;
1705 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1706 	int i, num_enqueued = 0;
1707 
1708 	half_mask = (s->eqcr.pi_ci_mask>>1);
1709 	full_mask = s->eqcr.pi_ci_mask;
1710 	if (!s->eqcr.available) {
1711 		eqcr_ci = s->eqcr.ci;
1712 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
1713 				QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask;
1714 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1715 					eqcr_ci, s->eqcr.ci);
1716 		if (!s->eqcr.available)
1717 			return 0;
1718 	}
1719 
1720 	eqcr_pi = s->eqcr.pi;
1721 	num_enqueued = (s->eqcr.available < num_frames) ?
1722 			s->eqcr.available : num_frames;
1723 	s->eqcr.available -= num_enqueued;
1724 	/* Fill in the EQCR ring */
1725 	for (i = 0; i < num_enqueued; i++) {
1726 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1727 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1728 		cl = qb_cl(&d[i]);
1729 		memcpy(&p[1], &cl[1], 28);
1730 		memcpy(&p[8], &fd[i], sizeof(*fd));
1731 		eqcr_pi++;
1732 	}
1733 
1734 	/* Set the verb byte, have to substitute in the valid-bit */
1735 	eqcr_pi = s->eqcr.pi;
1736 	for (i = 0; i < num_enqueued; i++) {
1737 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1738 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1739 		cl = qb_cl(&d[i]);
1740 		p[0] = cl[0] | s->eqcr.pi_vb;
1741 		eqcr_pi++;
1742 		if (!(eqcr_pi & half_mask))
1743 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1744 	}
1745 
1746 	s->eqcr.pi = eqcr_pi & full_mask;
1747 
1748 	dma_wmb();
1749 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,
1750 				(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
1751 
1752 	return num_enqueued;
1753 }
qbman_swp_enqueue_multiple_desc(struct qbman_swp * s,const struct qbman_eq_desc * d,const struct qbman_fd * fd,int num_frames)1754 int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,
1755 					   const struct qbman_eq_desc *d,
1756 					   const struct qbman_fd *fd,
1757 					   int num_frames)
1758 {
1759 	if (!s->stash_off)
1760 		return qbman_swp_enqueue_multiple_desc_ptr(s, d, fd,
1761 					num_frames);
1762 	else
1763 		return qbman_swp_enqueue_multiple_desc_cinh_direct(s, d, fd,
1764 					num_frames);
1765 
1766 }
1767 
1768 /*************************/
1769 /* Static (push) dequeue */
1770 /*************************/
1771 
qbman_swp_push_get(struct qbman_swp * s,uint8_t channel_idx,int * enabled)1772 void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled)
1773 {
1774 	uint16_t src = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK;
1775 
1776 	QBMAN_BUG_ON(channel_idx > 15);
1777 	*enabled = src | (1 << channel_idx);
1778 }
1779 
qbman_swp_push_set(struct qbman_swp * s,uint8_t channel_idx,int enable)1780 void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable)
1781 {
1782 	uint16_t dqsrc;
1783 
1784 	QBMAN_BUG_ON(channel_idx > 15);
1785 	if (enable)
1786 		s->sdq |= 1 << channel_idx;
1787 	else
1788 		s->sdq &= ~(1 << channel_idx);
1789 
1790 	/* Read make the complete src map.  If no channels are enabled
1791 	 * the SDQCR must be 0 or else QMan will assert errors
1792 	 */
1793 	dqsrc = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK;
1794 	if (dqsrc != 0)
1795 		qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, s->sdq);
1796 	else
1797 		qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, 0);
1798 }
1799 
1800 /***************************/
1801 /* Volatile (pull) dequeue */
1802 /***************************/
1803 
1804 /* These should be const, eventually */
1805 #define QB_VDQCR_VERB_DCT_SHIFT    0
1806 #define QB_VDQCR_VERB_DT_SHIFT     2
1807 #define QB_VDQCR_VERB_RLS_SHIFT    4
1808 #define QB_VDQCR_VERB_WAE_SHIFT    5
1809 #define QB_VDQCR_VERB_RAD_SHIFT    6
1810 
1811 enum qb_pull_dt_e {
1812 	qb_pull_dt_channel,
1813 	qb_pull_dt_workqueue,
1814 	qb_pull_dt_framequeue
1815 };
1816 
qbman_pull_desc_clear(struct qbman_pull_desc * d)1817 void qbman_pull_desc_clear(struct qbman_pull_desc *d)
1818 {
1819 	memset(d, 0, sizeof(*d));
1820 }
1821 
qbman_pull_desc_set_storage(struct qbman_pull_desc * d,struct qbman_result * storage,dma_addr_t storage_phys,int stash)1822 void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
1823 				 struct qbman_result *storage,
1824 				 dma_addr_t storage_phys,
1825 				 int stash)
1826 {
1827 	d->pull.rsp_addr_virt = (size_t)storage;
1828 
1829 	if (!storage) {
1830 		d->pull.verb &= ~(1 << QB_VDQCR_VERB_RLS_SHIFT);
1831 		return;
1832 	}
1833 	d->pull.verb |= 1 << QB_VDQCR_VERB_RLS_SHIFT;
1834 	if (stash)
1835 		d->pull.verb |= 1 << QB_VDQCR_VERB_WAE_SHIFT;
1836 	else
1837 		d->pull.verb &= ~(1 << QB_VDQCR_VERB_WAE_SHIFT);
1838 
1839 	d->pull.rsp_addr = storage_phys;
1840 }
1841 
qbman_pull_desc_set_numframes(struct qbman_pull_desc * d,uint8_t numframes)1842 void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d,
1843 				   uint8_t numframes)
1844 {
1845 	d->pull.numf = numframes - 1;
1846 }
1847 
qbman_pull_desc_set_token(struct qbman_pull_desc * d,uint8_t token)1848 void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token)
1849 {
1850 	d->pull.tok = token;
1851 }
1852 
qbman_pull_desc_set_fq(struct qbman_pull_desc * d,uint32_t fqid)1853 void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid)
1854 {
1855 	d->pull.verb |= 1 << QB_VDQCR_VERB_DCT_SHIFT;
1856 	d->pull.verb |= qb_pull_dt_framequeue << QB_VDQCR_VERB_DT_SHIFT;
1857 	d->pull.dq_src = fqid;
1858 }
1859 
qbman_pull_desc_set_wq(struct qbman_pull_desc * d,uint32_t wqid,enum qbman_pull_type_e dct)1860 void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
1861 			    enum qbman_pull_type_e dct)
1862 {
1863 	d->pull.verb |= dct << QB_VDQCR_VERB_DCT_SHIFT;
1864 	d->pull.verb |= qb_pull_dt_workqueue << QB_VDQCR_VERB_DT_SHIFT;
1865 	d->pull.dq_src = wqid;
1866 }
1867 
qbman_pull_desc_set_channel(struct qbman_pull_desc * d,uint32_t chid,enum qbman_pull_type_e dct)1868 void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
1869 				 enum qbman_pull_type_e dct)
1870 {
1871 	d->pull.verb |= dct << QB_VDQCR_VERB_DCT_SHIFT;
1872 	d->pull.verb |= qb_pull_dt_channel << QB_VDQCR_VERB_DT_SHIFT;
1873 	d->pull.dq_src = chid;
1874 }
1875 
qbman_pull_desc_set_rad(struct qbman_pull_desc * d,int rad)1876 void qbman_pull_desc_set_rad(struct qbman_pull_desc *d, int rad)
1877 {
1878 	if (d->pull.verb & (1 << QB_VDQCR_VERB_RLS_SHIFT)) {
1879 		if (rad)
1880 			d->pull.verb |= 1 << QB_VDQCR_VERB_RAD_SHIFT;
1881 		else
1882 			d->pull.verb &= ~(1 << QB_VDQCR_VERB_RAD_SHIFT);
1883 	} else {
1884 		printf("The RAD feature is not valid when RLS = 0\n");
1885 	}
1886 }
1887 
qbman_swp_pull_direct(struct qbman_swp * s,struct qbman_pull_desc * d)1888 static int qbman_swp_pull_direct(struct qbman_swp *s,
1889 				 struct qbman_pull_desc *d)
1890 {
1891 	uint32_t *p;
1892 	uint32_t *cl = qb_cl(d);
1893 
1894 	if (!atomic_dec_and_test(&s->vdq.busy)) {
1895 		atomic_inc(&s->vdq.busy);
1896 		return -EBUSY;
1897 	}
1898 
1899 	d->pull.tok = s->sys.idx + 1;
1900 	s->vdq.storage = (void *)(size_t)d->pull.rsp_addr_virt;
1901 	p = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
1902 	memcpy(&p[1], &cl[1], 12);
1903 
1904 	/* Set the verb byte, have to substitute in the valid-bit */
1905 	lwsync();
1906 	p[0] = cl[0] | s->vdq.valid_bit;
1907 	s->vdq.valid_bit ^= QB_VALID_BIT;
1908 	qbman_cena_write_complete_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
1909 
1910 	return 0;
1911 }
1912 
qbman_swp_pull_cinh_direct(struct qbman_swp * s,struct qbman_pull_desc * d)1913 static int qbman_swp_pull_cinh_direct(struct qbman_swp *s,
1914 				 struct qbman_pull_desc *d)
1915 {
1916 	uint32_t *p;
1917 	uint32_t *cl = qb_cl(d);
1918 
1919 	if (!atomic_dec_and_test(&s->vdq.busy)) {
1920 		atomic_inc(&s->vdq.busy);
1921 		return -EBUSY;
1922 	}
1923 
1924 	d->pull.tok = s->sys.idx + 1;
1925 	s->vdq.storage = (void *)(size_t)d->pull.rsp_addr_virt;
1926 	p = qbman_cinh_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
1927 	memcpy_byte_by_byte(&p[1], &cl[1], 12);
1928 
1929 	/* Set the verb byte, have to substitute in the valid-bit */
1930 	lwsync();
1931 	p[0] = cl[0] | s->vdq.valid_bit;
1932 	s->vdq.valid_bit ^= QB_VALID_BIT;
1933 
1934 	return 0;
1935 }
1936 
qbman_swp_pull_mem_back(struct qbman_swp * s,struct qbman_pull_desc * d)1937 static int qbman_swp_pull_mem_back(struct qbman_swp *s,
1938 				   struct qbman_pull_desc *d)
1939 {
1940 	uint32_t *p;
1941 	uint32_t *cl = qb_cl(d);
1942 
1943 	if (!atomic_dec_and_test(&s->vdq.busy)) {
1944 		atomic_inc(&s->vdq.busy);
1945 		return -EBUSY;
1946 	}
1947 
1948 	d->pull.tok = s->sys.idx + 1;
1949 	s->vdq.storage = (void *)(size_t)d->pull.rsp_addr_virt;
1950 	p = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR_MEM);
1951 	memcpy(&p[1], &cl[1], 12);
1952 
1953 	/* Set the verb byte, have to substitute in the valid-bit */
1954 	p[0] = cl[0] | s->vdq.valid_bit;
1955 	s->vdq.valid_bit ^= QB_VALID_BIT;
1956 	dma_wmb();
1957 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE);
1958 
1959 	return 0;
1960 }
1961 
qbman_swp_pull(struct qbman_swp * s,struct qbman_pull_desc * d)1962 int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
1963 {
1964 	if (!s->stash_off)
1965 		return qbman_swp_pull_ptr(s, d);
1966 	else
1967 		return qbman_swp_pull_cinh_direct(s, d);
1968 }
1969 
1970 /****************/
1971 /* Polling DQRR */
1972 /****************/
1973 
1974 #define QMAN_DQRR_PI_MASK              0xf
1975 
1976 #define QBMAN_RESULT_DQ        0x60
1977 #define QBMAN_RESULT_FQRN      0x21
1978 #define QBMAN_RESULT_FQRNI     0x22
1979 #define QBMAN_RESULT_FQPN      0x24
1980 #define QBMAN_RESULT_FQDAN     0x25
1981 #define QBMAN_RESULT_CDAN      0x26
1982 #define QBMAN_RESULT_CSCN_MEM  0x27
1983 #define QBMAN_RESULT_CGCU      0x28
1984 #define QBMAN_RESULT_BPSCN     0x29
1985 #define QBMAN_RESULT_CSCN_WQ   0x2a
1986 
1987 #include <rte_prefetch.h>
1988 
qbman_swp_prefetch_dqrr_next(struct qbman_swp * s)1989 void qbman_swp_prefetch_dqrr_next(struct qbman_swp *s)
1990 {
1991 	const struct qbman_result *p;
1992 
1993 	p = qbman_cena_read_wo_shadow(&s->sys,
1994 		QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
1995 	rte_prefetch0(p);
1996 }
1997 
1998 /* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
1999  * only once, so repeated calls can return a sequence of DQRR entries, without
2000  * requiring they be consumed immediately or in any particular order.
2001  */
qbman_swp_dqrr_next(struct qbman_swp * s)2002 const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)
2003 {
2004 	if (!s->stash_off)
2005 		return qbman_swp_dqrr_next_ptr(s);
2006 	else
2007 		return qbman_swp_dqrr_next_cinh_direct(s);
2008 }
2009 
qbman_swp_dqrr_next_direct(struct qbman_swp * s)2010 const struct qbman_result *qbman_swp_dqrr_next_direct(struct qbman_swp *s)
2011 {
2012 	uint32_t verb;
2013 	uint32_t response_verb;
2014 	uint32_t flags;
2015 	const struct qbman_result *p;
2016 
2017 	/* Before using valid-bit to detect if something is there, we have to
2018 	 * handle the case of the DQRR reset bug...
2019 	 */
2020 	if (s->dqrr.reset_bug) {
2021 		/* We pick up new entries by cache-inhibited producer index,
2022 		 * which means that a non-coherent mapping would require us to
2023 		 * invalidate and read *only* once that PI has indicated that
2024 		 * there's an entry here. The first trip around the DQRR ring
2025 		 * will be much less efficient than all subsequent trips around
2026 		 * it...
2027 		 */
2028 		uint8_t pi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI) &
2029 			     QMAN_DQRR_PI_MASK;
2030 
2031 		/* there are new entries if pi != next_idx */
2032 		if (pi == s->dqrr.next_idx)
2033 			return NULL;
2034 
2035 		/* if next_idx is/was the last ring index, and 'pi' is
2036 		 * different, we can disable the workaround as all the ring
2037 		 * entries have now been DMA'd to so valid-bit checking is
2038 		 * repaired. Note: this logic needs to be based on next_idx
2039 		 * (which increments one at a time), rather than on pi (which
2040 		 * can burst and wrap-around between our snapshots of it).
2041 		 */
2042 		QBMAN_BUG_ON((s->dqrr.dqrr_size - 1) < 0);
2043 		if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1u)) {
2044 			pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n",
2045 				 s->dqrr.next_idx, pi);
2046 			s->dqrr.reset_bug = 0;
2047 		}
2048 		qbman_cena_invalidate_prefetch(&s->sys,
2049 					QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
2050 	}
2051 	p = qbman_cena_read_wo_shadow(&s->sys,
2052 			QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
2053 
2054 	verb = p->dq.verb;
2055 
2056 	/* If the valid-bit isn't of the expected polarity, nothing there. Note,
2057 	 * in the DQRR reset bug workaround, we shouldn't need to skip these
2058 	 * check, because we've already determined that a new entry is available
2059 	 * and we've invalidated the cacheline before reading it, so the
2060 	 * valid-bit behaviour is repaired and should tell us what we already
2061 	 * knew from reading PI.
2062 	 */
2063 	if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)
2064 		return NULL;
2065 
2066 	/* There's something there. Move "next_idx" attention to the next ring
2067 	 * entry (and prefetch it) before returning what we found.
2068 	 */
2069 	s->dqrr.next_idx++;
2070 	if (s->dqrr.next_idx == s->dqrr.dqrr_size) {
2071 		s->dqrr.next_idx = 0;
2072 		s->dqrr.valid_bit ^= QB_VALID_BIT;
2073 	}
2074 	/* If this is the final response to a volatile dequeue command
2075 	 * indicate that the vdq is no longer busy
2076 	 */
2077 	flags = p->dq.stat;
2078 	response_verb = verb & QBMAN_RESPONSE_VERB_MASK;
2079 	if ((response_verb == QBMAN_RESULT_DQ) &&
2080 	    (flags & QBMAN_DQ_STAT_VOLATILE) &&
2081 	    (flags & QBMAN_DQ_STAT_EXPIRED))
2082 		atomic_inc(&s->vdq.busy);
2083 
2084 	return p;
2085 }
2086 
qbman_swp_dqrr_next_cinh_direct(struct qbman_swp * s)2087 const struct qbman_result *qbman_swp_dqrr_next_cinh_direct(struct qbman_swp *s)
2088 {
2089 	uint32_t verb;
2090 	uint32_t response_verb;
2091 	uint32_t flags;
2092 	const struct qbman_result *p;
2093 
2094 	/* Before using valid-bit to detect if something is there, we have to
2095 	 * handle the case of the DQRR reset bug...
2096 	 */
2097 	if (s->dqrr.reset_bug) {
2098 		/* We pick up new entries by cache-inhibited producer index,
2099 		 * which means that a non-coherent mapping would require us to
2100 		 * invalidate and read *only* once that PI has indicated that
2101 		 * there's an entry here. The first trip around the DQRR ring
2102 		 * will be much less efficient than all subsequent trips around
2103 		 * it...
2104 		 */
2105 		uint8_t pi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI) &
2106 			     QMAN_DQRR_PI_MASK;
2107 
2108 		/* there are new entries if pi != next_idx */
2109 		if (pi == s->dqrr.next_idx)
2110 			return NULL;
2111 
2112 		/* if next_idx is/was the last ring index, and 'pi' is
2113 		 * different, we can disable the workaround as all the ring
2114 		 * entries have now been DMA'd to so valid-bit checking is
2115 		 * repaired. Note: this logic needs to be based on next_idx
2116 		 * (which increments one at a time), rather than on pi (which
2117 		 * can burst and wrap-around between our snapshots of it).
2118 		 */
2119 		QBMAN_BUG_ON((s->dqrr.dqrr_size - 1) < 0);
2120 		if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1u)) {
2121 			pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n",
2122 				 s->dqrr.next_idx, pi);
2123 			s->dqrr.reset_bug = 0;
2124 		}
2125 	}
2126 	p = qbman_cinh_read_wo_shadow(&s->sys,
2127 			QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
2128 
2129 	verb = p->dq.verb;
2130 
2131 	/* If the valid-bit isn't of the expected polarity, nothing there. Note,
2132 	 * in the DQRR reset bug workaround, we shouldn't need to skip these
2133 	 * check, because we've already determined that a new entry is available
2134 	 * and we've invalidated the cacheline before reading it, so the
2135 	 * valid-bit behaviour is repaired and should tell us what we already
2136 	 * knew from reading PI.
2137 	 */
2138 	if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)
2139 		return NULL;
2140 
2141 	/* There's something there. Move "next_idx" attention to the next ring
2142 	 * entry (and prefetch it) before returning what we found.
2143 	 */
2144 	s->dqrr.next_idx++;
2145 	if (s->dqrr.next_idx == s->dqrr.dqrr_size) {
2146 		s->dqrr.next_idx = 0;
2147 		s->dqrr.valid_bit ^= QB_VALID_BIT;
2148 	}
2149 	/* If this is the final response to a volatile dequeue command
2150 	 * indicate that the vdq is no longer busy
2151 	 */
2152 	flags = p->dq.stat;
2153 	response_verb = verb & QBMAN_RESPONSE_VERB_MASK;
2154 	if ((response_verb == QBMAN_RESULT_DQ) &&
2155 	    (flags & QBMAN_DQ_STAT_VOLATILE) &&
2156 	    (flags & QBMAN_DQ_STAT_EXPIRED))
2157 		atomic_inc(&s->vdq.busy);
2158 
2159 	return p;
2160 }
2161 
qbman_swp_dqrr_next_mem_back(struct qbman_swp * s)2162 const struct qbman_result *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s)
2163 {
2164 	uint32_t verb;
2165 	uint32_t response_verb;
2166 	uint32_t flags;
2167 	const struct qbman_result *p;
2168 
2169 	p = qbman_cena_read_wo_shadow(&s->sys,
2170 			QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx));
2171 
2172 	verb = p->dq.verb;
2173 
2174 	/* If the valid-bit isn't of the expected polarity, nothing there. Note,
2175 	 * in the DQRR reset bug workaround, we shouldn't need to skip these
2176 	 * check, because we've already determined that a new entry is available
2177 	 * and we've invalidated the cacheline before reading it, so the
2178 	 * valid-bit behaviour is repaired and should tell us what we already
2179 	 * knew from reading PI.
2180 	 */
2181 	if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)
2182 		return NULL;
2183 
2184 	/* There's something there. Move "next_idx" attention to the next ring
2185 	 * entry (and prefetch it) before returning what we found.
2186 	 */
2187 	s->dqrr.next_idx++;
2188 	if (s->dqrr.next_idx == s->dqrr.dqrr_size) {
2189 		s->dqrr.next_idx = 0;
2190 		s->dqrr.valid_bit ^= QB_VALID_BIT;
2191 	}
2192 	/* If this is the final response to a volatile dequeue command
2193 	 * indicate that the vdq is no longer busy
2194 	 */
2195 	flags = p->dq.stat;
2196 	response_verb = verb & QBMAN_RESPONSE_VERB_MASK;
2197 	if ((response_verb == QBMAN_RESULT_DQ)
2198 			&& (flags & QBMAN_DQ_STAT_VOLATILE)
2199 			&& (flags & QBMAN_DQ_STAT_EXPIRED))
2200 		atomic_inc(&s->vdq.busy);
2201 	return p;
2202 }
2203 
2204 /* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
qbman_swp_dqrr_consume(struct qbman_swp * s,const struct qbman_result * dq)2205 void qbman_swp_dqrr_consume(struct qbman_swp *s,
2206 			    const struct qbman_result *dq)
2207 {
2208 	qbman_cinh_write(&s->sys,
2209 			QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
2210 }
2211 
2212 /* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
qbman_swp_dqrr_idx_consume(struct qbman_swp * s,uint8_t dqrr_index)2213 void qbman_swp_dqrr_idx_consume(struct qbman_swp *s,
2214 			    uint8_t dqrr_index)
2215 {
2216 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, dqrr_index);
2217 }
2218 
2219 /*********************************/
2220 /* Polling user-provided storage */
2221 /*********************************/
2222 
qbman_result_has_new_result(struct qbman_swp * s,struct qbman_result * dq)2223 int qbman_result_has_new_result(struct qbman_swp *s,
2224 				struct qbman_result *dq)
2225 {
2226 	if (dq->dq.tok == 0)
2227 		return 0;
2228 
2229 	/*
2230 	 * Set token to be 0 so we will detect change back to 1
2231 	 * next time the looping is traversed. Const is cast away here
2232 	 * as we want users to treat the dequeue responses as read only.
2233 	 */
2234 	((struct qbman_result *)dq)->dq.tok = 0;
2235 
2236 	/*
2237 	 * VDQCR "no longer busy" hook - not quite the same as DQRR, because
2238 	 * the fact "VDQCR" shows busy doesn't mean that we hold the result
2239 	 * that makes it available. Eg. we may be looking at our 10th dequeue
2240 	 * result, having released VDQCR after the 1st result and it is now
2241 	 * busy due to some other command!
2242 	 */
2243 	if (s->vdq.storage == dq) {
2244 		s->vdq.storage = NULL;
2245 		atomic_inc(&s->vdq.busy);
2246 	}
2247 
2248 	return 1;
2249 }
2250 
qbman_check_new_result(struct qbman_result * dq)2251 int qbman_check_new_result(struct qbman_result *dq)
2252 {
2253 	if (dq->dq.tok == 0)
2254 		return 0;
2255 
2256 	/*
2257 	 * Set token to be 0 so we will detect change back to 1
2258 	 * next time the looping is traversed. Const is cast away here
2259 	 * as we want users to treat the dequeue responses as read only.
2260 	 */
2261 	((struct qbman_result *)dq)->dq.tok = 0;
2262 
2263 	return 1;
2264 }
2265 
qbman_check_command_complete(struct qbman_result * dq)2266 int qbman_check_command_complete(struct qbman_result *dq)
2267 {
2268 	struct qbman_swp *s;
2269 
2270 	if (dq->dq.tok == 0)
2271 		return 0;
2272 
2273 	s = portal_idx_map[dq->dq.tok - 1];
2274 	/*
2275 	 * VDQCR "no longer busy" hook - not quite the same as DQRR, because
2276 	 * the fact "VDQCR" shows busy doesn't mean that we hold the result
2277 	 * that makes it available. Eg. we may be looking at our 10th dequeue
2278 	 * result, having released VDQCR after the 1st result and it is now
2279 	 * busy due to some other command!
2280 	 */
2281 	if (s->vdq.storage == dq) {
2282 		s->vdq.storage = NULL;
2283 		atomic_inc(&s->vdq.busy);
2284 	}
2285 
2286 	return 1;
2287 }
2288 
2289 /********************************/
2290 /* Categorising qbman results   */
2291 /********************************/
2292 
__qbman_result_is_x(const struct qbman_result * dq,uint8_t x)2293 static inline int __qbman_result_is_x(const struct qbman_result *dq,
2294 				      uint8_t x)
2295 {
2296 	uint8_t response_verb = dq->dq.verb & QBMAN_RESPONSE_VERB_MASK;
2297 
2298 	return (response_verb == x);
2299 }
2300 
qbman_result_is_DQ(const struct qbman_result * dq)2301 int qbman_result_is_DQ(const struct qbman_result *dq)
2302 {
2303 	return __qbman_result_is_x(dq, QBMAN_RESULT_DQ);
2304 }
2305 
qbman_result_is_FQDAN(const struct qbman_result * dq)2306 int qbman_result_is_FQDAN(const struct qbman_result *dq)
2307 {
2308 	return __qbman_result_is_x(dq, QBMAN_RESULT_FQDAN);
2309 }
2310 
qbman_result_is_CDAN(const struct qbman_result * dq)2311 int qbman_result_is_CDAN(const struct qbman_result *dq)
2312 {
2313 	return __qbman_result_is_x(dq, QBMAN_RESULT_CDAN);
2314 }
2315 
qbman_result_is_CSCN(const struct qbman_result * dq)2316 int qbman_result_is_CSCN(const struct qbman_result *dq)
2317 {
2318 	return __qbman_result_is_x(dq, QBMAN_RESULT_CSCN_MEM) ||
2319 		__qbman_result_is_x(dq, QBMAN_RESULT_CSCN_WQ);
2320 }
2321 
qbman_result_is_BPSCN(const struct qbman_result * dq)2322 int qbman_result_is_BPSCN(const struct qbman_result *dq)
2323 {
2324 	return __qbman_result_is_x(dq, QBMAN_RESULT_BPSCN);
2325 }
2326 
qbman_result_is_CGCU(const struct qbman_result * dq)2327 int qbman_result_is_CGCU(const struct qbman_result *dq)
2328 {
2329 	return __qbman_result_is_x(dq, QBMAN_RESULT_CGCU);
2330 }
2331 
qbman_result_is_FQRN(const struct qbman_result * dq)2332 int qbman_result_is_FQRN(const struct qbman_result *dq)
2333 {
2334 	return __qbman_result_is_x(dq, QBMAN_RESULT_FQRN);
2335 }
2336 
qbman_result_is_FQRNI(const struct qbman_result * dq)2337 int qbman_result_is_FQRNI(const struct qbman_result *dq)
2338 {
2339 	return __qbman_result_is_x(dq, QBMAN_RESULT_FQRNI);
2340 }
2341 
qbman_result_is_FQPN(const struct qbman_result * dq)2342 int qbman_result_is_FQPN(const struct qbman_result *dq)
2343 {
2344 	return __qbman_result_is_x(dq, QBMAN_RESULT_FQPN);
2345 }
2346 
2347 /*********************************/
2348 /* Parsing frame dequeue results */
2349 /*********************************/
2350 
2351 /* These APIs assume qbman_result_is_DQ() is TRUE */
2352 
qbman_result_DQ_flags(const struct qbman_result * dq)2353 uint8_t qbman_result_DQ_flags(const struct qbman_result *dq)
2354 {
2355 	return dq->dq.stat;
2356 }
2357 
qbman_result_DQ_seqnum(const struct qbman_result * dq)2358 uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq)
2359 {
2360 	return dq->dq.seqnum;
2361 }
2362 
qbman_result_DQ_odpid(const struct qbman_result * dq)2363 uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq)
2364 {
2365 	return dq->dq.oprid;
2366 }
2367 
qbman_result_DQ_fqid(const struct qbman_result * dq)2368 uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq)
2369 {
2370 	return dq->dq.fqid;
2371 }
2372 
qbman_result_DQ_byte_count(const struct qbman_result * dq)2373 uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq)
2374 {
2375 	return dq->dq.fq_byte_cnt;
2376 }
2377 
qbman_result_DQ_frame_count(const struct qbman_result * dq)2378 uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq)
2379 {
2380 	return dq->dq.fq_frm_cnt;
2381 }
2382 
qbman_result_DQ_fqd_ctx(const struct qbman_result * dq)2383 uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq)
2384 {
2385 	return dq->dq.fqd_ctx;
2386 }
2387 
qbman_result_DQ_fd(const struct qbman_result * dq)2388 const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq)
2389 {
2390 	return (const struct qbman_fd *)&dq->dq.fd[0];
2391 }
2392 
2393 /**************************************/
2394 /* Parsing state-change notifications */
2395 /**************************************/
qbman_result_SCN_state(const struct qbman_result * scn)2396 uint8_t qbman_result_SCN_state(const struct qbman_result *scn)
2397 {
2398 	return scn->scn.state;
2399 }
2400 
qbman_result_SCN_rid(const struct qbman_result * scn)2401 uint32_t qbman_result_SCN_rid(const struct qbman_result *scn)
2402 {
2403 	return scn->scn.rid_tok;
2404 }
2405 
qbman_result_SCN_ctx(const struct qbman_result * scn)2406 uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn)
2407 {
2408 	return scn->scn.ctx;
2409 }
2410 
2411 /*****************/
2412 /* Parsing BPSCN */
2413 /*****************/
qbman_result_bpscn_bpid(const struct qbman_result * scn)2414 uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn)
2415 {
2416 	return (uint16_t)qbman_result_SCN_rid(scn) & 0x3FFF;
2417 }
2418 
qbman_result_bpscn_has_free_bufs(const struct qbman_result * scn)2419 int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn)
2420 {
2421 	return !(int)(qbman_result_SCN_state(scn) & 0x1);
2422 }
2423 
qbman_result_bpscn_is_depleted(const struct qbman_result * scn)2424 int qbman_result_bpscn_is_depleted(const struct qbman_result *scn)
2425 {
2426 	return (int)(qbman_result_SCN_state(scn) & 0x2);
2427 }
2428 
qbman_result_bpscn_is_surplus(const struct qbman_result * scn)2429 int qbman_result_bpscn_is_surplus(const struct qbman_result *scn)
2430 {
2431 	return (int)(qbman_result_SCN_state(scn) & 0x4);
2432 }
2433 
qbman_result_bpscn_ctx(const struct qbman_result * scn)2434 uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn)
2435 {
2436 	return qbman_result_SCN_ctx(scn);
2437 }
2438 
2439 /*****************/
2440 /* Parsing CGCU  */
2441 /*****************/
qbman_result_cgcu_cgid(const struct qbman_result * scn)2442 uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn)
2443 {
2444 	return (uint16_t)qbman_result_SCN_rid(scn) & 0xFFFF;
2445 }
2446 
qbman_result_cgcu_icnt(const struct qbman_result * scn)2447 uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn)
2448 {
2449 	return qbman_result_SCN_ctx(scn);
2450 }
2451 
2452 /********************/
2453 /* Parsing EQ RESP  */
2454 /********************/
qbman_result_eqresp_fd(struct qbman_result * eqresp)2455 struct qbman_fd *qbman_result_eqresp_fd(struct qbman_result *eqresp)
2456 {
2457 	return (struct qbman_fd *)&eqresp->eq_resp.fd[0];
2458 }
2459 
qbman_result_eqresp_set_rspid(struct qbman_result * eqresp,uint8_t val)2460 void qbman_result_eqresp_set_rspid(struct qbman_result *eqresp, uint8_t val)
2461 {
2462 	eqresp->eq_resp.rspid = val;
2463 }
2464 
qbman_result_eqresp_rspid(struct qbman_result * eqresp)2465 uint8_t qbman_result_eqresp_rspid(struct qbman_result *eqresp)
2466 {
2467 	return eqresp->eq_resp.rspid;
2468 }
2469 
qbman_result_eqresp_rc(struct qbman_result * eqresp)2470 uint8_t qbman_result_eqresp_rc(struct qbman_result *eqresp)
2471 {
2472 	if (eqresp->eq_resp.rc == 0xE)
2473 		return 0;
2474 	else
2475 		return -1;
2476 }
2477 
2478 /******************/
2479 /* Buffer release */
2480 /******************/
2481 #define QB_BR_RC_VALID_SHIFT  5
2482 #define QB_BR_RCDI_SHIFT      6
2483 
qbman_release_desc_clear(struct qbman_release_desc * d)2484 void qbman_release_desc_clear(struct qbman_release_desc *d)
2485 {
2486 	memset(d, 0, sizeof(*d));
2487 	d->br.verb = 1 << QB_BR_RC_VALID_SHIFT;
2488 }
2489 
qbman_release_desc_set_bpid(struct qbman_release_desc * d,uint16_t bpid)2490 void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint16_t bpid)
2491 {
2492 	d->br.bpid = bpid;
2493 }
2494 
qbman_release_desc_set_rcdi(struct qbman_release_desc * d,int enable)2495 void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
2496 {
2497 	if (enable)
2498 		d->br.verb |= 1 << QB_BR_RCDI_SHIFT;
2499 	else
2500 		d->br.verb &= ~(1 << QB_BR_RCDI_SHIFT);
2501 }
2502 
2503 #define RAR_IDX(rar)     ((rar) & 0x7)
2504 #define RAR_VB(rar)      ((rar) & 0x80)
2505 #define RAR_SUCCESS(rar) ((rar) & 0x100)
2506 
qbman_swp_release_direct(struct qbman_swp * s,const struct qbman_release_desc * d,const uint64_t * buffers,unsigned int num_buffers)2507 static int qbman_swp_release_direct(struct qbman_swp *s,
2508 				    const struct qbman_release_desc *d,
2509 				    const uint64_t *buffers,
2510 				    unsigned int num_buffers)
2511 {
2512 	uint32_t *p;
2513 	const uint32_t *cl = qb_cl(d);
2514 	uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
2515 
2516 	pr_debug("RAR=%08x\n", rar);
2517 	if (!RAR_SUCCESS(rar))
2518 		return -EBUSY;
2519 
2520 	QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
2521 
2522 	/* Start the release command */
2523 	p = qbman_cena_write_start_wo_shadow(&s->sys,
2524 				     QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
2525 
2526 	/* Copy the caller's buffer pointers to the command */
2527 	u64_to_le32_copy(&p[2], buffers, num_buffers);
2528 
2529 	/* Set the verb byte, have to substitute in the valid-bit and the
2530 	 * number of buffers.
2531 	 */
2532 	lwsync();
2533 	p[0] = cl[0] | RAR_VB(rar) | num_buffers;
2534 	qbman_cena_write_complete_wo_shadow(&s->sys,
2535 				    QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
2536 
2537 	return 0;
2538 }
2539 
qbman_swp_release_cinh_direct(struct qbman_swp * s,const struct qbman_release_desc * d,const uint64_t * buffers,unsigned int num_buffers)2540 static int qbman_swp_release_cinh_direct(struct qbman_swp *s,
2541 				    const struct qbman_release_desc *d,
2542 				    const uint64_t *buffers,
2543 				    unsigned int num_buffers)
2544 {
2545 	uint32_t *p;
2546 	const uint32_t *cl = qb_cl(d);
2547 	uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
2548 
2549 	pr_debug("RAR=%08x\n", rar);
2550 	if (!RAR_SUCCESS(rar))
2551 		return -EBUSY;
2552 
2553 	QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
2554 
2555 	/* Start the release command */
2556 	p = qbman_cinh_write_start_wo_shadow(&s->sys,
2557 				     QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
2558 
2559 	/* Copy the caller's buffer pointers to the command */
2560 	memcpy_byte_by_byte(&p[2], buffers, num_buffers * sizeof(uint64_t));
2561 
2562 	/* Set the verb byte, have to substitute in the valid-bit and the
2563 	 * number of buffers.
2564 	 */
2565 	lwsync();
2566 	p[0] = cl[0] | RAR_VB(rar) | num_buffers;
2567 
2568 	return 0;
2569 }
2570 
qbman_swp_release_mem_back(struct qbman_swp * s,const struct qbman_release_desc * d,const uint64_t * buffers,unsigned int num_buffers)2571 static int qbman_swp_release_mem_back(struct qbman_swp *s,
2572 				      const struct qbman_release_desc *d,
2573 				      const uint64_t *buffers,
2574 				      unsigned int num_buffers)
2575 {
2576 	uint32_t *p;
2577 	const uint32_t *cl = qb_cl(d);
2578 	uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
2579 
2580 	pr_debug("RAR=%08x\n", rar);
2581 	if (!RAR_SUCCESS(rar))
2582 		return -EBUSY;
2583 
2584 	QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
2585 
2586 	/* Start the release command */
2587 	p = qbman_cena_write_start_wo_shadow(&s->sys,
2588 		QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar)));
2589 
2590 	/* Copy the caller's buffer pointers to the command */
2591 	u64_to_le32_copy(&p[2], buffers, num_buffers);
2592 
2593 	/* Set the verb byte, have to substitute in the valid-bit and the
2594 	 * number of buffers.
2595 	 */
2596 	p[0] = cl[0] | RAR_VB(rar) | num_buffers;
2597 	lwsync();
2598 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_RCR_AM_RT +
2599 		RAR_IDX(rar) * 4, QMAN_RT_MODE);
2600 
2601 	return 0;
2602 }
2603 
qbman_swp_release(struct qbman_swp * s,const struct qbman_release_desc * d,const uint64_t * buffers,unsigned int num_buffers)2604 int qbman_swp_release(struct qbman_swp *s,
2605 			     const struct qbman_release_desc *d,
2606 			     const uint64_t *buffers,
2607 			     unsigned int num_buffers)
2608 {
2609 	if (!s->stash_off)
2610 		return qbman_swp_release_ptr(s, d, buffers, num_buffers);
2611 	else
2612 		return qbman_swp_release_cinh_direct(s, d, buffers,
2613 						num_buffers);
2614 }
2615 
2616 /*******************/
2617 /* Buffer acquires */
2618 /*******************/
2619 struct qbman_acquire_desc {
2620 	uint8_t verb;
2621 	uint8_t reserved;
2622 	uint16_t bpid;
2623 	uint8_t num;
2624 	uint8_t reserved2[59];
2625 };
2626 
2627 struct qbman_acquire_rslt {
2628 	uint8_t verb;
2629 	uint8_t rslt;
2630 	uint16_t reserved;
2631 	uint8_t num;
2632 	uint8_t reserved2[3];
2633 	uint64_t buf[7];
2634 };
2635 
qbman_swp_acquire_direct(struct qbman_swp * s,uint16_t bpid,uint64_t * buffers,unsigned int num_buffers)2636 static int qbman_swp_acquire_direct(struct qbman_swp *s, uint16_t bpid,
2637 				uint64_t *buffers, unsigned int num_buffers)
2638 {
2639 	struct qbman_acquire_desc *p;
2640 	struct qbman_acquire_rslt *r;
2641 
2642 	if (!num_buffers || (num_buffers > 7))
2643 		return -EINVAL;
2644 
2645 	/* Start the management command */
2646 	p = qbman_swp_mc_start(s);
2647 
2648 	if (!p)
2649 		return -EBUSY;
2650 
2651 	/* Encode the caller-provided attributes */
2652 	p->bpid = bpid;
2653 	p->num = num_buffers;
2654 
2655 	/* Complete the management command */
2656 	r = qbman_swp_mc_complete(s, p, QBMAN_MC_ACQUIRE);
2657 	if (!r) {
2658 		pr_err("qbman: acquire from BPID %d failed, no response\n",
2659 		       bpid);
2660 		return -EIO;
2661 	}
2662 
2663 	/* Decode the outcome */
2664 	QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_MC_ACQUIRE);
2665 
2666 	/* Determine success or failure */
2667 	if (r->rslt != QBMAN_MC_RSLT_OK) {
2668 		pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
2669 		       bpid, r->rslt);
2670 		return -EIO;
2671 	}
2672 
2673 	QBMAN_BUG_ON(r->num > num_buffers);
2674 
2675 	/* Copy the acquired buffers to the caller's array */
2676 	u64_from_le32_copy(buffers, &r->buf[0], r->num);
2677 
2678 	return (int)r->num;
2679 }
2680 
qbman_swp_acquire_cinh_direct(struct qbman_swp * s,uint16_t bpid,uint64_t * buffers,unsigned int num_buffers)2681 static int qbman_swp_acquire_cinh_direct(struct qbman_swp *s, uint16_t bpid,
2682 			uint64_t *buffers, unsigned int num_buffers)
2683 {
2684 	struct qbman_acquire_desc *p;
2685 	struct qbman_acquire_rslt *r;
2686 
2687 	if (!num_buffers || (num_buffers > 7))
2688 		return -EINVAL;
2689 
2690 	/* Start the management command */
2691 	p = qbman_swp_mc_start(s);
2692 
2693 	if (!p)
2694 		return -EBUSY;
2695 
2696 	/* Encode the caller-provided attributes */
2697 	p->bpid = bpid;
2698 	p->num = num_buffers;
2699 
2700 	/* Complete the management command */
2701 	r = qbman_swp_mc_complete_cinh(s, p, QBMAN_MC_ACQUIRE);
2702 	if (!r) {
2703 		pr_err("qbman: acquire from BPID %d failed, no response\n",
2704 		       bpid);
2705 		return -EIO;
2706 	}
2707 
2708 	/* Decode the outcome */
2709 	QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_MC_ACQUIRE);
2710 
2711 	/* Determine success or failure */
2712 	if (r->rslt != QBMAN_MC_RSLT_OK) {
2713 		pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
2714 		       bpid, r->rslt);
2715 		return -EIO;
2716 	}
2717 
2718 	QBMAN_BUG_ON(r->num > num_buffers);
2719 
2720 	/* Copy the acquired buffers to the caller's array */
2721 	u64_from_le32_copy(buffers, &r->buf[0], r->num);
2722 
2723 	return (int)r->num;
2724 }
2725 
qbman_swp_acquire(struct qbman_swp * s,uint16_t bpid,uint64_t * buffers,unsigned int num_buffers)2726 int qbman_swp_acquire(struct qbman_swp *s, uint16_t bpid, uint64_t *buffers,
2727 		      unsigned int num_buffers)
2728 {
2729 	if (!s->stash_off)
2730 		return qbman_swp_acquire_direct(s, bpid, buffers, num_buffers);
2731 	else
2732 		return qbman_swp_acquire_cinh_direct(s, bpid, buffers,
2733 					num_buffers);
2734 }
2735 
2736 /*****************/
2737 /* FQ management */
2738 /*****************/
2739 struct qbman_alt_fq_state_desc {
2740 	uint8_t verb;
2741 	uint8_t reserved[3];
2742 	uint32_t fqid;
2743 	uint8_t reserved2[56];
2744 };
2745 
2746 struct qbman_alt_fq_state_rslt {
2747 	uint8_t verb;
2748 	uint8_t rslt;
2749 	uint8_t reserved[62];
2750 };
2751 
2752 #define ALT_FQ_FQID_MASK 0x00FFFFFF
2753 
qbman_swp_alt_fq_state(struct qbman_swp * s,uint32_t fqid,uint8_t alt_fq_verb)2754 static int qbman_swp_alt_fq_state(struct qbman_swp *s, uint32_t fqid,
2755 				  uint8_t alt_fq_verb)
2756 {
2757 	struct qbman_alt_fq_state_desc *p;
2758 	struct qbman_alt_fq_state_rslt *r;
2759 
2760 	/* Start the management command */
2761 	p = qbman_swp_mc_start(s);
2762 	if (!p)
2763 		return -EBUSY;
2764 
2765 	p->fqid = fqid & ALT_FQ_FQID_MASK;
2766 
2767 	/* Complete the management command */
2768 	r = qbman_swp_mc_complete(s, p, alt_fq_verb);
2769 	if (!r) {
2770 		pr_err("qbman: mgmt cmd failed, no response (verb=0x%x)\n",
2771 		       alt_fq_verb);
2772 		return -EIO;
2773 	}
2774 
2775 	/* Decode the outcome */
2776 	QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != alt_fq_verb);
2777 
2778 	/* Determine success or failure */
2779 	if (r->rslt != QBMAN_MC_RSLT_OK) {
2780 		pr_err("ALT FQID %d failed: verb = 0x%08x, code = 0x%02x\n",
2781 		       fqid, alt_fq_verb, r->rslt);
2782 		return -EIO;
2783 	}
2784 
2785 	return 0;
2786 }
2787 
qbman_swp_fq_schedule(struct qbman_swp * s,uint32_t fqid)2788 int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid)
2789 {
2790 	return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE);
2791 }
2792 
qbman_swp_fq_force(struct qbman_swp * s,uint32_t fqid)2793 int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid)
2794 {
2795 	return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE);
2796 }
2797 
qbman_swp_fq_xon(struct qbman_swp * s,uint32_t fqid)2798 int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid)
2799 {
2800 	return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON);
2801 }
2802 
qbman_swp_fq_xoff(struct qbman_swp * s,uint32_t fqid)2803 int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid)
2804 {
2805 	return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF);
2806 }
2807 
2808 /**********************/
2809 /* Channel management */
2810 /**********************/
2811 
2812 struct qbman_cdan_ctrl_desc {
2813 	uint8_t verb;
2814 	uint8_t reserved;
2815 	uint16_t ch;
2816 	uint8_t we;
2817 	uint8_t ctrl;
2818 	uint16_t reserved2;
2819 	uint64_t cdan_ctx;
2820 	uint8_t reserved3[48];
2821 
2822 };
2823 
2824 struct qbman_cdan_ctrl_rslt {
2825 	uint8_t verb;
2826 	uint8_t rslt;
2827 	uint16_t ch;
2828 	uint8_t reserved[60];
2829 };
2830 
2831 /* Hide "ICD" for now as we don't use it, don't set it, and don't test it, so it
2832  * would be irresponsible to expose it.
2833  */
2834 #define CODE_CDAN_WE_EN    0x1
2835 #define CODE_CDAN_WE_CTX   0x4
2836 
qbman_swp_CDAN_set(struct qbman_swp * s,uint16_t channelid,uint8_t we_mask,uint8_t cdan_en,uint64_t ctx)2837 static int qbman_swp_CDAN_set(struct qbman_swp *s, uint16_t channelid,
2838 			      uint8_t we_mask, uint8_t cdan_en,
2839 			      uint64_t ctx)
2840 {
2841 	struct qbman_cdan_ctrl_desc *p;
2842 	struct qbman_cdan_ctrl_rslt *r;
2843 
2844 	/* Start the management command */
2845 	p = qbman_swp_mc_start(s);
2846 	if (!p)
2847 		return -EBUSY;
2848 
2849 	/* Encode the caller-provided attributes */
2850 	p->ch = channelid;
2851 	p->we = we_mask;
2852 	if (cdan_en)
2853 		p->ctrl = 1;
2854 	else
2855 		p->ctrl = 0;
2856 	p->cdan_ctx = ctx;
2857 
2858 	/* Complete the management command */
2859 	r = qbman_swp_mc_complete(s, p, QBMAN_WQCHAN_CONFIGURE);
2860 	if (!r) {
2861 		pr_err("qbman: wqchan config failed, no response\n");
2862 		return -EIO;
2863 	}
2864 
2865 	/* Decode the outcome */
2866 	QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK)
2867 		     != QBMAN_WQCHAN_CONFIGURE);
2868 
2869 	/* Determine success or failure */
2870 	if (r->rslt != QBMAN_MC_RSLT_OK) {
2871 		pr_err("CDAN cQID %d failed: code = 0x%02x\n",
2872 		       channelid, r->rslt);
2873 		return -EIO;
2874 	}
2875 
2876 	return 0;
2877 }
2878 
qbman_swp_CDAN_set_context(struct qbman_swp * s,uint16_t channelid,uint64_t ctx)2879 int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
2880 			       uint64_t ctx)
2881 {
2882 	return qbman_swp_CDAN_set(s, channelid,
2883 				  CODE_CDAN_WE_CTX,
2884 				  0, ctx);
2885 }
2886 
qbman_swp_CDAN_enable(struct qbman_swp * s,uint16_t channelid)2887 int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid)
2888 {
2889 	return qbman_swp_CDAN_set(s, channelid,
2890 				  CODE_CDAN_WE_EN,
2891 				  1, 0);
2892 }
2893 
qbman_swp_CDAN_disable(struct qbman_swp * s,uint16_t channelid)2894 int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid)
2895 {
2896 	return qbman_swp_CDAN_set(s, channelid,
2897 				  CODE_CDAN_WE_EN,
2898 				  0, 0);
2899 }
2900 
qbman_swp_CDAN_set_context_enable(struct qbman_swp * s,uint16_t channelid,uint64_t ctx)2901 int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
2902 				      uint64_t ctx)
2903 {
2904 	return qbman_swp_CDAN_set(s, channelid,
2905 				  CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX,
2906 				  1, ctx);
2907 }
2908 
qbman_get_dqrr_idx(const struct qbman_result * dqrr)2909 uint8_t qbman_get_dqrr_idx(const struct qbman_result *dqrr)
2910 {
2911 	return QBMAN_IDX_FROM_DQRR(dqrr);
2912 }
2913 
qbman_get_dqrr_from_idx(struct qbman_swp * s,uint8_t idx)2914 struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx)
2915 {
2916 	struct qbman_result *dq;
2917 
2918 	dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(idx));
2919 	return dq;
2920 }
2921