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