git: fd8d34ce272b - main - dpaa: Migrate from NCSW base to a home-grown driver
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 03 May 2026 19:11:57 UTC
The branch main has been updated by jhibbits:
URL: https://cgit.FreeBSD.org/src/commit/?id=fd8d34ce272ba40f3e0218198ba542a29c390a4a
commit fd8d34ce272ba40f3e0218198ba542a29c390a4a
Author: Justin Hibbits <jhibbits@FreeBSD.org>
AuthorDate: 2026-04-24 03:38:19 +0000
Commit: Justin Hibbits <jhibbits@FreeBSD.org>
CommitDate: 2026-05-03 19:09:29 +0000
dpaa: Migrate from NCSW base to a home-grown driver
The NCSW reference base requires tuning for each target, and currently
is configured for FMANv2. This doesn't readily work on FMANv3 devices,
such as the T-series powerpc, or the LS1043 ARM. Since Freescale/NXP
abandoned the NCSW driver a decade ago, it makes sense to abandon it
ourselves as well. This new driver uses a combination of the NCSW
driver and the Linux driver (BSD/GPL dual licensed) as a reference, but
contains no actual code from them.
The DPAA (Data Path Acceleration Architecture) subsystem consists of the
following components:
* BMan -- Buffer Manager. Manages buffer pools of different sizes (one
size per pool, up to 64 pools)
* QMan -- Queue Manager. Manages the interfaces between DPAA-based
components and the CPU(s).
* FMan -- Frame Manager. Responsible for all ethernet-related
processing. Consists itself of the following components:
* Ports -- interfaces to the QMan. An ethernet interface consists of
2 ports.
Ports use "Next-invoked action" (NIA) descriptors to form a pipeline
for processing on receive and transmit.
* Parser -- performs protocol header parsing and validation. Both
hardware and software parsers are available.
* KeyGen -- Key generator, used to start the classification process
(for the Policer), generating FQIDs and other keys based on the
frame input.
* Policer -- performs traffic shaping and classification
* MAC -- SoC specific ethernet MAC (dTSEC, TGEC, mEMAC). Currently
supports dTSEC and mEMAC, along with their MDIO blocks.
Additional components not yet handled:
SEC -- Security engine (crypto)
RE -- RAID engine
RapidIO
DCE -- Decompression/Compression engine, supports ZLIB, DEFLATE, and
GZIP, as well as base64 encoding and decoding.
BMan and QMan are accessed via cache-coherent portals, using ring
buffers as I/O. The intent is for portals to be per-CPU (core/thread)
to reduce locking contention and improve performance. This driver pins
interrupt handlers to the CPU "owning" a given portal, and uses critical
sections to prevent switching while accessing the portal.
---
sys/conf/files.powerpc | 21 +
sys/dev/dpaa/bman.c | 439 +++++++--------
sys/dev/dpaa/bman.h | 172 ++----
sys/dev/dpaa/bman_fdt.c | 154 +-----
sys/dev/dpaa/bman_portals.c | 378 +++++++++----
sys/dev/dpaa/bman_var.h | 44 ++
sys/dev/dpaa/dpaa_common.c | 82 +++
sys/dev/dpaa/dpaa_common.h | 165 ++++++
sys/dev/dpaa/dpaa_eth.c | 634 +++++++++++++++++++++
sys/dev/dpaa/dpaa_eth.h | 116 ++++
sys/dev/dpaa/fman.c | 858 +++++++++++++++++++++--------
sys/dev/dpaa/fman.h | 73 ++-
sys/dev/dpaa/fman_fdt.c | 14 +-
sys/dev/dpaa/fman_if.m | 38 ++
sys/dev/dpaa/fman_mdio.c | 16 +-
sys/dev/dpaa/fman_muram.c | 70 +++
sys/dev/dpaa/fman_port.c | 680 +++++++++++++++++++++++
sys/dev/dpaa/fman_port.h | 29 +
sys/dev/dpaa/fman_port_if.m | 55 ++
sys/dev/dpaa/fman_xmdio.c | 284 ++++++++++
sys/dev/dpaa/if_dtsec.c | 614 +++++++--------------
sys/dev/dpaa/if_dtsec.h | 96 +---
sys/dev/dpaa/if_dtsec_fdt.c | 55 +-
sys/dev/dpaa/if_dtsec_im.c | 260 ---------
sys/dev/dpaa/if_dtsec_im.h | 39 --
sys/dev/dpaa/if_dtsec_rm.c | 651 ----------------------
sys/dev/dpaa/if_memac.c | 802 +++++++++++++++++++++++++++
sys/dev/dpaa/{if_dtsec_rm.h => if_memac.h} | 50 +-
sys/dev/dpaa/if_memac_fdt.c | 190 +++++++
sys/dev/dpaa/portals.h | 51 +-
sys/dev/dpaa/portals_common.c | 135 +----
sys/dev/dpaa/qman.c | 794 +++++++++++++++-----------
sys/dev/dpaa/qman.h | 184 +++++--
sys/dev/dpaa/qman_fdt.c | 176 ++----
sys/dev/dpaa/qman_portal_if.m | 37 ++
sys/dev/dpaa/qman_portals.c | 490 ++++++++++++----
sys/dev/dpaa/qman_var.h | 167 ++++++
sys/powerpc/conf/QORIQ64 | 4 +-
sys/powerpc/conf/dpaa/DPAA | 99 ----
sys/powerpc/conf/dpaa/config.dpaa | 24 -
sys/powerpc/conf/dpaa/files.dpaa | 122 ----
41 files changed, 6006 insertions(+), 3356 deletions(-)
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index 164a5d01d4b9..a754f78b35f2 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -89,6 +89,27 @@ dev/adb/adb_hb_if.m optional adb
dev/adb/adb_if.m optional adb
dev/adb/adb_buttons.c optional adb
dev/agp/agp_apple.c optional agp powermac
+dev/dpaa/bman_portals.c optional dpaa fdt
+dev/dpaa/bman.c optional dpaa
+dev/dpaa/bman_fdt.c optional dpaa fdt
+dev/dpaa/dpaa_eth.c optional dpaa
+dev/dpaa/fman.c optional dpaa fdt
+dev/dpaa/fman_fdt.c optional dpaa fdt
+dev/dpaa/fman_if.m optional dpaa
+dev/dpaa/fman_mdio.c optional dpaa fdt
+dev/dpaa/fman_port_if.m optional dpaa
+dev/dpaa/fman_port.c optional dpaa
+dev/dpaa/fman_xmdio.c optional dpaa fdt mdio miibus
+dev/dpaa/dpaa_common.c optional dpaa
+dev/dpaa/if_dtsec.c optional dpaa
+dev/dpaa/if_dtsec_fdt.c optional dpaa fdt
+dev/dpaa/if_memac.c optional dpaa
+dev/dpaa/if_memac_fdt.c optional dpaa
+dev/dpaa/portals_common.c optional dpaa
+dev/dpaa/qman_portal_if.m optional dpaa
+dev/dpaa/qman_portals.c optional dpaa fdt
+dev/dpaa/qman.c optional dpaa
+dev/dpaa/qman_fdt.c optional dpaa fdt
dev/fb/fb.c optional sc
dev/gpio/qoriq_gpio.c optional mpc85xx gpio
dev/hwpmc/hwpmc_e500.c optional hwpmc
diff --git a/sys/dev/dpaa/bman.c b/sys/dev/dpaa/bman.c
index c275d2335eb8..90095427f10d 100644
--- a/sys/dev/dpaa/bman.c
+++ b/sys/dev/dpaa/bman.c
@@ -1,27 +1,7 @@
-/*-
- * Copyright (c) 2011-2012 Semihalf.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * Copyright (c) 2026 Justin Hibbits
*/
#include <sys/param.h>
@@ -29,6 +9,7 @@
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/lock.h>
+#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/proc.h>
@@ -36,63 +17,161 @@
#include <sys/rman.h>
#include <sys/sched.h>
+#include <machine/bus.h>
#include <machine/tlb.h>
#include "bman.h"
+#include "dpaa_common.h"
+#include "bman_var.h"
+
+#define BMAN_POOL_SWDET(n) (0x000 + 4 * (n))
+#define BMAN_POOL_HWDET(n) (0x100 + 4 * (n))
+#define BMAN_POOL_SWDXT(n) (0x200 + 4 * (n))
+#define BMAN_POOL_HWDXT(n) (0x300 + 4 * (n))
+#define FBPR_FP_LWIT 0x804
+#define BMAN_IP_REV_1 0x0bf8
+#define IP_MAJ_S 8
+#define IP_MAJ_M 0x0000ff00
+#define IP_MIN_M 0x000000ff
+#define BMAN_IP_REV_2 0x0bfc
+#define BMAN_FBPR_BARE 0x0c00
+#define BMAN_FBPR_BAR 0x0c04
+#define BMAN_FBPR_AR 0x0c10
+#define BMAN_LIODNR 0x0d08
+
+#define BMAN_POOL_CONTENT(n) (0x0600 + 4 * (n))
+#define BMAN_ECSR 0x0a00
+#define BMAN_ECIR 0x0a04
+#define ECIR_PORTAL(r) (((r) >> 24) & 0x0f)
+#define ECIR_VERB(r) (((r) >> 16) & 0x07)
+#define ECIR_R 0x00080000
+#define ECIR_POOL(r) ((r) & 0x3f)
+#define BMAN_CECR 0x0a34 /* Corruption Error Capture Register */
+#define BMAN_CEAR 0x0a38 /* Corruption Error Address Register */
+#define BMAN_AECR 0x0a34 /* Acces Error Capture Register */
+#define BMAN_AEAR 0x0a38 /* Acces Error Address Register */
+#define BMAN_ERR_ISR 0x0e00
+#define BMAN_ERR_IER 0x0e04
+#define BMAN_ERR_ISDR 0x0e08
+#define ERR_EMAI 0x00000040
+#define ERR_EMCI 0x00000020
+#define ERR_IVCI 0x00000010
+#define ERR_FLWI 0x00000008
+#define ERR_MBEI 0x00000004
+#define ERR_SBEI 0x00000002
+#define ERR_BSCN 0x00000001
+
+static MALLOC_DEFINE(M_BMAN, "bman", "DPAA Buffer Manager structures");
static struct bman_softc *bman_sc;
-extern t_Handle bman_portal_setup(struct bman_softc *bsc);
+static void
+bman_isr(void *arg)
+{
+ struct bman_softc *sc = arg;
+ uint32_t ier, isr, isr_bit;
+ uint32_t reg;
+
+ ier = bus_read_4(sc->sc_rres, BMAN_ERR_IER);
+ isr = bus_read_4(sc->sc_rres, BMAN_ERR_ISR);
+
+ isr_bit = (isr & ier);
+ if (isr_bit == 0)
+ goto end;
+
+ if (isr_bit & ERR_EMAI) {
+ device_printf(sc->sc_dev, "External memory access error\n");
+ reg = bus_read_4(sc->sc_rres, BMAN_AECR);
+ if (reg <= 63)
+ device_printf(sc->sc_dev, " pool %d\n", reg);
+ else
+ device_printf(sc->sc_dev, " FBPR free list\n");
+ reg = bus_read_4(sc->sc_rres, BMAN_AEAR);
+ device_printf(sc->sc_dev, " offset: %#x\n", reg);
+ }
+
+ if (isr_bit & ERR_EMCI) {
+ device_printf(sc->sc_dev, "External memory corruption error\n");
+ reg = bus_read_4(sc->sc_rres, BMAN_CECR);
+ if (reg <= 63)
+ device_printf(sc->sc_dev, " pool %d\n", reg);
+ else
+ device_printf(sc->sc_dev, " FBPR free list\n");
+ reg = bus_read_4(sc->sc_rres, BMAN_CEAR);
+ device_printf(sc->sc_dev, " offset: %#x\n", reg);
+ }
+ if (isr_bit & ERR_IVCI) {
+ reg = bus_read_4(sc->sc_rres, BMAN_ECIR);
+ device_printf(sc->sc_dev, "Invalid verb command\n");
+ device_printf(sc->sc_dev, "Portal: %d, ring: %s\n",
+ ECIR_POOL(reg), (reg & ECIR_R) ? "RCR" : "Command");
+ device_printf(sc->sc_dev, "verb: 0x%02x, pool: %d\n",
+ ECIR_VERB(reg), ECIR_POOL(reg));
+ }
+ if (isr_bit & (ERR_MBEI | ERR_SBEI)) {
+ if (isr_bit & ERR_MBEI)
+ device_printf(sc->sc_dev, "Multi-bit ECC error\n");
+ if (isr_bit & ERR_MBEI)
+ device_printf(sc->sc_dev, "Single-bit ECC error\n");
+ /* TODO: Add more error details for ECC errors. */
+ }
+
+end:
+ bus_write_4(sc->sc_rres, BMAN_ERR_ISR, isr);
+}
static void
-bman_exception(t_Handle h_App, e_BmExceptions exception)
+bman_get_version(struct bman_softc *sc)
{
- struct bman_softc *sc;
- const char *message;
-
- sc = h_App;
-
- switch (exception) {
- case e_BM_EX_INVALID_COMMAND:
- message = "Invalid Command Verb";
- break;
- case e_BM_EX_FBPR_THRESHOLD:
- message = "FBPR pool exhaused. Consider increasing "
- "BMAN_MAX_BUFFERS";
- break;
- case e_BM_EX_SINGLE_ECC:
- message = "Single bit ECC error";
- break;
- case e_BM_EX_MULTI_ECC:
- message = "Multi bit ECC error";
- break;
- default:
- message = "Unknown error";
+ uint32_t reg = bus_read_4(sc->sc_rres, BMAN_IP_REV_1);
+
+ sc->sc_major = (reg & IP_MAJ_M) >> IP_MAJ_S;
+ sc->sc_minor = (reg & IP_MIN_M);
+}
+
+static int
+bman_set_memory(struct bman_softc *sc, vm_paddr_t pa, vm_size_t size)
+{
+ vm_paddr_t bar_pa;
+ if ((pa & (size - 1)) != 0 || (size & (size - 1)) != 0) {
+ device_printf(sc->sc_dev,
+ "invalid memory configuration: pa: %#jx, size: %#jx\n",
+ (uintmax_t)pa, (uintmax_t)size);
+ return (ENXIO);
}
+ bar_pa = bus_read_4(sc->sc_rres, BMAN_FBPR_BARE);
+ bar_pa <<= 32;
+ bar_pa |= bus_read_4(sc->sc_rres, BMAN_FBPR_BAR);
+ if (bar_pa != 0 && bar_pa != pa) {
+ device_printf(sc->sc_dev,
+ "attempted to reinitialize BMan with different BAR\n");
+ return (ENOMEM);
+ } else if (bar_pa == pa)
+ return (0);
+
+ bus_write_4(sc->sc_rres, BMAN_FBPR_BARE, pa >> 32);
+ bus_write_4(sc->sc_rres, BMAN_FBPR_BAR, pa & 0xffffffff);
+ bus_write_4(sc->sc_rres, BMAN_FBPR_AR, ilog2(size) - 1);
- device_printf(sc->sc_dev, "BMAN Exception: %s.\n", message);
+ return (0);
}
int
bman_attach(device_t dev)
{
struct bman_softc *sc;
- t_BmRevisionInfo rev;
- t_Error error;
- t_BmParam bp;
+ vm_paddr_t bp_pa;
+ size_t bp_size;
+ int bp_count;
sc = device_get_softc(dev);
sc->sc_dev = dev;
bman_sc = sc;
- /* Check if MallocSmart allocator is ready */
- if (XX_MallocSmartInit() != E_OK)
- return (ENXIO);
-
/* Allocate resources */
sc->sc_rrid = 0;
- sc->sc_rres = bus_alloc_resource_anywhere(dev, SYS_RES_MEMORY,
- &sc->sc_rrid, BMAN_CCSR_SIZE, RF_ACTIVE);
+ sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ sc->sc_rrid, RF_ACTIVE);
if (sc->sc_rres == NULL)
return (ENXIO);
@@ -102,36 +181,33 @@ bman_attach(device_t dev)
if (sc->sc_ires == NULL)
goto err;
- /* Initialize BMAN */
- memset(&bp, 0, sizeof(bp));
- bp.guestId = NCSW_MASTER_ID;
- bp.baseAddress = rman_get_bushandle(sc->sc_rres);
- bp.totalNumOfBuffers = BMAN_MAX_BUFFERS;
- bp.f_Exception = bman_exception;
- bp.h_App = sc;
- bp.errIrq = (uintptr_t)sc->sc_ires;
- bp.partBpidBase = 0;
- bp.partNumOfPools = BM_MAX_NUM_OF_POOLS;
-
- sc->sc_bh = BM_Config(&bp);
- if (sc->sc_bh == NULL)
- goto err;
+ bman_get_version(sc);
+ if (sc->sc_major == 2 && sc->sc_minor == 0)
+ bp_count = BMAN_MAX_POOLS_1023;
+ else
+ bp_count = BMAN_MAX_POOLS;
- /* Warn if there is less than 5% free FPBR's in pool */
- error = BM_ConfigFbprThreshold(sc->sc_bh, (BMAN_MAX_BUFFERS / 8) / 20);
- if (error != E_OK)
- goto err;
+ /* TODO: LIODN */
+ bus_write_4(sc->sc_rres, BMAN_LIODNR, 0);
- error = BM_Init(sc->sc_bh);
- if (error != E_OK)
- goto err;
+ sc->sc_vmem = vmem_create("BMan Pools", 0, bp_count, 1, 0, M_WAITOK);
- error = BM_GetRevision(sc->sc_bh, &rev);
- if (error != E_OK)
- goto err;
+ /* Pool is reserved memory, so no need to track it ourselves. */
+ dpaa_map_private_memory(dev, 0, "fsl,bman-fbpr", &bp_pa, &bp_size);
+ bman_set_memory(sc, bp_pa, bp_size);
+
+ /* Warn if FBPR drops below 5% total. */
+ bus_write_4(sc->sc_rres, FBPR_FP_LWIT, (bp_size / 8) / 20);
- device_printf(dev, "Hardware version: %d.%d.\n",
- rev.majorRev, rev.minorRev);
+ /* Clear interrupt status, and enable all interrupts. */
+ bus_write_4(sc->sc_rres, BMAN_ERR_ISR, 0xffffffff);
+ bus_write_4(sc->sc_rres, BMAN_ERR_IER, 0xffffffff);
+ bus_write_4(sc->sc_rres, BMAN_ERR_ISDR, 0);
+
+ /* Enable the IRQ line now. */
+ if (bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_NET, NULL, bman_isr,
+ sc, &sc->sc_icookie) != 0)
+ goto err;
return (0);
@@ -147,9 +223,10 @@ bman_detach(device_t dev)
sc = device_get_softc(dev);
- if (sc->sc_bh != NULL)
- BM_Free(sc->sc_bh);
-
+ if (sc->sc_vmem != NULL)
+ vmem_destroy(sc->sc_vmem);
+ if (sc->sc_icookie != NULL)
+ bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie);
if (sc->sc_ires != NULL)
bus_release_resource(dev, SYS_RES_IRQ,
sc->sc_irid, sc->sc_ires);
@@ -186,179 +263,105 @@ bman_shutdown(device_t dev)
* BMAN API
*/
-t_Handle
-bman_pool_create(uint8_t *bpid, uint16_t bufferSize, uint16_t maxBuffers,
- uint16_t minBuffers, uint16_t allocBuffers, t_GetBufFunction *f_GetBuf,
- t_PutBufFunction *f_PutBuf, uint32_t dep_sw_entry, uint32_t dep_sw_exit,
- uint32_t dep_hw_entry, uint32_t dep_hw_exit,
- t_BmDepletionCallback *f_Depletion, t_Handle h_BufferPool,
- t_PhysToVirt *f_PhysToVirt, t_VirtToPhys *f_VirtToPhys)
+struct bman_pool *
+bman_new_pool(void)
{
- uint32_t thresholds[MAX_DEPLETION_THRESHOLDS];
struct bman_softc *sc;
- t_Handle pool, portal;
- t_BmPoolParam bpp;
- int error;
+ vmem_addr_t bpid;
+ struct bman_pool *pool;
sc = bman_sc;
pool = NULL;
- sched_pin();
-
- portal = bman_portal_setup(sc);
- if (portal == NULL)
- goto err;
-
- memset(&bpp, 0, sizeof(bpp));
- bpp.h_Bm = sc->sc_bh;
- bpp.h_BmPortal = portal;
- bpp.h_App = h_BufferPool;
- bpp.numOfBuffers = allocBuffers;
-
- bpp.bufferPoolInfo.h_BufferPool = h_BufferPool;
- bpp.bufferPoolInfo.f_GetBuf = f_GetBuf;
- bpp.bufferPoolInfo.f_PutBuf = f_PutBuf;
- bpp.bufferPoolInfo.f_PhysToVirt = f_PhysToVirt;
- bpp.bufferPoolInfo.f_VirtToPhys = f_VirtToPhys;
- bpp.bufferPoolInfo.bufferSize = bufferSize;
-
- pool = BM_POOL_Config(&bpp);
- if (pool == NULL)
- goto err;
-
- /*
- * Buffer context must be disabled on FreeBSD
- * as it could cause memory corruption.
- */
- BM_POOL_ConfigBuffContextMode(pool, 0);
-
- if (minBuffers != 0 || maxBuffers != 0) {
- error = BM_POOL_ConfigStockpile(pool, maxBuffers, minBuffers);
- if (error != E_OK)
- goto err;
- }
-
- if (f_Depletion != NULL) {
- thresholds[BM_POOL_DEP_THRESH_SW_ENTRY] = dep_sw_entry;
- thresholds[BM_POOL_DEP_THRESH_SW_EXIT] = dep_sw_exit;
- thresholds[BM_POOL_DEP_THRESH_HW_ENTRY] = dep_hw_entry;
- thresholds[BM_POOL_DEP_THRESH_HW_EXIT] = dep_hw_exit;
- error = BM_POOL_ConfigDepletion(pool, f_Depletion, thresholds);
- if (error != E_OK)
- goto err;
- }
-
- error = BM_POOL_Init(pool);
- if (error != E_OK)
- goto err;
+ if (vmem_alloc(sc->sc_vmem, 1, M_FIRSTFIT | M_NOWAIT, &bpid) != 0)
+ return (NULL);
- *bpid = BM_POOL_GetId(pool);
- sc->sc_bpool_cpu[*bpid] = PCPU_GET(cpuid);
+ pool = malloc(sizeof(*pool), M_BMAN, M_WAITOK | M_ZERO);
- sched_unpin();
+ pool->bpid = bpid;
return (pool);
-
-err:
- if (pool != NULL)
- BM_POOL_Free(pool);
-
- sched_unpin();
-
- return (NULL);
}
-int
-bman_pool_destroy(t_Handle pool)
+struct bman_pool *
+bman_pool_create(uint8_t *bpid, uint16_t buffer_size, uint16_t max_buffers,
+ uint32_t dep_sw_entry, uint32_t dep_sw_exit,
+ uint32_t dep_hw_entry, uint32_t dep_hw_exit,
+ bm_depletion_handler dep_cb, void *arg)
{
struct bman_softc *sc;
+ struct bman_pool *bp;
sc = bman_sc;
- thread_lock(curthread);
- sched_bind(curthread, sc->sc_bpool_cpu[BM_POOL_GetId(pool)]);
- thread_unlock(curthread);
+ bp = bman_new_pool();
+ if (bpid != NULL)
+ *bpid = bp->bpid;
+
+ if (dep_cb) {
+ bp->dep_cb = dep_cb;
+ bus_write_4(sc->sc_rres, BMAN_POOL_SWDET(bp->bpid),
+ dep_sw_entry);
+ bus_write_4(sc->sc_rres, BMAN_POOL_SWDXT(bp->bpid),
+ dep_sw_exit);
+ bus_write_4(sc->sc_rres, BMAN_POOL_HWDET(bp->bpid),
+ dep_hw_entry);
+ bus_write_4(sc->sc_rres, BMAN_POOL_HWDXT(bp->bpid),
+ dep_hw_exit);
+ bp->arg = arg;
+ bman_portal_enable_scn(DPCPU_GET(bman_affine_portal), bp);
+ }
- BM_POOL_Free(pool);
+ return (bp);
+}
- thread_lock(curthread);
- sched_unbind(curthread);
- thread_unlock(curthread);
+int
+bman_pool_destroy(struct bman_pool *pool)
+{
+ /* Need to error, or print a warning, if the pool isn't empty */
+ if (bman_count(pool) != 0)
+ return (EBUSY);
+ vmem_free(bman_sc->sc_vmem, pool->bpid, 1);
+ free(pool, M_BMAN);
return (0);
}
int
-bman_pool_fill(t_Handle pool, uint16_t nbufs)
+bman_put_buffers(struct bman_pool *pool, struct bman_buffer *buffers, int count)
{
- struct bman_softc *sc;
- t_Handle portal;
+ struct bman_portal_softc *portal;
int error;
- sc = bman_sc;
- sched_pin();
+ critical_enter();
- portal = bman_portal_setup(sc);
+ portal = DPCPU_GET(bman_affine_portal);
if (portal == NULL) {
- sched_unpin();
+ critical_exit();
return (EIO);
}
- error = BM_POOL_FillBufs(pool, portal, nbufs);
-
- sched_unpin();
-
- return ((error == E_OK) ? 0 : EIO);
-}
-
-void *
-bman_get_buffer(t_Handle pool)
-{
- struct bman_softc *sc;
- t_Handle portal;
- void *buffer;
-
- sc = bman_sc;
- sched_pin();
-
- portal = bman_portal_setup(sc);
- if (portal == NULL) {
- sched_unpin();
- return (NULL);
+ while (count > 0) {
+ int c = min(count, 8);
+ error = bman_release(pool, buffers, c);
+ buffers += c;
+ count -= c;
}
- buffer = BM_POOL_GetBuf(pool, portal);
+ critical_exit();
- sched_unpin();
-
- return (buffer);
+ return (error);
}
-int
-bman_put_buffer(t_Handle pool, void *buffer)
+uint32_t
+bman_get_bpid(struct bman_pool *pool)
{
- struct bman_softc *sc;
- t_Handle portal;
- int error;
-
- sc = bman_sc;
- sched_pin();
-
- portal = bman_portal_setup(sc);
- if (portal == NULL) {
- sched_unpin();
- return (EIO);
- }
-
- error = BM_POOL_PutBuf(pool, portal, buffer);
-
- sched_unpin();
-
- return ((error == E_OK) ? 0 : EIO);
+ return (pool->bpid);
}
uint32_t
-bman_count(t_Handle pool)
+bman_count(struct bman_pool *pool)
{
- return (BM_POOL_GetCounter(pool, e_BM_POOL_COUNTERS_CONTENT));
+ return (bus_read_4(bman_sc->sc_rres, BMAN_POOL_CONTENT(pool->bpid)));
}
+
diff --git a/sys/dev/dpaa/bman.h b/sys/dev/dpaa/bman.h
index 01c09489890c..d8a76bfa672b 100644
--- a/sys/dev/dpaa/bman.h
+++ b/sys/dev/dpaa/bman.h
@@ -1,3 +1,9 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 Justin Hibbits
+ */
+
/*-
* Copyright (c) 2011-2012 Semihalf.
* All rights reserved.
@@ -27,29 +33,16 @@
#ifndef _BMAN_H
#define _BMAN_H
+#include <sys/vmem.h>
#include <machine/vmparam.h>
-#include <contrib/ncsw/inc/Peripherals/bm_ext.h>
-
/*
* BMAN Configuration
*/
-/* Maximum number of buffers in all BMAN pools */
-#define BMAN_MAX_BUFFERS 4096
-
/*
* Portal definitions
*/
-#define BMAN_CE_PA(base) (base)
-#define BMAN_CI_PA(base) ((base) + 0x100000)
-
-#define BMAN_PORTAL_CE_PA(base, n) \
- (BMAN_CE_PA(base) + ((n) * BMAN_PORTAL_CE_SIZE))
-#define BMAN_PORTAL_CI_PA(base, n) \
- (BMAN_CI_PA(base) + ((n) * BMAN_PORTAL_CI_SIZE))
-
-#define BMAN_CCSR_SIZE 0x1000
struct bman_softc {
device_t sc_dev; /* device handle */
@@ -57,129 +50,42 @@ struct bman_softc {
struct resource *sc_rres; /* register resource */
int sc_irid; /* interrupt rid */
struct resource *sc_ires; /* interrupt resource */
+ void *sc_icookie;
+ vmem_t *sc_vmem; /* resource pool */
+ int sc_major;
+ int sc_minor;
+};
- bool sc_regs_mapped[MAXCPU]; /* register mapping status */
+struct bman_buffer {
+ uint16_t bpid;
+ uint16_t buf_hi;
+ uint32_t buf_lo;
+} __aligned(8);
- t_Handle sc_bh; /* BMAN handle */
- t_Handle sc_bph[MAXCPU]; /* BMAN portal handles */
- vm_paddr_t sc_bp_pa; /* BMAN portals PA */
- unsigned int sc_bpool_cpu[BM_MAX_NUM_OF_POOLS];
-};
+struct bman_pool;
+struct bman_buffer;
-/*
- * External API
- */
+typedef void (*bm_depletion_handler)(void *, bool);
/*
- * @brief Function to create BMAN pool.
- *
- * @param bpid The pointer to variable where Buffer Pool ID will be
- * stored.
- *
- * @param bufferSize The size of buffers in newly created pool.
- *
- * @param maxBuffers The maximum number of buffers in software stockpile.
- * Set to 0 if software stockpile should not be created.
- *
- * @param minBuffers The minimum number of buffers in software stockpile.
- * Set to 0 if software stockpile should not be created.
- *
- * @param allocBuffers The number of buffers to preallocate during pool
- * creation.
- *
- * @param f_GetBuf The buffer allocating function. Called only by
- * bman_pool_create() and bman_pool_fill().
- *
- * @param f_PutBuf The buffer freeing function. Called only by
- * bman_pool_destroy().
- *
- * @param dep_sw_entry The software portal depletion entry threshold.
- * Set to 0 if depletion should not be signaled on
- * software portal.
- *
- * @param dep_sw_exit The software portal depletion exit threshold.
- * Set to 0 if depletion should not be signaled on
- * software portal.
- *
- * @param dep_hw_entry The hardware portal depletion entry threshold.
- * Set to 0 if depletion should not be signaled on
- * hardware portal.
- *
- * @param dep_hw_exit The hardware portal depletion exit threshold.
- * Set to 0 if depletion should not be signaled on
- * hardware portal.
- *
- * @param f_Depletion The software portal depletion notification function.
- * Set to NULL if depletion notification is not used.
- *
- * @param h_BufferPool The user provided buffer pool context passed to
- * f_GetBuf, f_PutBuf and f_Depletion functions.
- *
- * @param f_PhysToVirt The PA to VA translation function. Set to NULL if
- * default one should be used.
- *
- * @param f_VirtToPhys The VA to PA translation function. Set to NULL if
- * default one should be used.
- *
- * @returns Handle to newly created BMAN pool or NULL on error.
- *
- * @cautions If pool uses software stockpile, all accesses to given
- * pool must be protected by lock. Even if only hardware
- * portal depletion notification is used, the caller must
- * provide valid @p f_Depletion function.
+ * External API
*/
-t_Handle bman_pool_create(uint8_t *bpid, uint16_t bufferSize,
- uint16_t maxBuffers, uint16_t minBuffers, uint16_t allocBuffers,
- t_GetBufFunction *f_GetBuf, t_PutBufFunction *f_PutBuf,
- uint32_t dep_sw_entry, uint32_t dep_sw_exit, uint32_t dep_hw_entry,
- uint32_t dep_hw_exit, t_BmDepletionCallback *f_Depletion,
- t_Handle h_BufferPool, t_PhysToVirt *f_PhysToVirt,
- t_VirtToPhys *f_VirtToPhys);
-/*
- * @brief Fill pool with buffers.
- *
- * The bman_pool_fill() function fills the BMAN pool with buffers. The buffers
- * are allocated through f_GetBuf function (see bman_pool_create() description).
- *
- * @param pool The BMAN pool handle.
- * @param nbufs The number of buffers to allocate. To maximize
- * performance this value should be multiple of 8.
- *
- * @returns Zero on success or error code on failure.
- */
-int bman_pool_fill(t_Handle pool, uint16_t nbufs);
+struct bman_pool *bman_new_pool(void);
+struct bman_pool *bman_pool_create(uint8_t *bpid, uint16_t buffer_size,
+ uint16_t max_buffers, uint32_t dep_sw_entry, uint32_t dep_sw_exit, uint32_t
+ dep_hw_entry, uint32_t dep_hw_exit, bm_depletion_handler dep_cb, void *arg);
/*
* @brief Destroy pool.
*
- * The bman_pool_destroy() function destroys the BMAN pool. Buffers for pool
- * are free through f_PutBuf function (see bman_pool_create() description).
+ * The bman_pool_destroy() function destroys the BMAN pool.
+ * The buffer pool must be empty.
*
* @param pool The BMAN pool handle.
- *
- * @returns Zero on success or error code on failure.
- */
-int bman_pool_destroy(t_Handle pool);
-
-/*
- * @brief Get a buffer from BMAN pool.
- *
- * @param pool The BMAN pool handle.
- *
- * @returns Pointer to the buffer or NULL if pool is empty.
- */
-void *bman_get_buffer(t_Handle pool);
-
-/*
- * @brief Put a buffer to BMAN pool.
- *
- * @param pool The BMAN pool handle.
- * @param buffer The pointer to buffer.
- *
- * @returns Zero on success or error code on failure.
+ * @return 0 on success, EBUSY if the pool is not empty.
*/
-int bman_put_buffer(t_Handle pool, void *buffer);
+int bman_pool_destroy(struct bman_pool *pool);
/*
* @brief Count free buffers in given pool.
@@ -188,7 +94,25 @@ int bman_put_buffer(t_Handle pool, void *buffer);
*
* @returns Number of free buffers in pool.
*/
-uint32_t bman_count(t_Handle pool);
+uint32_t bman_count(struct bman_pool *pool);
+
+int bman_put_buffers(struct bman_pool *, struct bman_buffer *, int);
+static inline int
+bman_put_buffer(struct bman_pool *p, vm_paddr_t buf, int bpid)
+{
+ struct bman_buffer b = {
+ .bpid = bpid,
+ .buf_hi = ((uintptr_t)buf) >> 32,
+ .buf_lo = ((uintptr_t)buf) & 0xffffffff
+ };
+ return (bman_put_buffers(p, &b, 1));
+}
+
+int bman_acquire(struct bman_pool *, struct bman_buffer *, uint8_t);
+
+int bman_create_affine_portal(device_t, vm_offset_t, vm_offset_t, int);
+void bman_destroy_affine_portal(int);
+uint32_t bman_get_bpid(struct bman_pool *);
/*
* Bus i/f
diff --git a/sys/dev/dpaa/bman_fdt.c b/sys/dev/dpaa/bman_fdt.c
index 330db7b89715..c77d58cf118d 100644
--- a/sys/dev/dpaa/bman_fdt.c
+++ b/sys/dev/dpaa/bman_fdt.c
@@ -40,6 +40,7 @@
#include <dev/ofw/ofw_subr.h>
#include "bman.h"
+#include "bman_var.h"
#include "portals.h"
#define FBMAN_DEVSTR "Freescale Buffer Manager"
@@ -59,12 +60,7 @@ static device_method_t bman_methods[] = {
DEVMETHOD_END
};
-static driver_t bman_driver = {
- "bman",
- bman_methods,
- sizeof(struct bman_softc),
-};
-
+DEFINE_CLASS_0(bman, bman_driver, bman_methods, sizeof(struct bman_softc));
EARLY_DRIVER_MODULE(bman, simplebus, bman_driver, 0, 0, BUS_PASS_SUPPORTDEV);
static int
@@ -82,144 +78,46 @@ bman_fdt_probe(device_t dev)
/*
* BMAN Portals
*/
-#define BMAN_PORT_DEVSTR "Freescale Buffer Manager - Portals"
+#define BMAN_PORT_DEVSTR "Freescale Buffer Manager - Portal"
-static device_probe_t bman_portals_fdt_probe;
-static device_attach_t bman_portals_fdt_attach;
+static int portal_ncpus;
+static device_probe_t bman_portal_fdt_probe;
+static device_attach_t bman_portal_fdt_attach;
-static device_method_t bm_portals_methods[] = {
+static device_method_t bman_portal_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, bman_portals_fdt_probe),
- DEVMETHOD(device_attach, bman_portals_fdt_attach),
- DEVMETHOD(device_detach, bman_portals_detach),
+ DEVMETHOD(device_probe, bman_portal_fdt_probe),
+ DEVMETHOD(device_attach, bman_portal_fdt_attach),
+ DEVMETHOD(device_detach, bman_portal_detach),
DEVMETHOD_END
};
-static driver_t bm_portals_driver = {
- "bman-portals",
- bm_portals_methods,
- sizeof(struct dpaa_portals_softc),
-};
-
-EARLY_DRIVER_MODULE(bman_portals, ofwbus, bm_portals_driver, 0, 0,
- BUS_PASS_BUS);
-
-static void
-get_addr_props(phandle_t node, uint32_t *addrp, uint32_t *sizep)
-{
-
- *addrp = 2;
- *sizep = 1;
- OF_getencprop(node, "#address-cells", addrp, sizeof(*addrp));
- OF_getencprop(node, "#size-cells", sizep, sizeof(*sizep));
-}
+DEFINE_CLASS_0(bman_portal, bman_portal_driver, bman_portal_methods,
+ sizeof(struct bman_portal_softc));
+EARLY_DRIVER_MODULE(bman_portal, simplebus, bman_portal_driver, 0, 0,
+ BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE);
static int
-bman_portals_fdt_probe(device_t dev)
+bman_portal_fdt_probe(device_t dev)
{
- phandle_t node;
-
- if (ofw_bus_is_compatible(dev, "simple-bus")) {
*** 9976 LINES SKIPPED ***