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