Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 03 May 2026 19:11:57 +0000
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: fd8d34ce272b - main - dpaa: Migrate from NCSW base to a home-grown driver
Message-ID:  <69f79dfd.3d681.162b0f5@gitrepo.freebsd.org>

index | next in thread | raw e-mail

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 ***


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f79dfd.3d681.162b0f5>