10aeed3e9SJustin Hibbits /*- 20aeed3e9SJustin Hibbits * Copyright (c) 2011-2012 Semihalf. 30aeed3e9SJustin Hibbits * All rights reserved. 40aeed3e9SJustin Hibbits * 50aeed3e9SJustin Hibbits * Redistribution and use in source and binary forms, with or without 60aeed3e9SJustin Hibbits * modification, are permitted provided that the following conditions 70aeed3e9SJustin Hibbits * are met: 80aeed3e9SJustin Hibbits * 1. Redistributions of source code must retain the above copyright 90aeed3e9SJustin Hibbits * notice, this list of conditions and the following disclaimer. 100aeed3e9SJustin Hibbits * 2. Redistributions in binary form must reproduce the above copyright 110aeed3e9SJustin Hibbits * notice, this list of conditions and the following disclaimer in the 120aeed3e9SJustin Hibbits * documentation and/or other materials provided with the distribution. 130aeed3e9SJustin Hibbits * 140aeed3e9SJustin Hibbits * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 150aeed3e9SJustin Hibbits * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 160aeed3e9SJustin Hibbits * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 170aeed3e9SJustin Hibbits * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 180aeed3e9SJustin Hibbits * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 190aeed3e9SJustin Hibbits * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 200aeed3e9SJustin Hibbits * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 210aeed3e9SJustin Hibbits * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 220aeed3e9SJustin Hibbits * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 230aeed3e9SJustin Hibbits * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 240aeed3e9SJustin Hibbits * SUCH DAMAGE. 250aeed3e9SJustin Hibbits */ 260aeed3e9SJustin Hibbits 270aeed3e9SJustin Hibbits #include <sys/cdefs.h> 280aeed3e9SJustin Hibbits __FBSDID("$FreeBSD$"); 290aeed3e9SJustin Hibbits 300aeed3e9SJustin Hibbits #include <sys/param.h> 310aeed3e9SJustin Hibbits #include <sys/systm.h> 320aeed3e9SJustin Hibbits #include <sys/kernel.h> 330aeed3e9SJustin Hibbits #include <sys/bus.h> 340aeed3e9SJustin Hibbits #include <sys/lock.h> 350aeed3e9SJustin Hibbits #include <sys/module.h> 360aeed3e9SJustin Hibbits #include <sys/mutex.h> 370aeed3e9SJustin Hibbits #include <sys/proc.h> 380aeed3e9SJustin Hibbits #include <sys/pcpu.h> 390aeed3e9SJustin Hibbits #include <sys/rman.h> 400aeed3e9SJustin Hibbits #include <sys/sched.h> 410aeed3e9SJustin Hibbits #include <sys/smp.h> 420aeed3e9SJustin Hibbits 430aeed3e9SJustin Hibbits #include <machine/bus.h> 440aeed3e9SJustin Hibbits #include <machine/resource.h> 450aeed3e9SJustin Hibbits #include <machine/tlb.h> 460aeed3e9SJustin Hibbits 470aeed3e9SJustin Hibbits #include "qman.h" 480aeed3e9SJustin Hibbits #include "portals.h" 490aeed3e9SJustin Hibbits 500aeed3e9SJustin Hibbits extern struct dpaa_portals_softc *qp_sc; 510aeed3e9SJustin Hibbits static struct qman_softc *qman_sc; 520aeed3e9SJustin Hibbits 530aeed3e9SJustin Hibbits extern t_Handle qman_portal_setup(struct qman_softc *qsc); 540aeed3e9SJustin Hibbits 550aeed3e9SJustin Hibbits static void 560aeed3e9SJustin Hibbits qman_exception(t_Handle app, e_QmExceptions exception) 570aeed3e9SJustin Hibbits { 580aeed3e9SJustin Hibbits struct qman_softc *sc; 590aeed3e9SJustin Hibbits const char *message; 600aeed3e9SJustin Hibbits 610aeed3e9SJustin Hibbits sc = app; 620aeed3e9SJustin Hibbits 630aeed3e9SJustin Hibbits switch (exception) { 640aeed3e9SJustin Hibbits case e_QM_EX_CORENET_INITIATOR_DATA: 650aeed3e9SJustin Hibbits message = "Initiator Data Error"; 660aeed3e9SJustin Hibbits break; 670aeed3e9SJustin Hibbits case e_QM_EX_CORENET_TARGET_DATA: 680aeed3e9SJustin Hibbits message = "CoreNet Target Data Error"; 690aeed3e9SJustin Hibbits break; 700aeed3e9SJustin Hibbits case e_QM_EX_CORENET_INVALID_TARGET_TRANSACTION: 710aeed3e9SJustin Hibbits message = "Invalid Target Transaction"; 720aeed3e9SJustin Hibbits break; 730aeed3e9SJustin Hibbits case e_QM_EX_PFDR_THRESHOLD: 740aeed3e9SJustin Hibbits message = "PFDR Low Watermark Interrupt"; 750aeed3e9SJustin Hibbits break; 760aeed3e9SJustin Hibbits case e_QM_EX_PFDR_ENQUEUE_BLOCKED: 770aeed3e9SJustin Hibbits message = "PFDR Enqueues Blocked Interrupt"; 780aeed3e9SJustin Hibbits break; 790aeed3e9SJustin Hibbits case e_QM_EX_SINGLE_ECC: 800aeed3e9SJustin Hibbits message = "Single Bit ECC Error Interrupt"; 810aeed3e9SJustin Hibbits break; 820aeed3e9SJustin Hibbits case e_QM_EX_MULTI_ECC: 830aeed3e9SJustin Hibbits message = "Multi Bit ECC Error Interrupt"; 840aeed3e9SJustin Hibbits break; 850aeed3e9SJustin Hibbits case e_QM_EX_INVALID_COMMAND: 860aeed3e9SJustin Hibbits message = "Invalid Command Verb Interrupt"; 870aeed3e9SJustin Hibbits break; 880aeed3e9SJustin Hibbits case e_QM_EX_DEQUEUE_DCP: 890aeed3e9SJustin Hibbits message = "Invalid Dequeue Direct Connect Portal Interrupt"; 900aeed3e9SJustin Hibbits break; 910aeed3e9SJustin Hibbits case e_QM_EX_DEQUEUE_FQ: 920aeed3e9SJustin Hibbits message = "Invalid Dequeue FQ Interrupt"; 930aeed3e9SJustin Hibbits break; 940aeed3e9SJustin Hibbits case e_QM_EX_DEQUEUE_SOURCE: 950aeed3e9SJustin Hibbits message = "Invalid Dequeue Source Interrupt"; 960aeed3e9SJustin Hibbits break; 970aeed3e9SJustin Hibbits case e_QM_EX_DEQUEUE_QUEUE: 980aeed3e9SJustin Hibbits message = "Invalid Dequeue Queue Interrupt"; 990aeed3e9SJustin Hibbits break; 1000aeed3e9SJustin Hibbits case e_QM_EX_ENQUEUE_OVERFLOW: 1010aeed3e9SJustin Hibbits message = "Invalid Enqueue Overflow Interrupt"; 1020aeed3e9SJustin Hibbits break; 1030aeed3e9SJustin Hibbits case e_QM_EX_ENQUEUE_STATE: 1040aeed3e9SJustin Hibbits message = "Invalid Enqueue State Interrupt"; 1050aeed3e9SJustin Hibbits break; 1060aeed3e9SJustin Hibbits case e_QM_EX_ENQUEUE_CHANNEL: 1070aeed3e9SJustin Hibbits message = "Invalid Enqueue Channel Interrupt"; 1080aeed3e9SJustin Hibbits break; 1090aeed3e9SJustin Hibbits case e_QM_EX_ENQUEUE_QUEUE: 1100aeed3e9SJustin Hibbits message = "Invalid Enqueue Queue Interrupt"; 1110aeed3e9SJustin Hibbits break; 1120aeed3e9SJustin Hibbits case e_QM_EX_CG_STATE_CHANGE: 1130aeed3e9SJustin Hibbits message = "CG change state notification"; 1140aeed3e9SJustin Hibbits break; 1150aeed3e9SJustin Hibbits default: 1160aeed3e9SJustin Hibbits message = "Unknown error"; 1170aeed3e9SJustin Hibbits } 1180aeed3e9SJustin Hibbits 1190aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "QMan Exception: %s.\n", message); 1200aeed3e9SJustin Hibbits } 1210aeed3e9SJustin Hibbits 1220aeed3e9SJustin Hibbits /** 1230aeed3e9SJustin Hibbits * General received frame callback. 1240aeed3e9SJustin Hibbits * This is called, when user did not register his own callback for a given 1250aeed3e9SJustin Hibbits * frame queue range (fqr). 1260aeed3e9SJustin Hibbits */ 1270aeed3e9SJustin Hibbits e_RxStoreResponse 1280aeed3e9SJustin Hibbits qman_received_frame_callback(t_Handle app, t_Handle qm_fqr, t_Handle qm_portal, 1290aeed3e9SJustin Hibbits uint32_t fqid_offset, t_DpaaFD *frame) 1300aeed3e9SJustin Hibbits { 1310aeed3e9SJustin Hibbits struct qman_softc *sc; 1320aeed3e9SJustin Hibbits 1330aeed3e9SJustin Hibbits sc = app; 1340aeed3e9SJustin Hibbits 1350aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "dummy callback for received frame.\n"); 1360aeed3e9SJustin Hibbits return (e_RX_STORE_RESPONSE_CONTINUE); 1370aeed3e9SJustin Hibbits } 1380aeed3e9SJustin Hibbits 1390aeed3e9SJustin Hibbits /** 1400aeed3e9SJustin Hibbits * General rejected frame callback. 1410aeed3e9SJustin Hibbits * This is called, when user did not register his own callback for a given 1420aeed3e9SJustin Hibbits * frame queue range (fqr). 1430aeed3e9SJustin Hibbits */ 1440aeed3e9SJustin Hibbits e_RxStoreResponse 1450aeed3e9SJustin Hibbits qman_rejected_frame_callback(t_Handle app, t_Handle qm_fqr, t_Handle qm_portal, 1460aeed3e9SJustin Hibbits uint32_t fqid_offset, t_DpaaFD *frame, 1470aeed3e9SJustin Hibbits t_QmRejectedFrameInfo *qm_rejected_frame_info) 1480aeed3e9SJustin Hibbits { 1490aeed3e9SJustin Hibbits struct qman_softc *sc; 1500aeed3e9SJustin Hibbits 1510aeed3e9SJustin Hibbits sc = app; 1520aeed3e9SJustin Hibbits 1530aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "dummy callback for rejected frame.\n"); 1540aeed3e9SJustin Hibbits return (e_RX_STORE_RESPONSE_CONTINUE); 1550aeed3e9SJustin Hibbits } 1560aeed3e9SJustin Hibbits 1570aeed3e9SJustin Hibbits int 1580aeed3e9SJustin Hibbits qman_attach(device_t dev) 1590aeed3e9SJustin Hibbits { 1600aeed3e9SJustin Hibbits struct qman_softc *sc; 1610aeed3e9SJustin Hibbits t_QmParam qp; 1620aeed3e9SJustin Hibbits t_Error error; 1630aeed3e9SJustin Hibbits t_QmRevisionInfo rev; 1640aeed3e9SJustin Hibbits 1650aeed3e9SJustin Hibbits sc = device_get_softc(dev); 1660aeed3e9SJustin Hibbits sc->sc_dev = dev; 1670aeed3e9SJustin Hibbits qman_sc = sc; 1680aeed3e9SJustin Hibbits 1690aeed3e9SJustin Hibbits if (XX_MallocSmartInit() != E_OK) { 1700aeed3e9SJustin Hibbits device_printf(dev, "could not initialize smart allocator.\n"); 1710aeed3e9SJustin Hibbits return (ENXIO); 1720aeed3e9SJustin Hibbits } 1730aeed3e9SJustin Hibbits 1740aeed3e9SJustin Hibbits sched_pin(); 1750aeed3e9SJustin Hibbits 1760aeed3e9SJustin Hibbits /* Allocate resources */ 1770aeed3e9SJustin Hibbits sc->sc_rrid = 0; 1780aeed3e9SJustin Hibbits sc->sc_rres = bus_alloc_resource(dev, SYS_RES_MEMORY, 1790aeed3e9SJustin Hibbits &sc->sc_rrid, 0, ~0, QMAN_CCSR_SIZE, RF_ACTIVE); 1800aeed3e9SJustin Hibbits if (sc->sc_rres == NULL) { 1810aeed3e9SJustin Hibbits device_printf(dev, "could not allocate memory.\n"); 1820aeed3e9SJustin Hibbits goto err; 1830aeed3e9SJustin Hibbits } 1840aeed3e9SJustin Hibbits 1850aeed3e9SJustin Hibbits sc->sc_irid = 0; 1860aeed3e9SJustin Hibbits sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, 1870aeed3e9SJustin Hibbits &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE); 1880aeed3e9SJustin Hibbits if (sc->sc_ires == NULL) { 1890aeed3e9SJustin Hibbits device_printf(dev, "could not allocate error interrupt.\n"); 1900aeed3e9SJustin Hibbits goto err; 1910aeed3e9SJustin Hibbits } 1920aeed3e9SJustin Hibbits 1930aeed3e9SJustin Hibbits if (qp_sc == NULL) 1940aeed3e9SJustin Hibbits goto err; 1950aeed3e9SJustin Hibbits 1960aeed3e9SJustin Hibbits dpaa_portal_map_registers(qp_sc); 1970aeed3e9SJustin Hibbits 1980aeed3e9SJustin Hibbits /* Initialize QMan */ 1990aeed3e9SJustin Hibbits qp.guestId = NCSW_MASTER_ID; 2000aeed3e9SJustin Hibbits qp.baseAddress = rman_get_bushandle(sc->sc_rres); 2010aeed3e9SJustin Hibbits qp.swPortalsBaseAddress = rman_get_bushandle(qp_sc->sc_rres[0]); 2020aeed3e9SJustin Hibbits qp.liodn = 0; 2030aeed3e9SJustin Hibbits qp.totalNumOfFqids = QMAN_MAX_FQIDS; 2040aeed3e9SJustin Hibbits qp.fqdMemPartitionId = NCSW_MASTER_ID; 2050aeed3e9SJustin Hibbits qp.pfdrMemPartitionId = NCSW_MASTER_ID; 2060aeed3e9SJustin Hibbits qp.f_Exception = qman_exception; 2070aeed3e9SJustin Hibbits qp.h_App = sc; 208*f77405e3SJustin Hibbits qp.errIrq = (uintptr_t)sc->sc_ires; 2090aeed3e9SJustin Hibbits qp.partFqidBase = QMAN_FQID_BASE; 2100aeed3e9SJustin Hibbits qp.partNumOfFqids = QMAN_MAX_FQIDS; 2110aeed3e9SJustin Hibbits qp.partCgsBase = 0; 2120aeed3e9SJustin Hibbits qp.partNumOfCgs = 0; 2130aeed3e9SJustin Hibbits 2140aeed3e9SJustin Hibbits sc->sc_qh = QM_Config(&qp); 2150aeed3e9SJustin Hibbits if (sc->sc_qh == NULL) { 2160aeed3e9SJustin Hibbits device_printf(dev, "could not be configured\n"); 2170aeed3e9SJustin Hibbits goto err; 2180aeed3e9SJustin Hibbits } 2190aeed3e9SJustin Hibbits 2200aeed3e9SJustin Hibbits error = QM_Init(sc->sc_qh); 2210aeed3e9SJustin Hibbits if (error != E_OK) { 2220aeed3e9SJustin Hibbits device_printf(dev, "could not be initialized\n"); 2230aeed3e9SJustin Hibbits goto err; 2240aeed3e9SJustin Hibbits } 2250aeed3e9SJustin Hibbits 2260aeed3e9SJustin Hibbits error = QM_GetRevision(sc->sc_qh, &rev); 2270aeed3e9SJustin Hibbits if (error != E_OK) { 2280aeed3e9SJustin Hibbits device_printf(dev, "could not get QMan revision\n"); 2290aeed3e9SJustin Hibbits goto err; 2300aeed3e9SJustin Hibbits } 2310aeed3e9SJustin Hibbits 2320aeed3e9SJustin Hibbits device_printf(dev, "Hardware version: %d.%d.\n", 2330aeed3e9SJustin Hibbits rev.majorRev, rev.minorRev); 2340aeed3e9SJustin Hibbits 2350aeed3e9SJustin Hibbits sched_unpin(); 2360aeed3e9SJustin Hibbits 2370aeed3e9SJustin Hibbits qman_portal_setup(sc); 2380aeed3e9SJustin Hibbits 2390aeed3e9SJustin Hibbits return (0); 2400aeed3e9SJustin Hibbits 2410aeed3e9SJustin Hibbits err: 2420aeed3e9SJustin Hibbits sched_unpin(); 2430aeed3e9SJustin Hibbits qman_detach(dev); 2440aeed3e9SJustin Hibbits return (ENXIO); 2450aeed3e9SJustin Hibbits } 2460aeed3e9SJustin Hibbits 2470aeed3e9SJustin Hibbits int 2480aeed3e9SJustin Hibbits qman_detach(device_t dev) 2490aeed3e9SJustin Hibbits { 2500aeed3e9SJustin Hibbits struct qman_softc *sc; 2510aeed3e9SJustin Hibbits 2520aeed3e9SJustin Hibbits sc = device_get_softc(dev); 2530aeed3e9SJustin Hibbits 2540aeed3e9SJustin Hibbits if (sc->sc_qh) 2550aeed3e9SJustin Hibbits QM_Free(sc->sc_qh); 2560aeed3e9SJustin Hibbits 2570aeed3e9SJustin Hibbits if (sc->sc_ires != NULL) 258*f77405e3SJustin Hibbits XX_DeallocIntr((uintptr_t)sc->sc_ires); 2590aeed3e9SJustin Hibbits 2600aeed3e9SJustin Hibbits if (sc->sc_ires != NULL) 2610aeed3e9SJustin Hibbits bus_release_resource(dev, SYS_RES_IRQ, 2620aeed3e9SJustin Hibbits sc->sc_irid, sc->sc_ires); 2630aeed3e9SJustin Hibbits 2640aeed3e9SJustin Hibbits if (sc->sc_rres != NULL) 2650aeed3e9SJustin Hibbits bus_release_resource(dev, SYS_RES_MEMORY, 2660aeed3e9SJustin Hibbits sc->sc_rrid, sc->sc_rres); 2670aeed3e9SJustin Hibbits 2680aeed3e9SJustin Hibbits return (0); 2690aeed3e9SJustin Hibbits } 2700aeed3e9SJustin Hibbits 2710aeed3e9SJustin Hibbits int 2720aeed3e9SJustin Hibbits qman_suspend(device_t dev) 2730aeed3e9SJustin Hibbits { 2740aeed3e9SJustin Hibbits 2750aeed3e9SJustin Hibbits return (0); 2760aeed3e9SJustin Hibbits } 2770aeed3e9SJustin Hibbits 2780aeed3e9SJustin Hibbits int 2790aeed3e9SJustin Hibbits qman_resume(device_t dev) 2800aeed3e9SJustin Hibbits { 2810aeed3e9SJustin Hibbits 2820aeed3e9SJustin Hibbits return (0); 2830aeed3e9SJustin Hibbits } 2840aeed3e9SJustin Hibbits 2850aeed3e9SJustin Hibbits int 2860aeed3e9SJustin Hibbits qman_shutdown(device_t dev) 2870aeed3e9SJustin Hibbits { 2880aeed3e9SJustin Hibbits 2890aeed3e9SJustin Hibbits return (0); 2900aeed3e9SJustin Hibbits } 2910aeed3e9SJustin Hibbits 2920aeed3e9SJustin Hibbits 2930aeed3e9SJustin Hibbits /** 2940aeed3e9SJustin Hibbits * @group QMan API functions implementation. 2950aeed3e9SJustin Hibbits * @{ 2960aeed3e9SJustin Hibbits */ 2970aeed3e9SJustin Hibbits 2980aeed3e9SJustin Hibbits t_Handle 2990aeed3e9SJustin Hibbits qman_fqr_create(uint32_t fqids_num, e_QmFQChannel channel, uint8_t wq, 3000aeed3e9SJustin Hibbits bool force_fqid, uint32_t fqid_or_align, bool init_parked, 3010aeed3e9SJustin Hibbits bool hold_active, bool prefer_in_cache, bool congst_avoid_ena, 3020aeed3e9SJustin Hibbits t_Handle congst_group, int8_t overhead_accounting_len, 3030aeed3e9SJustin Hibbits uint32_t tail_drop_threshold) 3040aeed3e9SJustin Hibbits { 3050aeed3e9SJustin Hibbits struct qman_softc *sc; 3060aeed3e9SJustin Hibbits t_QmFqrParams fqr; 3070aeed3e9SJustin Hibbits unsigned int cpu; 3080aeed3e9SJustin Hibbits t_Handle fqrh, portal; 3090aeed3e9SJustin Hibbits 3100aeed3e9SJustin Hibbits sc = qman_sc; 3110aeed3e9SJustin Hibbits 3120aeed3e9SJustin Hibbits sched_pin(); 3130aeed3e9SJustin Hibbits cpu = PCPU_GET(cpuid); 3140aeed3e9SJustin Hibbits 3150aeed3e9SJustin Hibbits /* Ensure we have got QMan port initialized */ 3160aeed3e9SJustin Hibbits portal = qman_portal_setup(sc); 3170aeed3e9SJustin Hibbits if (portal == NULL) { 3180aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "could not setup QMan portal\n"); 3190aeed3e9SJustin Hibbits goto err; 3200aeed3e9SJustin Hibbits } 3210aeed3e9SJustin Hibbits 3220aeed3e9SJustin Hibbits fqr.h_Qm = sc->sc_qh; 3230aeed3e9SJustin Hibbits fqr.h_QmPortal = portal; 3240aeed3e9SJustin Hibbits fqr.initParked = init_parked; 3250aeed3e9SJustin Hibbits fqr.holdActive = hold_active; 3260aeed3e9SJustin Hibbits fqr.preferInCache = prefer_in_cache; 3270aeed3e9SJustin Hibbits 3280aeed3e9SJustin Hibbits /* We do not support stashing */ 3290aeed3e9SJustin Hibbits fqr.useContextAForStash = FALSE; 3300aeed3e9SJustin Hibbits fqr.p_ContextA = 0; 3310aeed3e9SJustin Hibbits fqr.p_ContextB = 0; 3320aeed3e9SJustin Hibbits 3330aeed3e9SJustin Hibbits fqr.channel = channel; 3340aeed3e9SJustin Hibbits fqr.wq = wq; 3350aeed3e9SJustin Hibbits fqr.shadowMode = FALSE; 3360aeed3e9SJustin Hibbits fqr.numOfFqids = fqids_num; 3370aeed3e9SJustin Hibbits 3380aeed3e9SJustin Hibbits /* FQID */ 3390aeed3e9SJustin Hibbits fqr.useForce = force_fqid; 3400aeed3e9SJustin Hibbits if (force_fqid) { 3410aeed3e9SJustin Hibbits fqr.qs.frcQ.fqid = fqid_or_align; 3420aeed3e9SJustin Hibbits } else { 3430aeed3e9SJustin Hibbits fqr.qs.nonFrcQs.align = fqid_or_align; 3440aeed3e9SJustin Hibbits } 3450aeed3e9SJustin Hibbits 3460aeed3e9SJustin Hibbits /* Congestion Avoidance */ 3470aeed3e9SJustin Hibbits fqr.congestionAvoidanceEnable = congst_avoid_ena; 3480aeed3e9SJustin Hibbits if (congst_avoid_ena) { 3490aeed3e9SJustin Hibbits fqr.congestionAvoidanceParams.h_QmCg = congst_group; 3500aeed3e9SJustin Hibbits fqr.congestionAvoidanceParams.overheadAccountingLength = 3510aeed3e9SJustin Hibbits overhead_accounting_len; 3520aeed3e9SJustin Hibbits fqr.congestionAvoidanceParams.fqTailDropThreshold = 3530aeed3e9SJustin Hibbits tail_drop_threshold; 3540aeed3e9SJustin Hibbits } else { 3550aeed3e9SJustin Hibbits fqr.congestionAvoidanceParams.h_QmCg = 0; 3560aeed3e9SJustin Hibbits fqr.congestionAvoidanceParams.overheadAccountingLength = 0; 3570aeed3e9SJustin Hibbits fqr.congestionAvoidanceParams.fqTailDropThreshold = 0; 3580aeed3e9SJustin Hibbits } 3590aeed3e9SJustin Hibbits 3600aeed3e9SJustin Hibbits fqrh = QM_FQR_Create(&fqr); 3610aeed3e9SJustin Hibbits if (fqrh == NULL) { 3620aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "could not create Frame Queue Range" 3630aeed3e9SJustin Hibbits "\n"); 3640aeed3e9SJustin Hibbits goto err; 3650aeed3e9SJustin Hibbits } 3660aeed3e9SJustin Hibbits 3670aeed3e9SJustin Hibbits sc->sc_fqr_cpu[QM_FQR_GetFqid(fqrh)] = PCPU_GET(cpuid); 3680aeed3e9SJustin Hibbits 3690aeed3e9SJustin Hibbits sched_unpin(); 3700aeed3e9SJustin Hibbits 3710aeed3e9SJustin Hibbits return (fqrh); 3720aeed3e9SJustin Hibbits 3730aeed3e9SJustin Hibbits err: 3740aeed3e9SJustin Hibbits sched_unpin(); 3750aeed3e9SJustin Hibbits 3760aeed3e9SJustin Hibbits return (NULL); 3770aeed3e9SJustin Hibbits } 3780aeed3e9SJustin Hibbits 3790aeed3e9SJustin Hibbits t_Error 3800aeed3e9SJustin Hibbits qman_fqr_free(t_Handle fqr) 3810aeed3e9SJustin Hibbits { 3820aeed3e9SJustin Hibbits struct qman_softc *sc; 3830aeed3e9SJustin Hibbits t_Error error; 3840aeed3e9SJustin Hibbits 3850aeed3e9SJustin Hibbits sc = qman_sc; 3860aeed3e9SJustin Hibbits thread_lock(curthread); 3870aeed3e9SJustin Hibbits sched_bind(curthread, sc->sc_fqr_cpu[QM_FQR_GetFqid(fqr)]); 3880aeed3e9SJustin Hibbits thread_unlock(curthread); 3890aeed3e9SJustin Hibbits 3900aeed3e9SJustin Hibbits error = QM_FQR_Free(fqr); 3910aeed3e9SJustin Hibbits 3920aeed3e9SJustin Hibbits thread_lock(curthread); 3930aeed3e9SJustin Hibbits sched_unbind(curthread); 3940aeed3e9SJustin Hibbits thread_unlock(curthread); 3950aeed3e9SJustin Hibbits 3960aeed3e9SJustin Hibbits return (error); 3970aeed3e9SJustin Hibbits } 3980aeed3e9SJustin Hibbits 3990aeed3e9SJustin Hibbits t_Error 4000aeed3e9SJustin Hibbits qman_fqr_register_cb(t_Handle fqr, t_QmReceivedFrameCallback *callback, 4010aeed3e9SJustin Hibbits t_Handle app) 4020aeed3e9SJustin Hibbits { 4030aeed3e9SJustin Hibbits struct qman_softc *sc; 4040aeed3e9SJustin Hibbits t_Error error; 4050aeed3e9SJustin Hibbits t_Handle portal; 4060aeed3e9SJustin Hibbits 4070aeed3e9SJustin Hibbits sc = qman_sc; 4080aeed3e9SJustin Hibbits sched_pin(); 4090aeed3e9SJustin Hibbits 4100aeed3e9SJustin Hibbits /* Ensure we have got QMan port initialized */ 4110aeed3e9SJustin Hibbits portal = qman_portal_setup(sc); 4120aeed3e9SJustin Hibbits if (portal == NULL) { 4130aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "could not setup QMan portal\n"); 4140aeed3e9SJustin Hibbits sched_unpin(); 4150aeed3e9SJustin Hibbits return (E_NOT_SUPPORTED); 4160aeed3e9SJustin Hibbits } 4170aeed3e9SJustin Hibbits 4180aeed3e9SJustin Hibbits error = QM_FQR_RegisterCB(fqr, callback, app); 4190aeed3e9SJustin Hibbits 4200aeed3e9SJustin Hibbits sched_unpin(); 4210aeed3e9SJustin Hibbits 4220aeed3e9SJustin Hibbits return (error); 4230aeed3e9SJustin Hibbits } 4240aeed3e9SJustin Hibbits 4250aeed3e9SJustin Hibbits t_Error 4260aeed3e9SJustin Hibbits qman_fqr_enqueue(t_Handle fqr, uint32_t fqid_off, t_DpaaFD *frame) 4270aeed3e9SJustin Hibbits { 4280aeed3e9SJustin Hibbits struct qman_softc *sc; 4290aeed3e9SJustin Hibbits t_Error error; 4300aeed3e9SJustin Hibbits t_Handle portal; 4310aeed3e9SJustin Hibbits 4320aeed3e9SJustin Hibbits sc = qman_sc; 4330aeed3e9SJustin Hibbits sched_pin(); 4340aeed3e9SJustin Hibbits 4350aeed3e9SJustin Hibbits /* Ensure we have got QMan port initialized */ 4360aeed3e9SJustin Hibbits portal = qman_portal_setup(sc); 4370aeed3e9SJustin Hibbits if (portal == NULL) { 4380aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "could not setup QMan portal\n"); 4390aeed3e9SJustin Hibbits sched_unpin(); 4400aeed3e9SJustin Hibbits return (E_NOT_SUPPORTED); 4410aeed3e9SJustin Hibbits } 4420aeed3e9SJustin Hibbits 4430aeed3e9SJustin Hibbits error = QM_FQR_Enqueue(fqr, portal, fqid_off, frame); 4440aeed3e9SJustin Hibbits 4450aeed3e9SJustin Hibbits sched_unpin(); 4460aeed3e9SJustin Hibbits 4470aeed3e9SJustin Hibbits return (error); 4480aeed3e9SJustin Hibbits } 4490aeed3e9SJustin Hibbits 4500aeed3e9SJustin Hibbits uint32_t 4510aeed3e9SJustin Hibbits qman_fqr_get_counter(t_Handle fqr, uint32_t fqid_off, 4520aeed3e9SJustin Hibbits e_QmFqrCounters counter) 4530aeed3e9SJustin Hibbits { 4540aeed3e9SJustin Hibbits struct qman_softc *sc; 4550aeed3e9SJustin Hibbits uint32_t val; 4560aeed3e9SJustin Hibbits t_Handle portal; 4570aeed3e9SJustin Hibbits 4580aeed3e9SJustin Hibbits sc = qman_sc; 4590aeed3e9SJustin Hibbits sched_pin(); 4600aeed3e9SJustin Hibbits 4610aeed3e9SJustin Hibbits /* Ensure we have got QMan port initialized */ 4620aeed3e9SJustin Hibbits portal = qman_portal_setup(sc); 4630aeed3e9SJustin Hibbits if (portal == NULL) { 4640aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "could not setup QMan portal\n"); 4650aeed3e9SJustin Hibbits sched_unpin(); 4660aeed3e9SJustin Hibbits return (0); 4670aeed3e9SJustin Hibbits } 4680aeed3e9SJustin Hibbits 4690aeed3e9SJustin Hibbits val = QM_FQR_GetCounter(fqr, portal, fqid_off, counter); 4700aeed3e9SJustin Hibbits 4710aeed3e9SJustin Hibbits sched_unpin(); 4720aeed3e9SJustin Hibbits 4730aeed3e9SJustin Hibbits return (val); 4740aeed3e9SJustin Hibbits } 4750aeed3e9SJustin Hibbits 4760aeed3e9SJustin Hibbits t_Error 4770aeed3e9SJustin Hibbits qman_fqr_pull_frame(t_Handle fqr, uint32_t fqid_off, t_DpaaFD *frame) 4780aeed3e9SJustin Hibbits { 4790aeed3e9SJustin Hibbits struct qman_softc *sc; 4800aeed3e9SJustin Hibbits t_Error error; 4810aeed3e9SJustin Hibbits t_Handle portal; 4820aeed3e9SJustin Hibbits 4830aeed3e9SJustin Hibbits sc = qman_sc; 4840aeed3e9SJustin Hibbits sched_pin(); 4850aeed3e9SJustin Hibbits 4860aeed3e9SJustin Hibbits /* Ensure we have got QMan port initialized */ 4870aeed3e9SJustin Hibbits portal = qman_portal_setup(sc); 4880aeed3e9SJustin Hibbits if (portal == NULL) { 4890aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "could not setup QMan portal\n"); 4900aeed3e9SJustin Hibbits sched_unpin(); 4910aeed3e9SJustin Hibbits return (E_NOT_SUPPORTED); 4920aeed3e9SJustin Hibbits } 4930aeed3e9SJustin Hibbits 4940aeed3e9SJustin Hibbits error = QM_FQR_PullFrame(fqr, portal, fqid_off, frame); 4950aeed3e9SJustin Hibbits 4960aeed3e9SJustin Hibbits sched_unpin(); 4970aeed3e9SJustin Hibbits 4980aeed3e9SJustin Hibbits return (error); 4990aeed3e9SJustin Hibbits } 5000aeed3e9SJustin Hibbits 5010aeed3e9SJustin Hibbits uint32_t 5020aeed3e9SJustin Hibbits qman_fqr_get_base_fqid(t_Handle fqr) 5030aeed3e9SJustin Hibbits { 5040aeed3e9SJustin Hibbits struct qman_softc *sc; 5050aeed3e9SJustin Hibbits uint32_t val; 5060aeed3e9SJustin Hibbits t_Handle portal; 5070aeed3e9SJustin Hibbits 5080aeed3e9SJustin Hibbits sc = qman_sc; 5090aeed3e9SJustin Hibbits sched_pin(); 5100aeed3e9SJustin Hibbits 5110aeed3e9SJustin Hibbits /* Ensure we have got QMan port initialized */ 5120aeed3e9SJustin Hibbits portal = qman_portal_setup(sc); 5130aeed3e9SJustin Hibbits if (portal == NULL) { 5140aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "could not setup QMan portal\n"); 5150aeed3e9SJustin Hibbits sched_unpin(); 5160aeed3e9SJustin Hibbits return (0); 5170aeed3e9SJustin Hibbits } 5180aeed3e9SJustin Hibbits 5190aeed3e9SJustin Hibbits val = QM_FQR_GetFqid(fqr); 5200aeed3e9SJustin Hibbits 5210aeed3e9SJustin Hibbits sched_unpin(); 5220aeed3e9SJustin Hibbits 5230aeed3e9SJustin Hibbits return (val); 5240aeed3e9SJustin Hibbits } 5250aeed3e9SJustin Hibbits 5260aeed3e9SJustin Hibbits t_Error 5270aeed3e9SJustin Hibbits qman_poll(e_QmPortalPollSource source) 5280aeed3e9SJustin Hibbits { 5290aeed3e9SJustin Hibbits struct qman_softc *sc; 5300aeed3e9SJustin Hibbits t_Error error; 5310aeed3e9SJustin Hibbits t_Handle portal; 5320aeed3e9SJustin Hibbits 5330aeed3e9SJustin Hibbits sc = qman_sc; 5340aeed3e9SJustin Hibbits sched_pin(); 5350aeed3e9SJustin Hibbits 5360aeed3e9SJustin Hibbits /* Ensure we have got QMan port initialized */ 5370aeed3e9SJustin Hibbits portal = qman_portal_setup(sc); 5380aeed3e9SJustin Hibbits if (portal == NULL) { 5390aeed3e9SJustin Hibbits device_printf(sc->sc_dev, "could not setup QMan portal\n"); 5400aeed3e9SJustin Hibbits sched_unpin(); 5410aeed3e9SJustin Hibbits return (E_NOT_SUPPORTED); 5420aeed3e9SJustin Hibbits } 5430aeed3e9SJustin Hibbits 5440aeed3e9SJustin Hibbits error = QM_Poll(sc->sc_qh, source); 5450aeed3e9SJustin Hibbits 5460aeed3e9SJustin Hibbits sched_unpin(); 5470aeed3e9SJustin Hibbits 5480aeed3e9SJustin Hibbits return (error); 5490aeed3e9SJustin Hibbits } 5500aeed3e9SJustin Hibbits 5510aeed3e9SJustin Hibbits /* 5520aeed3e9SJustin Hibbits * TODO: add polling and/or congestion support. 5530aeed3e9SJustin Hibbits */ 5540aeed3e9SJustin Hibbits 5550aeed3e9SJustin Hibbits /** @} */ 556