xref: /freebsd/sys/dev/dpaa/qman_portals.c (revision aefd61a1de86521abc1551aa98ed94316fc83d86)
1 /*
2  * Copyright (c) 2026 Justin Hibbits
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include "opt_platform.h"
8 
9 #include <sys/param.h>
10 #include <sys/systm.h>
11 #include <sys/kernel.h>
12 #include <sys/bus.h>
13 #include <sys/lock.h>
14 #include <sys/module.h>
15 #include <sys/mutex.h>
16 #include <sys/proc.h>
17 #include <sys/pcpu.h>
18 #include <sys/sched.h>
19 #include <sys/smp.h>	/* For CPU_FOREACH() */
20 #include <sys/sysctl.h>
21 #include <ddb/ddb.h>
22 
23 #include <machine/bus.h>
24 #include <machine/tlb.h>
25 
26 #include <dev/ofw/ofw_bus.h>
27 #include <dev/ofw/ofw_bus_subr.h>
28 
29 #include <powerpc/mpc85xx/mpc85xx.h>
30 
31 #include "qman.h"
32 #include "portals.h"
33 #include "qman_var.h"
34 
35 
36 /* Cache-enabled registers */
37 #define	QCSP_EQCR_N(n)		(0x0000 + (n * 64))
38 #define	QMAN_EQCR_COUNT		8
39 #define	QCSP_DQRR_N(n)		(0x1000 + (n * 64))
40 #define	QMAN_DQRR_COUNT		16
41 #define	QCSP_MR_N(n)		(0x2000 + (n * 64))
42 #define	QMAN_MR_COUNT		8
43 #define	QCSP_CR			0x3800
44 #define	QCSP_RR(n)		(0x3900 + 0x40 * (n))
45 
46 #define	QCSP_EQCR_PI_CENA	0x0000
47 #define	  EQCR_PI_VP		  0x00000008
48 #define	  EQCR_PI_PI_M		  0x00000007
49 #define	QCSP_EQCR_CI_CENA	0x0004
50 #define	  EQCR_CI_C		  0x00000008
51 #define	  EQCR_CI_CI_M		  0x00000007
52 #define	QCSP_DQRR_PI_CENA	0x0000
53 #define	  DQRR_PI_VP		  0x00000010
54 #define	  DQRR_PI_PI_M		  0x0000000f
55 #define	QCSP_DQRR_CI_CENA	0x0004
56 #define	  DQRR_CI_C		  0x00000010
57 #define	  DQRR_CI_CI_M		  0x0000000f
58 
59 #define	QMAN_MC_VERB_VBIT	0x80
60 
61 
62 /* Cache-inhibited registers */
63 #define	QCSP_EQCR_PI_CINH	0x0000
64 #define	QCSP_EQCR_CI_CINH	0x0004
65 #define	QCSP_DQRR_PI_CINH	0x0040
66 #define	QCSP_DQRR_CI_CINH	0x0044
67 #define	QCSP_EQCR_ITR		0x0008
68 #define	QCSP_DQRR_ITR		0x0048
69 #define	QCSP_DQRR_SDQCR		0x0054
70 #define	  SDQCR_SS		  0x40000000
71 #define	  SDQCR_FC		  0x20000000
72 #define	  SDQCR_DP		  0x10000000
73 #define	  SDQCR_DCT_NUL		  0x00000000
74 #define	  SDQCR_DCT_PRI_PREC	  0x01000000
75 #define	  SDQCR_DCT_ACTIVE_WQ	  0x02000000
76 #define	  SDQCR_DCT_ACTIVE_FQ_O	  0x03000000
77 #define	  SDQCR_DCT_M		  0x03000000
78 #define	  SDQCR_TOKEN_M		  0x00ff0000
79 #define	  SDQCR_TOKEN_S		  16
80 #define	  DQRR_DQ_SRC_M		  0x0000ffff
81 #define	  DQRR_DQ_SRC_DCP	  0x00008000
82 #define	  SDQCR_DQ_SRC_CHAN(n)	  (0x8000 >> (n + 1))
83 #define	QCSP_DQRR_VDQCR		0x0058
84 #define	QCSP_DQRR_PDQCR		0x005c
85 #define	QCSP_MR_ITR		0x0088
86 #define	QCSP_CFG		0x0100
87 #define	  CFG_EST_M		  0x70000000
88 #define	  CFG_EST_S		  28
89 #define	  CFG_EP		  0x04000000
90 #define	  CFG_EPM_M		  0x03000000
91 #define	  CFG_EPM_PI_CI		  0x00000000
92 #define	  CFG_EPM_PI_CE		  0x01000000
93 #define	  CFG_EPM_VB1		  0x02000000
94 #define	  CFG_EPM_VB2		  0x03000000
95 #define	  CFG_DQRR_MF_M		  0x00f00000
96 #define	  CFG_DQRR_MF_S		  20
97 #define	  CFG_DP		  0x00040000
98 #define	  CFG_DCM_C_M		  0x00030000
99 #define	  CFG_DCM_CI_CI		  0x00000000
100 #define	  CFG_DCM_CI_CE		  0x00010000
101 #define	  CFG_DCM_DCA1		  0x00020000
102 #define	  CFG_DCM_DCA2		  0x00030000
103 #define	  CFG_SD		  0x00000200
104 #define	  CFG_MM		  0x00000100
105 #define	  CFG_RE		  0x00000080
106 #define	  CFG_RP		  0x00000040
107 #define	  CFG_SE		  0x00000020
108 #define	  CFG_SP		  0x00000010
109 #define	  CFG_SDEST_M		  0x00000007
110 #define	QCSP_ISR		0x0e00
111 #define	  QM_PIRQ_CSCI		  0x00100000
112 #define	  QM_PIRQ_EQCI		  0x00080000
113 #define	  QM_PIRQ_EQRI		  0x00040000
114 #define	  QM_PIRQ_DQRI		  0x00020000
115 #define	  QM_PIRQ_MRI		  0x00010000
116 #define	  QM_PIRQ_DQ_AVAIL_M	  0x0000ffff
117 #define	QCSP_IER		0x0e04
118 #define	QCSP_ISDR		0x0e08
119 #define	QCSP_IIR		0xe0c
120 #define	QCSP_ITPR		0x0e14
121 
122 #define	QM_EQCR_VERB_CMD_ENQUEUE	0x01
123 #define	QM_EQCR_VERB_BIT_INT		0x04
124 
125 #define	DEF_SDQCR_TOKEN		0xab
126 
127 static void qman_portal_loop_rings(struct qman_portal_softc *sc);
128 static void qman_portal_isr(void *);
129 
130 DPCPU_DEFINE(device_t, qman_affine_portal);
131 DPAA_RING(qman_eqcr, QMAN_EQCR_COUNT, QCSP_EQCR_PI_CENA, QCSP_EQCR_CI_CENA,
132 		QCSP_EQCR_PI_CINH, QCSP_EQCR_CI_CINH);
133 DPAA_RING(qman_dqrr, QMAN_DQRR_COUNT, QCSP_DQRR_PI_CENA, QCSP_DQRR_CI_CENA,
134 		QCSP_DQRR_PI_CINH, QCSP_DQRR_CI_CINH);
135 
136 /*
137  *  dqrr_ithresh: fire DQRR interrupt once N (of 16) dequeues queued (1-15)
138  *  mr_ithresh:   fire MR interrupt after N messages (1-7)
139  *  iperiod:      timer bound on interrupt latency, in units of 256 QMan
140  *                clocks (~32 us on typical QorIQ platform clock at 100)
141  */
142 static int qman_dqrr_ithresh = 12;
143 static int qman_mr_ithresh = 4;
144 static int qman_iperiod = 100;
145 
146 static void
qman_portal_update_reg(bus_size_t reg,uint32_t val)147 qman_portal_update_reg(bus_size_t reg, uint32_t val)
148 {
149 	struct qman_portal_softc *sc;
150 	device_t portal;
151 	int cpu;
152 
153 	CPU_FOREACH(cpu) {
154 		portal = DPCPU_ID_GET(cpu, qman_affine_portal);
155 		if (portal == NULL)
156 			continue;
157 		sc = device_get_softc(portal);
158 		bus_write_4(sc->sc_base.sc_mres[1], reg, val);
159 	}
160 }
161 
162 static int
qman_sysctl_reg(struct sysctl_oid * oidp,struct sysctl_req * req,int * var,int min,int max,bus_size_t reg)163 qman_sysctl_reg(struct sysctl_oid *oidp, struct sysctl_req *req,
164     int *var, int min, int max, bus_size_t reg)
165 {
166 	int val, error;
167 
168 	val = *var;
169 	error = sysctl_handle_int(oidp, &val, 0, req);
170 	if (error != 0 || req->newptr == NULL)
171 		return (error);
172 	if (val < min || val > max)
173 		return (EINVAL);
174 	*var = val;
175 	qman_portal_update_reg(reg, val);
176 	return (0);
177 }
178 
179 static int
qman_sysctl_dqrr_ithresh(SYSCTL_HANDLER_ARGS)180 qman_sysctl_dqrr_ithresh(SYSCTL_HANDLER_ARGS)
181 {
182 	return (qman_sysctl_reg(oidp, req,
183 	    &qman_dqrr_ithresh, 1, 15, QCSP_DQRR_ITR));
184 }
185 
186 static int
qman_sysctl_mr_ithresh(SYSCTL_HANDLER_ARGS)187 qman_sysctl_mr_ithresh(SYSCTL_HANDLER_ARGS)
188 {
189 	return (qman_sysctl_reg(oidp, req,
190 	    &qman_mr_ithresh, 1, 7, QCSP_MR_ITR));
191 }
192 
193 static int
qman_sysctl_iperiod(SYSCTL_HANDLER_ARGS)194 qman_sysctl_iperiod(SYSCTL_HANDLER_ARGS)
195 {
196 	return (qman_sysctl_reg(oidp, req,
197 	    &qman_iperiod, 1, 65535, QCSP_ITPR));
198 }
199 
200 SYSCTL_NODE(_hw, OID_AUTO, qman, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
201     "QMan portal tunables");
202 SYSCTL_PROC(_hw_qman, OID_AUTO, dqrr_ithresh,
203     CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
204     NULL, 0, qman_sysctl_dqrr_ithresh, "I",
205     "DQRR interrupt threshold (dequeues queued before interrupt; 1-15)");
206 SYSCTL_PROC(_hw_qman, OID_AUTO, mr_ithresh,
207     CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
208     NULL, 0, qman_sysctl_mr_ithresh, "I",
209     "Message Ring interrupt threshold (messages queued before interrupt; 1-7)");
210 SYSCTL_PROC(_hw_qman, OID_AUTO, iperiod,
211     CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
212     NULL, 0, qman_sysctl_iperiod, "I",
213     "Interrupt time period (units of 256 QMan clocks)");
214 
215 /*
216  * pmode: one of the CFG_EPM constants.
217  * stash_prio: 0 or CFG_EP
218  * stash_thresh: 0-7
219  */
220 static int
qman_eqcr_init(struct qman_portal_softc * sc,int pmode,u_int stash_thresh,u_int stash_prio)221 qman_eqcr_init(struct qman_portal_softc *sc, int pmode, u_int stash_thresh,
222     u_int stash_prio)
223 {
224 	struct resource *regs = sc->sc_base.sc_mres[1];
225 	uint32_t reg;
226 
227 	sc->sc_eqcr.ring =
228 	    (struct qman_eqcr_entry *)(sc->sc_base.sc_ce_va + QCSP_EQCR_N(0));
229 	qman_eqcr_ring_init(&sc->sc_eqcr, &sc->sc_base);
230 	reg = bus_read_4(regs, QCSP_CFG);
231 	reg &= 0x00ffffff;
232 	reg |= pmode;
233 	reg |= ((stash_thresh << CFG_EST_S) & CFG_EST_M);
234 	reg |= stash_prio;
235 
236 	bus_write_4(regs, QCSP_CFG, reg);
237 	return (0);
238 }
239 
240 static int
qman_dqrr_init(struct qman_portal_softc * sc)241 qman_dqrr_init(struct qman_portal_softc *sc)
242 {
243 	struct resource *regs = sc->sc_base.sc_mres[1];
244 	uint32_t reg;
245 
246 	/* Dequeue from the direct-connect channel and pool 0, up to 3 frames */
247 	bus_write_4(regs, QCSP_DQRR_SDQCR,
248 	    SDQCR_FC | SDQCR_DP | SDQCR_DCT_PRI_PREC |
249 	    (DEF_SDQCR_TOKEN << SDQCR_TOKEN_S) | DQRR_DQ_SRC_DCP);
250 	bus_write_4(regs, QCSP_DQRR_VDQCR, 0);
251 	bus_write_4(regs, QCSP_DQRR_PDQCR, 0);
252 
253 	sc->sc_dqrr.ring =
254 	    (struct qman_dqrr_entry *)(sc->sc_base.sc_ce_va + QCSP_DQRR_N(0));
255 	qman_dqrr_ring_init(&sc->sc_dqrr, &sc->sc_base);
256 
257 	/* Set DQRR max fill to 15 */
258 	reg = bus_read_4(regs, QCSP_CFG);
259 	reg |= (0xf << CFG_DQRR_MF_S);
260 	bus_write_4(regs, QCSP_CFG, reg);
261 
262 	for (int i = 0; i < QMAN_DQRR_COUNT; i++)
263 		__asm __volatile ("dcbi 0,%0" :: "r"(&sc->sc_dqrr.ring[i]) : "memory");
264 
265 	return (0);
266 }
267 
268 int
qman_portal_attach(device_t dev,int cpu)269 qman_portal_attach(device_t dev, int cpu)
270 {
271 	struct qman_portal_softc *sc = device_get_softc(dev);
272 	union qman_mc_command *cr;
273 	pcell_t cell;
274 	phandle_t node;
275 
276 	sc->sc_base.sc_cpu = cpu;
277 	dpaa_portal_alloc_res(dev, cpu);
278 
279 	qman_eqcr_init(sc, CFG_EPM_VB1, 0, 0);
280 	qman_dqrr_init(sc);
281 	bus_setup_intr(dev, sc->sc_base.sc_ires, INTR_TYPE_NET | INTR_MPSAFE,
282 	    NULL, qman_portal_isr, sc, &sc->sc_base.sc_intr_cookie);
283 	bus_bind_intr(dev, sc->sc_base.sc_ires, cpu);
284 
285 	node = ofw_bus_get_node(dev);
286 	if (OF_getencprop(node, "cell-index", &cell, sizeof(cell)) <= 0) {
287 		device_printf(dev, "missing 'cell-index' property\n");
288 		return (ENXIO);
289 	}
290 	sc->sc_affine_channel = cell;
291 	DPCPU_ID_SET(cpu, qman_affine_portal, dev);
292 
293 	/* Interrupt coalescing.  See tunables above. */
294 	bus_write_4(sc->sc_base.sc_mres[1], QCSP_DQRR_ITR, qman_dqrr_ithresh);
295 	bus_write_4(sc->sc_base.sc_mres[1], QCSP_MR_ITR, qman_mr_ithresh);
296 	bus_write_4(sc->sc_base.sc_mres[1], QCSP_ITPR, qman_iperiod);
297 
298 	bus_write_4(sc->sc_base.sc_mres[1], QCSP_IER,
299 	    QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI | QM_PIRQ_CSCI |
300 	    QM_PIRQ_DQRI);
301 	bus_write_4(sc->sc_base.sc_mres[1], QCSP_ISDR, 0);
302 
303 	/* Initialize the MC polarity bit, it may not be 0. */
304 	cr = (union qman_mc_command *)(sc->sc_base.sc_ce_va + QCSP_CR);
305 	sc->sc_mc.polarity =
306 	    (cr->common.verb & QMAN_MC_VERB_VBIT) ^ QMAN_MC_VERB_VBIT;
307 	/* TODO: LIODN.  Fake it for now */
308 
309 	qman_set_sdest(sc->sc_affine_channel, cpu);
310 
311 	return (0);
312 }
313 
314 
315 int
qman_portal_detach(device_t dev)316 qman_portal_detach(device_t dev)
317 {
318 	struct qman_portal_softc *sc;
319 	int i;
320 
321 	sc = device_get_softc(dev);
322 
323 	/* TODO: Unmap TLB regions */
324 	thread_lock(curthread);
325 	sched_bind(curthread, sc->sc_base.sc_cpu);
326 	thread_unlock(curthread);
327 
328 	if (sc->sc_base.sc_ires != NULL)
329 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_base.sc_ires);
330 
331 	for (i = 0; i < nitems(sc->sc_base.sc_mres); i++) {
332 		if (sc->sc_base.sc_mres[i] != NULL)
333 			bus_release_resource(dev, SYS_RES_MEMORY,
334 			    i, sc->sc_base.sc_mres[i]);
335 	}
336 	thread_lock(curthread);
337 	sched_unbind(curthread);
338 	thread_unlock(curthread);
339 
340 
341 	return (0);
342 }
343 
344 static void
qman_portal_isr(void * arg)345 qman_portal_isr(void *arg)
346 {
347 	struct qman_portal_softc *sc = arg;
348 
349 	qman_portal_loop_rings(sc);
350 }
351 
352 int
qman_portal_fq_enqueue(device_t dev,struct qman_fq * fq,struct dpaa_fd * frame)353 qman_portal_fq_enqueue(device_t dev, struct qman_fq *fq, struct dpaa_fd *frame)
354 {
355 	struct qman_portal_softc *sc = device_get_softc(dev);
356 	struct qman_eqcr_entry *eqcr;
357 
358 	/* Get available... */
359 	eqcr = qman_eqcr_start(&sc->sc_eqcr, &sc->sc_base);
360 	if (eqcr == NULL)
361 		return (EBUSY);
362 	eqcr->fd = *frame;
363 	eqcr->fqid = fq->fqid;
364 	qman_eqcr_commit(&sc->sc_eqcr, QM_EQCR_VERB_CMD_ENQUEUE);
365 
366 	return (0);
367 }
368 
369 static int
qman_portal_loop_dqrr(struct qman_portal_softc * sc)370 qman_portal_loop_dqrr(struct qman_portal_softc *sc)
371 {
372 	SLIST_HEAD(, qman_fq) dirty_fqs = SLIST_HEAD_INITIALIZER(dirty_fqs);
373 	struct qman_dqrr_entry *dqrr;
374 	struct qman_dqrr_entry *base;
375 	struct qman_fq *fq;
376 	int ci = bus_read_4(sc->sc_base.sc_mres[1], QCSP_DQRR_CI_CINH) &
377 	    DQRR_CI_CI_M;
378 	int pi = bus_read_4(sc->sc_base.sc_mres[1], QCSP_DQRR_PI_CINH) &
379 	    DQRR_PI_PI_M;
380 	int start_ci = ci;
381 
382 	base = sc->sc_dqrr.ring;
383 	do {
384 		dqrr = &base[ci];
385 		dpaa_flush_line(dqrr);
386 		dpaa_touch_line(dqrr);
387 		if ((dqrr->stat & QMAN_DQRR_STAT_HAS_FRAME) == 0)
388 			break;
389 
390 		fq = qman_fq_from_index(dqrr->fqid);
391 		if (fq != NULL && fq->cb.dqrr != NULL) {
392 			fq->cb.dqrr(sc->sc_base.sc_dev, fq,
393 			    &dqrr->fd, fq->cb.ctx);
394 			/*
395 			 * Track the FQ for post-poll flush.  Only need to track
396 			 * once.
397 			 */
398 			if (fq->cb.flush != NULL && !fq->dirty) {
399 				fq->dirty = true;
400 				SLIST_INSERT_HEAD(&dirty_fqs, fq,
401 				    dirty_next);
402 			}
403 		}
404 		ci = (ci + 1) & DQRR_CI_CI_M;
405 	} while (ci != pi);
406 
407 	/* Update CI after the loop.  CI writes are expensive. */
408 	if (ci != start_ci)
409 		bus_write_4(sc->sc_base.sc_mres[1], QCSP_DQRR_CI_CINH, ci);
410 
411 	/* Drain the dirty list, invoking the per-FQ flush hook. */
412 	while (!SLIST_EMPTY(&dirty_fqs)) {
413 		fq = SLIST_FIRST(&dirty_fqs);
414 		SLIST_REMOVE_HEAD(&dirty_fqs, dirty_next);
415 		fq->dirty = false;
416 		fq->cb.flush(fq, fq->cb.ctx);
417 	}
418 
419 	return (0);
420 }
421 
422 static void
qman_portal_loop_rings(struct qman_portal_softc * sc)423 qman_portal_loop_rings(struct qman_portal_softc *sc)
424 {
425 	uint32_t isr;
426 
427 	isr = bus_read_4(sc->sc_base.sc_mres[1], QCSP_ISR);
428 
429 	/* Handle DQRR first. */
430 	if ((isr & QM_PIRQ_DQRI)) {
431 		qman_portal_loop_dqrr(sc);
432 	}
433 	if ((isr & QM_PIRQ_CSCI)) {
434 	}
435 	if ((isr & QM_PIRQ_EQRI)) {
436 		qman_eqcr_update(&sc->sc_eqcr, &sc->sc_base);
437 	}
438 	bus_write_4(sc->sc_base.sc_mres[1], QCSP_ISR, isr);
439 }
440 
441 /* MC commands */
442 
443 /* Assumes pinned */
444 union qman_mc_result *
qman_portal_mc_send_raw(device_t dev,union qman_mc_command * c)445 qman_portal_mc_send_raw(device_t dev, union qman_mc_command *c)
446 {
447 	struct qman_portal_softc *sc;
448 	int res_idx;
449 	union qman_mc_result *rr;
450 	union qman_mc_command *cr;
451 	int timeout = 10000;
452 	uint8_t verb;
453 
454 	sc = device_get_softc(dev);
455 
456 	verb = c->common.verb;
457 	c->common.verb = 0;
458 	cr = (union qman_mc_command *)(sc->sc_base.sc_ce_va + QCSP_CR);
459 	dpaa_zero_line(cr);
460 	*cr = *c;
461 	dpaa_lw_barrier();
462 	cr->common.verb = verb | sc->sc_mc.polarity;
463 	res_idx = (sc->sc_mc.polarity ? 1 : 0);
464 	sc->sc_mc.polarity ^= QMAN_MC_VERB_VBIT;
465 	dpaa_flush_line(cr);
466 	dpaa_touch_line(cr);
467 
468 	rr = (union qman_mc_result *)(sc->sc_base.sc_ce_va + QCSP_RR(res_idx));
469 	for (; timeout > 0; --timeout) {
470 		dpaa_flush_line(rr);
471 		if (rr->common.verb != 0)
472 			break;
473 	}
474 	if (timeout == 0)
475 		return (NULL);
476 	return (rr);
477 }
478 
479 void
qman_portal_static_dequeue_channel(device_t dev,int channel)480 qman_portal_static_dequeue_channel(device_t dev, int channel)
481 {
482 	struct qman_portal_softc *sc = device_get_softc(dev);
483 	uint32_t reg;
484 
485 	reg = bus_read_4(sc->sc_base.sc_mres[1], QCSP_DQRR_SDQCR);
486 	reg |= (1 << (14 - (channel - qman_channel_base)));
487 	bus_write_4(sc->sc_base.sc_mres[1], QCSP_DQRR_SDQCR, reg);
488 }
489 
490 void
qman_portal_static_dequeue_rm_channel(device_t dev,int channel)491 qman_portal_static_dequeue_rm_channel(device_t dev, int channel)
492 {
493 	struct qman_portal_softc *sc = device_get_softc(dev);
494 	uint32_t reg;
495 
496 	reg = bus_read_4(sc->sc_base.sc_mres[1], QCSP_DQRR_SDQCR);
497 	reg &= ~(1 << (14 - (channel - qman_channel_base)));
498 	bus_write_4(sc->sc_base.sc_mres[1], QCSP_DQRR_SDQCR, reg);
499 }
500 
DB_SHOW_COMMAND(fqid,qman_show_fqid)501 DB_SHOW_COMMAND(fqid, qman_show_fqid)
502 {
503 	union qman_mc_command cmd;
504 	union qman_mc_result *res;
505 	union qman_mc_result save_res;
506 	device_t portal;
507 
508 	if (!have_addr)
509 		return;
510 
511 	bzero(&cmd, sizeof(cmd));
512 	cmd.query_fq_np.verb = QCSP_VERB_QUERY_FQ_NP;
513 	cmd.query_fq_np.fqid = addr;
514 
515 	/* Ensure we have got QMan port initialized */
516 	portal = DPCPU_GET(qman_affine_portal);
517 	res = qman_portal_mc_send_raw(portal, &cmd);
518 
519 	if (res != NULL)
520 		save_res = *res;
521 
522 	/* Dump all NP fields */
523 	if (res != NULL && save_res.query_fq_np.rslt == 0xf0) {
524 		db_printf("FQID: %d\n", (int)addr);
525 		db_printf("  Non-programmable:\n");
526 		db_printf("  State: %x\n", save_res.query_fq_np.state);
527 		db_printf("  Link: %x\n", save_res.query_fq_np.fqd_link);
528 		db_printf("  ODP_SEQ: %x\n", save_res.query_fq_np.odp_seq);
529 		db_printf("  ORP_NESN: %x\n", save_res.query_fq_np.orp_nesn);
530 		db_printf("  ORP_EA_HSEQ: %x\n",
531 		    save_res.query_fq_np.orp_ea_hseq);
532 		db_printf("  ORP_EA_TSEQ: %x\n",
533 		    save_res.query_fq_np.orp_ea_tseq);
534 		db_printf("  ORP_EA_HPTR: %x\n",
535 		    save_res.query_fq_np.orp_ea_hptr);
536 		db_printf("  ORP_EA_TPTR: %x\n",
537 		    save_res.query_fq_np.orp_ea_tptr);
538 		db_printf("  pfdr_hptr: %x\n", save_res.query_fq_np.pfdr_hptr);
539 		db_printf("  pfdr_tptr: %x\n", save_res.query_fq_np.pfdr_tptr);
540 		db_printf("  IS: %x\n", save_res.query_fq_np.is);
541 		db_printf("  ICS_SURP: %x\n", save_res.query_fq_np.ics_surp);
542 		db_printf("  byte_cnt: %x\n", save_res.query_fq_np.byte_cnt);
543 		db_printf("  frm_cnt: %x\n", save_res.query_fq_np.frm_cnt);
544 		db_printf("  ra1_sfdr: %x\n", save_res.query_fq_np.ra1_sfdr);
545 		db_printf("  ra2_sfdr: %x\n", save_res.query_fq_np.ra2_sfdr);
546 		db_printf("  od1_sfdr: %x\n", save_res.query_fq_np.od1_sfdr);
547 		db_printf("  od2_sfdr: %x\n", save_res.query_fq_np.od2_sfdr);
548 		db_printf("  od3_sfdr: %x\n", save_res.query_fq_np.od3_sfdr);
549 	}
550 
551 	bzero(&cmd, sizeof(cmd));
552 	cmd.query_fq.verb = QCSP_VERB_QUERY_FQ;
553 	cmd.query_fq.fqid = addr;
554 
555 	res = qman_portal_mc_send_raw(portal, &cmd);
556 	if (res != NULL)
557 		save_res = *res;
558 
559 	if (res != NULL && save_res.query_fq.rslt == 0xf0) {
560 		db_printf("  Programmable:\n");
561 		db_printf("  ORPC: %02x\n", save_res.query_fq.orpc);
562 		db_printf("  CGID: %02x\n", save_res.query_fq.cgid);
563 		db_printf("  FQ_CTRL: %04x\n", save_res.query_fq.fq_ctrl);
564 		db_printf("  DEST_WQ: %04x\n", save_res.query_fq.dest_wq);
565 		db_printf("  ICS_CRED: %04x\n", save_res.query_fq.ics_cred);
566 		db_printf("  TD_thresh: %04x\n", save_res.query_fq.td_thresh);
567 		db_printf("  Context_B: %08x\n", save_res.query_fq.context_b);
568 		db_printf("  Context_A: %16lx\n", save_res.query_fq.context_a);
569 		db_printf("  OAC: %04x\n", save_res.query_fq.oac);
570 	}
571 }
572