xref: /freebsd/sys/dev/dpaa/qman.c (revision 0aeed3e99367bed5755068d9218cd8041644ff2b)
1*0aeed3e9SJustin Hibbits /*-
2*0aeed3e9SJustin Hibbits  * Copyright (c) 2011-2012 Semihalf.
3*0aeed3e9SJustin Hibbits  * All rights reserved.
4*0aeed3e9SJustin Hibbits  *
5*0aeed3e9SJustin Hibbits  * Redistribution and use in source and binary forms, with or without
6*0aeed3e9SJustin Hibbits  * modification, are permitted provided that the following conditions
7*0aeed3e9SJustin Hibbits  * are met:
8*0aeed3e9SJustin Hibbits  * 1. Redistributions of source code must retain the above copyright
9*0aeed3e9SJustin Hibbits  *    notice, this list of conditions and the following disclaimer.
10*0aeed3e9SJustin Hibbits  * 2. Redistributions in binary form must reproduce the above copyright
11*0aeed3e9SJustin Hibbits  *    notice, this list of conditions and the following disclaimer in the
12*0aeed3e9SJustin Hibbits  *    documentation and/or other materials provided with the distribution.
13*0aeed3e9SJustin Hibbits  *
14*0aeed3e9SJustin Hibbits  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*0aeed3e9SJustin Hibbits  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*0aeed3e9SJustin Hibbits  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*0aeed3e9SJustin Hibbits  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*0aeed3e9SJustin Hibbits  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*0aeed3e9SJustin Hibbits  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*0aeed3e9SJustin Hibbits  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*0aeed3e9SJustin Hibbits  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*0aeed3e9SJustin Hibbits  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*0aeed3e9SJustin Hibbits  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*0aeed3e9SJustin Hibbits  * SUCH DAMAGE.
25*0aeed3e9SJustin Hibbits  */
26*0aeed3e9SJustin Hibbits 
27*0aeed3e9SJustin Hibbits #include <sys/cdefs.h>
28*0aeed3e9SJustin Hibbits __FBSDID("$FreeBSD$");
29*0aeed3e9SJustin Hibbits 
30*0aeed3e9SJustin Hibbits #include <sys/param.h>
31*0aeed3e9SJustin Hibbits #include <sys/systm.h>
32*0aeed3e9SJustin Hibbits #include <sys/kernel.h>
33*0aeed3e9SJustin Hibbits #include <sys/bus.h>
34*0aeed3e9SJustin Hibbits #include <sys/lock.h>
35*0aeed3e9SJustin Hibbits #include <sys/module.h>
36*0aeed3e9SJustin Hibbits #include <sys/mutex.h>
37*0aeed3e9SJustin Hibbits #include <sys/proc.h>
38*0aeed3e9SJustin Hibbits #include <sys/pcpu.h>
39*0aeed3e9SJustin Hibbits #include <sys/rman.h>
40*0aeed3e9SJustin Hibbits #include <sys/sched.h>
41*0aeed3e9SJustin Hibbits #include <sys/smp.h>
42*0aeed3e9SJustin Hibbits 
43*0aeed3e9SJustin Hibbits #include <machine/bus.h>
44*0aeed3e9SJustin Hibbits #include <machine/resource.h>
45*0aeed3e9SJustin Hibbits #include <machine/tlb.h>
46*0aeed3e9SJustin Hibbits 
47*0aeed3e9SJustin Hibbits #include "qman.h"
48*0aeed3e9SJustin Hibbits #include "portals.h"
49*0aeed3e9SJustin Hibbits 
50*0aeed3e9SJustin Hibbits extern struct dpaa_portals_softc *qp_sc;
51*0aeed3e9SJustin Hibbits static struct qman_softc *qman_sc;
52*0aeed3e9SJustin Hibbits 
53*0aeed3e9SJustin Hibbits extern t_Handle qman_portal_setup(struct qman_softc *qsc);
54*0aeed3e9SJustin Hibbits 
55*0aeed3e9SJustin Hibbits static void
56*0aeed3e9SJustin Hibbits qman_exception(t_Handle app, e_QmExceptions exception)
57*0aeed3e9SJustin Hibbits {
58*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
59*0aeed3e9SJustin Hibbits 	const char *message;
60*0aeed3e9SJustin Hibbits 
61*0aeed3e9SJustin Hibbits 	sc = app;
62*0aeed3e9SJustin Hibbits 
63*0aeed3e9SJustin Hibbits 	switch (exception) {
64*0aeed3e9SJustin Hibbits 	case e_QM_EX_CORENET_INITIATOR_DATA:
65*0aeed3e9SJustin Hibbits 		message = "Initiator Data Error";
66*0aeed3e9SJustin Hibbits 		break;
67*0aeed3e9SJustin Hibbits 	case e_QM_EX_CORENET_TARGET_DATA:
68*0aeed3e9SJustin Hibbits 		message = "CoreNet Target Data Error";
69*0aeed3e9SJustin Hibbits 		break;
70*0aeed3e9SJustin Hibbits 	case e_QM_EX_CORENET_INVALID_TARGET_TRANSACTION:
71*0aeed3e9SJustin Hibbits 		message = "Invalid Target Transaction";
72*0aeed3e9SJustin Hibbits 		break;
73*0aeed3e9SJustin Hibbits 	case e_QM_EX_PFDR_THRESHOLD:
74*0aeed3e9SJustin Hibbits 		message = "PFDR Low Watermark Interrupt";
75*0aeed3e9SJustin Hibbits 		break;
76*0aeed3e9SJustin Hibbits 	case e_QM_EX_PFDR_ENQUEUE_BLOCKED:
77*0aeed3e9SJustin Hibbits 		message = "PFDR Enqueues Blocked Interrupt";
78*0aeed3e9SJustin Hibbits 		break;
79*0aeed3e9SJustin Hibbits 	case e_QM_EX_SINGLE_ECC:
80*0aeed3e9SJustin Hibbits 		message = "Single Bit ECC Error Interrupt";
81*0aeed3e9SJustin Hibbits 		break;
82*0aeed3e9SJustin Hibbits 	case e_QM_EX_MULTI_ECC:
83*0aeed3e9SJustin Hibbits 		message = "Multi Bit ECC Error Interrupt";
84*0aeed3e9SJustin Hibbits 		break;
85*0aeed3e9SJustin Hibbits 	case e_QM_EX_INVALID_COMMAND:
86*0aeed3e9SJustin Hibbits 		message = "Invalid Command Verb Interrupt";
87*0aeed3e9SJustin Hibbits 		break;
88*0aeed3e9SJustin Hibbits 	case e_QM_EX_DEQUEUE_DCP:
89*0aeed3e9SJustin Hibbits 		message = "Invalid Dequeue Direct Connect Portal Interrupt";
90*0aeed3e9SJustin Hibbits 		break;
91*0aeed3e9SJustin Hibbits 	case e_QM_EX_DEQUEUE_FQ:
92*0aeed3e9SJustin Hibbits 		message = "Invalid Dequeue FQ Interrupt";
93*0aeed3e9SJustin Hibbits 		break;
94*0aeed3e9SJustin Hibbits 	case e_QM_EX_DEQUEUE_SOURCE:
95*0aeed3e9SJustin Hibbits 		message = "Invalid Dequeue Source Interrupt";
96*0aeed3e9SJustin Hibbits 		break;
97*0aeed3e9SJustin Hibbits 	case e_QM_EX_DEQUEUE_QUEUE:
98*0aeed3e9SJustin Hibbits 		message = "Invalid Dequeue Queue Interrupt";
99*0aeed3e9SJustin Hibbits 		break;
100*0aeed3e9SJustin Hibbits 	case e_QM_EX_ENQUEUE_OVERFLOW:
101*0aeed3e9SJustin Hibbits 		message = "Invalid Enqueue Overflow Interrupt";
102*0aeed3e9SJustin Hibbits 		break;
103*0aeed3e9SJustin Hibbits 	case e_QM_EX_ENQUEUE_STATE:
104*0aeed3e9SJustin Hibbits 		message = "Invalid Enqueue State Interrupt";
105*0aeed3e9SJustin Hibbits 		break;
106*0aeed3e9SJustin Hibbits 	case e_QM_EX_ENQUEUE_CHANNEL:
107*0aeed3e9SJustin Hibbits 		message = "Invalid Enqueue Channel Interrupt";
108*0aeed3e9SJustin Hibbits 		break;
109*0aeed3e9SJustin Hibbits 	case e_QM_EX_ENQUEUE_QUEUE:
110*0aeed3e9SJustin Hibbits 		message = "Invalid Enqueue Queue Interrupt";
111*0aeed3e9SJustin Hibbits 		break;
112*0aeed3e9SJustin Hibbits 	case e_QM_EX_CG_STATE_CHANGE:
113*0aeed3e9SJustin Hibbits 		message = "CG change state notification";
114*0aeed3e9SJustin Hibbits 		break;
115*0aeed3e9SJustin Hibbits 	default:
116*0aeed3e9SJustin Hibbits 		message = "Unknown error";
117*0aeed3e9SJustin Hibbits 	}
118*0aeed3e9SJustin Hibbits 
119*0aeed3e9SJustin Hibbits 	device_printf(sc->sc_dev, "QMan Exception: %s.\n", message);
120*0aeed3e9SJustin Hibbits }
121*0aeed3e9SJustin Hibbits 
122*0aeed3e9SJustin Hibbits /**
123*0aeed3e9SJustin Hibbits  * General received frame callback.
124*0aeed3e9SJustin Hibbits  * This is called, when user did not register his own callback for a given
125*0aeed3e9SJustin Hibbits  * frame queue range (fqr).
126*0aeed3e9SJustin Hibbits  */
127*0aeed3e9SJustin Hibbits e_RxStoreResponse
128*0aeed3e9SJustin Hibbits qman_received_frame_callback(t_Handle app, t_Handle qm_fqr, t_Handle qm_portal,
129*0aeed3e9SJustin Hibbits     uint32_t fqid_offset, t_DpaaFD *frame)
130*0aeed3e9SJustin Hibbits {
131*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
132*0aeed3e9SJustin Hibbits 
133*0aeed3e9SJustin Hibbits 	sc = app;
134*0aeed3e9SJustin Hibbits 
135*0aeed3e9SJustin Hibbits 	device_printf(sc->sc_dev, "dummy callback for received frame.\n");
136*0aeed3e9SJustin Hibbits 	return (e_RX_STORE_RESPONSE_CONTINUE);
137*0aeed3e9SJustin Hibbits }
138*0aeed3e9SJustin Hibbits 
139*0aeed3e9SJustin Hibbits /**
140*0aeed3e9SJustin Hibbits  * General rejected frame callback.
141*0aeed3e9SJustin Hibbits  * This is called, when user did not register his own callback for a given
142*0aeed3e9SJustin Hibbits  * frame queue range (fqr).
143*0aeed3e9SJustin Hibbits  */
144*0aeed3e9SJustin Hibbits e_RxStoreResponse
145*0aeed3e9SJustin Hibbits qman_rejected_frame_callback(t_Handle app, t_Handle qm_fqr, t_Handle qm_portal,
146*0aeed3e9SJustin Hibbits     uint32_t fqid_offset, t_DpaaFD *frame,
147*0aeed3e9SJustin Hibbits     t_QmRejectedFrameInfo *qm_rejected_frame_info)
148*0aeed3e9SJustin Hibbits {
149*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
150*0aeed3e9SJustin Hibbits 
151*0aeed3e9SJustin Hibbits 	sc = app;
152*0aeed3e9SJustin Hibbits 
153*0aeed3e9SJustin Hibbits 	device_printf(sc->sc_dev, "dummy callback for rejected frame.\n");
154*0aeed3e9SJustin Hibbits 	return (e_RX_STORE_RESPONSE_CONTINUE);
155*0aeed3e9SJustin Hibbits }
156*0aeed3e9SJustin Hibbits 
157*0aeed3e9SJustin Hibbits int
158*0aeed3e9SJustin Hibbits qman_attach(device_t dev)
159*0aeed3e9SJustin Hibbits {
160*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
161*0aeed3e9SJustin Hibbits 	t_QmParam qp;
162*0aeed3e9SJustin Hibbits 	t_Error error;
163*0aeed3e9SJustin Hibbits 	t_QmRevisionInfo rev;
164*0aeed3e9SJustin Hibbits 
165*0aeed3e9SJustin Hibbits 	sc = device_get_softc(dev);
166*0aeed3e9SJustin Hibbits 	sc->sc_dev = dev;
167*0aeed3e9SJustin Hibbits 	qman_sc = sc;
168*0aeed3e9SJustin Hibbits 
169*0aeed3e9SJustin Hibbits 	if (XX_MallocSmartInit() != E_OK) {
170*0aeed3e9SJustin Hibbits 		device_printf(dev, "could not initialize smart allocator.\n");
171*0aeed3e9SJustin Hibbits 		return (ENXIO);
172*0aeed3e9SJustin Hibbits 	}
173*0aeed3e9SJustin Hibbits 
174*0aeed3e9SJustin Hibbits 	sched_pin();
175*0aeed3e9SJustin Hibbits 
176*0aeed3e9SJustin Hibbits 	/* Allocate resources */
177*0aeed3e9SJustin Hibbits 	sc->sc_rrid = 0;
178*0aeed3e9SJustin Hibbits 	sc->sc_rres = bus_alloc_resource(dev, SYS_RES_MEMORY,
179*0aeed3e9SJustin Hibbits 	    &sc->sc_rrid, 0, ~0, QMAN_CCSR_SIZE, RF_ACTIVE);
180*0aeed3e9SJustin Hibbits 	if (sc->sc_rres == NULL) {
181*0aeed3e9SJustin Hibbits 		device_printf(dev, "could not allocate memory.\n");
182*0aeed3e9SJustin Hibbits 		goto err;
183*0aeed3e9SJustin Hibbits 	}
184*0aeed3e9SJustin Hibbits 
185*0aeed3e9SJustin Hibbits 	sc->sc_irid = 0;
186*0aeed3e9SJustin Hibbits 	sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
187*0aeed3e9SJustin Hibbits 	    &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE);
188*0aeed3e9SJustin Hibbits 	if (sc->sc_ires == NULL) {
189*0aeed3e9SJustin Hibbits 		device_printf(dev, "could not allocate error interrupt.\n");
190*0aeed3e9SJustin Hibbits 		goto err;
191*0aeed3e9SJustin Hibbits 	}
192*0aeed3e9SJustin Hibbits 
193*0aeed3e9SJustin Hibbits 	if (qp_sc == NULL)
194*0aeed3e9SJustin Hibbits 		goto err;
195*0aeed3e9SJustin Hibbits 
196*0aeed3e9SJustin Hibbits 	dpaa_portal_map_registers(qp_sc);
197*0aeed3e9SJustin Hibbits 
198*0aeed3e9SJustin Hibbits 	/* Initialize QMan */
199*0aeed3e9SJustin Hibbits 	qp.guestId = NCSW_MASTER_ID;
200*0aeed3e9SJustin Hibbits 	qp.baseAddress = rman_get_bushandle(sc->sc_rres);
201*0aeed3e9SJustin Hibbits 	qp.swPortalsBaseAddress = rman_get_bushandle(qp_sc->sc_rres[0]);
202*0aeed3e9SJustin Hibbits 	qp.liodn = 0;
203*0aeed3e9SJustin Hibbits 	qp.totalNumOfFqids = QMAN_MAX_FQIDS;
204*0aeed3e9SJustin Hibbits 	qp.fqdMemPartitionId = NCSW_MASTER_ID;
205*0aeed3e9SJustin Hibbits 	qp.pfdrMemPartitionId = NCSW_MASTER_ID;
206*0aeed3e9SJustin Hibbits 	qp.f_Exception = qman_exception;
207*0aeed3e9SJustin Hibbits 	qp.h_App = sc;
208*0aeed3e9SJustin Hibbits 	qp.errIrq = (int)sc->sc_ires;
209*0aeed3e9SJustin Hibbits 	qp.partFqidBase = QMAN_FQID_BASE;
210*0aeed3e9SJustin Hibbits 	qp.partNumOfFqids = QMAN_MAX_FQIDS;
211*0aeed3e9SJustin Hibbits 	qp.partCgsBase = 0;
212*0aeed3e9SJustin Hibbits 	qp.partNumOfCgs = 0;
213*0aeed3e9SJustin Hibbits 
214*0aeed3e9SJustin Hibbits 	sc->sc_qh = QM_Config(&qp);
215*0aeed3e9SJustin Hibbits 	if (sc->sc_qh == NULL) {
216*0aeed3e9SJustin Hibbits 		device_printf(dev, "could not be configured\n");
217*0aeed3e9SJustin Hibbits 		goto err;
218*0aeed3e9SJustin Hibbits 	}
219*0aeed3e9SJustin Hibbits 
220*0aeed3e9SJustin Hibbits 	error = QM_Init(sc->sc_qh);
221*0aeed3e9SJustin Hibbits 	if (error != E_OK) {
222*0aeed3e9SJustin Hibbits 		device_printf(dev, "could not be initialized\n");
223*0aeed3e9SJustin Hibbits 		goto err;
224*0aeed3e9SJustin Hibbits 	}
225*0aeed3e9SJustin Hibbits 
226*0aeed3e9SJustin Hibbits 	error = QM_GetRevision(sc->sc_qh, &rev);
227*0aeed3e9SJustin Hibbits 	if (error != E_OK) {
228*0aeed3e9SJustin Hibbits 		device_printf(dev, "could not get QMan revision\n");
229*0aeed3e9SJustin Hibbits 		goto err;
230*0aeed3e9SJustin Hibbits 	}
231*0aeed3e9SJustin Hibbits 
232*0aeed3e9SJustin Hibbits 	device_printf(dev, "Hardware version: %d.%d.\n",
233*0aeed3e9SJustin Hibbits 	    rev.majorRev, rev.minorRev);
234*0aeed3e9SJustin Hibbits 
235*0aeed3e9SJustin Hibbits 	sched_unpin();
236*0aeed3e9SJustin Hibbits 
237*0aeed3e9SJustin Hibbits 	qman_portal_setup(sc);
238*0aeed3e9SJustin Hibbits 
239*0aeed3e9SJustin Hibbits 	return (0);
240*0aeed3e9SJustin Hibbits 
241*0aeed3e9SJustin Hibbits err:
242*0aeed3e9SJustin Hibbits 	sched_unpin();
243*0aeed3e9SJustin Hibbits 	qman_detach(dev);
244*0aeed3e9SJustin Hibbits 	return (ENXIO);
245*0aeed3e9SJustin Hibbits }
246*0aeed3e9SJustin Hibbits 
247*0aeed3e9SJustin Hibbits int
248*0aeed3e9SJustin Hibbits qman_detach(device_t dev)
249*0aeed3e9SJustin Hibbits {
250*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
251*0aeed3e9SJustin Hibbits 
252*0aeed3e9SJustin Hibbits 	sc = device_get_softc(dev);
253*0aeed3e9SJustin Hibbits 
254*0aeed3e9SJustin Hibbits 	if (sc->sc_qh)
255*0aeed3e9SJustin Hibbits 		QM_Free(sc->sc_qh);
256*0aeed3e9SJustin Hibbits 
257*0aeed3e9SJustin Hibbits 	if (sc->sc_ires != NULL)
258*0aeed3e9SJustin Hibbits 		XX_DeallocIntr((int)sc->sc_ires);
259*0aeed3e9SJustin Hibbits 
260*0aeed3e9SJustin Hibbits 	if (sc->sc_ires != NULL)
261*0aeed3e9SJustin Hibbits 		bus_release_resource(dev, SYS_RES_IRQ,
262*0aeed3e9SJustin Hibbits 		    sc->sc_irid, sc->sc_ires);
263*0aeed3e9SJustin Hibbits 
264*0aeed3e9SJustin Hibbits 	if (sc->sc_rres != NULL)
265*0aeed3e9SJustin Hibbits 		bus_release_resource(dev, SYS_RES_MEMORY,
266*0aeed3e9SJustin Hibbits 		    sc->sc_rrid, sc->sc_rres);
267*0aeed3e9SJustin Hibbits 
268*0aeed3e9SJustin Hibbits 	return (0);
269*0aeed3e9SJustin Hibbits }
270*0aeed3e9SJustin Hibbits 
271*0aeed3e9SJustin Hibbits int
272*0aeed3e9SJustin Hibbits qman_suspend(device_t dev)
273*0aeed3e9SJustin Hibbits {
274*0aeed3e9SJustin Hibbits 
275*0aeed3e9SJustin Hibbits 	return (0);
276*0aeed3e9SJustin Hibbits }
277*0aeed3e9SJustin Hibbits 
278*0aeed3e9SJustin Hibbits int
279*0aeed3e9SJustin Hibbits qman_resume(device_t dev)
280*0aeed3e9SJustin Hibbits {
281*0aeed3e9SJustin Hibbits 
282*0aeed3e9SJustin Hibbits 	return (0);
283*0aeed3e9SJustin Hibbits }
284*0aeed3e9SJustin Hibbits 
285*0aeed3e9SJustin Hibbits int
286*0aeed3e9SJustin Hibbits qman_shutdown(device_t dev)
287*0aeed3e9SJustin Hibbits {
288*0aeed3e9SJustin Hibbits 
289*0aeed3e9SJustin Hibbits 	return (0);
290*0aeed3e9SJustin Hibbits }
291*0aeed3e9SJustin Hibbits 
292*0aeed3e9SJustin Hibbits 
293*0aeed3e9SJustin Hibbits /**
294*0aeed3e9SJustin Hibbits  * @group QMan API functions implementation.
295*0aeed3e9SJustin Hibbits  * @{
296*0aeed3e9SJustin Hibbits  */
297*0aeed3e9SJustin Hibbits 
298*0aeed3e9SJustin Hibbits t_Handle
299*0aeed3e9SJustin Hibbits qman_fqr_create(uint32_t fqids_num, e_QmFQChannel channel, uint8_t wq,
300*0aeed3e9SJustin Hibbits     bool force_fqid, uint32_t fqid_or_align, bool init_parked,
301*0aeed3e9SJustin Hibbits     bool hold_active, bool prefer_in_cache, bool congst_avoid_ena,
302*0aeed3e9SJustin Hibbits     t_Handle congst_group, int8_t overhead_accounting_len,
303*0aeed3e9SJustin Hibbits     uint32_t tail_drop_threshold)
304*0aeed3e9SJustin Hibbits {
305*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
306*0aeed3e9SJustin Hibbits 	t_QmFqrParams fqr;
307*0aeed3e9SJustin Hibbits 	unsigned int cpu;
308*0aeed3e9SJustin Hibbits 	t_Handle fqrh, portal;
309*0aeed3e9SJustin Hibbits 
310*0aeed3e9SJustin Hibbits 	sc = qman_sc;
311*0aeed3e9SJustin Hibbits 
312*0aeed3e9SJustin Hibbits 	sched_pin();
313*0aeed3e9SJustin Hibbits 	cpu = PCPU_GET(cpuid);
314*0aeed3e9SJustin Hibbits 
315*0aeed3e9SJustin Hibbits 	/* Ensure we have got QMan port initialized */
316*0aeed3e9SJustin Hibbits 	portal = qman_portal_setup(sc);
317*0aeed3e9SJustin Hibbits 	if (portal == NULL) {
318*0aeed3e9SJustin Hibbits 		device_printf(sc->sc_dev, "could not setup QMan portal\n");
319*0aeed3e9SJustin Hibbits 		goto err;
320*0aeed3e9SJustin Hibbits 	}
321*0aeed3e9SJustin Hibbits 
322*0aeed3e9SJustin Hibbits 	fqr.h_Qm = sc->sc_qh;
323*0aeed3e9SJustin Hibbits 	fqr.h_QmPortal = portal;
324*0aeed3e9SJustin Hibbits 	fqr.initParked = init_parked;
325*0aeed3e9SJustin Hibbits 	fqr.holdActive = hold_active;
326*0aeed3e9SJustin Hibbits 	fqr.preferInCache = prefer_in_cache;
327*0aeed3e9SJustin Hibbits 
328*0aeed3e9SJustin Hibbits 	/* We do not support stashing */
329*0aeed3e9SJustin Hibbits 	fqr.useContextAForStash = FALSE;
330*0aeed3e9SJustin Hibbits 	fqr.p_ContextA = 0;
331*0aeed3e9SJustin Hibbits 	fqr.p_ContextB = 0;
332*0aeed3e9SJustin Hibbits 
333*0aeed3e9SJustin Hibbits 	fqr.channel = channel;
334*0aeed3e9SJustin Hibbits 	fqr.wq = wq;
335*0aeed3e9SJustin Hibbits 	fqr.shadowMode = FALSE;
336*0aeed3e9SJustin Hibbits 	fqr.numOfFqids = fqids_num;
337*0aeed3e9SJustin Hibbits 
338*0aeed3e9SJustin Hibbits 	/* FQID */
339*0aeed3e9SJustin Hibbits 	fqr.useForce = force_fqid;
340*0aeed3e9SJustin Hibbits 	if (force_fqid) {
341*0aeed3e9SJustin Hibbits 		fqr.qs.frcQ.fqid = fqid_or_align;
342*0aeed3e9SJustin Hibbits 	} else {
343*0aeed3e9SJustin Hibbits 		fqr.qs.nonFrcQs.align = fqid_or_align;
344*0aeed3e9SJustin Hibbits 	}
345*0aeed3e9SJustin Hibbits 
346*0aeed3e9SJustin Hibbits 	/* Congestion Avoidance */
347*0aeed3e9SJustin Hibbits 	fqr.congestionAvoidanceEnable = congst_avoid_ena;
348*0aeed3e9SJustin Hibbits 	if (congst_avoid_ena) {
349*0aeed3e9SJustin Hibbits 		fqr.congestionAvoidanceParams.h_QmCg = congst_group;
350*0aeed3e9SJustin Hibbits 		fqr.congestionAvoidanceParams.overheadAccountingLength =
351*0aeed3e9SJustin Hibbits 		    overhead_accounting_len;
352*0aeed3e9SJustin Hibbits 		fqr.congestionAvoidanceParams.fqTailDropThreshold =
353*0aeed3e9SJustin Hibbits 		    tail_drop_threshold;
354*0aeed3e9SJustin Hibbits 	} else {
355*0aeed3e9SJustin Hibbits 		fqr.congestionAvoidanceParams.h_QmCg = 0;
356*0aeed3e9SJustin Hibbits 		fqr.congestionAvoidanceParams.overheadAccountingLength = 0;
357*0aeed3e9SJustin Hibbits 		fqr.congestionAvoidanceParams.fqTailDropThreshold = 0;
358*0aeed3e9SJustin Hibbits 	}
359*0aeed3e9SJustin Hibbits 
360*0aeed3e9SJustin Hibbits 	fqrh = QM_FQR_Create(&fqr);
361*0aeed3e9SJustin Hibbits 	if (fqrh == NULL) {
362*0aeed3e9SJustin Hibbits 		device_printf(sc->sc_dev, "could not create Frame Queue Range"
363*0aeed3e9SJustin Hibbits 		    "\n");
364*0aeed3e9SJustin Hibbits 		goto err;
365*0aeed3e9SJustin Hibbits 	}
366*0aeed3e9SJustin Hibbits 
367*0aeed3e9SJustin Hibbits 	sc->sc_fqr_cpu[QM_FQR_GetFqid(fqrh)] = PCPU_GET(cpuid);
368*0aeed3e9SJustin Hibbits 
369*0aeed3e9SJustin Hibbits 	sched_unpin();
370*0aeed3e9SJustin Hibbits 
371*0aeed3e9SJustin Hibbits 	return (fqrh);
372*0aeed3e9SJustin Hibbits 
373*0aeed3e9SJustin Hibbits err:
374*0aeed3e9SJustin Hibbits 	sched_unpin();
375*0aeed3e9SJustin Hibbits 
376*0aeed3e9SJustin Hibbits 	return (NULL);
377*0aeed3e9SJustin Hibbits }
378*0aeed3e9SJustin Hibbits 
379*0aeed3e9SJustin Hibbits t_Error
380*0aeed3e9SJustin Hibbits qman_fqr_free(t_Handle fqr)
381*0aeed3e9SJustin Hibbits {
382*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
383*0aeed3e9SJustin Hibbits 	t_Error error;
384*0aeed3e9SJustin Hibbits 
385*0aeed3e9SJustin Hibbits 	sc = qman_sc;
386*0aeed3e9SJustin Hibbits 	thread_lock(curthread);
387*0aeed3e9SJustin Hibbits 	sched_bind(curthread, sc->sc_fqr_cpu[QM_FQR_GetFqid(fqr)]);
388*0aeed3e9SJustin Hibbits 	thread_unlock(curthread);
389*0aeed3e9SJustin Hibbits 
390*0aeed3e9SJustin Hibbits 	error = QM_FQR_Free(fqr);
391*0aeed3e9SJustin Hibbits 
392*0aeed3e9SJustin Hibbits 	thread_lock(curthread);
393*0aeed3e9SJustin Hibbits 	sched_unbind(curthread);
394*0aeed3e9SJustin Hibbits 	thread_unlock(curthread);
395*0aeed3e9SJustin Hibbits 
396*0aeed3e9SJustin Hibbits 	return (error);
397*0aeed3e9SJustin Hibbits }
398*0aeed3e9SJustin Hibbits 
399*0aeed3e9SJustin Hibbits t_Error
400*0aeed3e9SJustin Hibbits qman_fqr_register_cb(t_Handle fqr, t_QmReceivedFrameCallback *callback,
401*0aeed3e9SJustin Hibbits     t_Handle app)
402*0aeed3e9SJustin Hibbits {
403*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
404*0aeed3e9SJustin Hibbits 	t_Error error;
405*0aeed3e9SJustin Hibbits 	t_Handle portal;
406*0aeed3e9SJustin Hibbits 
407*0aeed3e9SJustin Hibbits 	sc = qman_sc;
408*0aeed3e9SJustin Hibbits 	sched_pin();
409*0aeed3e9SJustin Hibbits 
410*0aeed3e9SJustin Hibbits 	/* Ensure we have got QMan port initialized */
411*0aeed3e9SJustin Hibbits 	portal = qman_portal_setup(sc);
412*0aeed3e9SJustin Hibbits 	if (portal == NULL) {
413*0aeed3e9SJustin Hibbits 		device_printf(sc->sc_dev, "could not setup QMan portal\n");
414*0aeed3e9SJustin Hibbits 		sched_unpin();
415*0aeed3e9SJustin Hibbits 		return (E_NOT_SUPPORTED);
416*0aeed3e9SJustin Hibbits 	}
417*0aeed3e9SJustin Hibbits 
418*0aeed3e9SJustin Hibbits 	error = QM_FQR_RegisterCB(fqr, callback, app);
419*0aeed3e9SJustin Hibbits 
420*0aeed3e9SJustin Hibbits 	sched_unpin();
421*0aeed3e9SJustin Hibbits 
422*0aeed3e9SJustin Hibbits 	return (error);
423*0aeed3e9SJustin Hibbits }
424*0aeed3e9SJustin Hibbits 
425*0aeed3e9SJustin Hibbits t_Error
426*0aeed3e9SJustin Hibbits qman_fqr_enqueue(t_Handle fqr, uint32_t fqid_off, t_DpaaFD *frame)
427*0aeed3e9SJustin Hibbits {
428*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
429*0aeed3e9SJustin Hibbits 	t_Error error;
430*0aeed3e9SJustin Hibbits 	t_Handle portal;
431*0aeed3e9SJustin Hibbits 
432*0aeed3e9SJustin Hibbits 	sc = qman_sc;
433*0aeed3e9SJustin Hibbits 	sched_pin();
434*0aeed3e9SJustin Hibbits 
435*0aeed3e9SJustin Hibbits 	/* Ensure we have got QMan port initialized */
436*0aeed3e9SJustin Hibbits 	portal = qman_portal_setup(sc);
437*0aeed3e9SJustin Hibbits 	if (portal == NULL) {
438*0aeed3e9SJustin Hibbits 		device_printf(sc->sc_dev, "could not setup QMan portal\n");
439*0aeed3e9SJustin Hibbits 		sched_unpin();
440*0aeed3e9SJustin Hibbits 		return (E_NOT_SUPPORTED);
441*0aeed3e9SJustin Hibbits 	}
442*0aeed3e9SJustin Hibbits 
443*0aeed3e9SJustin Hibbits 	error = QM_FQR_Enqueue(fqr, portal, fqid_off, frame);
444*0aeed3e9SJustin Hibbits 
445*0aeed3e9SJustin Hibbits 	sched_unpin();
446*0aeed3e9SJustin Hibbits 
447*0aeed3e9SJustin Hibbits 	return (error);
448*0aeed3e9SJustin Hibbits }
449*0aeed3e9SJustin Hibbits 
450*0aeed3e9SJustin Hibbits uint32_t
451*0aeed3e9SJustin Hibbits qman_fqr_get_counter(t_Handle fqr, uint32_t fqid_off,
452*0aeed3e9SJustin Hibbits     e_QmFqrCounters counter)
453*0aeed3e9SJustin Hibbits {
454*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
455*0aeed3e9SJustin Hibbits 	uint32_t val;
456*0aeed3e9SJustin Hibbits 	t_Handle portal;
457*0aeed3e9SJustin Hibbits 
458*0aeed3e9SJustin Hibbits 	sc = qman_sc;
459*0aeed3e9SJustin Hibbits 	sched_pin();
460*0aeed3e9SJustin Hibbits 
461*0aeed3e9SJustin Hibbits 	/* Ensure we have got QMan port initialized */
462*0aeed3e9SJustin Hibbits 	portal = qman_portal_setup(sc);
463*0aeed3e9SJustin Hibbits 	if (portal == NULL) {
464*0aeed3e9SJustin Hibbits 		device_printf(sc->sc_dev, "could not setup QMan portal\n");
465*0aeed3e9SJustin Hibbits 		sched_unpin();
466*0aeed3e9SJustin Hibbits 		return (0);
467*0aeed3e9SJustin Hibbits 	}
468*0aeed3e9SJustin Hibbits 
469*0aeed3e9SJustin Hibbits 	val = QM_FQR_GetCounter(fqr, portal, fqid_off, counter);
470*0aeed3e9SJustin Hibbits 
471*0aeed3e9SJustin Hibbits 	sched_unpin();
472*0aeed3e9SJustin Hibbits 
473*0aeed3e9SJustin Hibbits 	return (val);
474*0aeed3e9SJustin Hibbits }
475*0aeed3e9SJustin Hibbits 
476*0aeed3e9SJustin Hibbits t_Error
477*0aeed3e9SJustin Hibbits qman_fqr_pull_frame(t_Handle fqr, uint32_t fqid_off, t_DpaaFD *frame)
478*0aeed3e9SJustin Hibbits {
479*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
480*0aeed3e9SJustin Hibbits 	t_Error error;
481*0aeed3e9SJustin Hibbits 	t_Handle portal;
482*0aeed3e9SJustin Hibbits 
483*0aeed3e9SJustin Hibbits 	sc = qman_sc;
484*0aeed3e9SJustin Hibbits 	sched_pin();
485*0aeed3e9SJustin Hibbits 
486*0aeed3e9SJustin Hibbits 	/* Ensure we have got QMan port initialized */
487*0aeed3e9SJustin Hibbits 	portal = qman_portal_setup(sc);
488*0aeed3e9SJustin Hibbits 	if (portal == NULL) {
489*0aeed3e9SJustin Hibbits 		device_printf(sc->sc_dev, "could not setup QMan portal\n");
490*0aeed3e9SJustin Hibbits 		sched_unpin();
491*0aeed3e9SJustin Hibbits 		return (E_NOT_SUPPORTED);
492*0aeed3e9SJustin Hibbits 	}
493*0aeed3e9SJustin Hibbits 
494*0aeed3e9SJustin Hibbits 	error = QM_FQR_PullFrame(fqr, portal, fqid_off, frame);
495*0aeed3e9SJustin Hibbits 
496*0aeed3e9SJustin Hibbits 	sched_unpin();
497*0aeed3e9SJustin Hibbits 
498*0aeed3e9SJustin Hibbits 	return (error);
499*0aeed3e9SJustin Hibbits }
500*0aeed3e9SJustin Hibbits 
501*0aeed3e9SJustin Hibbits uint32_t
502*0aeed3e9SJustin Hibbits qman_fqr_get_base_fqid(t_Handle fqr)
503*0aeed3e9SJustin Hibbits {
504*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
505*0aeed3e9SJustin Hibbits 	uint32_t val;
506*0aeed3e9SJustin Hibbits 	t_Handle portal;
507*0aeed3e9SJustin Hibbits 
508*0aeed3e9SJustin Hibbits 	sc = qman_sc;
509*0aeed3e9SJustin Hibbits 	sched_pin();
510*0aeed3e9SJustin Hibbits 
511*0aeed3e9SJustin Hibbits 	/* Ensure we have got QMan port initialized */
512*0aeed3e9SJustin Hibbits 	portal = qman_portal_setup(sc);
513*0aeed3e9SJustin Hibbits 	if (portal == NULL) {
514*0aeed3e9SJustin Hibbits 		device_printf(sc->sc_dev, "could not setup QMan portal\n");
515*0aeed3e9SJustin Hibbits 		sched_unpin();
516*0aeed3e9SJustin Hibbits 		return (0);
517*0aeed3e9SJustin Hibbits 	}
518*0aeed3e9SJustin Hibbits 
519*0aeed3e9SJustin Hibbits 	val = QM_FQR_GetFqid(fqr);
520*0aeed3e9SJustin Hibbits 
521*0aeed3e9SJustin Hibbits 	sched_unpin();
522*0aeed3e9SJustin Hibbits 
523*0aeed3e9SJustin Hibbits 	return (val);
524*0aeed3e9SJustin Hibbits }
525*0aeed3e9SJustin Hibbits 
526*0aeed3e9SJustin Hibbits t_Error
527*0aeed3e9SJustin Hibbits qman_poll(e_QmPortalPollSource source)
528*0aeed3e9SJustin Hibbits {
529*0aeed3e9SJustin Hibbits 	struct qman_softc *sc;
530*0aeed3e9SJustin Hibbits 	t_Error error;
531*0aeed3e9SJustin Hibbits 	t_Handle portal;
532*0aeed3e9SJustin Hibbits 
533*0aeed3e9SJustin Hibbits 	sc = qman_sc;
534*0aeed3e9SJustin Hibbits 	sched_pin();
535*0aeed3e9SJustin Hibbits 
536*0aeed3e9SJustin Hibbits 	/* Ensure we have got QMan port initialized */
537*0aeed3e9SJustin Hibbits 	portal = qman_portal_setup(sc);
538*0aeed3e9SJustin Hibbits 	if (portal == NULL) {
539*0aeed3e9SJustin Hibbits 		device_printf(sc->sc_dev, "could not setup QMan portal\n");
540*0aeed3e9SJustin Hibbits 		sched_unpin();
541*0aeed3e9SJustin Hibbits 		return (E_NOT_SUPPORTED);
542*0aeed3e9SJustin Hibbits 	}
543*0aeed3e9SJustin Hibbits 
544*0aeed3e9SJustin Hibbits 	error = QM_Poll(sc->sc_qh, source);
545*0aeed3e9SJustin Hibbits 
546*0aeed3e9SJustin Hibbits 	sched_unpin();
547*0aeed3e9SJustin Hibbits 
548*0aeed3e9SJustin Hibbits 	return (error);
549*0aeed3e9SJustin Hibbits }
550*0aeed3e9SJustin Hibbits 
551*0aeed3e9SJustin Hibbits /*
552*0aeed3e9SJustin Hibbits  * TODO: add polling and/or congestion support.
553*0aeed3e9SJustin Hibbits  */
554*0aeed3e9SJustin Hibbits 
555*0aeed3e9SJustin Hibbits /** @} */
556