xref: /dpdk/drivers/bus/fslmc/qbman/qbman_portal.c (revision 98cfbbbe0f2bacdaffb12faadb984610055efc09)
1131a75b6SHemant Agrawal /* SPDX-License-Identifier: BSD-3-Clause
2531b17a7SHemant Agrawal  *
3531b17a7SHemant Agrawal  * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
4a116979aSJun Yang  * Copyright 2018-2020,2023-2024 NXP
5531b17a7SHemant Agrawal  *
6531b17a7SHemant Agrawal  */
7531b17a7SHemant Agrawal 
8293c0ca9SNipun Gupta #include "qbman_sys.h"
9531b17a7SHemant Agrawal #include "qbman_portal.h"
10531b17a7SHemant Agrawal 
11531b17a7SHemant Agrawal /* QBMan portal management command codes */
12531b17a7SHemant Agrawal #define QBMAN_MC_ACQUIRE       0x30
13531b17a7SHemant Agrawal #define QBMAN_WQCHAN_CONFIGURE 0x46
14531b17a7SHemant Agrawal 
15531b17a7SHemant Agrawal /* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
16531b17a7SHemant Agrawal #define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6)
17531b17a7SHemant Agrawal 
18531b17a7SHemant Agrawal /* QBMan FQ management command codes */
19531b17a7SHemant Agrawal #define QBMAN_FQ_SCHEDULE	0x48
20531b17a7SHemant Agrawal #define QBMAN_FQ_FORCE		0x49
21531b17a7SHemant Agrawal #define QBMAN_FQ_XON		0x4d
22531b17a7SHemant Agrawal #define QBMAN_FQ_XOFF		0x4e
23531b17a7SHemant Agrawal 
24531b17a7SHemant Agrawal /*******************************/
25531b17a7SHemant Agrawal /* Pre-defined attribute codes */
26531b17a7SHemant Agrawal /*******************************/
27531b17a7SHemant Agrawal 
2869293c77SHemant Agrawal #define QBMAN_RESPONSE_VERB_MASK   0x7f
29531b17a7SHemant Agrawal 
30531b17a7SHemant Agrawal /*************************/
31531b17a7SHemant Agrawal /* SDQCR attribute codes */
32531b17a7SHemant Agrawal /*************************/
3369293c77SHemant Agrawal #define QB_SDQCR_FC_SHIFT   29
3469293c77SHemant Agrawal #define QB_SDQCR_FC_MASK    0x1
3569293c77SHemant Agrawal #define QB_SDQCR_DCT_SHIFT  24
3669293c77SHemant Agrawal #define QB_SDQCR_DCT_MASK   0x3
3769293c77SHemant Agrawal #define QB_SDQCR_TOK_SHIFT  16
3869293c77SHemant Agrawal #define QB_SDQCR_TOK_MASK   0xff
3969293c77SHemant Agrawal #define QB_SDQCR_SRC_SHIFT  0
4069293c77SHemant Agrawal #define QB_SDQCR_SRC_MASK   0xffff
41531b17a7SHemant Agrawal 
4269293c77SHemant Agrawal /* opaque token for static dequeues */
4369293c77SHemant Agrawal #define QMAN_SDQCR_TOKEN    0xbb
4469293c77SHemant Agrawal 
45a116979aSJun Yang #define BMAN_VALID_RSLT_NUM_MASK 0x7
46a116979aSJun Yang 
47531b17a7SHemant Agrawal enum qbman_sdqcr_dct {
48531b17a7SHemant Agrawal 	qbman_sdqcr_dct_null = 0,
49531b17a7SHemant Agrawal 	qbman_sdqcr_dct_prio_ics,
50531b17a7SHemant Agrawal 	qbman_sdqcr_dct_active_ics,
51531b17a7SHemant Agrawal 	qbman_sdqcr_dct_active
52531b17a7SHemant Agrawal };
53531b17a7SHemant Agrawal 
54531b17a7SHemant Agrawal enum qbman_sdqcr_fc {
55531b17a7SHemant Agrawal 	qbman_sdqcr_fc_one = 0,
56531b17a7SHemant Agrawal 	qbman_sdqcr_fc_up_to_3 = 1
57531b17a7SHemant Agrawal };
58531b17a7SHemant Agrawal 
59531b17a7SHemant Agrawal /* We need to keep track of which SWP triggered a pull command
60531b17a7SHemant Agrawal  * so keep an array of portal IDs and use the token field to
61531b17a7SHemant Agrawal  * be able to find the proper portal
62531b17a7SHemant Agrawal  */
6369293c77SHemant Agrawal #define MAX_QBMAN_PORTALS  64
64531b17a7SHemant Agrawal static struct qbman_swp *portal_idx_map[MAX_QBMAN_PORTALS];
65531b17a7SHemant Agrawal 
66dc111b5eSFerruh Yigit uint32_t qman_version;
67dc111b5eSFerruh Yigit 
68293c0ca9SNipun Gupta /* Internal Function declaration */
69293c0ca9SNipun Gupta static int
70293c0ca9SNipun Gupta qbman_swp_enqueue_array_mode_direct(struct qbman_swp *s,
71293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
72293c0ca9SNipun Gupta 		const struct qbman_fd *fd);
73293c0ca9SNipun Gupta static int
74293c0ca9SNipun Gupta qbman_swp_enqueue_array_mode_mem_back(struct qbman_swp *s,
75293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
76293c0ca9SNipun Gupta 		const struct qbman_fd *fd);
77293c0ca9SNipun Gupta 
78293c0ca9SNipun Gupta static int
79293c0ca9SNipun Gupta qbman_swp_enqueue_ring_mode_direct(struct qbman_swp *s,
80293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
81293c0ca9SNipun Gupta 		const struct qbman_fd *fd);
82293c0ca9SNipun Gupta static int
8379e5b5edSNipun Gupta qbman_swp_enqueue_ring_mode_cinh_read_direct(struct qbman_swp *s,
8463d5d0afSNipun Gupta 		const struct qbman_eq_desc *d,
8563d5d0afSNipun Gupta 		const struct qbman_fd *fd);
8663d5d0afSNipun Gupta static int
87b3bd7a50SNipun Gupta qbman_swp_enqueue_ring_mode_cinh_direct(struct qbman_swp *s,
88b3bd7a50SNipun Gupta 		const struct qbman_eq_desc *d,
89b3bd7a50SNipun Gupta 		const struct qbman_fd *fd);
90b3bd7a50SNipun Gupta static int
91293c0ca9SNipun Gupta qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp *s,
92293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
93293c0ca9SNipun Gupta 		const struct qbman_fd *fd);
94293c0ca9SNipun Gupta 
95293c0ca9SNipun Gupta static int
96293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
97293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
98293c0ca9SNipun Gupta 		const struct qbman_fd *fd,
99293c0ca9SNipun Gupta 		uint32_t *flags,
100293c0ca9SNipun Gupta 		int num_frames);
101293c0ca9SNipun Gupta static int
10279e5b5edSNipun Gupta qbman_swp_enqueue_multiple_cinh_read_direct(struct qbman_swp *s,
10363d5d0afSNipun Gupta 		const struct qbman_eq_desc *d,
10463d5d0afSNipun Gupta 		const struct qbman_fd *fd,
10563d5d0afSNipun Gupta 		uint32_t *flags,
10663d5d0afSNipun Gupta 		int num_frames);
10763d5d0afSNipun Gupta static int
108b3bd7a50SNipun Gupta qbman_swp_enqueue_multiple_cinh_direct(struct qbman_swp *s,
109b3bd7a50SNipun Gupta 		const struct qbman_eq_desc *d,
110b3bd7a50SNipun Gupta 		const struct qbman_fd *fd,
111b3bd7a50SNipun Gupta 		uint32_t *flags,
112b3bd7a50SNipun Gupta 		int num_frames);
113b3bd7a50SNipun Gupta static int
114293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,
115293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
116293c0ca9SNipun Gupta 		const struct qbman_fd *fd,
117293c0ca9SNipun Gupta 		uint32_t *flags,
118293c0ca9SNipun Gupta 		int num_frames);
119293c0ca9SNipun Gupta 
120293c0ca9SNipun Gupta static int
121a3a997f0SHemant Agrawal qbman_swp_enqueue_multiple_fd_direct(struct qbman_swp *s,
122a3a997f0SHemant Agrawal 		const struct qbman_eq_desc *d,
123a3a997f0SHemant Agrawal 		struct qbman_fd **fd,
124a3a997f0SHemant Agrawal 		uint32_t *flags,
125a3a997f0SHemant Agrawal 		int num_frames);
12663d5d0afSNipun Gupta static int
12779e5b5edSNipun Gupta qbman_swp_enqueue_multiple_fd_cinh_read_direct(struct qbman_swp *s,
12863d5d0afSNipun Gupta 		const struct qbman_eq_desc *d,
12963d5d0afSNipun Gupta 		struct qbman_fd **fd,
13063d5d0afSNipun Gupta 		uint32_t *flags,
13163d5d0afSNipun Gupta 		int num_frames);
132a3a997f0SHemant Agrawal static int
133b3bd7a50SNipun Gupta qbman_swp_enqueue_multiple_fd_cinh_direct(struct qbman_swp *s,
134b3bd7a50SNipun Gupta 		const struct qbman_eq_desc *d,
135b3bd7a50SNipun Gupta 		struct qbman_fd **fd,
136b3bd7a50SNipun Gupta 		uint32_t *flags,
137b3bd7a50SNipun Gupta 		int num_frames);
138b3bd7a50SNipun Gupta static int
139a3a997f0SHemant Agrawal qbman_swp_enqueue_multiple_fd_mem_back(struct qbman_swp *s,
140a3a997f0SHemant Agrawal 		const struct qbman_eq_desc *d,
141a3a997f0SHemant Agrawal 		struct qbman_fd **fd,
142a3a997f0SHemant Agrawal 		uint32_t *flags,
143a3a997f0SHemant Agrawal 		int num_frames);
144a3a997f0SHemant Agrawal 
145a3a997f0SHemant Agrawal static int
146293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
147293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
148293c0ca9SNipun Gupta 		const struct qbman_fd *fd,
149293c0ca9SNipun Gupta 		int num_frames);
150293c0ca9SNipun Gupta static int
15179e5b5edSNipun Gupta qbman_swp_enqueue_multiple_desc_cinh_read_direct(struct qbman_swp *s,
15263d5d0afSNipun Gupta 		const struct qbman_eq_desc *d,
15363d5d0afSNipun Gupta 		const struct qbman_fd *fd,
15463d5d0afSNipun Gupta 		int num_frames);
15563d5d0afSNipun Gupta static int
156b3bd7a50SNipun Gupta qbman_swp_enqueue_multiple_desc_cinh_direct(struct qbman_swp *s,
157b3bd7a50SNipun Gupta 		const struct qbman_eq_desc *d,
158b3bd7a50SNipun Gupta 		const struct qbman_fd *fd,
159b3bd7a50SNipun Gupta 		int num_frames);
160b3bd7a50SNipun Gupta static int
161293c0ca9SNipun Gupta qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,
162293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
163293c0ca9SNipun Gupta 		const struct qbman_fd *fd,
164293c0ca9SNipun Gupta 		int num_frames);
165293c0ca9SNipun Gupta 
166293c0ca9SNipun Gupta static int
167293c0ca9SNipun Gupta qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d);
168293c0ca9SNipun Gupta static int
169b3bd7a50SNipun Gupta qbman_swp_pull_cinh_direct(struct qbman_swp *s, struct qbman_pull_desc *d);
170b3bd7a50SNipun Gupta static int
171293c0ca9SNipun Gupta qbman_swp_pull_mem_back(struct qbman_swp *s, struct qbman_pull_desc *d);
172293c0ca9SNipun Gupta 
173293c0ca9SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_direct(struct qbman_swp *s);
174b3bd7a50SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_cinh_direct(struct qbman_swp *s);
175293c0ca9SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s);
176293c0ca9SNipun Gupta 
177293c0ca9SNipun Gupta static int
178293c0ca9SNipun Gupta qbman_swp_release_direct(struct qbman_swp *s,
179293c0ca9SNipun Gupta 		const struct qbman_release_desc *d,
180293c0ca9SNipun Gupta 		const uint64_t *buffers, unsigned int num_buffers);
181293c0ca9SNipun Gupta static int
182b3bd7a50SNipun Gupta qbman_swp_release_cinh_direct(struct qbman_swp *s,
183b3bd7a50SNipun Gupta 		const struct qbman_release_desc *d,
184b3bd7a50SNipun Gupta 		const uint64_t *buffers, unsigned int num_buffers);
185b3bd7a50SNipun Gupta static int
186293c0ca9SNipun Gupta qbman_swp_release_mem_back(struct qbman_swp *s,
187293c0ca9SNipun Gupta 		const struct qbman_release_desc *d,
188293c0ca9SNipun Gupta 		const uint64_t *buffers, unsigned int num_buffers);
189293c0ca9SNipun Gupta 
190293c0ca9SNipun Gupta /* Function pointers */
191293c0ca9SNipun Gupta static int (*qbman_swp_enqueue_array_mode_ptr)(struct qbman_swp *s,
192293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
193293c0ca9SNipun Gupta 		const struct qbman_fd *fd)
194293c0ca9SNipun Gupta 	= qbman_swp_enqueue_array_mode_direct;
195293c0ca9SNipun Gupta 
196293c0ca9SNipun Gupta static int (*qbman_swp_enqueue_ring_mode_ptr)(struct qbman_swp *s,
197293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
198293c0ca9SNipun Gupta 		const struct qbman_fd *fd)
199293c0ca9SNipun Gupta 	= qbman_swp_enqueue_ring_mode_direct;
200293c0ca9SNipun Gupta 
201293c0ca9SNipun Gupta static int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s,
202293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
203293c0ca9SNipun Gupta 		const struct qbman_fd *fd,
204293c0ca9SNipun Gupta 		uint32_t *flags,
205293c0ca9SNipun Gupta 		int num_frames)
206293c0ca9SNipun Gupta 	= qbman_swp_enqueue_multiple_direct;
207293c0ca9SNipun Gupta 
208a3a997f0SHemant Agrawal static int (*qbman_swp_enqueue_multiple_fd_ptr)(struct qbman_swp *s,
209a3a997f0SHemant Agrawal 		const struct qbman_eq_desc *d,
210a3a997f0SHemant Agrawal 		struct qbman_fd **fd,
211a3a997f0SHemant Agrawal 		uint32_t *flags,
212a3a997f0SHemant Agrawal 		int num_frames)
213a3a997f0SHemant Agrawal 	= qbman_swp_enqueue_multiple_fd_direct;
214a3a997f0SHemant Agrawal 
215293c0ca9SNipun Gupta static int (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s,
216293c0ca9SNipun Gupta 		const struct qbman_eq_desc *d,
217293c0ca9SNipun Gupta 		const struct qbman_fd *fd,
218293c0ca9SNipun Gupta 		int num_frames)
219293c0ca9SNipun Gupta 	= qbman_swp_enqueue_multiple_desc_direct;
220293c0ca9SNipun Gupta 
221293c0ca9SNipun Gupta static int (*qbman_swp_pull_ptr)(struct qbman_swp *s,
222293c0ca9SNipun Gupta 		struct qbman_pull_desc *d)
223293c0ca9SNipun Gupta 	= qbman_swp_pull_direct;
224293c0ca9SNipun Gupta 
225293c0ca9SNipun Gupta const struct qbman_result *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s)
226293c0ca9SNipun Gupta 		= qbman_swp_dqrr_next_direct;
227293c0ca9SNipun Gupta 
228293c0ca9SNipun Gupta static int (*qbman_swp_release_ptr)(struct qbman_swp *s,
229293c0ca9SNipun Gupta 			const struct qbman_release_desc *d,
230293c0ca9SNipun Gupta 			const uint64_t *buffers, unsigned int num_buffers)
231293c0ca9SNipun Gupta 			= qbman_swp_release_direct;
232293c0ca9SNipun Gupta 
233531b17a7SHemant Agrawal /*********************************/
234531b17a7SHemant Agrawal /* Portal constructor/destructor */
235531b17a7SHemant Agrawal /*********************************/
236531b17a7SHemant Agrawal 
237531b17a7SHemant Agrawal /* Software portals should always be in the power-on state when we initialise,
238531b17a7SHemant Agrawal  * due to the CCSR-based portal reset functionality that MC has.
239531b17a7SHemant Agrawal  *
240531b17a7SHemant Agrawal  * Erk! Turns out that QMan versions prior to 4.1 do not correctly reset DQRR
241531b17a7SHemant Agrawal  * valid-bits, so we need to support a workaround where we don't trust
242531b17a7SHemant Agrawal  * valid-bits when detecting new entries until any stale ring entries have been
243531b17a7SHemant Agrawal  * overwritten at least once. The idea is that we read PI for the first few
244531b17a7SHemant Agrawal  * entries, then switch to valid-bit after that. The trick is to clear the
245531b17a7SHemant Agrawal  * bug-work-around boolean once the PI wraps around the ring for the first time.
246531b17a7SHemant Agrawal  *
247531b17a7SHemant Agrawal  * Note: this still carries a slight additional cost once the decrementer hits
248531b17a7SHemant Agrawal  * zero.
249531b17a7SHemant Agrawal  */
250531b17a7SHemant Agrawal struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
251531b17a7SHemant Agrawal {
252531b17a7SHemant Agrawal 	int ret;
253531b17a7SHemant Agrawal 	uint32_t eqcr_pi;
254293c0ca9SNipun Gupta 	uint32_t mask_size;
255d95bdc09SHemant Agrawal 	struct qbman_swp *p = malloc(sizeof(*p));
256531b17a7SHemant Agrawal 
257531b17a7SHemant Agrawal 	if (!p)
258531b17a7SHemant Agrawal 		return NULL;
259293c0ca9SNipun Gupta 
260293c0ca9SNipun Gupta 	memset(p, 0, sizeof(struct qbman_swp));
261293c0ca9SNipun Gupta 
262531b17a7SHemant Agrawal 	p->desc = *d;
263531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING
264531b17a7SHemant Agrawal 	p->mc.check = swp_mc_can_start;
265531b17a7SHemant Agrawal #endif
266531b17a7SHemant Agrawal 	p->mc.valid_bit = QB_VALID_BIT;
26769293c77SHemant Agrawal 	p->sdq |= qbman_sdqcr_dct_prio_ics << QB_SDQCR_DCT_SHIFT;
26869293c77SHemant Agrawal 	p->sdq |= qbman_sdqcr_fc_up_to_3 << QB_SDQCR_FC_SHIFT;
26969293c77SHemant Agrawal 	p->sdq |= QMAN_SDQCR_TOKEN << QB_SDQCR_TOK_SHIFT;
2703f28677aSHemant Agrawal 	if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
2713f28677aSHemant Agrawal 			&& (d->cena_access_mode == qman_cena_fastest_access))
272293c0ca9SNipun Gupta 		p->mr.valid_bit = QB_VALID_BIT;
27369293c77SHemant Agrawal 
274531b17a7SHemant Agrawal 	atomic_set(&p->vdq.busy, 1);
275531b17a7SHemant Agrawal 	p->vdq.valid_bit = QB_VALID_BIT;
276531b17a7SHemant Agrawal 	p->dqrr.valid_bit = QB_VALID_BIT;
277293c0ca9SNipun Gupta 	qman_version = p->desc.qman_version;
278ff8e5f10SHemant Agrawal 	if ((qman_version & QMAN_REV_MASK) < QMAN_REV_4100) {
279531b17a7SHemant Agrawal 		p->dqrr.dqrr_size = 4;
280531b17a7SHemant Agrawal 		p->dqrr.reset_bug = 1;
281531b17a7SHemant Agrawal 	} else {
282531b17a7SHemant Agrawal 		p->dqrr.dqrr_size = 8;
283531b17a7SHemant Agrawal 		p->dqrr.reset_bug = 0;
284531b17a7SHemant Agrawal 	}
285531b17a7SHemant Agrawal 
286531b17a7SHemant Agrawal 	ret = qbman_swp_sys_init(&p->sys, d, p->dqrr.dqrr_size);
287531b17a7SHemant Agrawal 	if (ret) {
288d95bdc09SHemant Agrawal 		free(p);
289531b17a7SHemant Agrawal 		pr_err("qbman_swp_sys_init() failed %d\n", ret);
290531b17a7SHemant Agrawal 		return NULL;
291531b17a7SHemant Agrawal 	}
292293c0ca9SNipun Gupta 
293293c0ca9SNipun Gupta 	/* Verify that the DQRRPI is 0 - if it is not the portal isn't
294293c0ca9SNipun Gupta 	 * in default state which is an error
295293c0ca9SNipun Gupta 	 */
296293c0ca9SNipun Gupta 	if (qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_DQPI) & 0xF) {
297293c0ca9SNipun Gupta 		pr_err("qbman DQRR PI is not zero, portal is not clean\n");
298293c0ca9SNipun Gupta 		free(p);
299293c0ca9SNipun Gupta 		return NULL;
300293c0ca9SNipun Gupta 	}
301293c0ca9SNipun Gupta 
302531b17a7SHemant Agrawal 	/* SDQCR needs to be initialized to 0 when no channels are
303531b17a7SHemant Agrawal 	 * being dequeued from or else the QMan HW will indicate an
304531b17a7SHemant Agrawal 	 * error.  The values that were calculated above will be
30569293c77SHemant Agrawal 	 * applied when dequeues from a specific channel are enabled.
306531b17a7SHemant Agrawal 	 */
307531b17a7SHemant Agrawal 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, 0);
308293c0ca9SNipun Gupta 
309293c0ca9SNipun Gupta 	p->eqcr.pi_ring_size = 8;
3103f28677aSHemant Agrawal 	if ((qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
3113f28677aSHemant Agrawal 			&& (d->cena_access_mode == qman_cena_fastest_access)) {
312293c0ca9SNipun Gupta 		p->eqcr.pi_ring_size = 32;
313293c0ca9SNipun Gupta 		qbman_swp_enqueue_array_mode_ptr =
314293c0ca9SNipun Gupta 			qbman_swp_enqueue_array_mode_mem_back;
315293c0ca9SNipun Gupta 		qbman_swp_enqueue_ring_mode_ptr =
316293c0ca9SNipun Gupta 			qbman_swp_enqueue_ring_mode_mem_back;
317293c0ca9SNipun Gupta 		qbman_swp_enqueue_multiple_ptr =
318293c0ca9SNipun Gupta 			qbman_swp_enqueue_multiple_mem_back;
319a3a997f0SHemant Agrawal 		qbman_swp_enqueue_multiple_fd_ptr =
320a3a997f0SHemant Agrawal 			qbman_swp_enqueue_multiple_fd_mem_back;
321293c0ca9SNipun Gupta 		qbman_swp_enqueue_multiple_desc_ptr =
322293c0ca9SNipun Gupta 			qbman_swp_enqueue_multiple_desc_mem_back;
323293c0ca9SNipun Gupta 		qbman_swp_pull_ptr = qbman_swp_pull_mem_back;
324293c0ca9SNipun Gupta 		qbman_swp_dqrr_next_ptr = qbman_swp_dqrr_next_mem_back;
325293c0ca9SNipun Gupta 		qbman_swp_release_ptr = qbman_swp_release_mem_back;
326293c0ca9SNipun Gupta 	}
327293c0ca9SNipun Gupta 
32863d5d0afSNipun Gupta 	if (dpaa2_svr_family == SVR_LS1080A) {
32963d5d0afSNipun Gupta 		qbman_swp_enqueue_ring_mode_ptr =
33079e5b5edSNipun Gupta 			qbman_swp_enqueue_ring_mode_cinh_read_direct;
33163d5d0afSNipun Gupta 		qbman_swp_enqueue_multiple_ptr =
33279e5b5edSNipun Gupta 			qbman_swp_enqueue_multiple_cinh_read_direct;
33363d5d0afSNipun Gupta 		qbman_swp_enqueue_multiple_fd_ptr =
33479e5b5edSNipun Gupta 			qbman_swp_enqueue_multiple_fd_cinh_read_direct;
33563d5d0afSNipun Gupta 		qbman_swp_enqueue_multiple_desc_ptr =
33679e5b5edSNipun Gupta 			qbman_swp_enqueue_multiple_desc_cinh_read_direct;
33763d5d0afSNipun Gupta 	}
33863d5d0afSNipun Gupta 
339293c0ca9SNipun Gupta 	for (mask_size = p->eqcr.pi_ring_size; mask_size > 0; mask_size >>= 1)
3401b49352fSHemant Agrawal 		p->eqcr.pi_ci_mask = (p->eqcr.pi_ci_mask<<1) + 1;
341531b17a7SHemant Agrawal 	eqcr_pi = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI);
3421b49352fSHemant Agrawal 	p->eqcr.pi = eqcr_pi & p->eqcr.pi_ci_mask;
343531b17a7SHemant Agrawal 	p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT;
3441b49352fSHemant Agrawal 	p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI)
3451b49352fSHemant Agrawal 			& p->eqcr.pi_ci_mask;
346a675f35dSYouri Querry 	p->eqcr.available = p->eqcr.pi_ring_size;
347531b17a7SHemant Agrawal 
348531b17a7SHemant Agrawal 	portal_idx_map[p->desc.idx] = p;
349531b17a7SHemant Agrawal 	return p;
350531b17a7SHemant Agrawal }
351531b17a7SHemant Agrawal 
352b3bd7a50SNipun Gupta int qbman_swp_update(struct qbman_swp *p, int stash_off)
353b3bd7a50SNipun Gupta {
354b3bd7a50SNipun Gupta 	const struct qbman_swp_desc *d = &p->desc;
355b3bd7a50SNipun Gupta 	struct qbman_swp_sys *s = &p->sys;
356b3bd7a50SNipun Gupta 	int ret;
357b3bd7a50SNipun Gupta 
358b3bd7a50SNipun Gupta 	/* Nothing needs to be done for QBMAN rev > 5000 with fast access */
359b3bd7a50SNipun Gupta 	if ((qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
360b3bd7a50SNipun Gupta 			&& (d->cena_access_mode == qman_cena_fastest_access))
361b3bd7a50SNipun Gupta 		return 0;
362b3bd7a50SNipun Gupta 
363b3bd7a50SNipun Gupta 	ret = qbman_swp_sys_update(s, d, p->dqrr.dqrr_size, stash_off);
364b3bd7a50SNipun Gupta 	if (ret) {
365b3bd7a50SNipun Gupta 		pr_err("qbman_swp_sys_init() failed %d\n", ret);
366b3bd7a50SNipun Gupta 		return ret;
367b3bd7a50SNipun Gupta 	}
368b3bd7a50SNipun Gupta 
369b3bd7a50SNipun Gupta 	p->stash_off = stash_off;
370b3bd7a50SNipun Gupta 
371b3bd7a50SNipun Gupta 	return 0;
372b3bd7a50SNipun Gupta }
373b3bd7a50SNipun Gupta 
374531b17a7SHemant Agrawal void qbman_swp_finish(struct qbman_swp *p)
375531b17a7SHemant Agrawal {
376531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING
377531b17a7SHemant Agrawal 	QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
378531b17a7SHemant Agrawal #endif
379531b17a7SHemant Agrawal 	qbman_swp_sys_finish(&p->sys);
380531b17a7SHemant Agrawal 	portal_idx_map[p->desc.idx] = NULL;
381d95bdc09SHemant Agrawal 	free(p);
382531b17a7SHemant Agrawal }
383531b17a7SHemant Agrawal 
384531b17a7SHemant Agrawal const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p)
385531b17a7SHemant Agrawal {
386531b17a7SHemant Agrawal 	return &p->desc;
387531b17a7SHemant Agrawal }
388531b17a7SHemant Agrawal 
389531b17a7SHemant Agrawal /**************/
390531b17a7SHemant Agrawal /* Interrupts */
391531b17a7SHemant Agrawal /**************/
392531b17a7SHemant Agrawal 
393531b17a7SHemant Agrawal uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p)
394531b17a7SHemant Agrawal {
395531b17a7SHemant Agrawal 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISDR);
396531b17a7SHemant Agrawal }
397531b17a7SHemant Agrawal 
398531b17a7SHemant Agrawal void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask)
399531b17a7SHemant Agrawal {
400531b17a7SHemant Agrawal 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISDR, mask);
401531b17a7SHemant Agrawal }
402531b17a7SHemant Agrawal 
403531b17a7SHemant Agrawal uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p)
404531b17a7SHemant Agrawal {
405531b17a7SHemant Agrawal 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISR);
406531b17a7SHemant Agrawal }
407531b17a7SHemant Agrawal 
408531b17a7SHemant Agrawal void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask)
409531b17a7SHemant Agrawal {
410531b17a7SHemant Agrawal 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISR, mask);
411531b17a7SHemant Agrawal }
412531b17a7SHemant Agrawal 
4139ccb76b2SNipun Gupta uint32_t qbman_swp_dqrr_thrshld_read_status(struct qbman_swp *p)
4149ccb76b2SNipun Gupta {
4159ccb76b2SNipun Gupta 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_DQRR_ITR);
4169ccb76b2SNipun Gupta }
4179ccb76b2SNipun Gupta 
4189ccb76b2SNipun Gupta void qbman_swp_dqrr_thrshld_write(struct qbman_swp *p, uint32_t mask)
4199ccb76b2SNipun Gupta {
4209ccb76b2SNipun Gupta 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_DQRR_ITR, mask);
4219ccb76b2SNipun Gupta }
4229ccb76b2SNipun Gupta 
4239ccb76b2SNipun Gupta uint32_t qbman_swp_intr_timeout_read_status(struct qbman_swp *p)
4249ccb76b2SNipun Gupta {
4259ccb76b2SNipun Gupta 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ITPR);
4269ccb76b2SNipun Gupta }
4279ccb76b2SNipun Gupta 
4289ccb76b2SNipun Gupta void qbman_swp_intr_timeout_write(struct qbman_swp *p, uint32_t mask)
4299ccb76b2SNipun Gupta {
4309ccb76b2SNipun Gupta 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ITPR, mask);
4319ccb76b2SNipun Gupta }
4329ccb76b2SNipun Gupta 
433531b17a7SHemant Agrawal uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p)
434531b17a7SHemant Agrawal {
435531b17a7SHemant Agrawal 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IER);
436531b17a7SHemant Agrawal }
437531b17a7SHemant Agrawal 
438531b17a7SHemant Agrawal void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask)
439531b17a7SHemant Agrawal {
440531b17a7SHemant Agrawal 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IER, mask);
441531b17a7SHemant Agrawal }
442531b17a7SHemant Agrawal 
443531b17a7SHemant Agrawal int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)
444531b17a7SHemant Agrawal {
445531b17a7SHemant Agrawal 	return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IIR);
446531b17a7SHemant Agrawal }
447531b17a7SHemant Agrawal 
448531b17a7SHemant Agrawal void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)
449531b17a7SHemant Agrawal {
450293c0ca9SNipun Gupta 	qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IIR,
451293c0ca9SNipun Gupta 			 inhibit ? 0xffffffff : 0);
452531b17a7SHemant Agrawal }
453531b17a7SHemant Agrawal 
454531b17a7SHemant Agrawal /***********************/
455531b17a7SHemant Agrawal /* Management commands */
456531b17a7SHemant Agrawal /***********************/
457531b17a7SHemant Agrawal 
458531b17a7SHemant Agrawal /*
459531b17a7SHemant Agrawal  * Internal code common to all types of management commands.
460531b17a7SHemant Agrawal  */
461531b17a7SHemant Agrawal 
462531b17a7SHemant Agrawal void *qbman_swp_mc_start(struct qbman_swp *p)
463531b17a7SHemant Agrawal {
464531b17a7SHemant Agrawal 	void *ret;
465531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING
466531b17a7SHemant Agrawal 	QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
467531b17a7SHemant Agrawal #endif
4683f28677aSHemant Agrawal 	if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
4693f28677aSHemant Agrawal 		    && (p->desc.cena_access_mode == qman_cena_fastest_access))
470293c0ca9SNipun Gupta 		ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR_MEM);
4713f28677aSHemant Agrawal 	else
4723f28677aSHemant Agrawal 		ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
473531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING
474531b17a7SHemant Agrawal 	if (!ret)
475531b17a7SHemant Agrawal 		p->mc.check = swp_mc_can_submit;
476531b17a7SHemant Agrawal #endif
477531b17a7SHemant Agrawal 	return ret;
478531b17a7SHemant Agrawal }
479531b17a7SHemant Agrawal 
48069293c77SHemant Agrawal void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint8_t cmd_verb)
481531b17a7SHemant Agrawal {
48269293c77SHemant Agrawal 	uint8_t *v = cmd;
483531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING
484531b17a7SHemant Agrawal 	QBMAN_BUG_ON(!(p->mc.check != swp_mc_can_submit));
485531b17a7SHemant Agrawal #endif
486531b17a7SHemant Agrawal 	/* TBD: "|=" is going to hurt performance. Need to move as many fields
487531b17a7SHemant Agrawal 	 * out of word zero, and for those that remain, the "OR" needs to occur
488531b17a7SHemant Agrawal 	 * at the caller side. This debug check helps to catch cases where the
489531b17a7SHemant Agrawal 	 * caller wants to OR but has forgotten to do so.
490531b17a7SHemant Agrawal 	 */
491531b17a7SHemant Agrawal 	QBMAN_BUG_ON((*v & cmd_verb) != *v);
4923f28677aSHemant Agrawal 	if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
4933f28677aSHemant Agrawal 		    && (p->desc.cena_access_mode == qman_cena_fastest_access)) {
494293c0ca9SNipun Gupta 		*v = cmd_verb | p->mr.valid_bit;
495293c0ca9SNipun Gupta 		qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR_MEM, cmd);
496293c0ca9SNipun Gupta 		dma_wmb();
497293c0ca9SNipun Gupta 		qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_CR_RT, QMAN_RT_MODE);
4983f28677aSHemant Agrawal 	} else {
4993f28677aSHemant Agrawal 		dma_wmb();
5003f28677aSHemant Agrawal 		*v = cmd_verb | p->mc.valid_bit;
5013f28677aSHemant Agrawal 		qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
5023f28677aSHemant Agrawal 		clean(cmd);
503293c0ca9SNipun Gupta 	}
504531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING
505531b17a7SHemant Agrawal 	p->mc.check = swp_mc_can_poll;
506531b17a7SHemant Agrawal #endif
507531b17a7SHemant Agrawal }
508531b17a7SHemant Agrawal 
509b3bd7a50SNipun Gupta void qbman_swp_mc_submit_cinh(struct qbman_swp *p, void *cmd, uint8_t cmd_verb)
510b3bd7a50SNipun Gupta {
511b3bd7a50SNipun Gupta 	uint8_t *v = cmd;
512b3bd7a50SNipun Gupta #ifdef QBMAN_CHECKING
513b3bd7a50SNipun Gupta 	QBMAN_BUG_ON(!(p->mc.check != swp_mc_can_submit));
514b3bd7a50SNipun Gupta #endif
515b3bd7a50SNipun Gupta 	/* TBD: "|=" is going to hurt performance. Need to move as many fields
516b3bd7a50SNipun Gupta 	 * out of word zero, and for those that remain, the "OR" needs to occur
517b3bd7a50SNipun Gupta 	 * at the caller side. This debug check helps to catch cases where the
518b3bd7a50SNipun Gupta 	 * caller wants to OR but has forgotten to do so.
519b3bd7a50SNipun Gupta 	 */
520b3bd7a50SNipun Gupta 	QBMAN_BUG_ON((*v & cmd_verb) != *v);
521b3bd7a50SNipun Gupta 	dma_wmb();
522b3bd7a50SNipun Gupta 	*v = cmd_verb | p->mc.valid_bit;
523b3bd7a50SNipun Gupta 	qbman_cinh_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
524b3bd7a50SNipun Gupta 	clean(cmd);
525b3bd7a50SNipun Gupta #ifdef QBMAN_CHECKING
526b3bd7a50SNipun Gupta 	p->mc.check = swp_mc_can_poll;
527b3bd7a50SNipun Gupta #endif
528b3bd7a50SNipun Gupta }
529b3bd7a50SNipun Gupta 
530531b17a7SHemant Agrawal void *qbman_swp_mc_result(struct qbman_swp *p)
531531b17a7SHemant Agrawal {
532531b17a7SHemant Agrawal 	uint32_t *ret, verb;
533531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING
534531b17a7SHemant Agrawal 	QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll);
535531b17a7SHemant Agrawal #endif
5363f28677aSHemant Agrawal 	if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000
5373f28677aSHemant Agrawal 		&& (p->desc.cena_access_mode == qman_cena_fastest_access)) {
538293c0ca9SNipun Gupta 		ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR_MEM);
539293c0ca9SNipun Gupta 		/* Command completed if the valid bit is toggled */
540293c0ca9SNipun Gupta 		if (p->mr.valid_bit != (ret[0] & QB_VALID_BIT))
541293c0ca9SNipun Gupta 			return NULL;
542293c0ca9SNipun Gupta 		/* Remove the valid-bit -
543293c0ca9SNipun Gupta 		 * command completed iff the rest is non-zero
544293c0ca9SNipun Gupta 		 */
545293c0ca9SNipun Gupta 		verb = ret[0] & ~QB_VALID_BIT;
546293c0ca9SNipun Gupta 		if (!verb)
547293c0ca9SNipun Gupta 			return NULL;
548293c0ca9SNipun Gupta 		p->mr.valid_bit ^= QB_VALID_BIT;
5493f28677aSHemant Agrawal 	} else {
5503f28677aSHemant Agrawal 		qbman_cena_invalidate_prefetch(&p->sys,
5513f28677aSHemant Agrawal 			QBMAN_CENA_SWP_RR(p->mc.valid_bit));
5523f28677aSHemant Agrawal 		ret = qbman_cena_read(&p->sys,
5533f28677aSHemant Agrawal 				      QBMAN_CENA_SWP_RR(p->mc.valid_bit));
5543f28677aSHemant Agrawal 		/* Remove the valid-bit -
5553f28677aSHemant Agrawal 		 * command completed iff the rest is non-zero
5563f28677aSHemant Agrawal 		 */
5573f28677aSHemant Agrawal 		verb = ret[0] & ~QB_VALID_BIT;
5583f28677aSHemant Agrawal 		if (!verb)
5593f28677aSHemant Agrawal 			return NULL;
5603f28677aSHemant Agrawal 		p->mc.valid_bit ^= QB_VALID_BIT;
561293c0ca9SNipun Gupta 	}
562531b17a7SHemant Agrawal #ifdef QBMAN_CHECKING
563531b17a7SHemant Agrawal 	p->mc.check = swp_mc_can_start;
564531b17a7SHemant Agrawal #endif
565531b17a7SHemant Agrawal 	return ret;
566531b17a7SHemant Agrawal }
567531b17a7SHemant Agrawal 
568b3bd7a50SNipun Gupta void *qbman_swp_mc_result_cinh(struct qbman_swp *p)
569b3bd7a50SNipun Gupta {
570b3bd7a50SNipun Gupta 	uint32_t *ret, verb;
571b3bd7a50SNipun Gupta #ifdef QBMAN_CHECKING
572b3bd7a50SNipun Gupta 	QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll);
573b3bd7a50SNipun Gupta #endif
574b3bd7a50SNipun Gupta 	ret = qbman_cinh_read_shadow(&p->sys,
575b3bd7a50SNipun Gupta 			      QBMAN_CENA_SWP_RR(p->mc.valid_bit));
576b3bd7a50SNipun Gupta 	/* Remove the valid-bit -
577b3bd7a50SNipun Gupta 	 * command completed iff the rest is non-zero
578b3bd7a50SNipun Gupta 	 */
579b3bd7a50SNipun Gupta 	verb = ret[0] & ~QB_VALID_BIT;
580b3bd7a50SNipun Gupta 	if (!verb)
581b3bd7a50SNipun Gupta 		return NULL;
582b3bd7a50SNipun Gupta 	p->mc.valid_bit ^= QB_VALID_BIT;
583b3bd7a50SNipun Gupta #ifdef QBMAN_CHECKING
584b3bd7a50SNipun Gupta 	p->mc.check = swp_mc_can_start;
585b3bd7a50SNipun Gupta #endif
586b3bd7a50SNipun Gupta 	return ret;
587b3bd7a50SNipun Gupta }
588b3bd7a50SNipun Gupta 
589531b17a7SHemant Agrawal /***********/
590531b17a7SHemant Agrawal /* Enqueue */
591531b17a7SHemant Agrawal /***********/
592531b17a7SHemant Agrawal 
59369293c77SHemant Agrawal #define QB_ENQUEUE_CMD_OPTIONS_SHIFT    0
59469293c77SHemant Agrawal enum qb_enqueue_commands {
59569293c77SHemant Agrawal 	enqueue_empty = 0,
59669293c77SHemant Agrawal 	enqueue_response_always = 1,
59769293c77SHemant Agrawal 	enqueue_rejects_to_fq = 2
598531b17a7SHemant Agrawal };
599531b17a7SHemant Agrawal 
60069293c77SHemant Agrawal #define QB_ENQUEUE_CMD_EC_OPTION_MASK        0x3
60169293c77SHemant Agrawal #define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT      2
60269293c77SHemant Agrawal #define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3
60369293c77SHemant Agrawal #define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT     4
60469293c77SHemant Agrawal #define QB_ENQUEUE_CMD_DCA_PK_SHIFT          6
60569293c77SHemant Agrawal #define QB_ENQUEUE_CMD_DCA_EN_SHIFT          7
60669293c77SHemant Agrawal #define QB_ENQUEUE_CMD_NLIS_SHIFT            14
60769293c77SHemant Agrawal #define QB_ENQUEUE_CMD_IS_NESN_SHIFT         15
60869293c77SHemant Agrawal 
609531b17a7SHemant Agrawal void qbman_eq_desc_clear(struct qbman_eq_desc *d)
610531b17a7SHemant Agrawal {
611531b17a7SHemant Agrawal 	memset(d, 0, sizeof(*d));
612531b17a7SHemant Agrawal }
613531b17a7SHemant Agrawal 
614531b17a7SHemant Agrawal void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
615531b17a7SHemant Agrawal {
61669293c77SHemant Agrawal 	d->eq.verb &= ~(1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT);
61769293c77SHemant Agrawal 	if (respond_success)
61869293c77SHemant Agrawal 		d->eq.verb |= enqueue_response_always;
61969293c77SHemant Agrawal 	else
62069293c77SHemant Agrawal 		d->eq.verb |= enqueue_rejects_to_fq;
621531b17a7SHemant Agrawal }
622531b17a7SHemant Agrawal 
623531b17a7SHemant Agrawal void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
62469293c77SHemant Agrawal 			   uint16_t opr_id, uint16_t seqnum, int incomplete)
625531b17a7SHemant Agrawal {
62669293c77SHemant Agrawal 	d->eq.verb |= 1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT;
62769293c77SHemant Agrawal 	if (respond_success)
62869293c77SHemant Agrawal 		d->eq.verb |= enqueue_response_always;
62969293c77SHemant Agrawal 	else
63069293c77SHemant Agrawal 		d->eq.verb |= enqueue_rejects_to_fq;
631531b17a7SHemant Agrawal 
63269293c77SHemant Agrawal 	d->eq.orpid = opr_id;
63369293c77SHemant Agrawal 	d->eq.seqnum = seqnum;
63469293c77SHemant Agrawal 	if (incomplete)
63569293c77SHemant Agrawal 		d->eq.seqnum |= 1 << QB_ENQUEUE_CMD_NLIS_SHIFT;
63669293c77SHemant Agrawal 	else
63769293c77SHemant Agrawal 		d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_NLIS_SHIFT);
638531b17a7SHemant Agrawal }
639531b17a7SHemant Agrawal 
64069293c77SHemant Agrawal void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint16_t opr_id,
64169293c77SHemant Agrawal 				uint16_t seqnum)
642531b17a7SHemant Agrawal {
64369293c77SHemant Agrawal 	d->eq.verb |= 1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT;
64469293c77SHemant Agrawal 	d->eq.verb &= ~QB_ENQUEUE_CMD_EC_OPTION_MASK;
64569293c77SHemant Agrawal 	d->eq.orpid = opr_id;
64669293c77SHemant Agrawal 	d->eq.seqnum = seqnum;
64769293c77SHemant Agrawal 	d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_NLIS_SHIFT);
64869293c77SHemant Agrawal 	d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_IS_NESN_SHIFT);
649531b17a7SHemant Agrawal }
650531b17a7SHemant Agrawal 
65169293c77SHemant Agrawal void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint16_t opr_id,
65269293c77SHemant Agrawal 				uint16_t seqnum)
653531b17a7SHemant Agrawal {
65469293c77SHemant Agrawal 	d->eq.verb |= 1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT;
65569293c77SHemant Agrawal 	d->eq.verb &= ~QB_ENQUEUE_CMD_EC_OPTION_MASK;
65669293c77SHemant Agrawal 	d->eq.orpid = opr_id;
65769293c77SHemant Agrawal 	d->eq.seqnum = seqnum;
65869293c77SHemant Agrawal 	d->eq.seqnum &= ~(1 << QB_ENQUEUE_CMD_NLIS_SHIFT);
65969293c77SHemant Agrawal 	d->eq.seqnum |= 1 << QB_ENQUEUE_CMD_IS_NESN_SHIFT;
660531b17a7SHemant Agrawal }
661531b17a7SHemant Agrawal 
662531b17a7SHemant Agrawal void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
663531b17a7SHemant Agrawal 				dma_addr_t storage_phys,
664531b17a7SHemant Agrawal 				int stash)
665531b17a7SHemant Agrawal {
66669293c77SHemant Agrawal 	d->eq.rsp_addr = storage_phys;
66769293c77SHemant Agrawal 	d->eq.wae = stash;
668531b17a7SHemant Agrawal }
669531b17a7SHemant Agrawal 
670531b17a7SHemant Agrawal void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token)
671531b17a7SHemant Agrawal {
67269293c77SHemant Agrawal 	d->eq.rspid = token;
673531b17a7SHemant Agrawal }
674531b17a7SHemant Agrawal 
675531b17a7SHemant Agrawal void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid)
676531b17a7SHemant Agrawal {
67769293c77SHemant Agrawal 	d->eq.verb &= ~(1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT);
67869293c77SHemant Agrawal 	d->eq.tgtid = fqid;
679531b17a7SHemant Agrawal }
680531b17a7SHemant Agrawal 
681531b17a7SHemant Agrawal void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
68269293c77SHemant Agrawal 			  uint16_t qd_bin, uint8_t qd_prio)
683531b17a7SHemant Agrawal {
68469293c77SHemant Agrawal 	d->eq.verb |= 1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT;
68569293c77SHemant Agrawal 	d->eq.tgtid = qdid;
68669293c77SHemant Agrawal 	d->eq.qdbin = qd_bin;
68769293c77SHemant Agrawal 	d->eq.qpri = qd_prio;
688531b17a7SHemant Agrawal }
689531b17a7SHemant Agrawal 
690531b17a7SHemant Agrawal void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable)
691531b17a7SHemant Agrawal {
69269293c77SHemant Agrawal 	if (enable)
69369293c77SHemant Agrawal 		d->eq.verb |= 1 << QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT;
69469293c77SHemant Agrawal 	else
69569293c77SHemant Agrawal 		d->eq.verb &= ~(1 << QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT);
696531b17a7SHemant Agrawal }
697531b17a7SHemant Agrawal 
698531b17a7SHemant Agrawal void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
69969293c77SHemant Agrawal 			   uint8_t dqrr_idx, int park)
700531b17a7SHemant Agrawal {
701531b17a7SHemant Agrawal 	if (enable) {
70269293c77SHemant Agrawal 		d->eq.dca = dqrr_idx;
70369293c77SHemant Agrawal 		if (park)
70469293c77SHemant Agrawal 			d->eq.dca |= 1 << QB_ENQUEUE_CMD_DCA_PK_SHIFT;
70569293c77SHemant Agrawal 		else
70669293c77SHemant Agrawal 			d->eq.dca &= ~(1 << QB_ENQUEUE_CMD_DCA_PK_SHIFT);
70769293c77SHemant Agrawal 		d->eq.dca |= 1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT;
70869293c77SHemant Agrawal 	} else {
70969293c77SHemant Agrawal 		d->eq.dca &= ~(1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT);
710531b17a7SHemant Agrawal 	}
711531b17a7SHemant Agrawal }
712531b17a7SHemant Agrawal 
713293c0ca9SNipun Gupta #define EQAR_IDX(eqar)     ((eqar) & 0x1f)
714531b17a7SHemant Agrawal #define EQAR_VB(eqar)      ((eqar) & 0x80)
715531b17a7SHemant Agrawal #define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
71669293c77SHemant Agrawal 
717293c0ca9SNipun Gupta static inline void qbman_write_eqcr_am_rt_register(struct qbman_swp *p,
718293c0ca9SNipun Gupta 						   uint8_t idx)
719293c0ca9SNipun Gupta {
720293c0ca9SNipun Gupta 	if (idx < 16)
721293c0ca9SNipun Gupta 		qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_EQCR_AM_RT + idx * 4,
722293c0ca9SNipun Gupta 				     QMAN_RT_MODE);
723293c0ca9SNipun Gupta 	else
724293c0ca9SNipun Gupta 		qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_EQCR_AM_RT2 +
725293c0ca9SNipun Gupta 				     (idx - 16) * 4,
726293c0ca9SNipun Gupta 				     QMAN_RT_MODE);
727293c0ca9SNipun Gupta }
728293c0ca9SNipun Gupta 
729b3bd7a50SNipun Gupta static void memcpy_byte_by_byte(void *to, const void *from, size_t n)
730b3bd7a50SNipun Gupta {
731b3bd7a50SNipun Gupta 	const uint8_t *src = from;
732b3bd7a50SNipun Gupta 	volatile uint8_t *dest = to;
733b3bd7a50SNipun Gupta 	size_t i;
734b3bd7a50SNipun Gupta 
735b3bd7a50SNipun Gupta 	for (i = 0; i < n; i++)
736b3bd7a50SNipun Gupta 		dest[i] = src[i];
737b3bd7a50SNipun Gupta }
738b3bd7a50SNipun Gupta 
739293c0ca9SNipun Gupta 
740293c0ca9SNipun Gupta static int qbman_swp_enqueue_array_mode_direct(struct qbman_swp *s,
741531b17a7SHemant Agrawal 					       const struct qbman_eq_desc *d,
742531b17a7SHemant Agrawal 					       const struct qbman_fd *fd)
743531b17a7SHemant Agrawal {
744531b17a7SHemant Agrawal 	uint32_t *p;
745531b17a7SHemant Agrawal 	const uint32_t *cl = qb_cl(d);
746531b17a7SHemant Agrawal 	uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
747531b17a7SHemant Agrawal 
748531b17a7SHemant Agrawal 	pr_debug("EQAR=%08x\n", eqar);
749531b17a7SHemant Agrawal 	if (!EQAR_SUCCESS(eqar))
750531b17a7SHemant Agrawal 		return -EBUSY;
751531b17a7SHemant Agrawal 	p = qbman_cena_write_start_wo_shadow(&s->sys,
752531b17a7SHemant Agrawal 			QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
7538b870905SHaiying Wang 	memcpy(&p[1], &cl[1], 28);
7548b870905SHaiying Wang 	memcpy(&p[8], fd, sizeof(*fd));
755293c0ca9SNipun Gupta 
756531b17a7SHemant Agrawal 	/* Set the verb byte, have to substitute in the valid-bit */
757293c0ca9SNipun Gupta 	dma_wmb();
758531b17a7SHemant Agrawal 	p[0] = cl[0] | EQAR_VB(eqar);
759531b17a7SHemant Agrawal 	qbman_cena_write_complete_wo_shadow(&s->sys,
760531b17a7SHemant Agrawal 				QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
761531b17a7SHemant Agrawal 	return 0;
762531b17a7SHemant Agrawal }
763293c0ca9SNipun Gupta static int qbman_swp_enqueue_array_mode_mem_back(struct qbman_swp *s,
764531b17a7SHemant Agrawal 						 const struct qbman_eq_desc *d,
765531b17a7SHemant Agrawal 						 const struct qbman_fd *fd)
766531b17a7SHemant Agrawal {
767531b17a7SHemant Agrawal 	uint32_t *p;
768531b17a7SHemant Agrawal 	const uint32_t *cl = qb_cl(d);
769293c0ca9SNipun Gupta 	uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
770531b17a7SHemant Agrawal 
771293c0ca9SNipun Gupta 	pr_debug("EQAR=%08x\n", eqar);
772293c0ca9SNipun Gupta 	if (!EQAR_SUCCESS(eqar))
773293c0ca9SNipun Gupta 		return -EBUSY;
774293c0ca9SNipun Gupta 	p = qbman_cena_write_start_wo_shadow(&s->sys,
775293c0ca9SNipun Gupta 			QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
776293c0ca9SNipun Gupta 	memcpy(&p[1], &cl[1], 28);
777293c0ca9SNipun Gupta 	memcpy(&p[8], fd, sizeof(*fd));
778293c0ca9SNipun Gupta 
779293c0ca9SNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
780293c0ca9SNipun Gupta 	p[0] = cl[0] | EQAR_VB(eqar);
781293c0ca9SNipun Gupta 	dma_wmb();
782293c0ca9SNipun Gupta 	qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar));
783293c0ca9SNipun Gupta 	return 0;
784293c0ca9SNipun Gupta }
785293c0ca9SNipun Gupta 
786293c0ca9SNipun Gupta static inline int qbman_swp_enqueue_array_mode(struct qbman_swp *s,
787293c0ca9SNipun Gupta 					       const struct qbman_eq_desc *d,
788293c0ca9SNipun Gupta 					       const struct qbman_fd *fd)
789293c0ca9SNipun Gupta {
790293c0ca9SNipun Gupta 	return qbman_swp_enqueue_array_mode_ptr(s, d, fd);
791293c0ca9SNipun Gupta }
792293c0ca9SNipun Gupta 
793293c0ca9SNipun Gupta static int qbman_swp_enqueue_ring_mode_direct(struct qbman_swp *s,
794293c0ca9SNipun Gupta 					      const struct qbman_eq_desc *d,
795293c0ca9SNipun Gupta 					      const struct qbman_fd *fd)
796293c0ca9SNipun Gupta {
797293c0ca9SNipun Gupta 	uint32_t *p;
798293c0ca9SNipun Gupta 	const uint32_t *cl = qb_cl(d);
799293c0ca9SNipun Gupta 	uint32_t eqcr_ci, full_mask, half_mask;
800293c0ca9SNipun Gupta 
8011b49352fSHemant Agrawal 	half_mask = (s->eqcr.pi_ci_mask>>1);
8021b49352fSHemant Agrawal 	full_mask = s->eqcr.pi_ci_mask;
803531b17a7SHemant Agrawal 	if (!s->eqcr.available) {
804531b17a7SHemant Agrawal 		eqcr_ci = s->eqcr.ci;
805531b17a7SHemant Agrawal 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
806293c0ca9SNipun Gupta 				QBMAN_CENA_SWP_EQCR_CI) & full_mask;
807293c0ca9SNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
808531b17a7SHemant Agrawal 				eqcr_ci, s->eqcr.ci);
809293c0ca9SNipun Gupta 		if (!s->eqcr.available)
810531b17a7SHemant Agrawal 			return -EBUSY;
811531b17a7SHemant Agrawal 	}
812531b17a7SHemant Agrawal 
813531b17a7SHemant Agrawal 	p = qbman_cena_write_start_wo_shadow(&s->sys,
814293c0ca9SNipun Gupta 			QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));
8158b870905SHaiying Wang 	memcpy(&p[1], &cl[1], 28);
8168b870905SHaiying Wang 	memcpy(&p[8], fd, sizeof(*fd));
817531b17a7SHemant Agrawal 	lwsync();
81869293c77SHemant Agrawal 
819531b17a7SHemant Agrawal 	/* Set the verb byte, have to substitute in the valid-bit */
820531b17a7SHemant Agrawal 	p[0] = cl[0] | s->eqcr.pi_vb;
821531b17a7SHemant Agrawal 	qbman_cena_write_complete_wo_shadow(&s->sys,
822293c0ca9SNipun Gupta 			QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));
823531b17a7SHemant Agrawal 	s->eqcr.pi++;
824293c0ca9SNipun Gupta 	s->eqcr.pi &= full_mask;
825531b17a7SHemant Agrawal 	s->eqcr.available--;
826293c0ca9SNipun Gupta 	if (!(s->eqcr.pi & half_mask))
827531b17a7SHemant Agrawal 		s->eqcr.pi_vb ^= QB_VALID_BIT;
82869293c77SHemant Agrawal 
829531b17a7SHemant Agrawal 	return 0;
830531b17a7SHemant Agrawal }
831531b17a7SHemant Agrawal 
83279e5b5edSNipun Gupta static int qbman_swp_enqueue_ring_mode_cinh_read_direct(
83363d5d0afSNipun Gupta 		struct qbman_swp *s,
83463d5d0afSNipun Gupta 		const struct qbman_eq_desc *d,
83563d5d0afSNipun Gupta 		const struct qbman_fd *fd)
83663d5d0afSNipun Gupta {
83763d5d0afSNipun Gupta 	uint32_t *p;
83863d5d0afSNipun Gupta 	const uint32_t *cl = qb_cl(d);
83963d5d0afSNipun Gupta 	uint32_t eqcr_ci, full_mask, half_mask;
84063d5d0afSNipun Gupta 
84163d5d0afSNipun Gupta 	half_mask = (s->eqcr.pi_ci_mask>>1);
84263d5d0afSNipun Gupta 	full_mask = s->eqcr.pi_ci_mask;
84363d5d0afSNipun Gupta 	if (!s->eqcr.available) {
84463d5d0afSNipun Gupta 		eqcr_ci = s->eqcr.ci;
84563d5d0afSNipun Gupta 		s->eqcr.ci = qbman_cinh_read(&s->sys,
84663d5d0afSNipun Gupta 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
84763d5d0afSNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
84863d5d0afSNipun Gupta 				eqcr_ci, s->eqcr.ci);
84963d5d0afSNipun Gupta 		if (!s->eqcr.available)
85063d5d0afSNipun Gupta 			return -EBUSY;
85163d5d0afSNipun Gupta 	}
85263d5d0afSNipun Gupta 
853b3bd7a50SNipun Gupta 	p = qbman_cinh_write_start_wo_shadow(&s->sys,
85463d5d0afSNipun Gupta 			QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));
85563d5d0afSNipun Gupta 	memcpy(&p[1], &cl[1], 28);
85663d5d0afSNipun Gupta 	memcpy(&p[8], fd, sizeof(*fd));
85763d5d0afSNipun Gupta 	lwsync();
85863d5d0afSNipun Gupta 
85963d5d0afSNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
86063d5d0afSNipun Gupta 	p[0] = cl[0] | s->eqcr.pi_vb;
86163d5d0afSNipun Gupta 	s->eqcr.pi++;
86263d5d0afSNipun Gupta 	s->eqcr.pi &= full_mask;
86363d5d0afSNipun Gupta 	s->eqcr.available--;
86463d5d0afSNipun Gupta 	if (!(s->eqcr.pi & half_mask))
86563d5d0afSNipun Gupta 		s->eqcr.pi_vb ^= QB_VALID_BIT;
86663d5d0afSNipun Gupta 
86763d5d0afSNipun Gupta 	return 0;
86863d5d0afSNipun Gupta }
86963d5d0afSNipun Gupta 
87079e5b5edSNipun Gupta static int qbman_swp_enqueue_ring_mode_cinh_direct(
87179e5b5edSNipun Gupta 		struct qbman_swp *s,
87279e5b5edSNipun Gupta 		const struct qbman_eq_desc *d,
87379e5b5edSNipun Gupta 		const struct qbman_fd *fd)
87479e5b5edSNipun Gupta {
87579e5b5edSNipun Gupta 	uint32_t *p;
87679e5b5edSNipun Gupta 	const uint32_t *cl = qb_cl(d);
87779e5b5edSNipun Gupta 	uint32_t eqcr_ci, full_mask, half_mask;
87879e5b5edSNipun Gupta 
87979e5b5edSNipun Gupta 	half_mask = (s->eqcr.pi_ci_mask>>1);
88079e5b5edSNipun Gupta 	full_mask = s->eqcr.pi_ci_mask;
88179e5b5edSNipun Gupta 	if (!s->eqcr.available) {
88279e5b5edSNipun Gupta 		eqcr_ci = s->eqcr.ci;
88379e5b5edSNipun Gupta 		s->eqcr.ci = qbman_cinh_read(&s->sys,
88479e5b5edSNipun Gupta 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
88579e5b5edSNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
88679e5b5edSNipun Gupta 				eqcr_ci, s->eqcr.ci);
88779e5b5edSNipun Gupta 		if (!s->eqcr.available)
88879e5b5edSNipun Gupta 			return -EBUSY;
88979e5b5edSNipun Gupta 	}
89079e5b5edSNipun Gupta 
89179e5b5edSNipun Gupta 	p = qbman_cinh_write_start_wo_shadow(&s->sys,
89279e5b5edSNipun Gupta 			QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));
89379e5b5edSNipun Gupta 	memcpy_byte_by_byte(&p[1], &cl[1], 28);
89479e5b5edSNipun Gupta 	memcpy_byte_by_byte(&p[8], fd, sizeof(*fd));
89579e5b5edSNipun Gupta 	lwsync();
89679e5b5edSNipun Gupta 
89779e5b5edSNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
89879e5b5edSNipun Gupta 	p[0] = cl[0] | s->eqcr.pi_vb;
89979e5b5edSNipun Gupta 	s->eqcr.pi++;
90079e5b5edSNipun Gupta 	s->eqcr.pi &= full_mask;
90179e5b5edSNipun Gupta 	s->eqcr.available--;
90279e5b5edSNipun Gupta 	if (!(s->eqcr.pi & half_mask))
90379e5b5edSNipun Gupta 		s->eqcr.pi_vb ^= QB_VALID_BIT;
90479e5b5edSNipun Gupta 
90579e5b5edSNipun Gupta 	return 0;
90679e5b5edSNipun Gupta }
90779e5b5edSNipun Gupta 
908293c0ca9SNipun Gupta static int qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp *s,
909293c0ca9SNipun Gupta 						const struct qbman_eq_desc *d,
910293c0ca9SNipun Gupta 						const struct qbman_fd *fd)
911293c0ca9SNipun Gupta {
912293c0ca9SNipun Gupta 	uint32_t *p;
913293c0ca9SNipun Gupta 	const uint32_t *cl = qb_cl(d);
914293c0ca9SNipun Gupta 	uint32_t eqcr_ci, full_mask, half_mask;
915293c0ca9SNipun Gupta 
9161b49352fSHemant Agrawal 	half_mask = (s->eqcr.pi_ci_mask>>1);
9171b49352fSHemant Agrawal 	full_mask = s->eqcr.pi_ci_mask;
918293c0ca9SNipun Gupta 	if (!s->eqcr.available) {
919293c0ca9SNipun Gupta 		eqcr_ci = s->eqcr.ci;
9202557cf8fSYouri Querry 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
9212557cf8fSYouri Querry 				QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask;
922293c0ca9SNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
923293c0ca9SNipun Gupta 				eqcr_ci, s->eqcr.ci);
924293c0ca9SNipun Gupta 		if (!s->eqcr.available)
925293c0ca9SNipun Gupta 			return -EBUSY;
926293c0ca9SNipun Gupta 	}
927293c0ca9SNipun Gupta 
928293c0ca9SNipun Gupta 	p = qbman_cena_write_start_wo_shadow(&s->sys,
929293c0ca9SNipun Gupta 			QBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));
930293c0ca9SNipun Gupta 	memcpy(&p[1], &cl[1], 28);
931293c0ca9SNipun Gupta 	memcpy(&p[8], fd, sizeof(*fd));
932293c0ca9SNipun Gupta 
933293c0ca9SNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
934293c0ca9SNipun Gupta 	p[0] = cl[0] | s->eqcr.pi_vb;
935293c0ca9SNipun Gupta 	s->eqcr.pi++;
936293c0ca9SNipun Gupta 	s->eqcr.pi &= full_mask;
937293c0ca9SNipun Gupta 	s->eqcr.available--;
938293c0ca9SNipun Gupta 	if (!(s->eqcr.pi & half_mask))
939293c0ca9SNipun Gupta 		s->eqcr.pi_vb ^= QB_VALID_BIT;
940293c0ca9SNipun Gupta 	dma_wmb();
941293c0ca9SNipun Gupta 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,
942293c0ca9SNipun Gupta 				(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
943293c0ca9SNipun Gupta 	return 0;
944293c0ca9SNipun Gupta }
945293c0ca9SNipun Gupta 
946293c0ca9SNipun Gupta static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s,
947293c0ca9SNipun Gupta 				       const struct qbman_eq_desc *d,
948293c0ca9SNipun Gupta 				       const struct qbman_fd *fd)
949293c0ca9SNipun Gupta {
950b3bd7a50SNipun Gupta 	if (!s->stash_off)
951293c0ca9SNipun Gupta 		return qbman_swp_enqueue_ring_mode_ptr(s, d, fd);
952b3bd7a50SNipun Gupta 	else
953b3bd7a50SNipun Gupta 		return qbman_swp_enqueue_ring_mode_cinh_direct(s, d, fd);
954293c0ca9SNipun Gupta }
955293c0ca9SNipun Gupta 
956531b17a7SHemant Agrawal int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
957531b17a7SHemant Agrawal 		      const struct qbman_fd *fd)
958531b17a7SHemant Agrawal {
959531b17a7SHemant Agrawal 	if (s->sys.eqcr_mode == qman_eqcr_vb_array)
960531b17a7SHemant Agrawal 		return qbman_swp_enqueue_array_mode(s, d, fd);
961531b17a7SHemant Agrawal 	else    /* Use ring mode by default */
962531b17a7SHemant Agrawal 		return qbman_swp_enqueue_ring_mode(s, d, fd);
963531b17a7SHemant Agrawal }
964531b17a7SHemant Agrawal 
965293c0ca9SNipun Gupta static int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
96633ae0a29SNipun Gupta 					     const struct qbman_eq_desc *d,
96733ae0a29SNipun Gupta 					     const struct qbman_fd *fd,
968496324d2SNipun Gupta 					     uint32_t *flags,
96933ae0a29SNipun Gupta 					     int num_frames)
97033ae0a29SNipun Gupta {
971293c0ca9SNipun Gupta 	uint32_t *p = NULL;
97233ae0a29SNipun Gupta 	const uint32_t *cl = qb_cl(d);
973293c0ca9SNipun Gupta 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
97433ae0a29SNipun Gupta 	int i, num_enqueued = 0;
97533ae0a29SNipun Gupta 	uint64_t addr_cena;
97633ae0a29SNipun Gupta 
9771b49352fSHemant Agrawal 	half_mask = (s->eqcr.pi_ci_mask>>1);
9781b49352fSHemant Agrawal 	full_mask = s->eqcr.pi_ci_mask;
97933ae0a29SNipun Gupta 	if (!s->eqcr.available) {
98033ae0a29SNipun Gupta 		eqcr_ci = s->eqcr.ci;
98133ae0a29SNipun Gupta 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
982293c0ca9SNipun Gupta 				QBMAN_CENA_SWP_EQCR_CI) & full_mask;
983293c0ca9SNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
98433ae0a29SNipun Gupta 				eqcr_ci, s->eqcr.ci);
985293c0ca9SNipun Gupta 		if (!s->eqcr.available)
98633ae0a29SNipun Gupta 			return 0;
98733ae0a29SNipun Gupta 	}
98833ae0a29SNipun Gupta 
98933ae0a29SNipun Gupta 	eqcr_pi = s->eqcr.pi;
99033ae0a29SNipun Gupta 	num_enqueued = (s->eqcr.available < num_frames) ?
99133ae0a29SNipun Gupta 			s->eqcr.available : num_frames;
99233ae0a29SNipun Gupta 	s->eqcr.available -= num_enqueued;
99333ae0a29SNipun Gupta 	/* Fill in the EQCR ring */
99433ae0a29SNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
99533ae0a29SNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
996293c0ca9SNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
99733ae0a29SNipun Gupta 		memcpy(&p[1], &cl[1], 28);
99833ae0a29SNipun Gupta 		memcpy(&p[8], &fd[i], sizeof(*fd));
99933ae0a29SNipun Gupta 		eqcr_pi++;
100033ae0a29SNipun Gupta 	}
100133ae0a29SNipun Gupta 
100233ae0a29SNipun Gupta 	lwsync();
100333ae0a29SNipun Gupta 
100433ae0a29SNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
100533ae0a29SNipun Gupta 	eqcr_pi = s->eqcr.pi;
100633ae0a29SNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
100733ae0a29SNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1008293c0ca9SNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
100933ae0a29SNipun Gupta 		p[0] = cl[0] | s->eqcr.pi_vb;
1010496324d2SNipun Gupta 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1011*98cfbbbeSRohit Raj 			struct qbman_eq_desc *desc = (struct qbman_eq_desc *)p;
1012496324d2SNipun Gupta 
1013*98cfbbbeSRohit Raj 			desc->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1014496324d2SNipun Gupta 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1015496324d2SNipun Gupta 		}
101633ae0a29SNipun Gupta 		eqcr_pi++;
1017293c0ca9SNipun Gupta 		if (!(eqcr_pi & half_mask))
101833ae0a29SNipun Gupta 			s->eqcr.pi_vb ^= QB_VALID_BIT;
101943f7ff9dSHaiying Wang 	}
102043f7ff9dSHaiying Wang 
102143f7ff9dSHaiying Wang 	/* Flush all the cacheline without load/store in between */
102243f7ff9dSHaiying Wang 	eqcr_pi = s->eqcr.pi;
10235ae1edffSHemant Agrawal 	addr_cena = (size_t)s->sys.addr_cena;
102443f7ff9dSHaiying Wang 	for (i = 0; i < num_enqueued; i++) {
1025293c0ca9SNipun Gupta 		dcbf((uintptr_t)(addr_cena +
1026293c0ca9SNipun Gupta 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)));
102743f7ff9dSHaiying Wang 		eqcr_pi++;
102843f7ff9dSHaiying Wang 	}
1029293c0ca9SNipun Gupta 	s->eqcr.pi = eqcr_pi & full_mask;
103043f7ff9dSHaiying Wang 
103143f7ff9dSHaiying Wang 	return num_enqueued;
103243f7ff9dSHaiying Wang }
103343f7ff9dSHaiying Wang 
103479e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_cinh_read_direct(
103563d5d0afSNipun Gupta 		struct qbman_swp *s,
103663d5d0afSNipun Gupta 		const struct qbman_eq_desc *d,
103763d5d0afSNipun Gupta 		const struct qbman_fd *fd,
103863d5d0afSNipun Gupta 		uint32_t *flags,
103963d5d0afSNipun Gupta 		int num_frames)
104063d5d0afSNipun Gupta {
104163d5d0afSNipun Gupta 	uint32_t *p = NULL;
104263d5d0afSNipun Gupta 	const uint32_t *cl = qb_cl(d);
104363d5d0afSNipun Gupta 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
104463d5d0afSNipun Gupta 	int i, num_enqueued = 0;
104563d5d0afSNipun Gupta 	uint64_t addr_cena;
104663d5d0afSNipun Gupta 
104763d5d0afSNipun Gupta 	half_mask = (s->eqcr.pi_ci_mask>>1);
104863d5d0afSNipun Gupta 	full_mask = s->eqcr.pi_ci_mask;
104963d5d0afSNipun Gupta 	if (!s->eqcr.available) {
105063d5d0afSNipun Gupta 		eqcr_ci = s->eqcr.ci;
105163d5d0afSNipun Gupta 		s->eqcr.ci = qbman_cinh_read(&s->sys,
105263d5d0afSNipun Gupta 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
105363d5d0afSNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
105463d5d0afSNipun Gupta 				eqcr_ci, s->eqcr.ci);
105563d5d0afSNipun Gupta 		if (!s->eqcr.available)
105663d5d0afSNipun Gupta 			return 0;
105763d5d0afSNipun Gupta 	}
105863d5d0afSNipun Gupta 
105963d5d0afSNipun Gupta 	eqcr_pi = s->eqcr.pi;
106063d5d0afSNipun Gupta 	num_enqueued = (s->eqcr.available < num_frames) ?
106163d5d0afSNipun Gupta 			s->eqcr.available : num_frames;
106263d5d0afSNipun Gupta 	s->eqcr.available -= num_enqueued;
106363d5d0afSNipun Gupta 	/* Fill in the EQCR ring */
106463d5d0afSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
106563d5d0afSNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
106663d5d0afSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
106763d5d0afSNipun Gupta 		memcpy(&p[1], &cl[1], 28);
106863d5d0afSNipun Gupta 		memcpy(&p[8], &fd[i], sizeof(*fd));
106963d5d0afSNipun Gupta 		eqcr_pi++;
107063d5d0afSNipun Gupta 	}
107163d5d0afSNipun Gupta 
107263d5d0afSNipun Gupta 	lwsync();
107363d5d0afSNipun Gupta 
107463d5d0afSNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
107563d5d0afSNipun Gupta 	eqcr_pi = s->eqcr.pi;
107663d5d0afSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
107763d5d0afSNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
107863d5d0afSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
107963d5d0afSNipun Gupta 		p[0] = cl[0] | s->eqcr.pi_vb;
108063d5d0afSNipun Gupta 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
108163d5d0afSNipun Gupta 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
108263d5d0afSNipun Gupta 
108363d5d0afSNipun Gupta 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
108463d5d0afSNipun Gupta 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
108563d5d0afSNipun Gupta 		}
108663d5d0afSNipun Gupta 		eqcr_pi++;
108763d5d0afSNipun Gupta 		if (!(eqcr_pi & half_mask))
108863d5d0afSNipun Gupta 			s->eqcr.pi_vb ^= QB_VALID_BIT;
108963d5d0afSNipun Gupta 	}
109063d5d0afSNipun Gupta 
109163d5d0afSNipun Gupta 	/* Flush all the cacheline without load/store in between */
109263d5d0afSNipun Gupta 	eqcr_pi = s->eqcr.pi;
109363d5d0afSNipun Gupta 	addr_cena = (size_t)s->sys.addr_cena;
109463d5d0afSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
109563d5d0afSNipun Gupta 		dcbf(addr_cena +
109663d5d0afSNipun Gupta 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
109763d5d0afSNipun Gupta 		eqcr_pi++;
109863d5d0afSNipun Gupta 	}
109963d5d0afSNipun Gupta 	s->eqcr.pi = eqcr_pi & full_mask;
110063d5d0afSNipun Gupta 
110163d5d0afSNipun Gupta 	return num_enqueued;
110263d5d0afSNipun Gupta }
110363d5d0afSNipun Gupta 
110479e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_cinh_direct(
110579e5b5edSNipun Gupta 		struct qbman_swp *s,
110679e5b5edSNipun Gupta 		const struct qbman_eq_desc *d,
110779e5b5edSNipun Gupta 		const struct qbman_fd *fd,
110879e5b5edSNipun Gupta 		uint32_t *flags,
110979e5b5edSNipun Gupta 		int num_frames)
111079e5b5edSNipun Gupta {
111179e5b5edSNipun Gupta 	uint32_t *p = NULL;
111279e5b5edSNipun Gupta 	const uint32_t *cl = qb_cl(d);
111379e5b5edSNipun Gupta 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
111479e5b5edSNipun Gupta 	int i, num_enqueued = 0;
111579e5b5edSNipun Gupta 
111679e5b5edSNipun Gupta 	half_mask = (s->eqcr.pi_ci_mask>>1);
111779e5b5edSNipun Gupta 	full_mask = s->eqcr.pi_ci_mask;
111879e5b5edSNipun Gupta 	if (!s->eqcr.available) {
111979e5b5edSNipun Gupta 		eqcr_ci = s->eqcr.ci;
112079e5b5edSNipun Gupta 		s->eqcr.ci = qbman_cinh_read(&s->sys,
112179e5b5edSNipun Gupta 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
112279e5b5edSNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
112379e5b5edSNipun Gupta 				eqcr_ci, s->eqcr.ci);
112479e5b5edSNipun Gupta 		if (!s->eqcr.available)
112579e5b5edSNipun Gupta 			return 0;
112679e5b5edSNipun Gupta 	}
112779e5b5edSNipun Gupta 
112879e5b5edSNipun Gupta 	eqcr_pi = s->eqcr.pi;
112979e5b5edSNipun Gupta 	num_enqueued = (s->eqcr.available < num_frames) ?
113079e5b5edSNipun Gupta 			s->eqcr.available : num_frames;
113179e5b5edSNipun Gupta 	s->eqcr.available -= num_enqueued;
113279e5b5edSNipun Gupta 	/* Fill in the EQCR ring */
113379e5b5edSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
113479e5b5edSNipun Gupta 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
113579e5b5edSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
113679e5b5edSNipun Gupta 		memcpy_byte_by_byte(&p[1], &cl[1], 28);
113779e5b5edSNipun Gupta 		memcpy_byte_by_byte(&p[8], &fd[i], sizeof(*fd));
113879e5b5edSNipun Gupta 		eqcr_pi++;
113979e5b5edSNipun Gupta 	}
114079e5b5edSNipun Gupta 
114179e5b5edSNipun Gupta 	lwsync();
114279e5b5edSNipun Gupta 
114379e5b5edSNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
114479e5b5edSNipun Gupta 	eqcr_pi = s->eqcr.pi;
114579e5b5edSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
114679e5b5edSNipun Gupta 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
114779e5b5edSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
114879e5b5edSNipun Gupta 		p[0] = cl[0] | s->eqcr.pi_vb;
114979e5b5edSNipun Gupta 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
115079e5b5edSNipun Gupta 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
115179e5b5edSNipun Gupta 
115279e5b5edSNipun Gupta 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
115379e5b5edSNipun Gupta 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
115479e5b5edSNipun Gupta 		}
115579e5b5edSNipun Gupta 		eqcr_pi++;
115679e5b5edSNipun Gupta 		if (!(eqcr_pi & half_mask))
115779e5b5edSNipun Gupta 			s->eqcr.pi_vb ^= QB_VALID_BIT;
115879e5b5edSNipun Gupta 	}
115979e5b5edSNipun Gupta 
116079e5b5edSNipun Gupta 	s->eqcr.pi = eqcr_pi & full_mask;
116179e5b5edSNipun Gupta 
116279e5b5edSNipun Gupta 	return num_enqueued;
116379e5b5edSNipun Gupta }
116479e5b5edSNipun Gupta 
1165293c0ca9SNipun Gupta static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,
116643f7ff9dSHaiying Wang 					       const struct qbman_eq_desc *d,
116743f7ff9dSHaiying Wang 					       const struct qbman_fd *fd,
1168293c0ca9SNipun Gupta 					       uint32_t *flags,
116943f7ff9dSHaiying Wang 					       int num_frames)
117043f7ff9dSHaiying Wang {
1171293c0ca9SNipun Gupta 	uint32_t *p = NULL;
1172293c0ca9SNipun Gupta 	const uint32_t *cl = qb_cl(d);
1173293c0ca9SNipun Gupta 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
117443f7ff9dSHaiying Wang 	int i, num_enqueued = 0;
117543f7ff9dSHaiying Wang 
11761b49352fSHemant Agrawal 	half_mask = (s->eqcr.pi_ci_mask>>1);
11771b49352fSHemant Agrawal 	full_mask = s->eqcr.pi_ci_mask;
117843f7ff9dSHaiying Wang 	if (!s->eqcr.available) {
117943f7ff9dSHaiying Wang 		eqcr_ci = s->eqcr.ci;
11802557cf8fSYouri Querry 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
11812557cf8fSYouri Querry 				QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask;
1182293c0ca9SNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
118343f7ff9dSHaiying Wang 					eqcr_ci, s->eqcr.ci);
1184293c0ca9SNipun Gupta 		if (!s->eqcr.available)
118543f7ff9dSHaiying Wang 			return 0;
118643f7ff9dSHaiying Wang 	}
118743f7ff9dSHaiying Wang 
118843f7ff9dSHaiying Wang 	eqcr_pi = s->eqcr.pi;
118943f7ff9dSHaiying Wang 	num_enqueued = (s->eqcr.available < num_frames) ?
119043f7ff9dSHaiying Wang 			s->eqcr.available : num_frames;
119143f7ff9dSHaiying Wang 	s->eqcr.available -= num_enqueued;
119243f7ff9dSHaiying Wang 	/* Fill in the EQCR ring */
119343f7ff9dSHaiying Wang 	for (i = 0; i < num_enqueued; i++) {
119443f7ff9dSHaiying Wang 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1195293c0ca9SNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1196293c0ca9SNipun Gupta 		memcpy(&p[1], &cl[1], 28);
1197293c0ca9SNipun Gupta 		memcpy(&p[8], &fd[i], sizeof(*fd));
11988bd11d45SYouri Querry 		p[0] = cl[0] | s->eqcr.pi_vb;
11998bd11d45SYouri Querry 
1200293c0ca9SNipun Gupta 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1201293c0ca9SNipun Gupta 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1202293c0ca9SNipun Gupta 
1203293c0ca9SNipun Gupta 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1204293c0ca9SNipun Gupta 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1205293c0ca9SNipun Gupta 		}
1206293c0ca9SNipun Gupta 		eqcr_pi++;
12071b49352fSHemant Agrawal 
1208293c0ca9SNipun Gupta 		if (!(eqcr_pi & half_mask))
1209293c0ca9SNipun Gupta 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1210293c0ca9SNipun Gupta 	}
1211293c0ca9SNipun Gupta 	s->eqcr.pi = eqcr_pi & full_mask;
1212293c0ca9SNipun Gupta 
1213293c0ca9SNipun Gupta 	dma_wmb();
1214293c0ca9SNipun Gupta 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,
1215293c0ca9SNipun Gupta 				(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
1216293c0ca9SNipun Gupta 	return num_enqueued;
1217293c0ca9SNipun Gupta }
1218293c0ca9SNipun Gupta 
12190ff708edSFerruh Yigit int qbman_swp_enqueue_multiple(struct qbman_swp *s,
1220293c0ca9SNipun Gupta 				      const struct qbman_eq_desc *d,
1221293c0ca9SNipun Gupta 				      const struct qbman_fd *fd,
1222293c0ca9SNipun Gupta 				      uint32_t *flags,
1223293c0ca9SNipun Gupta 				      int num_frames)
1224293c0ca9SNipun Gupta {
1225b3bd7a50SNipun Gupta 	if (!s->stash_off)
1226b3bd7a50SNipun Gupta 		return qbman_swp_enqueue_multiple_ptr(s, d, fd, flags,
1227b3bd7a50SNipun Gupta 						num_frames);
1228b3bd7a50SNipun Gupta 	else
1229b3bd7a50SNipun Gupta 		return qbman_swp_enqueue_multiple_cinh_direct(s, d, fd, flags,
1230b3bd7a50SNipun Gupta 						num_frames);
1231293c0ca9SNipun Gupta }
1232293c0ca9SNipun Gupta 
1233a3a997f0SHemant Agrawal static int qbman_swp_enqueue_multiple_fd_direct(struct qbman_swp *s,
1234a3a997f0SHemant Agrawal 						const struct qbman_eq_desc *d,
1235a3a997f0SHemant Agrawal 						struct qbman_fd **fd,
1236a3a997f0SHemant Agrawal 						uint32_t *flags,
1237a3a997f0SHemant Agrawal 						int num_frames)
1238a3a997f0SHemant Agrawal {
1239a3a997f0SHemant Agrawal 	uint32_t *p = NULL;
1240a3a997f0SHemant Agrawal 	const uint32_t *cl = qb_cl(d);
1241a3a997f0SHemant Agrawal 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1242a3a997f0SHemant Agrawal 	int i, num_enqueued = 0;
1243a3a997f0SHemant Agrawal 	uint64_t addr_cena;
1244a3a997f0SHemant Agrawal 
1245a3a997f0SHemant Agrawal 	half_mask = (s->eqcr.pi_ci_mask>>1);
1246a3a997f0SHemant Agrawal 	full_mask = s->eqcr.pi_ci_mask;
1247a3a997f0SHemant Agrawal 	if (!s->eqcr.available) {
1248a3a997f0SHemant Agrawal 		eqcr_ci = s->eqcr.ci;
1249a3a997f0SHemant Agrawal 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
1250a3a997f0SHemant Agrawal 				QBMAN_CENA_SWP_EQCR_CI) & full_mask;
1251a3a997f0SHemant Agrawal 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1252a3a997f0SHemant Agrawal 				eqcr_ci, s->eqcr.ci);
1253a3a997f0SHemant Agrawal 		if (!s->eqcr.available)
1254a3a997f0SHemant Agrawal 			return 0;
1255a3a997f0SHemant Agrawal 	}
1256a3a997f0SHemant Agrawal 
1257a3a997f0SHemant Agrawal 	eqcr_pi = s->eqcr.pi;
1258a3a997f0SHemant Agrawal 	num_enqueued = (s->eqcr.available < num_frames) ?
1259a3a997f0SHemant Agrawal 			s->eqcr.available : num_frames;
1260a3a997f0SHemant Agrawal 	s->eqcr.available -= num_enqueued;
1261a3a997f0SHemant Agrawal 	/* Fill in the EQCR ring */
1262a3a997f0SHemant Agrawal 	for (i = 0; i < num_enqueued; i++) {
1263a3a997f0SHemant Agrawal 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1264a3a997f0SHemant Agrawal 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1265a3a997f0SHemant Agrawal 		memcpy(&p[1], &cl[1], 28);
1266a3a997f0SHemant Agrawal 		memcpy(&p[8], fd[i], sizeof(struct qbman_fd));
1267a3a997f0SHemant Agrawal 		eqcr_pi++;
1268a3a997f0SHemant Agrawal 	}
1269a3a997f0SHemant Agrawal 
1270a3a997f0SHemant Agrawal 	lwsync();
1271a3a997f0SHemant Agrawal 
1272a3a997f0SHemant Agrawal 	/* Set the verb byte, have to substitute in the valid-bit */
1273a3a997f0SHemant Agrawal 	eqcr_pi = s->eqcr.pi;
1274a3a997f0SHemant Agrawal 	for (i = 0; i < num_enqueued; i++) {
1275a3a997f0SHemant Agrawal 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1276a3a997f0SHemant Agrawal 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1277a3a997f0SHemant Agrawal 		p[0] = cl[0] | s->eqcr.pi_vb;
1278a3a997f0SHemant Agrawal 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1279a3a997f0SHemant Agrawal 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1280a3a997f0SHemant Agrawal 
1281a3a997f0SHemant Agrawal 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1282a3a997f0SHemant Agrawal 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1283a3a997f0SHemant Agrawal 		}
1284a3a997f0SHemant Agrawal 		eqcr_pi++;
1285a3a997f0SHemant Agrawal 		if (!(eqcr_pi & half_mask))
1286a3a997f0SHemant Agrawal 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1287a3a997f0SHemant Agrawal 	}
1288a3a997f0SHemant Agrawal 
1289a3a997f0SHemant Agrawal 	/* Flush all the cacheline without load/store in between */
1290a3a997f0SHemant Agrawal 	eqcr_pi = s->eqcr.pi;
1291a3a997f0SHemant Agrawal 	addr_cena = (size_t)s->sys.addr_cena;
1292a3a997f0SHemant Agrawal 	for (i = 0; i < num_enqueued; i++) {
1293a3a997f0SHemant Agrawal 		dcbf(addr_cena +
1294a3a997f0SHemant Agrawal 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1295a3a997f0SHemant Agrawal 		eqcr_pi++;
1296a3a997f0SHemant Agrawal 	}
1297a3a997f0SHemant Agrawal 	s->eqcr.pi = eqcr_pi & full_mask;
1298a3a997f0SHemant Agrawal 
1299a3a997f0SHemant Agrawal 	return num_enqueued;
1300a3a997f0SHemant Agrawal }
1301a3a997f0SHemant Agrawal 
130279e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_fd_cinh_read_direct(
130363d5d0afSNipun Gupta 		struct qbman_swp *s,
130463d5d0afSNipun Gupta 		const struct qbman_eq_desc *d,
130563d5d0afSNipun Gupta 		struct qbman_fd **fd,
130663d5d0afSNipun Gupta 		uint32_t *flags,
130763d5d0afSNipun Gupta 		int num_frames)
130863d5d0afSNipun Gupta {
130963d5d0afSNipun Gupta 	uint32_t *p = NULL;
131063d5d0afSNipun Gupta 	const uint32_t *cl = qb_cl(d);
131163d5d0afSNipun Gupta 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
131263d5d0afSNipun Gupta 	int i, num_enqueued = 0;
131363d5d0afSNipun Gupta 	uint64_t addr_cena;
131463d5d0afSNipun Gupta 
131563d5d0afSNipun Gupta 	half_mask = (s->eqcr.pi_ci_mask>>1);
131663d5d0afSNipun Gupta 	full_mask = s->eqcr.pi_ci_mask;
131763d5d0afSNipun Gupta 	if (!s->eqcr.available) {
131863d5d0afSNipun Gupta 		eqcr_ci = s->eqcr.ci;
131963d5d0afSNipun Gupta 		s->eqcr.ci = qbman_cinh_read(&s->sys,
132063d5d0afSNipun Gupta 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
132163d5d0afSNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
132263d5d0afSNipun Gupta 				eqcr_ci, s->eqcr.ci);
132363d5d0afSNipun Gupta 		if (!s->eqcr.available)
132463d5d0afSNipun Gupta 			return 0;
132563d5d0afSNipun Gupta 	}
132663d5d0afSNipun Gupta 
132763d5d0afSNipun Gupta 	eqcr_pi = s->eqcr.pi;
132863d5d0afSNipun Gupta 	num_enqueued = (s->eqcr.available < num_frames) ?
132963d5d0afSNipun Gupta 			s->eqcr.available : num_frames;
133063d5d0afSNipun Gupta 	s->eqcr.available -= num_enqueued;
133163d5d0afSNipun Gupta 	/* Fill in the EQCR ring */
133263d5d0afSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
133363d5d0afSNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
133463d5d0afSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
133563d5d0afSNipun Gupta 		memcpy(&p[1], &cl[1], 28);
133663d5d0afSNipun Gupta 		memcpy(&p[8], fd[i], sizeof(struct qbman_fd));
133763d5d0afSNipun Gupta 		eqcr_pi++;
133863d5d0afSNipun Gupta 	}
133963d5d0afSNipun Gupta 
134063d5d0afSNipun Gupta 	lwsync();
134163d5d0afSNipun Gupta 
134263d5d0afSNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
134363d5d0afSNipun Gupta 	eqcr_pi = s->eqcr.pi;
134463d5d0afSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
134563d5d0afSNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
134663d5d0afSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
134763d5d0afSNipun Gupta 		p[0] = cl[0] | s->eqcr.pi_vb;
134863d5d0afSNipun Gupta 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
134963d5d0afSNipun Gupta 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
135063d5d0afSNipun Gupta 
135163d5d0afSNipun Gupta 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
135263d5d0afSNipun Gupta 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
135363d5d0afSNipun Gupta 		}
135463d5d0afSNipun Gupta 		eqcr_pi++;
135563d5d0afSNipun Gupta 		if (!(eqcr_pi & half_mask))
135663d5d0afSNipun Gupta 			s->eqcr.pi_vb ^= QB_VALID_BIT;
135763d5d0afSNipun Gupta 	}
135863d5d0afSNipun Gupta 
135963d5d0afSNipun Gupta 	/* Flush all the cacheline without load/store in between */
136063d5d0afSNipun Gupta 	eqcr_pi = s->eqcr.pi;
136163d5d0afSNipun Gupta 	addr_cena = (size_t)s->sys.addr_cena;
136263d5d0afSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
136363d5d0afSNipun Gupta 		dcbf(addr_cena +
136463d5d0afSNipun Gupta 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
136563d5d0afSNipun Gupta 		eqcr_pi++;
136663d5d0afSNipun Gupta 	}
136763d5d0afSNipun Gupta 	s->eqcr.pi = eqcr_pi & full_mask;
136863d5d0afSNipun Gupta 
136963d5d0afSNipun Gupta 	return num_enqueued;
137063d5d0afSNipun Gupta }
137163d5d0afSNipun Gupta 
137279e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_fd_cinh_direct(
137379e5b5edSNipun Gupta 		struct qbman_swp *s,
137479e5b5edSNipun Gupta 		const struct qbman_eq_desc *d,
137579e5b5edSNipun Gupta 		struct qbman_fd **fd,
137679e5b5edSNipun Gupta 		uint32_t *flags,
137779e5b5edSNipun Gupta 		int num_frames)
137879e5b5edSNipun Gupta {
137979e5b5edSNipun Gupta 	uint32_t *p = NULL;
138079e5b5edSNipun Gupta 	const uint32_t *cl = qb_cl(d);
138179e5b5edSNipun Gupta 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
138279e5b5edSNipun Gupta 	int i, num_enqueued = 0;
138379e5b5edSNipun Gupta 
138479e5b5edSNipun Gupta 	half_mask = (s->eqcr.pi_ci_mask>>1);
138579e5b5edSNipun Gupta 	full_mask = s->eqcr.pi_ci_mask;
138679e5b5edSNipun Gupta 	if (!s->eqcr.available) {
138779e5b5edSNipun Gupta 		eqcr_ci = s->eqcr.ci;
138879e5b5edSNipun Gupta 		s->eqcr.ci = qbman_cinh_read(&s->sys,
138979e5b5edSNipun Gupta 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
139079e5b5edSNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
139179e5b5edSNipun Gupta 				eqcr_ci, s->eqcr.ci);
139279e5b5edSNipun Gupta 		if (!s->eqcr.available)
139379e5b5edSNipun Gupta 			return 0;
139479e5b5edSNipun Gupta 	}
139579e5b5edSNipun Gupta 
139679e5b5edSNipun Gupta 	eqcr_pi = s->eqcr.pi;
139779e5b5edSNipun Gupta 	num_enqueued = (s->eqcr.available < num_frames) ?
139879e5b5edSNipun Gupta 			s->eqcr.available : num_frames;
139979e5b5edSNipun Gupta 	s->eqcr.available -= num_enqueued;
140079e5b5edSNipun Gupta 	/* Fill in the EQCR ring */
140179e5b5edSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
140279e5b5edSNipun Gupta 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
140379e5b5edSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
140479e5b5edSNipun Gupta 		memcpy_byte_by_byte(&p[1], &cl[1], 28);
140579e5b5edSNipun Gupta 		memcpy_byte_by_byte(&p[8], fd[i], sizeof(struct qbman_fd));
140679e5b5edSNipun Gupta 		eqcr_pi++;
140779e5b5edSNipun Gupta 	}
140879e5b5edSNipun Gupta 
140979e5b5edSNipun Gupta 	lwsync();
141079e5b5edSNipun Gupta 
141179e5b5edSNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
141279e5b5edSNipun Gupta 	eqcr_pi = s->eqcr.pi;
141379e5b5edSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
141479e5b5edSNipun Gupta 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
141579e5b5edSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
141679e5b5edSNipun Gupta 		p[0] = cl[0] | s->eqcr.pi_vb;
141779e5b5edSNipun Gupta 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
141879e5b5edSNipun Gupta 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
141979e5b5edSNipun Gupta 
142079e5b5edSNipun Gupta 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
142179e5b5edSNipun Gupta 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
142279e5b5edSNipun Gupta 		}
142379e5b5edSNipun Gupta 		eqcr_pi++;
142479e5b5edSNipun Gupta 		if (!(eqcr_pi & half_mask))
142579e5b5edSNipun Gupta 			s->eqcr.pi_vb ^= QB_VALID_BIT;
142679e5b5edSNipun Gupta 	}
142779e5b5edSNipun Gupta 
142879e5b5edSNipun Gupta 	s->eqcr.pi = eqcr_pi & full_mask;
142979e5b5edSNipun Gupta 
143079e5b5edSNipun Gupta 	return num_enqueued;
143179e5b5edSNipun Gupta }
143279e5b5edSNipun Gupta 
1433a3a997f0SHemant Agrawal static int qbman_swp_enqueue_multiple_fd_mem_back(struct qbman_swp *s,
1434a3a997f0SHemant Agrawal 						  const struct qbman_eq_desc *d,
1435a3a997f0SHemant Agrawal 						  struct qbman_fd **fd,
1436a3a997f0SHemant Agrawal 						  uint32_t *flags,
1437a3a997f0SHemant Agrawal 						  int num_frames)
1438a3a997f0SHemant Agrawal {
1439a3a997f0SHemant Agrawal 	uint32_t *p = NULL;
1440a3a997f0SHemant Agrawal 	const uint32_t *cl = qb_cl(d);
1441a3a997f0SHemant Agrawal 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1442a3a997f0SHemant Agrawal 	int i, num_enqueued = 0;
1443a3a997f0SHemant Agrawal 
1444a3a997f0SHemant Agrawal 	half_mask = (s->eqcr.pi_ci_mask>>1);
1445a3a997f0SHemant Agrawal 	full_mask = s->eqcr.pi_ci_mask;
1446a3a997f0SHemant Agrawal 	if (!s->eqcr.available) {
1447a3a997f0SHemant Agrawal 		eqcr_ci = s->eqcr.ci;
1448a3a997f0SHemant Agrawal 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
1449a3a997f0SHemant Agrawal 				QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask;
1450a3a997f0SHemant Agrawal 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1451a3a997f0SHemant Agrawal 					eqcr_ci, s->eqcr.ci);
1452a3a997f0SHemant Agrawal 		if (!s->eqcr.available)
1453a3a997f0SHemant Agrawal 			return 0;
1454a3a997f0SHemant Agrawal 	}
1455a3a997f0SHemant Agrawal 
1456a3a997f0SHemant Agrawal 	eqcr_pi = s->eqcr.pi;
1457a3a997f0SHemant Agrawal 	num_enqueued = (s->eqcr.available < num_frames) ?
1458a3a997f0SHemant Agrawal 			s->eqcr.available : num_frames;
1459a3a997f0SHemant Agrawal 	s->eqcr.available -= num_enqueued;
1460a3a997f0SHemant Agrawal 	/* Fill in the EQCR ring */
1461a3a997f0SHemant Agrawal 	for (i = 0; i < num_enqueued; i++) {
1462a3a997f0SHemant Agrawal 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1463a3a997f0SHemant Agrawal 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1464a3a997f0SHemant Agrawal 		memcpy(&p[1], &cl[1], 28);
1465a3a997f0SHemant Agrawal 		memcpy(&p[8], fd[i], sizeof(struct qbman_fd));
1466a3a997f0SHemant Agrawal 		eqcr_pi++;
1467a3a997f0SHemant Agrawal 	}
1468a3a997f0SHemant Agrawal 
1469a3a997f0SHemant Agrawal 	/* Set the verb byte, have to substitute in the valid-bit */
1470a3a997f0SHemant Agrawal 	eqcr_pi = s->eqcr.pi;
1471a3a997f0SHemant Agrawal 	for (i = 0; i < num_enqueued; i++) {
1472a3a997f0SHemant Agrawal 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1473a3a997f0SHemant Agrawal 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1474a3a997f0SHemant Agrawal 		p[0] = cl[0] | s->eqcr.pi_vb;
1475a3a997f0SHemant Agrawal 		if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
1476a3a997f0SHemant Agrawal 			struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
1477a3a997f0SHemant Agrawal 
1478a3a997f0SHemant Agrawal 			d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
1479a3a997f0SHemant Agrawal 				((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
1480a3a997f0SHemant Agrawal 		}
1481a3a997f0SHemant Agrawal 		eqcr_pi++;
1482a3a997f0SHemant Agrawal 		if (!(eqcr_pi & half_mask))
1483a3a997f0SHemant Agrawal 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1484a3a997f0SHemant Agrawal 	}
1485a3a997f0SHemant Agrawal 	s->eqcr.pi = eqcr_pi & full_mask;
1486a3a997f0SHemant Agrawal 
1487a3a997f0SHemant Agrawal 	dma_wmb();
1488a3a997f0SHemant Agrawal 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,
1489a3a997f0SHemant Agrawal 				(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
1490a3a997f0SHemant Agrawal 	return num_enqueued;
1491a3a997f0SHemant Agrawal }
1492a3a997f0SHemant Agrawal 
14930ff708edSFerruh Yigit int qbman_swp_enqueue_multiple_fd(struct qbman_swp *s,
1494a3a997f0SHemant Agrawal 					 const struct qbman_eq_desc *d,
1495a3a997f0SHemant Agrawal 					 struct qbman_fd **fd,
1496a3a997f0SHemant Agrawal 					 uint32_t *flags,
1497a3a997f0SHemant Agrawal 					 int num_frames)
1498a3a997f0SHemant Agrawal {
1499b3bd7a50SNipun Gupta 	if (!s->stash_off)
1500b3bd7a50SNipun Gupta 		return qbman_swp_enqueue_multiple_fd_ptr(s, d, fd, flags,
1501b3bd7a50SNipun Gupta 					num_frames);
1502b3bd7a50SNipun Gupta 	else
1503b3bd7a50SNipun Gupta 		return qbman_swp_enqueue_multiple_fd_cinh_direct(s, d, fd,
1504b3bd7a50SNipun Gupta 					flags, num_frames);
1505a3a997f0SHemant Agrawal }
1506a3a997f0SHemant Agrawal 
1507293c0ca9SNipun Gupta static int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
1508293c0ca9SNipun Gupta 					const struct qbman_eq_desc *d,
1509293c0ca9SNipun Gupta 					const struct qbman_fd *fd,
1510293c0ca9SNipun Gupta 					int num_frames)
1511293c0ca9SNipun Gupta {
1512293c0ca9SNipun Gupta 	uint32_t *p;
1513293c0ca9SNipun Gupta 	const uint32_t *cl;
1514293c0ca9SNipun Gupta 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1515293c0ca9SNipun Gupta 	int i, num_enqueued = 0;
1516293c0ca9SNipun Gupta 	uint64_t addr_cena;
1517293c0ca9SNipun Gupta 
15181b49352fSHemant Agrawal 	half_mask = (s->eqcr.pi_ci_mask>>1);
15191b49352fSHemant Agrawal 	full_mask = s->eqcr.pi_ci_mask;
1520293c0ca9SNipun Gupta 	if (!s->eqcr.available) {
1521293c0ca9SNipun Gupta 		eqcr_ci = s->eqcr.ci;
1522293c0ca9SNipun Gupta 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
1523293c0ca9SNipun Gupta 				QBMAN_CENA_SWP_EQCR_CI) & full_mask;
1524293c0ca9SNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1525293c0ca9SNipun Gupta 					eqcr_ci, s->eqcr.ci);
1526293c0ca9SNipun Gupta 		if (!s->eqcr.available)
1527293c0ca9SNipun Gupta 			return 0;
1528293c0ca9SNipun Gupta 	}
1529293c0ca9SNipun Gupta 
1530293c0ca9SNipun Gupta 	eqcr_pi = s->eqcr.pi;
1531293c0ca9SNipun Gupta 	num_enqueued = (s->eqcr.available < num_frames) ?
1532293c0ca9SNipun Gupta 			s->eqcr.available : num_frames;
1533293c0ca9SNipun Gupta 	s->eqcr.available -= num_enqueued;
1534293c0ca9SNipun Gupta 	/* Fill in the EQCR ring */
1535293c0ca9SNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
1536293c0ca9SNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1537293c0ca9SNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
153843f7ff9dSHaiying Wang 		cl = qb_cl(&d[i]);
153943f7ff9dSHaiying Wang 		memcpy(&p[1], &cl[1], 28);
154043f7ff9dSHaiying Wang 		memcpy(&p[8], &fd[i], sizeof(*fd));
154143f7ff9dSHaiying Wang 		eqcr_pi++;
154243f7ff9dSHaiying Wang 	}
154343f7ff9dSHaiying Wang 
154443f7ff9dSHaiying Wang 	lwsync();
154543f7ff9dSHaiying Wang 
154643f7ff9dSHaiying Wang 	/* Set the verb byte, have to substitute in the valid-bit */
154743f7ff9dSHaiying Wang 	eqcr_pi = s->eqcr.pi;
154843f7ff9dSHaiying Wang 	for (i = 0; i < num_enqueued; i++) {
154943f7ff9dSHaiying Wang 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1550293c0ca9SNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
155143f7ff9dSHaiying Wang 		cl = qb_cl(&d[i]);
155243f7ff9dSHaiying Wang 		p[0] = cl[0] | s->eqcr.pi_vb;
155343f7ff9dSHaiying Wang 		eqcr_pi++;
1554293c0ca9SNipun Gupta 		if (!(eqcr_pi & half_mask))
155543f7ff9dSHaiying Wang 			s->eqcr.pi_vb ^= QB_VALID_BIT;
155633ae0a29SNipun Gupta 	}
155733ae0a29SNipun Gupta 
155833ae0a29SNipun Gupta 	/* Flush all the cacheline without load/store in between */
155933ae0a29SNipun Gupta 	eqcr_pi = s->eqcr.pi;
15605ae1edffSHemant Agrawal 	addr_cena = (size_t)s->sys.addr_cena;
156133ae0a29SNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
1562293c0ca9SNipun Gupta 		dcbf((uintptr_t)(addr_cena +
1563293c0ca9SNipun Gupta 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)));
156433ae0a29SNipun Gupta 		eqcr_pi++;
156533ae0a29SNipun Gupta 	}
1566293c0ca9SNipun Gupta 	s->eqcr.pi = eqcr_pi & full_mask;
156733ae0a29SNipun Gupta 
156833ae0a29SNipun Gupta 	return num_enqueued;
156933ae0a29SNipun Gupta }
157033ae0a29SNipun Gupta 
157179e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_desc_cinh_read_direct(
157263d5d0afSNipun Gupta 		struct qbman_swp *s,
157363d5d0afSNipun Gupta 		const struct qbman_eq_desc *d,
157463d5d0afSNipun Gupta 		const struct qbman_fd *fd,
157563d5d0afSNipun Gupta 		int num_frames)
157663d5d0afSNipun Gupta {
157763d5d0afSNipun Gupta 	uint32_t *p;
157863d5d0afSNipun Gupta 	const uint32_t *cl;
157963d5d0afSNipun Gupta 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
158063d5d0afSNipun Gupta 	int i, num_enqueued = 0;
158163d5d0afSNipun Gupta 	uint64_t addr_cena;
158263d5d0afSNipun Gupta 
158363d5d0afSNipun Gupta 	half_mask = (s->eqcr.pi_ci_mask>>1);
158463d5d0afSNipun Gupta 	full_mask = s->eqcr.pi_ci_mask;
158563d5d0afSNipun Gupta 	if (!s->eqcr.available) {
158663d5d0afSNipun Gupta 		eqcr_ci = s->eqcr.ci;
158763d5d0afSNipun Gupta 		s->eqcr.ci = qbman_cinh_read(&s->sys,
158863d5d0afSNipun Gupta 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
158963d5d0afSNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
159063d5d0afSNipun Gupta 					eqcr_ci, s->eqcr.ci);
159163d5d0afSNipun Gupta 		if (!s->eqcr.available)
159263d5d0afSNipun Gupta 			return 0;
159363d5d0afSNipun Gupta 	}
159463d5d0afSNipun Gupta 
159563d5d0afSNipun Gupta 	eqcr_pi = s->eqcr.pi;
159663d5d0afSNipun Gupta 	num_enqueued = (s->eqcr.available < num_frames) ?
159763d5d0afSNipun Gupta 			s->eqcr.available : num_frames;
159863d5d0afSNipun Gupta 	s->eqcr.available -= num_enqueued;
159963d5d0afSNipun Gupta 	/* Fill in the EQCR ring */
160063d5d0afSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
160163d5d0afSNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
160263d5d0afSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
160363d5d0afSNipun Gupta 		cl = qb_cl(&d[i]);
160463d5d0afSNipun Gupta 		memcpy(&p[1], &cl[1], 28);
160563d5d0afSNipun Gupta 		memcpy(&p[8], &fd[i], sizeof(*fd));
160663d5d0afSNipun Gupta 		eqcr_pi++;
160763d5d0afSNipun Gupta 	}
160863d5d0afSNipun Gupta 
160963d5d0afSNipun Gupta 	lwsync();
161063d5d0afSNipun Gupta 
161163d5d0afSNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
161263d5d0afSNipun Gupta 	eqcr_pi = s->eqcr.pi;
161363d5d0afSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
161463d5d0afSNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
161563d5d0afSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
161663d5d0afSNipun Gupta 		cl = qb_cl(&d[i]);
161763d5d0afSNipun Gupta 		p[0] = cl[0] | s->eqcr.pi_vb;
161863d5d0afSNipun Gupta 		eqcr_pi++;
161963d5d0afSNipun Gupta 		if (!(eqcr_pi & half_mask))
162063d5d0afSNipun Gupta 			s->eqcr.pi_vb ^= QB_VALID_BIT;
162163d5d0afSNipun Gupta 	}
162263d5d0afSNipun Gupta 
162363d5d0afSNipun Gupta 	/* Flush all the cacheline without load/store in between */
162463d5d0afSNipun Gupta 	eqcr_pi = s->eqcr.pi;
162563d5d0afSNipun Gupta 	addr_cena = (size_t)s->sys.addr_cena;
162663d5d0afSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
162763d5d0afSNipun Gupta 		dcbf(addr_cena +
162863d5d0afSNipun Gupta 			QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
162963d5d0afSNipun Gupta 		eqcr_pi++;
163063d5d0afSNipun Gupta 	}
163163d5d0afSNipun Gupta 	s->eqcr.pi = eqcr_pi & full_mask;
163263d5d0afSNipun Gupta 
163363d5d0afSNipun Gupta 	return num_enqueued;
163463d5d0afSNipun Gupta }
163563d5d0afSNipun Gupta 
163679e5b5edSNipun Gupta static int qbman_swp_enqueue_multiple_desc_cinh_direct(
163779e5b5edSNipun Gupta 		struct qbman_swp *s,
163879e5b5edSNipun Gupta 		const struct qbman_eq_desc *d,
163979e5b5edSNipun Gupta 		const struct qbman_fd *fd,
164079e5b5edSNipun Gupta 		int num_frames)
164179e5b5edSNipun Gupta {
164279e5b5edSNipun Gupta 	uint32_t *p;
164379e5b5edSNipun Gupta 	const uint32_t *cl;
164479e5b5edSNipun Gupta 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
164579e5b5edSNipun Gupta 	int i, num_enqueued = 0;
164679e5b5edSNipun Gupta 
164779e5b5edSNipun Gupta 	half_mask = (s->eqcr.pi_ci_mask>>1);
164879e5b5edSNipun Gupta 	full_mask = s->eqcr.pi_ci_mask;
164979e5b5edSNipun Gupta 	if (!s->eqcr.available) {
165079e5b5edSNipun Gupta 		eqcr_ci = s->eqcr.ci;
165179e5b5edSNipun Gupta 		s->eqcr.ci = qbman_cinh_read(&s->sys,
165279e5b5edSNipun Gupta 				QBMAN_CINH_SWP_EQCR_CI) & full_mask;
165379e5b5edSNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
165479e5b5edSNipun Gupta 					eqcr_ci, s->eqcr.ci);
165579e5b5edSNipun Gupta 		if (!s->eqcr.available)
165679e5b5edSNipun Gupta 			return 0;
165779e5b5edSNipun Gupta 	}
165879e5b5edSNipun Gupta 
165979e5b5edSNipun Gupta 	eqcr_pi = s->eqcr.pi;
166079e5b5edSNipun Gupta 	num_enqueued = (s->eqcr.available < num_frames) ?
166179e5b5edSNipun Gupta 			s->eqcr.available : num_frames;
166279e5b5edSNipun Gupta 	s->eqcr.available -= num_enqueued;
166379e5b5edSNipun Gupta 	/* Fill in the EQCR ring */
166479e5b5edSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
166579e5b5edSNipun Gupta 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
166679e5b5edSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
166779e5b5edSNipun Gupta 		cl = qb_cl(&d[i]);
166879e5b5edSNipun Gupta 		memcpy_byte_by_byte(&p[1], &cl[1], 28);
166979e5b5edSNipun Gupta 		memcpy_byte_by_byte(&p[8], &fd[i], sizeof(*fd));
167079e5b5edSNipun Gupta 		eqcr_pi++;
167179e5b5edSNipun Gupta 	}
167279e5b5edSNipun Gupta 
167379e5b5edSNipun Gupta 	lwsync();
167479e5b5edSNipun Gupta 
167579e5b5edSNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
167679e5b5edSNipun Gupta 	eqcr_pi = s->eqcr.pi;
167779e5b5edSNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
167879e5b5edSNipun Gupta 		p = qbman_cinh_write_start_wo_shadow(&s->sys,
167979e5b5edSNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
168079e5b5edSNipun Gupta 		cl = qb_cl(&d[i]);
168179e5b5edSNipun Gupta 		p[0] = cl[0] | s->eqcr.pi_vb;
168279e5b5edSNipun Gupta 		eqcr_pi++;
168379e5b5edSNipun Gupta 		if (!(eqcr_pi & half_mask))
168479e5b5edSNipun Gupta 			s->eqcr.pi_vb ^= QB_VALID_BIT;
168579e5b5edSNipun Gupta 	}
168679e5b5edSNipun Gupta 
168779e5b5edSNipun Gupta 	s->eqcr.pi = eqcr_pi & full_mask;
168879e5b5edSNipun Gupta 
168979e5b5edSNipun Gupta 	return num_enqueued;
169079e5b5edSNipun Gupta }
169179e5b5edSNipun Gupta 
1692293c0ca9SNipun Gupta static int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,
1693293c0ca9SNipun Gupta 					const struct qbman_eq_desc *d,
1694293c0ca9SNipun Gupta 					const struct qbman_fd *fd,
1695293c0ca9SNipun Gupta 					int num_frames)
1696293c0ca9SNipun Gupta {
1697293c0ca9SNipun Gupta 	uint32_t *p;
1698293c0ca9SNipun Gupta 	const uint32_t *cl;
1699293c0ca9SNipun Gupta 	uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
1700293c0ca9SNipun Gupta 	int i, num_enqueued = 0;
1701293c0ca9SNipun Gupta 
17021b49352fSHemant Agrawal 	half_mask = (s->eqcr.pi_ci_mask>>1);
17031b49352fSHemant Agrawal 	full_mask = s->eqcr.pi_ci_mask;
1704293c0ca9SNipun Gupta 	if (!s->eqcr.available) {
1705293c0ca9SNipun Gupta 		eqcr_ci = s->eqcr.ci;
17062557cf8fSYouri Querry 		s->eqcr.ci = qbman_cena_read_reg(&s->sys,
17072557cf8fSYouri Querry 				QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask;
1708293c0ca9SNipun Gupta 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
1709293c0ca9SNipun Gupta 					eqcr_ci, s->eqcr.ci);
1710293c0ca9SNipun Gupta 		if (!s->eqcr.available)
1711293c0ca9SNipun Gupta 			return 0;
1712293c0ca9SNipun Gupta 	}
1713293c0ca9SNipun Gupta 
1714293c0ca9SNipun Gupta 	eqcr_pi = s->eqcr.pi;
1715293c0ca9SNipun Gupta 	num_enqueued = (s->eqcr.available < num_frames) ?
1716293c0ca9SNipun Gupta 			s->eqcr.available : num_frames;
1717293c0ca9SNipun Gupta 	s->eqcr.available -= num_enqueued;
1718293c0ca9SNipun Gupta 	/* Fill in the EQCR ring */
1719293c0ca9SNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
1720293c0ca9SNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1721293c0ca9SNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1722293c0ca9SNipun Gupta 		cl = qb_cl(&d[i]);
1723293c0ca9SNipun Gupta 		memcpy(&p[1], &cl[1], 28);
1724293c0ca9SNipun Gupta 		memcpy(&p[8], &fd[i], sizeof(*fd));
1725293c0ca9SNipun Gupta 		eqcr_pi++;
1726293c0ca9SNipun Gupta 	}
1727293c0ca9SNipun Gupta 
1728293c0ca9SNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
1729293c0ca9SNipun Gupta 	eqcr_pi = s->eqcr.pi;
1730293c0ca9SNipun Gupta 	for (i = 0; i < num_enqueued; i++) {
1731293c0ca9SNipun Gupta 		p = qbman_cena_write_start_wo_shadow(&s->sys,
1732293c0ca9SNipun Gupta 				QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
1733293c0ca9SNipun Gupta 		cl = qb_cl(&d[i]);
1734293c0ca9SNipun Gupta 		p[0] = cl[0] | s->eqcr.pi_vb;
1735293c0ca9SNipun Gupta 		eqcr_pi++;
1736293c0ca9SNipun Gupta 		if (!(eqcr_pi & half_mask))
1737293c0ca9SNipun Gupta 			s->eqcr.pi_vb ^= QB_VALID_BIT;
1738293c0ca9SNipun Gupta 	}
1739293c0ca9SNipun Gupta 
1740293c0ca9SNipun Gupta 	s->eqcr.pi = eqcr_pi & full_mask;
1741293c0ca9SNipun Gupta 
1742293c0ca9SNipun Gupta 	dma_wmb();
1743293c0ca9SNipun Gupta 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,
1744293c0ca9SNipun Gupta 				(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
1745293c0ca9SNipun Gupta 
1746293c0ca9SNipun Gupta 	return num_enqueued;
1747293c0ca9SNipun Gupta }
17480ff708edSFerruh Yigit int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,
1749293c0ca9SNipun Gupta 					   const struct qbman_eq_desc *d,
1750293c0ca9SNipun Gupta 					   const struct qbman_fd *fd,
1751293c0ca9SNipun Gupta 					   int num_frames)
1752293c0ca9SNipun Gupta {
1753b3bd7a50SNipun Gupta 	if (!s->stash_off)
1754b3bd7a50SNipun Gupta 		return qbman_swp_enqueue_multiple_desc_ptr(s, d, fd,
1755b3bd7a50SNipun Gupta 					num_frames);
1756b3bd7a50SNipun Gupta 	else
1757b3bd7a50SNipun Gupta 		return qbman_swp_enqueue_multiple_desc_cinh_direct(s, d, fd,
1758b3bd7a50SNipun Gupta 					num_frames);
1759b3bd7a50SNipun Gupta 
1760293c0ca9SNipun Gupta }
1761293c0ca9SNipun Gupta 
1762531b17a7SHemant Agrawal /*************************/
1763531b17a7SHemant Agrawal /* Static (push) dequeue */
1764531b17a7SHemant Agrawal /*************************/
1765531b17a7SHemant Agrawal 
1766531b17a7SHemant Agrawal void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled)
1767531b17a7SHemant Agrawal {
176869293c77SHemant Agrawal 	uint16_t src = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK;
1769531b17a7SHemant Agrawal 
1770531b17a7SHemant Agrawal 	QBMAN_BUG_ON(channel_idx > 15);
177169293c77SHemant Agrawal 	*enabled = src | (1 << channel_idx);
1772531b17a7SHemant Agrawal }
1773531b17a7SHemant Agrawal 
1774531b17a7SHemant Agrawal void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable)
1775531b17a7SHemant Agrawal {
1776531b17a7SHemant Agrawal 	uint16_t dqsrc;
1777531b17a7SHemant Agrawal 
1778531b17a7SHemant Agrawal 	QBMAN_BUG_ON(channel_idx > 15);
177969293c77SHemant Agrawal 	if (enable)
178069293c77SHemant Agrawal 		s->sdq |= 1 << channel_idx;
178169293c77SHemant Agrawal 	else
178269293c77SHemant Agrawal 		s->sdq &= ~(1 << channel_idx);
178369293c77SHemant Agrawal 
1784531b17a7SHemant Agrawal 	/* Read make the complete src map.  If no channels are enabled
1785531b17a7SHemant Agrawal 	 * the SDQCR must be 0 or else QMan will assert errors
1786531b17a7SHemant Agrawal 	 */
178769293c77SHemant Agrawal 	dqsrc = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK;
1788531b17a7SHemant Agrawal 	if (dqsrc != 0)
1789531b17a7SHemant Agrawal 		qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, s->sdq);
1790531b17a7SHemant Agrawal 	else
1791531b17a7SHemant Agrawal 		qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, 0);
1792531b17a7SHemant Agrawal }
1793531b17a7SHemant Agrawal 
1794531b17a7SHemant Agrawal /***************************/
1795531b17a7SHemant Agrawal /* Volatile (pull) dequeue */
1796531b17a7SHemant Agrawal /***************************/
1797531b17a7SHemant Agrawal 
1798531b17a7SHemant Agrawal /* These should be const, eventually */
179969293c77SHemant Agrawal #define QB_VDQCR_VERB_DCT_SHIFT    0
180069293c77SHemant Agrawal #define QB_VDQCR_VERB_DT_SHIFT     2
180169293c77SHemant Agrawal #define QB_VDQCR_VERB_RLS_SHIFT    4
180269293c77SHemant Agrawal #define QB_VDQCR_VERB_WAE_SHIFT    5
1803293c0ca9SNipun Gupta #define QB_VDQCR_VERB_RAD_SHIFT    6
1804531b17a7SHemant Agrawal 
1805531b17a7SHemant Agrawal enum qb_pull_dt_e {
1806531b17a7SHemant Agrawal 	qb_pull_dt_channel,
1807531b17a7SHemant Agrawal 	qb_pull_dt_workqueue,
1808531b17a7SHemant Agrawal 	qb_pull_dt_framequeue
1809531b17a7SHemant Agrawal };
1810531b17a7SHemant Agrawal 
1811531b17a7SHemant Agrawal void qbman_pull_desc_clear(struct qbman_pull_desc *d)
1812531b17a7SHemant Agrawal {
1813531b17a7SHemant Agrawal 	memset(d, 0, sizeof(*d));
1814531b17a7SHemant Agrawal }
1815531b17a7SHemant Agrawal 
1816531b17a7SHemant Agrawal void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
1817531b17a7SHemant Agrawal 				 struct qbman_result *storage,
1818531b17a7SHemant Agrawal 				 dma_addr_t storage_phys,
1819531b17a7SHemant Agrawal 				 int stash)
1820531b17a7SHemant Agrawal {
18215ae1edffSHemant Agrawal 	d->pull.rsp_addr_virt = (size_t)storage;
182269293c77SHemant Agrawal 
1823531b17a7SHemant Agrawal 	if (!storage) {
182469293c77SHemant Agrawal 		d->pull.verb &= ~(1 << QB_VDQCR_VERB_RLS_SHIFT);
1825531b17a7SHemant Agrawal 		return;
1826531b17a7SHemant Agrawal 	}
182769293c77SHemant Agrawal 	d->pull.verb |= 1 << QB_VDQCR_VERB_RLS_SHIFT;
182869293c77SHemant Agrawal 	if (stash)
182969293c77SHemant Agrawal 		d->pull.verb |= 1 << QB_VDQCR_VERB_WAE_SHIFT;
183069293c77SHemant Agrawal 	else
183169293c77SHemant Agrawal 		d->pull.verb &= ~(1 << QB_VDQCR_VERB_WAE_SHIFT);
183269293c77SHemant Agrawal 
183369293c77SHemant Agrawal 	d->pull.rsp_addr = storage_phys;
1834531b17a7SHemant Agrawal }
1835531b17a7SHemant Agrawal 
1836293c0ca9SNipun Gupta void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d,
1837293c0ca9SNipun Gupta 				   uint8_t numframes)
1838531b17a7SHemant Agrawal {
183969293c77SHemant Agrawal 	d->pull.numf = numframes - 1;
1840531b17a7SHemant Agrawal }
1841531b17a7SHemant Agrawal 
1842531b17a7SHemant Agrawal void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token)
1843531b17a7SHemant Agrawal {
184469293c77SHemant Agrawal 	d->pull.tok = token;
1845531b17a7SHemant Agrawal }
1846531b17a7SHemant Agrawal 
1847531b17a7SHemant Agrawal void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid)
1848531b17a7SHemant Agrawal {
184969293c77SHemant Agrawal 	d->pull.verb |= 1 << QB_VDQCR_VERB_DCT_SHIFT;
185069293c77SHemant Agrawal 	d->pull.verb |= qb_pull_dt_framequeue << QB_VDQCR_VERB_DT_SHIFT;
185169293c77SHemant Agrawal 	d->pull.dq_src = fqid;
1852531b17a7SHemant Agrawal }
1853531b17a7SHemant Agrawal 
1854531b17a7SHemant Agrawal void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
1855531b17a7SHemant Agrawal 			    enum qbman_pull_type_e dct)
1856531b17a7SHemant Agrawal {
185769293c77SHemant Agrawal 	d->pull.verb |= dct << QB_VDQCR_VERB_DCT_SHIFT;
185869293c77SHemant Agrawal 	d->pull.verb |= qb_pull_dt_workqueue << QB_VDQCR_VERB_DT_SHIFT;
185969293c77SHemant Agrawal 	d->pull.dq_src = wqid;
1860531b17a7SHemant Agrawal }
1861531b17a7SHemant Agrawal 
1862531b17a7SHemant Agrawal void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
1863531b17a7SHemant Agrawal 				 enum qbman_pull_type_e dct)
1864531b17a7SHemant Agrawal {
186569293c77SHemant Agrawal 	d->pull.verb |= dct << QB_VDQCR_VERB_DCT_SHIFT;
186669293c77SHemant Agrawal 	d->pull.verb |= qb_pull_dt_channel << QB_VDQCR_VERB_DT_SHIFT;
186769293c77SHemant Agrawal 	d->pull.dq_src = chid;
1868531b17a7SHemant Agrawal }
1869531b17a7SHemant Agrawal 
187064f131a8SHemant Agrawal /**
187164f131a8SHemant Agrawal  * qbman_pull_desc_set_rad() - Decide whether reschedule the fq after dequeue
187264f131a8SHemant Agrawal  *
187364f131a8SHemant Agrawal  * @rad: 1 = Reschedule the FQ after dequeue.
187464f131a8SHemant Agrawal  *	 0 = Allow the FQ to remain active after dequeue.
187564f131a8SHemant Agrawal  */
1876293c0ca9SNipun Gupta void qbman_pull_desc_set_rad(struct qbman_pull_desc *d, int rad)
1877293c0ca9SNipun Gupta {
1878293c0ca9SNipun Gupta 	if (d->pull.verb & (1 << QB_VDQCR_VERB_RLS_SHIFT)) {
1879293c0ca9SNipun Gupta 		if (rad)
1880293c0ca9SNipun Gupta 			d->pull.verb |= 1 << QB_VDQCR_VERB_RAD_SHIFT;
1881293c0ca9SNipun Gupta 		else
1882293c0ca9SNipun Gupta 			d->pull.verb &= ~(1 << QB_VDQCR_VERB_RAD_SHIFT);
1883293c0ca9SNipun Gupta 	} else {
18840fcdbde0SHemant Agrawal 		pr_warn("The RAD feature is not valid when RLS = 0\n");
1885293c0ca9SNipun Gupta 	}
1886293c0ca9SNipun Gupta }
1887293c0ca9SNipun Gupta 
1888293c0ca9SNipun Gupta static int qbman_swp_pull_direct(struct qbman_swp *s,
1889293c0ca9SNipun Gupta 				 struct qbman_pull_desc *d)
1890531b17a7SHemant Agrawal {
1891531b17a7SHemant Agrawal 	uint32_t *p;
1892531b17a7SHemant Agrawal 	uint32_t *cl = qb_cl(d);
1893531b17a7SHemant Agrawal 
1894531b17a7SHemant Agrawal 	if (!atomic_dec_and_test(&s->vdq.busy)) {
1895531b17a7SHemant Agrawal 		atomic_inc(&s->vdq.busy);
1896531b17a7SHemant Agrawal 		return -EBUSY;
1897531b17a7SHemant Agrawal 	}
189869293c77SHemant Agrawal 
189969293c77SHemant Agrawal 	d->pull.tok = s->sys.idx + 1;
19005ae1edffSHemant Agrawal 	s->vdq.storage = (void *)(size_t)d->pull.rsp_addr_virt;
1901531b17a7SHemant Agrawal 	p = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
19028b870905SHaiying Wang 	memcpy(&p[1], &cl[1], 12);
190369293c77SHemant Agrawal 
1904531b17a7SHemant Agrawal 	/* Set the verb byte, have to substitute in the valid-bit */
1905531b17a7SHemant Agrawal 	lwsync();
1906531b17a7SHemant Agrawal 	p[0] = cl[0] | s->vdq.valid_bit;
1907531b17a7SHemant Agrawal 	s->vdq.valid_bit ^= QB_VALID_BIT;
1908531b17a7SHemant Agrawal 	qbman_cena_write_complete_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
190969293c77SHemant Agrawal 
1910531b17a7SHemant Agrawal 	return 0;
1911531b17a7SHemant Agrawal }
1912531b17a7SHemant Agrawal 
1913b3bd7a50SNipun Gupta static int qbman_swp_pull_cinh_direct(struct qbman_swp *s,
1914b3bd7a50SNipun Gupta 				 struct qbman_pull_desc *d)
1915b3bd7a50SNipun Gupta {
1916b3bd7a50SNipun Gupta 	uint32_t *p;
1917b3bd7a50SNipun Gupta 	uint32_t *cl = qb_cl(d);
1918b3bd7a50SNipun Gupta 
1919b3bd7a50SNipun Gupta 	if (!atomic_dec_and_test(&s->vdq.busy)) {
1920b3bd7a50SNipun Gupta 		atomic_inc(&s->vdq.busy);
1921b3bd7a50SNipun Gupta 		return -EBUSY;
1922b3bd7a50SNipun Gupta 	}
1923b3bd7a50SNipun Gupta 
1924b3bd7a50SNipun Gupta 	d->pull.tok = s->sys.idx + 1;
1925b3bd7a50SNipun Gupta 	s->vdq.storage = (void *)(size_t)d->pull.rsp_addr_virt;
1926b3bd7a50SNipun Gupta 	p = qbman_cinh_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
1927b3bd7a50SNipun Gupta 	memcpy_byte_by_byte(&p[1], &cl[1], 12);
1928b3bd7a50SNipun Gupta 
1929b3bd7a50SNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
1930b3bd7a50SNipun Gupta 	lwsync();
1931b3bd7a50SNipun Gupta 	p[0] = cl[0] | s->vdq.valid_bit;
1932b3bd7a50SNipun Gupta 	s->vdq.valid_bit ^= QB_VALID_BIT;
1933b3bd7a50SNipun Gupta 
1934b3bd7a50SNipun Gupta 	return 0;
1935b3bd7a50SNipun Gupta }
1936b3bd7a50SNipun Gupta 
1937293c0ca9SNipun Gupta static int qbman_swp_pull_mem_back(struct qbman_swp *s,
1938293c0ca9SNipun Gupta 				   struct qbman_pull_desc *d)
1939293c0ca9SNipun Gupta {
1940293c0ca9SNipun Gupta 	uint32_t *p;
1941293c0ca9SNipun Gupta 	uint32_t *cl = qb_cl(d);
1942293c0ca9SNipun Gupta 
1943293c0ca9SNipun Gupta 	if (!atomic_dec_and_test(&s->vdq.busy)) {
1944293c0ca9SNipun Gupta 		atomic_inc(&s->vdq.busy);
1945293c0ca9SNipun Gupta 		return -EBUSY;
1946293c0ca9SNipun Gupta 	}
1947293c0ca9SNipun Gupta 
1948293c0ca9SNipun Gupta 	d->pull.tok = s->sys.idx + 1;
1949293c0ca9SNipun Gupta 	s->vdq.storage = (void *)(size_t)d->pull.rsp_addr_virt;
1950293c0ca9SNipun Gupta 	p = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR_MEM);
1951293c0ca9SNipun Gupta 	memcpy(&p[1], &cl[1], 12);
1952293c0ca9SNipun Gupta 
1953293c0ca9SNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit */
1954293c0ca9SNipun Gupta 	p[0] = cl[0] | s->vdq.valid_bit;
1955293c0ca9SNipun Gupta 	s->vdq.valid_bit ^= QB_VALID_BIT;
1956293c0ca9SNipun Gupta 	dma_wmb();
1957293c0ca9SNipun Gupta 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE);
1958293c0ca9SNipun Gupta 
1959293c0ca9SNipun Gupta 	return 0;
1960293c0ca9SNipun Gupta }
1961293c0ca9SNipun Gupta 
19620ff708edSFerruh Yigit int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
1963293c0ca9SNipun Gupta {
1964b3bd7a50SNipun Gupta 	if (!s->stash_off)
1965293c0ca9SNipun Gupta 		return qbman_swp_pull_ptr(s, d);
1966b3bd7a50SNipun Gupta 	else
1967b3bd7a50SNipun Gupta 		return qbman_swp_pull_cinh_direct(s, d);
1968293c0ca9SNipun Gupta }
1969293c0ca9SNipun Gupta 
1970531b17a7SHemant Agrawal /****************/
1971531b17a7SHemant Agrawal /* Polling DQRR */
1972531b17a7SHemant Agrawal /****************/
1973531b17a7SHemant Agrawal 
197469293c77SHemant Agrawal #define QMAN_DQRR_PI_MASK              0xf
1975531b17a7SHemant Agrawal 
1976531b17a7SHemant Agrawal #define QBMAN_RESULT_DQ        0x60
1977531b17a7SHemant Agrawal #define QBMAN_RESULT_FQRN      0x21
1978531b17a7SHemant Agrawal #define QBMAN_RESULT_FQRNI     0x22
1979531b17a7SHemant Agrawal #define QBMAN_RESULT_FQPN      0x24
1980531b17a7SHemant Agrawal #define QBMAN_RESULT_FQDAN     0x25
1981531b17a7SHemant Agrawal #define QBMAN_RESULT_CDAN      0x26
1982531b17a7SHemant Agrawal #define QBMAN_RESULT_CSCN_MEM  0x27
1983531b17a7SHemant Agrawal #define QBMAN_RESULT_CGCU      0x28
1984531b17a7SHemant Agrawal #define QBMAN_RESULT_BPSCN     0x29
1985531b17a7SHemant Agrawal #define QBMAN_RESULT_CSCN_WQ   0x2a
1986531b17a7SHemant Agrawal 
19878a7833e1SNipun Gupta #include <rte_prefetch.h>
19888a7833e1SNipun Gupta 
19898a7833e1SNipun Gupta void qbman_swp_prefetch_dqrr_next(struct qbman_swp *s)
19908a7833e1SNipun Gupta {
19918a7833e1SNipun Gupta 	const struct qbman_result *p;
19928a7833e1SNipun Gupta 
19938a7833e1SNipun Gupta 	p = qbman_cena_read_wo_shadow(&s->sys,
19948a7833e1SNipun Gupta 		QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
19958a7833e1SNipun Gupta 	rte_prefetch0(p);
19968a7833e1SNipun Gupta }
19978a7833e1SNipun Gupta 
1998531b17a7SHemant Agrawal /* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
1999531b17a7SHemant Agrawal  * only once, so repeated calls can return a sequence of DQRR entries, without
2000531b17a7SHemant Agrawal  * requiring they be consumed immediately or in any particular order.
2001531b17a7SHemant Agrawal  */
20020ff708edSFerruh Yigit const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)
2003293c0ca9SNipun Gupta {
2004b3bd7a50SNipun Gupta 	if (!s->stash_off)
2005293c0ca9SNipun Gupta 		return qbman_swp_dqrr_next_ptr(s);
2006b3bd7a50SNipun Gupta 	else
2007b3bd7a50SNipun Gupta 		return qbman_swp_dqrr_next_cinh_direct(s);
2008293c0ca9SNipun Gupta }
2009293c0ca9SNipun Gupta 
2010293c0ca9SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_direct(struct qbman_swp *s)
2011531b17a7SHemant Agrawal {
2012531b17a7SHemant Agrawal 	uint32_t verb;
2013531b17a7SHemant Agrawal 	uint32_t response_verb;
2014531b17a7SHemant Agrawal 	uint32_t flags;
201569293c77SHemant Agrawal 	const struct qbman_result *p;
2016531b17a7SHemant Agrawal 
2017531b17a7SHemant Agrawal 	/* Before using valid-bit to detect if something is there, we have to
2018531b17a7SHemant Agrawal 	 * handle the case of the DQRR reset bug...
2019531b17a7SHemant Agrawal 	 */
2020293c0ca9SNipun Gupta 	if (s->dqrr.reset_bug) {
2021531b17a7SHemant Agrawal 		/* We pick up new entries by cache-inhibited producer index,
2022531b17a7SHemant Agrawal 		 * which means that a non-coherent mapping would require us to
2023531b17a7SHemant Agrawal 		 * invalidate and read *only* once that PI has indicated that
2024531b17a7SHemant Agrawal 		 * there's an entry here. The first trip around the DQRR ring
2025531b17a7SHemant Agrawal 		 * will be much less efficient than all subsequent trips around
2026531b17a7SHemant Agrawal 		 * it...
2027531b17a7SHemant Agrawal 		 */
202869293c77SHemant Agrawal 		uint8_t pi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI) &
202969293c77SHemant Agrawal 			     QMAN_DQRR_PI_MASK;
203069293c77SHemant Agrawal 
203198a7ea33SJerin Jacob 		/* there are new entries if pi != next_idx */
2032531b17a7SHemant Agrawal 		if (pi == s->dqrr.next_idx)
2033531b17a7SHemant Agrawal 			return NULL;
203469293c77SHemant Agrawal 
2035531b17a7SHemant Agrawal 		/* if next_idx is/was the last ring index, and 'pi' is
2036531b17a7SHemant Agrawal 		 * different, we can disable the workaround as all the ring
2037531b17a7SHemant Agrawal 		 * entries have now been DMA'd to so valid-bit checking is
2038531b17a7SHemant Agrawal 		 * repaired. Note: this logic needs to be based on next_idx
2039531b17a7SHemant Agrawal 		 * (which increments one at a time), rather than on pi (which
2040531b17a7SHemant Agrawal 		 * can burst and wrap-around between our snapshots of it).
2041531b17a7SHemant Agrawal 		 */
2042531b17a7SHemant Agrawal 		QBMAN_BUG_ON((s->dqrr.dqrr_size - 1) < 0);
2043531b17a7SHemant Agrawal 		if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1u)) {
2044531b17a7SHemant Agrawal 			pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n",
2045531b17a7SHemant Agrawal 				 s->dqrr.next_idx, pi);
2046531b17a7SHemant Agrawal 			s->dqrr.reset_bug = 0;
2047531b17a7SHemant Agrawal 		}
2048531b17a7SHemant Agrawal 		qbman_cena_invalidate_prefetch(&s->sys,
2049531b17a7SHemant Agrawal 					QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
2050531b17a7SHemant Agrawal 	}
205169293c77SHemant Agrawal 	p = qbman_cena_read_wo_shadow(&s->sys,
2052531b17a7SHemant Agrawal 			QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
2053293c0ca9SNipun Gupta 
205469293c77SHemant Agrawal 	verb = p->dq.verb;
205569293c77SHemant Agrawal 
2056531b17a7SHemant Agrawal 	/* If the valid-bit isn't of the expected polarity, nothing there. Note,
2057531b17a7SHemant Agrawal 	 * in the DQRR reset bug workaround, we shouldn't need to skip these
2058531b17a7SHemant Agrawal 	 * check, because we've already determined that a new entry is available
2059531b17a7SHemant Agrawal 	 * and we've invalidated the cacheline before reading it, so the
2060531b17a7SHemant Agrawal 	 * valid-bit behaviour is repaired and should tell us what we already
2061531b17a7SHemant Agrawal 	 * knew from reading PI.
2062531b17a7SHemant Agrawal 	 */
2063531b17a7SHemant Agrawal 	if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)
2064531b17a7SHemant Agrawal 		return NULL;
2065531b17a7SHemant Agrawal 
2066531b17a7SHemant Agrawal 	/* There's something there. Move "next_idx" attention to the next ring
2067531b17a7SHemant Agrawal 	 * entry (and prefetch it) before returning what we found.
2068531b17a7SHemant Agrawal 	 */
2069531b17a7SHemant Agrawal 	s->dqrr.next_idx++;
2070531b17a7SHemant Agrawal 	if (s->dqrr.next_idx == s->dqrr.dqrr_size) {
2071531b17a7SHemant Agrawal 		s->dqrr.next_idx = 0;
2072531b17a7SHemant Agrawal 		s->dqrr.valid_bit ^= QB_VALID_BIT;
2073531b17a7SHemant Agrawal 	}
2074531b17a7SHemant Agrawal 	/* If this is the final response to a volatile dequeue command
207569293c77SHemant Agrawal 	 * indicate that the vdq is no longer busy
2076531b17a7SHemant Agrawal 	 */
207769293c77SHemant Agrawal 	flags = p->dq.stat;
207869293c77SHemant Agrawal 	response_verb = verb & QBMAN_RESPONSE_VERB_MASK;
2079531b17a7SHemant Agrawal 	if ((response_verb == QBMAN_RESULT_DQ) &&
2080531b17a7SHemant Agrawal 	    (flags & QBMAN_DQ_STAT_VOLATILE) &&
2081531b17a7SHemant Agrawal 	    (flags & QBMAN_DQ_STAT_EXPIRED))
2082531b17a7SHemant Agrawal 		atomic_inc(&s->vdq.busy);
2083531b17a7SHemant Agrawal 
208469293c77SHemant Agrawal 	return p;
2085531b17a7SHemant Agrawal }
2086531b17a7SHemant Agrawal 
2087b3bd7a50SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_cinh_direct(struct qbman_swp *s)
2088b3bd7a50SNipun Gupta {
2089b3bd7a50SNipun Gupta 	uint32_t verb;
2090b3bd7a50SNipun Gupta 	uint32_t response_verb;
2091b3bd7a50SNipun Gupta 	uint32_t flags;
2092b3bd7a50SNipun Gupta 	const struct qbman_result *p;
2093b3bd7a50SNipun Gupta 
2094b3bd7a50SNipun Gupta 	/* Before using valid-bit to detect if something is there, we have to
2095b3bd7a50SNipun Gupta 	 * handle the case of the DQRR reset bug...
2096b3bd7a50SNipun Gupta 	 */
2097b3bd7a50SNipun Gupta 	if (s->dqrr.reset_bug) {
2098b3bd7a50SNipun Gupta 		/* We pick up new entries by cache-inhibited producer index,
2099b3bd7a50SNipun Gupta 		 * which means that a non-coherent mapping would require us to
2100b3bd7a50SNipun Gupta 		 * invalidate and read *only* once that PI has indicated that
2101b3bd7a50SNipun Gupta 		 * there's an entry here. The first trip around the DQRR ring
2102b3bd7a50SNipun Gupta 		 * will be much less efficient than all subsequent trips around
2103b3bd7a50SNipun Gupta 		 * it...
2104b3bd7a50SNipun Gupta 		 */
2105b3bd7a50SNipun Gupta 		uint8_t pi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI) &
2106b3bd7a50SNipun Gupta 			     QMAN_DQRR_PI_MASK;
2107b3bd7a50SNipun Gupta 
2108b3bd7a50SNipun Gupta 		/* there are new entries if pi != next_idx */
2109b3bd7a50SNipun Gupta 		if (pi == s->dqrr.next_idx)
2110b3bd7a50SNipun Gupta 			return NULL;
2111b3bd7a50SNipun Gupta 
2112b3bd7a50SNipun Gupta 		/* if next_idx is/was the last ring index, and 'pi' is
2113b3bd7a50SNipun Gupta 		 * different, we can disable the workaround as all the ring
2114b3bd7a50SNipun Gupta 		 * entries have now been DMA'd to so valid-bit checking is
2115b3bd7a50SNipun Gupta 		 * repaired. Note: this logic needs to be based on next_idx
2116b3bd7a50SNipun Gupta 		 * (which increments one at a time), rather than on pi (which
2117b3bd7a50SNipun Gupta 		 * can burst and wrap-around between our snapshots of it).
2118b3bd7a50SNipun Gupta 		 */
2119b3bd7a50SNipun Gupta 		QBMAN_BUG_ON((s->dqrr.dqrr_size - 1) < 0);
2120b3bd7a50SNipun Gupta 		if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1u)) {
2121b3bd7a50SNipun Gupta 			pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n",
2122b3bd7a50SNipun Gupta 				 s->dqrr.next_idx, pi);
2123b3bd7a50SNipun Gupta 			s->dqrr.reset_bug = 0;
2124b3bd7a50SNipun Gupta 		}
2125b3bd7a50SNipun Gupta 	}
2126b3bd7a50SNipun Gupta 	p = qbman_cinh_read_wo_shadow(&s->sys,
2127b3bd7a50SNipun Gupta 			QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
2128b3bd7a50SNipun Gupta 
2129b3bd7a50SNipun Gupta 	verb = p->dq.verb;
2130b3bd7a50SNipun Gupta 
2131b3bd7a50SNipun Gupta 	/* If the valid-bit isn't of the expected polarity, nothing there. Note,
2132b3bd7a50SNipun Gupta 	 * in the DQRR reset bug workaround, we shouldn't need to skip these
2133b3bd7a50SNipun Gupta 	 * check, because we've already determined that a new entry is available
2134b3bd7a50SNipun Gupta 	 * and we've invalidated the cacheline before reading it, so the
2135b3bd7a50SNipun Gupta 	 * valid-bit behaviour is repaired and should tell us what we already
2136b3bd7a50SNipun Gupta 	 * knew from reading PI.
2137b3bd7a50SNipun Gupta 	 */
2138b3bd7a50SNipun Gupta 	if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)
2139b3bd7a50SNipun Gupta 		return NULL;
2140b3bd7a50SNipun Gupta 
2141b3bd7a50SNipun Gupta 	/* There's something there. Move "next_idx" attention to the next ring
2142b3bd7a50SNipun Gupta 	 * entry (and prefetch it) before returning what we found.
2143b3bd7a50SNipun Gupta 	 */
2144b3bd7a50SNipun Gupta 	s->dqrr.next_idx++;
2145b3bd7a50SNipun Gupta 	if (s->dqrr.next_idx == s->dqrr.dqrr_size) {
2146b3bd7a50SNipun Gupta 		s->dqrr.next_idx = 0;
2147b3bd7a50SNipun Gupta 		s->dqrr.valid_bit ^= QB_VALID_BIT;
2148b3bd7a50SNipun Gupta 	}
2149b3bd7a50SNipun Gupta 	/* If this is the final response to a volatile dequeue command
2150b3bd7a50SNipun Gupta 	 * indicate that the vdq is no longer busy
2151b3bd7a50SNipun Gupta 	 */
2152b3bd7a50SNipun Gupta 	flags = p->dq.stat;
2153b3bd7a50SNipun Gupta 	response_verb = verb & QBMAN_RESPONSE_VERB_MASK;
2154b3bd7a50SNipun Gupta 	if ((response_verb == QBMAN_RESULT_DQ) &&
2155b3bd7a50SNipun Gupta 	    (flags & QBMAN_DQ_STAT_VOLATILE) &&
2156b3bd7a50SNipun Gupta 	    (flags & QBMAN_DQ_STAT_EXPIRED))
2157b3bd7a50SNipun Gupta 		atomic_inc(&s->vdq.busy);
2158b3bd7a50SNipun Gupta 
2159b3bd7a50SNipun Gupta 	return p;
2160b3bd7a50SNipun Gupta }
2161b3bd7a50SNipun Gupta 
2162293c0ca9SNipun Gupta const struct qbman_result *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s)
2163293c0ca9SNipun Gupta {
2164293c0ca9SNipun Gupta 	uint32_t verb;
2165293c0ca9SNipun Gupta 	uint32_t response_verb;
2166293c0ca9SNipun Gupta 	uint32_t flags;
2167293c0ca9SNipun Gupta 	const struct qbman_result *p;
2168293c0ca9SNipun Gupta 
2169293c0ca9SNipun Gupta 	p = qbman_cena_read_wo_shadow(&s->sys,
2170293c0ca9SNipun Gupta 			QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx));
2171293c0ca9SNipun Gupta 
2172293c0ca9SNipun Gupta 	verb = p->dq.verb;
2173293c0ca9SNipun Gupta 
2174293c0ca9SNipun Gupta 	/* If the valid-bit isn't of the expected polarity, nothing there. Note,
2175293c0ca9SNipun Gupta 	 * in the DQRR reset bug workaround, we shouldn't need to skip these
2176293c0ca9SNipun Gupta 	 * check, because we've already determined that a new entry is available
2177293c0ca9SNipun Gupta 	 * and we've invalidated the cacheline before reading it, so the
2178293c0ca9SNipun Gupta 	 * valid-bit behaviour is repaired and should tell us what we already
2179293c0ca9SNipun Gupta 	 * knew from reading PI.
2180293c0ca9SNipun Gupta 	 */
2181293c0ca9SNipun Gupta 	if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)
2182293c0ca9SNipun Gupta 		return NULL;
2183293c0ca9SNipun Gupta 
2184293c0ca9SNipun Gupta 	/* There's something there. Move "next_idx" attention to the next ring
2185293c0ca9SNipun Gupta 	 * entry (and prefetch it) before returning what we found.
2186293c0ca9SNipun Gupta 	 */
2187293c0ca9SNipun Gupta 	s->dqrr.next_idx++;
2188293c0ca9SNipun Gupta 	if (s->dqrr.next_idx == s->dqrr.dqrr_size) {
2189293c0ca9SNipun Gupta 		s->dqrr.next_idx = 0;
2190293c0ca9SNipun Gupta 		s->dqrr.valid_bit ^= QB_VALID_BIT;
2191293c0ca9SNipun Gupta 	}
2192293c0ca9SNipun Gupta 	/* If this is the final response to a volatile dequeue command
2193293c0ca9SNipun Gupta 	 * indicate that the vdq is no longer busy
2194293c0ca9SNipun Gupta 	 */
2195293c0ca9SNipun Gupta 	flags = p->dq.stat;
2196293c0ca9SNipun Gupta 	response_verb = verb & QBMAN_RESPONSE_VERB_MASK;
2197ff8e5f10SHemant Agrawal 	if ((response_verb == QBMAN_RESULT_DQ)
2198ff8e5f10SHemant Agrawal 			&& (flags & QBMAN_DQ_STAT_VOLATILE)
2199ff8e5f10SHemant Agrawal 			&& (flags & QBMAN_DQ_STAT_EXPIRED))
2200293c0ca9SNipun Gupta 		atomic_inc(&s->vdq.busy);
2201293c0ca9SNipun Gupta 	return p;
2202293c0ca9SNipun Gupta }
2203293c0ca9SNipun Gupta 
2204531b17a7SHemant Agrawal /* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
2205531b17a7SHemant Agrawal void qbman_swp_dqrr_consume(struct qbman_swp *s,
2206531b17a7SHemant Agrawal 			    const struct qbman_result *dq)
2207531b17a7SHemant Agrawal {
2208293c0ca9SNipun Gupta 	qbman_cinh_write(&s->sys,
2209293c0ca9SNipun Gupta 			QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
2210531b17a7SHemant Agrawal }
2211531b17a7SHemant Agrawal 
22124170dbe2SNipun Gupta /* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
22134170dbe2SNipun Gupta void qbman_swp_dqrr_idx_consume(struct qbman_swp *s,
22144170dbe2SNipun Gupta 			    uint8_t dqrr_index)
22154170dbe2SNipun Gupta {
22164170dbe2SNipun Gupta 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, dqrr_index);
22174170dbe2SNipun Gupta }
22184170dbe2SNipun Gupta 
2219531b17a7SHemant Agrawal /*********************************/
2220531b17a7SHemant Agrawal /* Polling user-provided storage */
2221531b17a7SHemant Agrawal /*********************************/
2222293c0ca9SNipun Gupta 
222369293c77SHemant Agrawal int qbman_result_has_new_result(struct qbman_swp *s,
222469293c77SHemant Agrawal 				struct qbman_result *dq)
2225531b17a7SHemant Agrawal {
222669293c77SHemant Agrawal 	if (dq->dq.tok == 0)
2227531b17a7SHemant Agrawal 		return 0;
2228531b17a7SHemant Agrawal 
222969293c77SHemant Agrawal 	/*
223069293c77SHemant Agrawal 	 * Set token to be 0 so we will detect change back to 1
223169293c77SHemant Agrawal 	 * next time the looping is traversed. Const is cast away here
223269293c77SHemant Agrawal 	 * as we want users to treat the dequeue responses as read only.
2233531b17a7SHemant Agrawal 	 */
223469293c77SHemant Agrawal 	((struct qbman_result *)dq)->dq.tok = 0;
2235531b17a7SHemant Agrawal 
223669293c77SHemant Agrawal 	/*
2237293c0ca9SNipun Gupta 	 * VDQCR "no longer busy" hook - not quite the same as DQRR, because
2238293c0ca9SNipun Gupta 	 * the fact "VDQCR" shows busy doesn't mean that we hold the result
2239293c0ca9SNipun Gupta 	 * that makes it available. Eg. we may be looking at our 10th dequeue
2240293c0ca9SNipun Gupta 	 * result, having released VDQCR after the 1st result and it is now
2241293c0ca9SNipun Gupta 	 * busy due to some other command!
2242531b17a7SHemant Agrawal 	 */
2243531b17a7SHemant Agrawal 	if (s->vdq.storage == dq) {
2244531b17a7SHemant Agrawal 		s->vdq.storage = NULL;
2245531b17a7SHemant Agrawal 		atomic_inc(&s->vdq.busy);
2246531b17a7SHemant Agrawal 	}
224769293c77SHemant Agrawal 
224869293c77SHemant Agrawal 	return 1;
224969293c77SHemant Agrawal }
225069293c77SHemant Agrawal 
225169293c77SHemant Agrawal int qbman_check_new_result(struct qbman_result *dq)
225269293c77SHemant Agrawal {
225369293c77SHemant Agrawal 	if (dq->dq.tok == 0)
225469293c77SHemant Agrawal 		return 0;
225569293c77SHemant Agrawal 
225669293c77SHemant Agrawal 	/*
225769293c77SHemant Agrawal 	 * Set token to be 0 so we will detect change back to 1
225869293c77SHemant Agrawal 	 * next time the looping is traversed. Const is cast away here
225969293c77SHemant Agrawal 	 * as we want users to treat the dequeue responses as read only.
226069293c77SHemant Agrawal 	 */
226169293c77SHemant Agrawal 	((struct qbman_result *)dq)->dq.tok = 0;
226269293c77SHemant Agrawal 
226369293c77SHemant Agrawal 	return 1;
226469293c77SHemant Agrawal }
226569293c77SHemant Agrawal 
226669293c77SHemant Agrawal int qbman_check_command_complete(struct qbman_result *dq)
226769293c77SHemant Agrawal {
226869293c77SHemant Agrawal 	struct qbman_swp *s;
226969293c77SHemant Agrawal 
227069293c77SHemant Agrawal 	if (dq->dq.tok == 0)
227169293c77SHemant Agrawal 		return 0;
227269293c77SHemant Agrawal 
227369293c77SHemant Agrawal 	s = portal_idx_map[dq->dq.tok - 1];
227469293c77SHemant Agrawal 	/*
2275293c0ca9SNipun Gupta 	 * VDQCR "no longer busy" hook - not quite the same as DQRR, because
2276293c0ca9SNipun Gupta 	 * the fact "VDQCR" shows busy doesn't mean that we hold the result
2277293c0ca9SNipun Gupta 	 * that makes it available. Eg. we may be looking at our 10th dequeue
2278293c0ca9SNipun Gupta 	 * result, having released VDQCR after the 1st result and it is now
2279293c0ca9SNipun Gupta 	 * busy due to some other command!
228069293c77SHemant Agrawal 	 */
228169293c77SHemant Agrawal 	if (s->vdq.storage == dq) {
228269293c77SHemant Agrawal 		s->vdq.storage = NULL;
228369293c77SHemant Agrawal 		atomic_inc(&s->vdq.busy);
228469293c77SHemant Agrawal 	}
228569293c77SHemant Agrawal 
2286531b17a7SHemant Agrawal 	return 1;
2287531b17a7SHemant Agrawal }
2288531b17a7SHemant Agrawal 
2289531b17a7SHemant Agrawal /********************************/
2290531b17a7SHemant Agrawal /* Categorising qbman results   */
2291531b17a7SHemant Agrawal /********************************/
2292531b17a7SHemant Agrawal 
2293531b17a7SHemant Agrawal static inline int __qbman_result_is_x(const struct qbman_result *dq,
229469293c77SHemant Agrawal 				      uint8_t x)
2295531b17a7SHemant Agrawal {
229669293c77SHemant Agrawal 	uint8_t response_verb = dq->dq.verb & QBMAN_RESPONSE_VERB_MASK;
2297531b17a7SHemant Agrawal 
2298531b17a7SHemant Agrawal 	return (response_verb == x);
2299531b17a7SHemant Agrawal }
2300531b17a7SHemant Agrawal 
2301531b17a7SHemant Agrawal int qbman_result_is_DQ(const struct qbman_result *dq)
2302531b17a7SHemant Agrawal {
2303531b17a7SHemant Agrawal 	return __qbman_result_is_x(dq, QBMAN_RESULT_DQ);
2304531b17a7SHemant Agrawal }
2305531b17a7SHemant Agrawal 
2306531b17a7SHemant Agrawal int qbman_result_is_FQDAN(const struct qbman_result *dq)
2307531b17a7SHemant Agrawal {
2308531b17a7SHemant Agrawal 	return __qbman_result_is_x(dq, QBMAN_RESULT_FQDAN);
2309531b17a7SHemant Agrawal }
2310531b17a7SHemant Agrawal 
2311531b17a7SHemant Agrawal int qbman_result_is_CDAN(const struct qbman_result *dq)
2312531b17a7SHemant Agrawal {
2313531b17a7SHemant Agrawal 	return __qbman_result_is_x(dq, QBMAN_RESULT_CDAN);
2314531b17a7SHemant Agrawal }
2315531b17a7SHemant Agrawal 
2316531b17a7SHemant Agrawal int qbman_result_is_CSCN(const struct qbman_result *dq)
2317531b17a7SHemant Agrawal {
231869293c77SHemant Agrawal 	return __qbman_result_is_x(dq, QBMAN_RESULT_CSCN_MEM) ||
2319531b17a7SHemant Agrawal 		__qbman_result_is_x(dq, QBMAN_RESULT_CSCN_WQ);
2320531b17a7SHemant Agrawal }
2321531b17a7SHemant Agrawal 
2322531b17a7SHemant Agrawal int qbman_result_is_BPSCN(const struct qbman_result *dq)
2323531b17a7SHemant Agrawal {
232469293c77SHemant Agrawal 	return __qbman_result_is_x(dq, QBMAN_RESULT_BPSCN);
2325531b17a7SHemant Agrawal }
2326531b17a7SHemant Agrawal 
2327531b17a7SHemant Agrawal int qbman_result_is_CGCU(const struct qbman_result *dq)
2328531b17a7SHemant Agrawal {
232969293c77SHemant Agrawal 	return __qbman_result_is_x(dq, QBMAN_RESULT_CGCU);
2330531b17a7SHemant Agrawal }
2331531b17a7SHemant Agrawal 
2332531b17a7SHemant Agrawal int qbman_result_is_FQRN(const struct qbman_result *dq)
2333531b17a7SHemant Agrawal {
233469293c77SHemant Agrawal 	return __qbman_result_is_x(dq, QBMAN_RESULT_FQRN);
2335531b17a7SHemant Agrawal }
2336531b17a7SHemant Agrawal 
2337531b17a7SHemant Agrawal int qbman_result_is_FQRNI(const struct qbman_result *dq)
2338531b17a7SHemant Agrawal {
233969293c77SHemant Agrawal 	return __qbman_result_is_x(dq, QBMAN_RESULT_FQRNI);
2340531b17a7SHemant Agrawal }
2341531b17a7SHemant Agrawal 
2342531b17a7SHemant Agrawal int qbman_result_is_FQPN(const struct qbman_result *dq)
2343531b17a7SHemant Agrawal {
2344531b17a7SHemant Agrawal 	return __qbman_result_is_x(dq, QBMAN_RESULT_FQPN);
2345531b17a7SHemant Agrawal }
2346531b17a7SHemant Agrawal 
2347531b17a7SHemant Agrawal /*********************************/
2348531b17a7SHemant Agrawal /* Parsing frame dequeue results */
2349531b17a7SHemant Agrawal /*********************************/
2350531b17a7SHemant Agrawal 
2351531b17a7SHemant Agrawal /* These APIs assume qbman_result_is_DQ() is TRUE */
2352531b17a7SHemant Agrawal 
235369293c77SHemant Agrawal uint8_t qbman_result_DQ_flags(const struct qbman_result *dq)
2354531b17a7SHemant Agrawal {
235569293c77SHemant Agrawal 	return dq->dq.stat;
2356531b17a7SHemant Agrawal }
2357531b17a7SHemant Agrawal 
2358531b17a7SHemant Agrawal uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq)
2359531b17a7SHemant Agrawal {
236069293c77SHemant Agrawal 	return dq->dq.seqnum;
2361531b17a7SHemant Agrawal }
2362531b17a7SHemant Agrawal 
2363531b17a7SHemant Agrawal uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq)
2364531b17a7SHemant Agrawal {
236569293c77SHemant Agrawal 	return dq->dq.oprid;
2366531b17a7SHemant Agrawal }
2367531b17a7SHemant Agrawal 
2368531b17a7SHemant Agrawal uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq)
2369531b17a7SHemant Agrawal {
237069293c77SHemant Agrawal 	return dq->dq.fqid;
2371531b17a7SHemant Agrawal }
2372531b17a7SHemant Agrawal 
2373531b17a7SHemant Agrawal uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq)
2374531b17a7SHemant Agrawal {
237569293c77SHemant Agrawal 	return dq->dq.fq_byte_cnt;
2376531b17a7SHemant Agrawal }
2377531b17a7SHemant Agrawal 
2378531b17a7SHemant Agrawal uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq)
2379531b17a7SHemant Agrawal {
238069293c77SHemant Agrawal 	return dq->dq.fq_frm_cnt;
2381531b17a7SHemant Agrawal }
2382531b17a7SHemant Agrawal 
2383531b17a7SHemant Agrawal uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq)
2384531b17a7SHemant Agrawal {
238569293c77SHemant Agrawal 	return dq->dq.fqd_ctx;
2386531b17a7SHemant Agrawal }
2387531b17a7SHemant Agrawal 
2388531b17a7SHemant Agrawal const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq)
2389531b17a7SHemant Agrawal {
239069293c77SHemant Agrawal 	return (const struct qbman_fd *)&dq->dq.fd[0];
2391531b17a7SHemant Agrawal }
2392531b17a7SHemant Agrawal 
2393531b17a7SHemant Agrawal /**************************************/
2394531b17a7SHemant Agrawal /* Parsing state-change notifications */
2395531b17a7SHemant Agrawal /**************************************/
2396531b17a7SHemant Agrawal uint8_t qbman_result_SCN_state(const struct qbman_result *scn)
2397531b17a7SHemant Agrawal {
239869293c77SHemant Agrawal 	return scn->scn.state;
2399531b17a7SHemant Agrawal }
2400531b17a7SHemant Agrawal 
2401531b17a7SHemant Agrawal uint32_t qbman_result_SCN_rid(const struct qbman_result *scn)
2402531b17a7SHemant Agrawal {
240369293c77SHemant Agrawal 	return scn->scn.rid_tok;
2404531b17a7SHemant Agrawal }
2405531b17a7SHemant Agrawal 
2406531b17a7SHemant Agrawal uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn)
2407531b17a7SHemant Agrawal {
240869293c77SHemant Agrawal 	return scn->scn.ctx;
2409531b17a7SHemant Agrawal }
2410531b17a7SHemant Agrawal 
2411531b17a7SHemant Agrawal /*****************/
2412531b17a7SHemant Agrawal /* Parsing BPSCN */
2413531b17a7SHemant Agrawal /*****************/
2414531b17a7SHemant Agrawal uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn)
2415531b17a7SHemant Agrawal {
241669293c77SHemant Agrawal 	return (uint16_t)qbman_result_SCN_rid(scn) & 0x3FFF;
2417531b17a7SHemant Agrawal }
2418531b17a7SHemant Agrawal 
2419531b17a7SHemant Agrawal int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn)
2420531b17a7SHemant Agrawal {
242169293c77SHemant Agrawal 	return !(int)(qbman_result_SCN_state(scn) & 0x1);
2422531b17a7SHemant Agrawal }
2423531b17a7SHemant Agrawal 
2424531b17a7SHemant Agrawal int qbman_result_bpscn_is_depleted(const struct qbman_result *scn)
2425531b17a7SHemant Agrawal {
242669293c77SHemant Agrawal 	return (int)(qbman_result_SCN_state(scn) & 0x2);
2427531b17a7SHemant Agrawal }
2428531b17a7SHemant Agrawal 
2429531b17a7SHemant Agrawal int qbman_result_bpscn_is_surplus(const struct qbman_result *scn)
2430531b17a7SHemant Agrawal {
243169293c77SHemant Agrawal 	return (int)(qbman_result_SCN_state(scn) & 0x4);
2432531b17a7SHemant Agrawal }
2433531b17a7SHemant Agrawal 
2434531b17a7SHemant Agrawal uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn)
2435531b17a7SHemant Agrawal {
2436d95bdc09SHemant Agrawal 	return qbman_result_SCN_ctx(scn);
2437531b17a7SHemant Agrawal }
2438531b17a7SHemant Agrawal 
2439531b17a7SHemant Agrawal /*****************/
2440531b17a7SHemant Agrawal /* Parsing CGCU  */
2441531b17a7SHemant Agrawal /*****************/
2442531b17a7SHemant Agrawal uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn)
2443531b17a7SHemant Agrawal {
244469293c77SHemant Agrawal 	return (uint16_t)qbman_result_SCN_rid(scn) & 0xFFFF;
2445531b17a7SHemant Agrawal }
2446531b17a7SHemant Agrawal 
2447531b17a7SHemant Agrawal uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn)
2448531b17a7SHemant Agrawal {
2449d95bdc09SHemant Agrawal 	return qbman_result_SCN_ctx(scn);
2450531b17a7SHemant Agrawal }
2451531b17a7SHemant Agrawal 
245216c4a3c4SNipun Gupta /********************/
245316c4a3c4SNipun Gupta /* Parsing EQ RESP  */
245416c4a3c4SNipun Gupta /********************/
245516c4a3c4SNipun Gupta struct qbman_fd *qbman_result_eqresp_fd(struct qbman_result *eqresp)
245616c4a3c4SNipun Gupta {
245716c4a3c4SNipun Gupta 	return (struct qbman_fd *)&eqresp->eq_resp.fd[0];
245816c4a3c4SNipun Gupta }
245916c4a3c4SNipun Gupta 
246016c4a3c4SNipun Gupta void qbman_result_eqresp_set_rspid(struct qbman_result *eqresp, uint8_t val)
246116c4a3c4SNipun Gupta {
246216c4a3c4SNipun Gupta 	eqresp->eq_resp.rspid = val;
246316c4a3c4SNipun Gupta }
246416c4a3c4SNipun Gupta 
246516c4a3c4SNipun Gupta uint8_t qbman_result_eqresp_rspid(struct qbman_result *eqresp)
246616c4a3c4SNipun Gupta {
246716c4a3c4SNipun Gupta 	return eqresp->eq_resp.rspid;
246816c4a3c4SNipun Gupta }
246916c4a3c4SNipun Gupta 
247016c4a3c4SNipun Gupta uint8_t qbman_result_eqresp_rc(struct qbman_result *eqresp)
247116c4a3c4SNipun Gupta {
247216c4a3c4SNipun Gupta 	if (eqresp->eq_resp.rc == 0xE)
247316c4a3c4SNipun Gupta 		return 0;
247416c4a3c4SNipun Gupta 	else
247516c4a3c4SNipun Gupta 		return -1;
247616c4a3c4SNipun Gupta }
247716c4a3c4SNipun Gupta 
2478531b17a7SHemant Agrawal /******************/
2479531b17a7SHemant Agrawal /* Buffer release */
2480531b17a7SHemant Agrawal /******************/
248169293c77SHemant Agrawal #define QB_BR_RC_VALID_SHIFT  5
248269293c77SHemant Agrawal #define QB_BR_RCDI_SHIFT      6
2483531b17a7SHemant Agrawal 
2484531b17a7SHemant Agrawal void qbman_release_desc_clear(struct qbman_release_desc *d)
2485531b17a7SHemant Agrawal {
2486531b17a7SHemant Agrawal 	memset(d, 0, sizeof(*d));
248769293c77SHemant Agrawal 	d->br.verb = 1 << QB_BR_RC_VALID_SHIFT;
2488531b17a7SHemant Agrawal }
2489531b17a7SHemant Agrawal 
249069293c77SHemant Agrawal void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint16_t bpid)
2491531b17a7SHemant Agrawal {
249269293c77SHemant Agrawal 	d->br.bpid = bpid;
2493531b17a7SHemant Agrawal }
2494531b17a7SHemant Agrawal 
2495531b17a7SHemant Agrawal void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
2496531b17a7SHemant Agrawal {
249769293c77SHemant Agrawal 	if (enable)
249869293c77SHemant Agrawal 		d->br.verb |= 1 << QB_BR_RCDI_SHIFT;
249969293c77SHemant Agrawal 	else
250069293c77SHemant Agrawal 		d->br.verb &= ~(1 << QB_BR_RCDI_SHIFT);
2501531b17a7SHemant Agrawal }
2502531b17a7SHemant Agrawal 
2503531b17a7SHemant Agrawal #define RAR_IDX(rar)     ((rar) & 0x7)
2504531b17a7SHemant Agrawal #define RAR_VB(rar)      ((rar) & 0x80)
2505531b17a7SHemant Agrawal #define RAR_SUCCESS(rar) ((rar) & 0x100)
2506531b17a7SHemant Agrawal 
2507293c0ca9SNipun Gupta static int qbman_swp_release_direct(struct qbman_swp *s,
2508293c0ca9SNipun Gupta 				    const struct qbman_release_desc *d,
2509293c0ca9SNipun Gupta 				    const uint64_t *buffers,
2510293c0ca9SNipun Gupta 				    unsigned int num_buffers)
2511531b17a7SHemant Agrawal {
2512531b17a7SHemant Agrawal 	uint32_t *p;
2513531b17a7SHemant Agrawal 	const uint32_t *cl = qb_cl(d);
2514531b17a7SHemant Agrawal 	uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
2515531b17a7SHemant Agrawal 
2516531b17a7SHemant Agrawal 	pr_debug("RAR=%08x\n", rar);
2517531b17a7SHemant Agrawal 	if (!RAR_SUCCESS(rar))
2518531b17a7SHemant Agrawal 		return -EBUSY;
251969293c77SHemant Agrawal 
2520531b17a7SHemant Agrawal 	QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
252169293c77SHemant Agrawal 
2522531b17a7SHemant Agrawal 	/* Start the release command */
2523531b17a7SHemant Agrawal 	p = qbman_cena_write_start_wo_shadow(&s->sys,
2524531b17a7SHemant Agrawal 				     QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
252569293c77SHemant Agrawal 
2526531b17a7SHemant Agrawal 	/* Copy the caller's buffer pointers to the command */
2527531b17a7SHemant Agrawal 	u64_to_le32_copy(&p[2], buffers, num_buffers);
252869293c77SHemant Agrawal 
2529293c0ca9SNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit and the
2530293c0ca9SNipun Gupta 	 * number of buffers.
2531531b17a7SHemant Agrawal 	 */
2532531b17a7SHemant Agrawal 	lwsync();
2533531b17a7SHemant Agrawal 	p[0] = cl[0] | RAR_VB(rar) | num_buffers;
2534531b17a7SHemant Agrawal 	qbman_cena_write_complete_wo_shadow(&s->sys,
2535531b17a7SHemant Agrawal 				    QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
253669293c77SHemant Agrawal 
2537531b17a7SHemant Agrawal 	return 0;
2538531b17a7SHemant Agrawal }
2539531b17a7SHemant Agrawal 
2540b3bd7a50SNipun Gupta static int qbman_swp_release_cinh_direct(struct qbman_swp *s,
2541b3bd7a50SNipun Gupta 				    const struct qbman_release_desc *d,
2542b3bd7a50SNipun Gupta 				    const uint64_t *buffers,
2543b3bd7a50SNipun Gupta 				    unsigned int num_buffers)
2544b3bd7a50SNipun Gupta {
2545b3bd7a50SNipun Gupta 	uint32_t *p;
2546b3bd7a50SNipun Gupta 	const uint32_t *cl = qb_cl(d);
2547b3bd7a50SNipun Gupta 	uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
2548b3bd7a50SNipun Gupta 
2549b3bd7a50SNipun Gupta 	pr_debug("RAR=%08x\n", rar);
2550b3bd7a50SNipun Gupta 	if (!RAR_SUCCESS(rar))
2551b3bd7a50SNipun Gupta 		return -EBUSY;
2552b3bd7a50SNipun Gupta 
2553b3bd7a50SNipun Gupta 	QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
2554b3bd7a50SNipun Gupta 
2555b3bd7a50SNipun Gupta 	/* Start the release command */
2556b3bd7a50SNipun Gupta 	p = qbman_cinh_write_start_wo_shadow(&s->sys,
2557b3bd7a50SNipun Gupta 				     QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
2558b3bd7a50SNipun Gupta 
2559b3bd7a50SNipun Gupta 	/* Copy the caller's buffer pointers to the command */
2560b3bd7a50SNipun Gupta 	memcpy_byte_by_byte(&p[2], buffers, num_buffers * sizeof(uint64_t));
2561b3bd7a50SNipun Gupta 
2562b3bd7a50SNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit and the
2563b3bd7a50SNipun Gupta 	 * number of buffers.
2564b3bd7a50SNipun Gupta 	 */
2565b3bd7a50SNipun Gupta 	lwsync();
2566b3bd7a50SNipun Gupta 	p[0] = cl[0] | RAR_VB(rar) | num_buffers;
2567b3bd7a50SNipun Gupta 
2568b3bd7a50SNipun Gupta 	return 0;
2569b3bd7a50SNipun Gupta }
2570b3bd7a50SNipun Gupta 
2571293c0ca9SNipun Gupta static int qbman_swp_release_mem_back(struct qbman_swp *s,
2572293c0ca9SNipun Gupta 				      const struct qbman_release_desc *d,
2573293c0ca9SNipun Gupta 				      const uint64_t *buffers,
2574293c0ca9SNipun Gupta 				      unsigned int num_buffers)
2575293c0ca9SNipun Gupta {
2576293c0ca9SNipun Gupta 	uint32_t *p;
2577293c0ca9SNipun Gupta 	const uint32_t *cl = qb_cl(d);
2578293c0ca9SNipun Gupta 	uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
2579293c0ca9SNipun Gupta 
2580293c0ca9SNipun Gupta 	pr_debug("RAR=%08x\n", rar);
2581293c0ca9SNipun Gupta 	if (!RAR_SUCCESS(rar))
2582293c0ca9SNipun Gupta 		return -EBUSY;
2583293c0ca9SNipun Gupta 
2584293c0ca9SNipun Gupta 	QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
2585293c0ca9SNipun Gupta 
2586293c0ca9SNipun Gupta 	/* Start the release command */
2587293c0ca9SNipun Gupta 	p = qbman_cena_write_start_wo_shadow(&s->sys,
2588293c0ca9SNipun Gupta 		QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar)));
2589293c0ca9SNipun Gupta 
2590293c0ca9SNipun Gupta 	/* Copy the caller's buffer pointers to the command */
2591293c0ca9SNipun Gupta 	u64_to_le32_copy(&p[2], buffers, num_buffers);
2592293c0ca9SNipun Gupta 
2593293c0ca9SNipun Gupta 	/* Set the verb byte, have to substitute in the valid-bit and the
2594293c0ca9SNipun Gupta 	 * number of buffers.
2595293c0ca9SNipun Gupta 	 */
2596293c0ca9SNipun Gupta 	p[0] = cl[0] | RAR_VB(rar) | num_buffers;
2597293c0ca9SNipun Gupta 	lwsync();
2598293c0ca9SNipun Gupta 	qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_RCR_AM_RT +
2599293c0ca9SNipun Gupta 		RAR_IDX(rar) * 4, QMAN_RT_MODE);
2600293c0ca9SNipun Gupta 
2601293c0ca9SNipun Gupta 	return 0;
2602293c0ca9SNipun Gupta }
2603293c0ca9SNipun Gupta 
26040ff708edSFerruh Yigit int qbman_swp_release(struct qbman_swp *s,
2605293c0ca9SNipun Gupta 			     const struct qbman_release_desc *d,
2606293c0ca9SNipun Gupta 			     const uint64_t *buffers,
2607293c0ca9SNipun Gupta 			     unsigned int num_buffers)
2608293c0ca9SNipun Gupta {
2609b3bd7a50SNipun Gupta 	if (!s->stash_off)
2610293c0ca9SNipun Gupta 		return qbman_swp_release_ptr(s, d, buffers, num_buffers);
2611b3bd7a50SNipun Gupta 	else
2612b3bd7a50SNipun Gupta 		return qbman_swp_release_cinh_direct(s, d, buffers,
2613b3bd7a50SNipun Gupta 						num_buffers);
2614293c0ca9SNipun Gupta }
2615293c0ca9SNipun Gupta 
2616531b17a7SHemant Agrawal /*******************/
2617531b17a7SHemant Agrawal /* Buffer acquires */
2618531b17a7SHemant Agrawal /*******************/
261969293c77SHemant Agrawal struct qbman_acquire_desc {
262069293c77SHemant Agrawal 	uint8_t verb;
262169293c77SHemant Agrawal 	uint8_t reserved;
262269293c77SHemant Agrawal 	uint16_t bpid;
262369293c77SHemant Agrawal 	uint8_t num;
262469293c77SHemant Agrawal 	uint8_t reserved2[59];
262569293c77SHemant Agrawal };
2626531b17a7SHemant Agrawal 
262769293c77SHemant Agrawal struct qbman_acquire_rslt {
262869293c77SHemant Agrawal 	uint8_t verb;
262969293c77SHemant Agrawal 	uint8_t rslt;
263069293c77SHemant Agrawal 	uint16_t reserved;
263169293c77SHemant Agrawal 	uint8_t num;
263269293c77SHemant Agrawal 	uint8_t reserved2[3];
2633a116979aSJun Yang 	uint64_t buf[BMAN_VALID_RSLT_NUM_MASK];
263469293c77SHemant Agrawal };
2635531b17a7SHemant Agrawal 
2636b3bd7a50SNipun Gupta static int qbman_swp_acquire_direct(struct qbman_swp *s, uint16_t bpid,
2637b3bd7a50SNipun Gupta 				uint64_t *buffers, unsigned int num_buffers)
2638531b17a7SHemant Agrawal {
263969293c77SHemant Agrawal 	struct qbman_acquire_desc *p;
264069293c77SHemant Agrawal 	struct qbman_acquire_rslt *r;
2641a116979aSJun Yang 	int num;
2642531b17a7SHemant Agrawal 
2643a116979aSJun Yang 	if (!num_buffers || (num_buffers > BMAN_VALID_RSLT_NUM_MASK))
264469293c77SHemant Agrawal 		return -EINVAL;
2645531b17a7SHemant Agrawal 
2646531b17a7SHemant Agrawal 	/* Start the management command */
2647531b17a7SHemant Agrawal 	p = qbman_swp_mc_start(s);
2648531b17a7SHemant Agrawal 
2649531b17a7SHemant Agrawal 	if (!p)
2650531b17a7SHemant Agrawal 		return -EBUSY;
2651531b17a7SHemant Agrawal 
2652531b17a7SHemant Agrawal 	/* Encode the caller-provided attributes */
265369293c77SHemant Agrawal 	p->bpid = bpid;
265469293c77SHemant Agrawal 	p->num = num_buffers;
2655531b17a7SHemant Agrawal 
2656531b17a7SHemant Agrawal 	/* Complete the management command */
265769293c77SHemant Agrawal 	r = qbman_swp_mc_complete(s, p, QBMAN_MC_ACQUIRE);
2658293c0ca9SNipun Gupta 	if (!r) {
265969293c77SHemant Agrawal 		pr_err("qbman: acquire from BPID %d failed, no response\n",
266069293c77SHemant Agrawal 		       bpid);
2661531b17a7SHemant Agrawal 		return -EIO;
2662531b17a7SHemant Agrawal 	}
266369293c77SHemant Agrawal 
266469293c77SHemant Agrawal 	/* Decode the outcome */
266569293c77SHemant Agrawal 	QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_MC_ACQUIRE);
266669293c77SHemant Agrawal 
266769293c77SHemant Agrawal 	/* Determine success or failure */
2668293c0ca9SNipun Gupta 	if (r->rslt != QBMAN_MC_RSLT_OK) {
266969293c77SHemant Agrawal 		pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
267069293c77SHemant Agrawal 		       bpid, r->rslt);
267169293c77SHemant Agrawal 		return -EIO;
267269293c77SHemant Agrawal 	}
267369293c77SHemant Agrawal 
2674a116979aSJun Yang 	num = r->num & BMAN_VALID_RSLT_NUM_MASK;
2675a116979aSJun Yang 	QBMAN_BUG_ON(num > num_buffers);
267669293c77SHemant Agrawal 
2677531b17a7SHemant Agrawal 	/* Copy the acquired buffers to the caller's array */
2678a116979aSJun Yang 	u64_from_le32_copy(buffers, &r->buf[0], num);
267969293c77SHemant Agrawal 
2680a116979aSJun Yang 	return num;
2681531b17a7SHemant Agrawal }
2682531b17a7SHemant Agrawal 
2683b3bd7a50SNipun Gupta static int qbman_swp_acquire_cinh_direct(struct qbman_swp *s, uint16_t bpid,
2684b3bd7a50SNipun Gupta 			uint64_t *buffers, unsigned int num_buffers)
2685b3bd7a50SNipun Gupta {
2686b3bd7a50SNipun Gupta 	struct qbman_acquire_desc *p;
2687b3bd7a50SNipun Gupta 	struct qbman_acquire_rslt *r;
2688a116979aSJun Yang 	int num;
2689b3bd7a50SNipun Gupta 
2690a116979aSJun Yang 	if (!num_buffers || (num_buffers > BMAN_VALID_RSLT_NUM_MASK))
2691b3bd7a50SNipun Gupta 		return -EINVAL;
2692b3bd7a50SNipun Gupta 
2693b3bd7a50SNipun Gupta 	/* Start the management command */
2694b3bd7a50SNipun Gupta 	p = qbman_swp_mc_start(s);
2695b3bd7a50SNipun Gupta 
2696b3bd7a50SNipun Gupta 	if (!p)
2697b3bd7a50SNipun Gupta 		return -EBUSY;
2698b3bd7a50SNipun Gupta 
2699b3bd7a50SNipun Gupta 	/* Encode the caller-provided attributes */
2700b3bd7a50SNipun Gupta 	p->bpid = bpid;
2701b3bd7a50SNipun Gupta 	p->num = num_buffers;
2702b3bd7a50SNipun Gupta 
2703b3bd7a50SNipun Gupta 	/* Complete the management command */
2704b3bd7a50SNipun Gupta 	r = qbman_swp_mc_complete_cinh(s, p, QBMAN_MC_ACQUIRE);
2705b3bd7a50SNipun Gupta 	if (!r) {
2706b3bd7a50SNipun Gupta 		pr_err("qbman: acquire from BPID %d failed, no response\n",
2707b3bd7a50SNipun Gupta 		       bpid);
2708b3bd7a50SNipun Gupta 		return -EIO;
2709b3bd7a50SNipun Gupta 	}
2710b3bd7a50SNipun Gupta 
2711b3bd7a50SNipun Gupta 	/* Decode the outcome */
2712b3bd7a50SNipun Gupta 	QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_MC_ACQUIRE);
2713b3bd7a50SNipun Gupta 
2714b3bd7a50SNipun Gupta 	/* Determine success or failure */
2715b3bd7a50SNipun Gupta 	if (r->rslt != QBMAN_MC_RSLT_OK) {
2716b3bd7a50SNipun Gupta 		pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
2717b3bd7a50SNipun Gupta 		       bpid, r->rslt);
2718b3bd7a50SNipun Gupta 		return -EIO;
2719b3bd7a50SNipun Gupta 	}
2720b3bd7a50SNipun Gupta 
2721a116979aSJun Yang 	num = r->num & BMAN_VALID_RSLT_NUM_MASK;
2722a116979aSJun Yang 	QBMAN_BUG_ON(num > num_buffers);
2723b3bd7a50SNipun Gupta 
2724b3bd7a50SNipun Gupta 	/* Copy the acquired buffers to the caller's array */
2725a116979aSJun Yang 	u64_from_le32_copy(buffers, &r->buf[0], num);
2726b3bd7a50SNipun Gupta 
2727a116979aSJun Yang 	return num;
2728b3bd7a50SNipun Gupta }
2729b3bd7a50SNipun Gupta 
2730b3bd7a50SNipun Gupta int qbman_swp_acquire(struct qbman_swp *s, uint16_t bpid, uint64_t *buffers,
2731b3bd7a50SNipun Gupta 		      unsigned int num_buffers)
2732b3bd7a50SNipun Gupta {
2733b3bd7a50SNipun Gupta 	if (!s->stash_off)
2734b3bd7a50SNipun Gupta 		return qbman_swp_acquire_direct(s, bpid, buffers, num_buffers);
2735b3bd7a50SNipun Gupta 	else
2736b3bd7a50SNipun Gupta 		return qbman_swp_acquire_cinh_direct(s, bpid, buffers,
2737b3bd7a50SNipun Gupta 					num_buffers);
2738b3bd7a50SNipun Gupta }
2739b3bd7a50SNipun Gupta 
2740531b17a7SHemant Agrawal /*****************/
2741531b17a7SHemant Agrawal /* FQ management */
2742531b17a7SHemant Agrawal /*****************/
274369293c77SHemant Agrawal struct qbman_alt_fq_state_desc {
274469293c77SHemant Agrawal 	uint8_t verb;
274569293c77SHemant Agrawal 	uint8_t reserved[3];
274669293c77SHemant Agrawal 	uint32_t fqid;
274769293c77SHemant Agrawal 	uint8_t reserved2[56];
274869293c77SHemant Agrawal };
2749531b17a7SHemant Agrawal 
275069293c77SHemant Agrawal struct qbman_alt_fq_state_rslt {
275169293c77SHemant Agrawal 	uint8_t verb;
275269293c77SHemant Agrawal 	uint8_t rslt;
275369293c77SHemant Agrawal 	uint8_t reserved[62];
275469293c77SHemant Agrawal };
275569293c77SHemant Agrawal 
275669293c77SHemant Agrawal #define ALT_FQ_FQID_MASK 0x00FFFFFF
2757531b17a7SHemant Agrawal 
2758531b17a7SHemant Agrawal static int qbman_swp_alt_fq_state(struct qbman_swp *s, uint32_t fqid,
2759531b17a7SHemant Agrawal 				  uint8_t alt_fq_verb)
2760531b17a7SHemant Agrawal {
276169293c77SHemant Agrawal 	struct qbman_alt_fq_state_desc *p;
276269293c77SHemant Agrawal 	struct qbman_alt_fq_state_rslt *r;
2763531b17a7SHemant Agrawal 
2764531b17a7SHemant Agrawal 	/* Start the management command */
2765531b17a7SHemant Agrawal 	p = qbman_swp_mc_start(s);
2766531b17a7SHemant Agrawal 	if (!p)
2767531b17a7SHemant Agrawal 		return -EBUSY;
2768531b17a7SHemant Agrawal 
276969293c77SHemant Agrawal 	p->fqid = fqid & ALT_FQ_FQID_MASK;
277069293c77SHemant Agrawal 
2771531b17a7SHemant Agrawal 	/* Complete the management command */
277269293c77SHemant Agrawal 	r = qbman_swp_mc_complete(s, p, alt_fq_verb);
2773293c0ca9SNipun Gupta 	if (!r) {
277469293c77SHemant Agrawal 		pr_err("qbman: mgmt cmd failed, no response (verb=0x%x)\n",
277569293c77SHemant Agrawal 		       alt_fq_verb);
277669293c77SHemant Agrawal 		return -EIO;
277769293c77SHemant Agrawal 	}
2778531b17a7SHemant Agrawal 
2779531b17a7SHemant Agrawal 	/* Decode the outcome */
278069293c77SHemant Agrawal 	QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != alt_fq_verb);
2781531b17a7SHemant Agrawal 
2782531b17a7SHemant Agrawal 	/* Determine success or failure */
2783293c0ca9SNipun Gupta 	if (r->rslt != QBMAN_MC_RSLT_OK) {
2784531b17a7SHemant Agrawal 		pr_err("ALT FQID %d failed: verb = 0x%08x, code = 0x%02x\n",
278569293c77SHemant Agrawal 		       fqid, alt_fq_verb, r->rslt);
2786531b17a7SHemant Agrawal 		return -EIO;
2787531b17a7SHemant Agrawal 	}
2788531b17a7SHemant Agrawal 
2789531b17a7SHemant Agrawal 	return 0;
2790531b17a7SHemant Agrawal }
2791531b17a7SHemant Agrawal 
2792531b17a7SHemant Agrawal int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid)
2793531b17a7SHemant Agrawal {
2794531b17a7SHemant Agrawal 	return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE);
2795531b17a7SHemant Agrawal }
2796531b17a7SHemant Agrawal 
2797531b17a7SHemant Agrawal int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid)
2798531b17a7SHemant Agrawal {
2799531b17a7SHemant Agrawal 	return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE);
2800531b17a7SHemant Agrawal }
2801531b17a7SHemant Agrawal 
2802531b17a7SHemant Agrawal int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid)
2803531b17a7SHemant Agrawal {
2804531b17a7SHemant Agrawal 	return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON);
2805531b17a7SHemant Agrawal }
2806531b17a7SHemant Agrawal 
2807531b17a7SHemant Agrawal int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid)
2808531b17a7SHemant Agrawal {
2809531b17a7SHemant Agrawal 	return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF);
2810531b17a7SHemant Agrawal }
2811531b17a7SHemant Agrawal 
2812531b17a7SHemant Agrawal /**********************/
2813531b17a7SHemant Agrawal /* Channel management */
2814531b17a7SHemant Agrawal /**********************/
2815531b17a7SHemant Agrawal 
281669293c77SHemant Agrawal struct qbman_cdan_ctrl_desc {
281769293c77SHemant Agrawal 	uint8_t verb;
281869293c77SHemant Agrawal 	uint8_t reserved;
281969293c77SHemant Agrawal 	uint16_t ch;
282069293c77SHemant Agrawal 	uint8_t we;
282169293c77SHemant Agrawal 	uint8_t ctrl;
282269293c77SHemant Agrawal 	uint16_t reserved2;
282369293c77SHemant Agrawal 	uint64_t cdan_ctx;
282469293c77SHemant Agrawal 	uint8_t reserved3[48];
282569293c77SHemant Agrawal 
282669293c77SHemant Agrawal };
282769293c77SHemant Agrawal 
282869293c77SHemant Agrawal struct qbman_cdan_ctrl_rslt {
282969293c77SHemant Agrawal 	uint8_t verb;
283069293c77SHemant Agrawal 	uint8_t rslt;
283169293c77SHemant Agrawal 	uint16_t ch;
283269293c77SHemant Agrawal 	uint8_t reserved[60];
283369293c77SHemant Agrawal };
2834531b17a7SHemant Agrawal 
2835531b17a7SHemant Agrawal /* Hide "ICD" for now as we don't use it, don't set it, and don't test it, so it
2836531b17a7SHemant Agrawal  * would be irresponsible to expose it.
2837531b17a7SHemant Agrawal  */
2838531b17a7SHemant Agrawal #define CODE_CDAN_WE_EN    0x1
2839531b17a7SHemant Agrawal #define CODE_CDAN_WE_CTX   0x4
2840531b17a7SHemant Agrawal 
2841531b17a7SHemant Agrawal static int qbman_swp_CDAN_set(struct qbman_swp *s, uint16_t channelid,
2842531b17a7SHemant Agrawal 			      uint8_t we_mask, uint8_t cdan_en,
2843531b17a7SHemant Agrawal 			      uint64_t ctx)
2844531b17a7SHemant Agrawal {
284569293c77SHemant Agrawal 	struct qbman_cdan_ctrl_desc *p;
284669293c77SHemant Agrawal 	struct qbman_cdan_ctrl_rslt *r;
2847531b17a7SHemant Agrawal 
2848531b17a7SHemant Agrawal 	/* Start the management command */
2849531b17a7SHemant Agrawal 	p = qbman_swp_mc_start(s);
2850531b17a7SHemant Agrawal 	if (!p)
2851531b17a7SHemant Agrawal 		return -EBUSY;
2852531b17a7SHemant Agrawal 
2853531b17a7SHemant Agrawal 	/* Encode the caller-provided attributes */
285469293c77SHemant Agrawal 	p->ch = channelid;
285569293c77SHemant Agrawal 	p->we = we_mask;
285669293c77SHemant Agrawal 	if (cdan_en)
285769293c77SHemant Agrawal 		p->ctrl = 1;
285869293c77SHemant Agrawal 	else
285969293c77SHemant Agrawal 		p->ctrl = 0;
286069293c77SHemant Agrawal 	p->cdan_ctx = ctx;
286169293c77SHemant Agrawal 
2862531b17a7SHemant Agrawal 	/* Complete the management command */
286369293c77SHemant Agrawal 	r = qbman_swp_mc_complete(s, p, QBMAN_WQCHAN_CONFIGURE);
2864293c0ca9SNipun Gupta 	if (!r) {
286569293c77SHemant Agrawal 		pr_err("qbman: wqchan config failed, no response\n");
286669293c77SHemant Agrawal 		return -EIO;
286769293c77SHemant Agrawal 	}
2868531b17a7SHemant Agrawal 
2869531b17a7SHemant Agrawal 	/* Decode the outcome */
287069293c77SHemant Agrawal 	QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK)
2871531b17a7SHemant Agrawal 		     != QBMAN_WQCHAN_CONFIGURE);
2872531b17a7SHemant Agrawal 
2873531b17a7SHemant Agrawal 	/* Determine success or failure */
2874293c0ca9SNipun Gupta 	if (r->rslt != QBMAN_MC_RSLT_OK) {
2875531b17a7SHemant Agrawal 		pr_err("CDAN cQID %d failed: code = 0x%02x\n",
287669293c77SHemant Agrawal 		       channelid, r->rslt);
2877531b17a7SHemant Agrawal 		return -EIO;
2878531b17a7SHemant Agrawal 	}
2879531b17a7SHemant Agrawal 
2880531b17a7SHemant Agrawal 	return 0;
2881531b17a7SHemant Agrawal }
2882531b17a7SHemant Agrawal 
2883531b17a7SHemant Agrawal int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
2884531b17a7SHemant Agrawal 			       uint64_t ctx)
2885531b17a7SHemant Agrawal {
2886531b17a7SHemant Agrawal 	return qbman_swp_CDAN_set(s, channelid,
2887531b17a7SHemant Agrawal 				  CODE_CDAN_WE_CTX,
2888531b17a7SHemant Agrawal 				  0, ctx);
2889531b17a7SHemant Agrawal }
2890531b17a7SHemant Agrawal 
2891531b17a7SHemant Agrawal int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid)
2892531b17a7SHemant Agrawal {
2893531b17a7SHemant Agrawal 	return qbman_swp_CDAN_set(s, channelid,
2894531b17a7SHemant Agrawal 				  CODE_CDAN_WE_EN,
2895531b17a7SHemant Agrawal 				  1, 0);
2896531b17a7SHemant Agrawal }
2897531b17a7SHemant Agrawal 
2898531b17a7SHemant Agrawal int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid)
2899531b17a7SHemant Agrawal {
2900531b17a7SHemant Agrawal 	return qbman_swp_CDAN_set(s, channelid,
2901531b17a7SHemant Agrawal 				  CODE_CDAN_WE_EN,
2902531b17a7SHemant Agrawal 				  0, 0);
2903531b17a7SHemant Agrawal }
2904531b17a7SHemant Agrawal 
2905531b17a7SHemant Agrawal int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
2906531b17a7SHemant Agrawal 				      uint64_t ctx)
2907531b17a7SHemant Agrawal {
2908531b17a7SHemant Agrawal 	return qbman_swp_CDAN_set(s, channelid,
2909531b17a7SHemant Agrawal 				  CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX,
2910531b17a7SHemant Agrawal 				  1, ctx);
2911531b17a7SHemant Agrawal }
2912531b17a7SHemant Agrawal 
29136070ce43SNipun Gupta uint8_t qbman_get_dqrr_idx(const struct qbman_result *dqrr)
2914531b17a7SHemant Agrawal {
2915531b17a7SHemant Agrawal 	return QBMAN_IDX_FROM_DQRR(dqrr);
2916531b17a7SHemant Agrawal }
2917531b17a7SHemant Agrawal 
2918531b17a7SHemant Agrawal struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx)
2919531b17a7SHemant Agrawal {
2920531b17a7SHemant Agrawal 	struct qbman_result *dq;
2921531b17a7SHemant Agrawal 
2922531b17a7SHemant Agrawal 	dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(idx));
2923531b17a7SHemant Agrawal 	return dq;
2924531b17a7SHemant Agrawal }
2925