git: 8e994533806d - main - dpaa2: Extract frame-specific routines to dpaa2_frame.[h,c]
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 08 Apr 2026 19:48:53 UTC
The branch main has been updated by dsl:
URL: https://cgit.FreeBSD.org/src/commit/?id=8e994533806d8aa0ae4582a52d811ede2b19bb26
commit 8e994533806d8aa0ae4582a52d811ede2b19bb26
Author: Dmitry Salychev <dsl@FreeBSD.org>
AuthorDate: 2026-01-25 16:53:57 +0000
Commit: Dmitry Salychev <dsl@FreeBSD.org>
CommitDate: 2026-04-08 19:48:11 +0000
dpaa2: Extract frame-specific routines to dpaa2_frame.[h,c]
As soon as we need information from the hardware frame annotation to
make sure that checksums of the ingress frames were verified by the
DPAA2 HW, I've decided to make a preparation and extracted all of the
frame related routines into the separate dpaa2_frame.[h,c] along with
some clean up and improvements, e.g. no more dpaa2_fa, but dpaa2_swa
and dpaa2_hwa structures to describe software and hardware frame
annotations respectively, dpaa2_fa_get_swa/dpaa2_fa_get_hwa to obtain
those annotations from the frame descriptor. The next step is to
implement dpaa2_fa_get_hwa.
PR: 292006
Approved by: tuexen
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D56315
---
sys/conf/files.arm64 | 1 +
sys/dev/dpaa2/dpaa2_buf.c | 9 +-
sys/dev/dpaa2/dpaa2_buf.h | 2 +
sys/dev/dpaa2/dpaa2_frame.c | 165 ++++++++++++++++++++++++++++++++++
sys/dev/dpaa2/dpaa2_frame.h | 174 ++++++++++++++++++++++++++++++++++++
sys/dev/dpaa2/dpaa2_ni.c | 210 ++++++++++++++------------------------------
sys/dev/dpaa2/dpaa2_ni.h | 3 +-
sys/dev/dpaa2/dpaa2_swp.h | 51 +----------
sys/dev/dpaa2/dpaa2_types.h | 5 ++
sys/modules/dpaa2/Makefile | 1 +
10 files changed, 420 insertions(+), 201 deletions(-)
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index 2a607748db8d..59a65a8251ca 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -262,6 +262,7 @@ dev/dpaa2/dpaa2_channel.c optional soc_nxp_ls dpaa2
dev/dpaa2/dpaa2_cmd_if.m optional soc_nxp_ls dpaa2
dev/dpaa2/dpaa2_con.c optional soc_nxp_ls dpaa2
dev/dpaa2/dpaa2_console.c optional soc_nxp_ls dpaa2 fdt
+dev/dpaa2/dpaa2_frame.c optional soc_nxp_ls dpaa2
dev/dpaa2/dpaa2_io.c optional soc_nxp_ls dpaa2
dev/dpaa2/dpaa2_mac.c optional soc_nxp_ls dpaa2
dev/dpaa2/dpaa2_mc.c optional soc_nxp_ls dpaa2
diff --git a/sys/dev/dpaa2/dpaa2_buf.c b/sys/dev/dpaa2/dpaa2_buf.c
index 8505b074fe4f..228e4448210d 100644
--- a/sys/dev/dpaa2/dpaa2_buf.c
+++ b/sys/dev/dpaa2/dpaa2_buf.c
@@ -42,6 +42,7 @@
#include "dpaa2_swp.h"
#include "dpaa2_swp_if.h"
#include "dpaa2_ni.h"
+#include "dpaa2_frame.h"
MALLOC_DEFINE(M_DPAA2_RXB, "dpaa2_rxb", "DPAA2 DMA-mapped buffer (Rx)");
@@ -129,7 +130,7 @@ dpaa2_buf_seed_rxb(device_t dev, struct dpaa2_buf *buf, int size,
struct mtx *dma_mtx)
{
struct dpaa2_ni_softc *sc = device_get_softc(dev);
- struct dpaa2_fa *fa;
+ struct dpaa2_swa *swa;
bool map_created = false;
bool mbuf_alloc = false;
int error;
@@ -179,9 +180,9 @@ dpaa2_buf_seed_rxb(device_t dev, struct dpaa2_buf *buf, int size,
buf->vaddr = buf->m->m_data;
/* Populate frame annotation for future use */
- fa = (struct dpaa2_fa *)buf->vaddr;
- fa->magic = DPAA2_MAGIC;
- fa->buf = buf;
+ swa = (struct dpaa2_swa *)buf->vaddr;
+ swa->magic = DPAA2_MAGIC;
+ swa->buf = buf;
bus_dmamap_sync(buf->dmat, buf->dmap, BUS_DMASYNC_PREREAD);
diff --git a/sys/dev/dpaa2/dpaa2_buf.h b/sys/dev/dpaa2/dpaa2_buf.h
index 853a4fa78d3a..16ea7e1905ac 100644
--- a/sys/dev/dpaa2/dpaa2_buf.h
+++ b/sys/dev/dpaa2/dpaa2_buf.h
@@ -33,6 +33,8 @@
#include <sys/malloc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
#include <machine/bus.h>
diff --git a/sys/dev/dpaa2/dpaa2_frame.c b/sys/dev/dpaa2/dpaa2_frame.c
new file mode 100644
index 000000000000..4a155f7cb32f
--- /dev/null
+++ b/sys/dev/dpaa2/dpaa2_frame.c
@@ -0,0 +1,165 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright © 2026 Dmitry Salychev
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/errno.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/vmparam.h>
+
+#include "dpaa2_types.h"
+#include "dpaa2_frame.h"
+#include "dpaa2_buf.h"
+#include "dpaa2_swp.h"
+
+/**
+ * @brief Build a DPAA2 frame descriptor.
+ */
+int
+dpaa2_fd_build(device_t dev, const uint16_t tx_data_off, struct dpaa2_buf *buf,
+ bus_dma_segment_t *segs, const int nsegs, struct dpaa2_fd *fd)
+{
+ struct dpaa2_buf *sgt = buf->sgt;
+ struct dpaa2_sg_entry *sge;
+ struct dpaa2_swa *swa;
+ int i, error;
+
+ if (buf == NULL || segs == NULL || nsegs == 0 || fd == NULL)
+ return (EINVAL);
+
+ KASSERT(nsegs <= DPAA2_TX_SEGLIMIT, ("%s: too many segments", __func__));
+ KASSERT(buf->opt != NULL, ("%s: no Tx ring?", __func__));
+ KASSERT(sgt != NULL, ("%s: no S/G table?", __func__));
+ KASSERT(sgt->vaddr != NULL, ("%s: no S/G vaddr?", __func__));
+
+ memset(fd, 0, sizeof(*fd));
+
+ /* Populate and map S/G table */
+ if (__predict_true(nsegs <= DPAA2_TX_SEGLIMIT)) {
+ sge = (struct dpaa2_sg_entry *)sgt->vaddr + tx_data_off;
+ for (i = 0; i < nsegs; i++) {
+ sge[i].addr = (uint64_t)segs[i].ds_addr;
+ sge[i].len = (uint32_t)segs[i].ds_len;
+ sge[i].offset_fmt = 0u;
+ }
+ sge[i-1].offset_fmt |= 0x8000u; /* set final entry flag */
+
+ KASSERT(sgt->paddr == 0, ("%s: paddr(%#jx) != 0", __func__,
+ sgt->paddr));
+
+ error = bus_dmamap_load(sgt->dmat, sgt->dmap, sgt->vaddr,
+ DPAA2_TX_SGT_SZ, dpaa2_dmamap_oneseg_cb, &sgt->paddr,
+ BUS_DMA_NOWAIT);
+ if (__predict_false(error != 0)) {
+ device_printf(dev, "%s: bus_dmamap_load() failed: "
+ "error=%d\n", __func__, error);
+ return (error);
+ }
+
+ buf->paddr = sgt->paddr;
+ buf->vaddr = sgt->vaddr;
+ } else {
+ return (EINVAL);
+ }
+
+ swa = (struct dpaa2_swa *)sgt->vaddr;
+ swa->magic = DPAA2_MAGIC;
+ swa->buf = buf;
+
+ fd->addr = buf->paddr;
+ fd->data_length = (uint32_t)buf->m->m_pkthdr.len;
+ fd->bpid_ivp_bmt = 0;
+ fd->offset_fmt_sl = 0x2000u | tx_data_off;
+ fd->ctrl = (0x4u & DPAA2_FD_PTAC_MASK) << DPAA2_FD_PTAC_SHIFT;
+
+ return (0);
+}
+
+int
+dpaa2_fd_err(struct dpaa2_fd *fd)
+{
+ return ((fd->ctrl >> DPAA2_FD_ERR_SHIFT) & DPAA2_FD_ERR_MASK);
+}
+
+uint32_t
+dpaa2_fd_data_len(struct dpaa2_fd *fd)
+{
+ if (dpaa2_fd_short_len(fd)) {
+ return (fd->data_length & DPAA2_FD_LEN_MASK);
+ }
+ return (fd->data_length);
+}
+
+int
+dpaa2_fd_format(struct dpaa2_fd *fd)
+{
+ return ((enum dpaa2_fd_format)((fd->offset_fmt_sl >>
+ DPAA2_FD_FMT_SHIFT) & DPAA2_FD_FMT_MASK));
+}
+
+bool
+dpaa2_fd_short_len(struct dpaa2_fd *fd)
+{
+ return (((fd->offset_fmt_sl >> DPAA2_FD_SL_SHIFT)
+ & DPAA2_FD_SL_MASK) == 1);
+}
+
+int
+dpaa2_fd_offset(struct dpaa2_fd *fd)
+{
+ return (fd->offset_fmt_sl & DPAA2_FD_OFFSET_MASK);
+}
+
+int
+dpaa2_fa_get_swa(struct dpaa2_fd *fd, struct dpaa2_swa **swa)
+{
+ int rc;
+
+ if (fd == NULL || swa == NULL)
+ return (EINVAL);
+
+ if (((fd->ctrl >> DPAA2_FD_PTAC_SHIFT) & DPAA2_FD_PTAC_MASK) >= 0x4u) {
+ *swa = (struct dpaa2_swa *)PHYS_TO_DMAP((bus_addr_t)fd->addr);
+ rc = 0;
+ } else {
+ *swa = NULL;
+ rc = ENOENT;
+ }
+
+ return (rc);
+}
+
+int
+dpaa2_fa_get_hwa(struct dpaa2_fd *fd, struct dpaa2_hwa **hwa)
+{
+ /* TODO: To be implemented next. */
+ return (ENOENT);
+}
diff --git a/sys/dev/dpaa2/dpaa2_frame.h b/sys/dev/dpaa2/dpaa2_frame.h
new file mode 100644
index 000000000000..0b2a5a7d8e74
--- /dev/null
+++ b/sys/dev/dpaa2/dpaa2_frame.h
@@ -0,0 +1,174 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright © 2026 Dmitry Salychev
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#ifndef _DPAA2_FRAME_H
+#define _DPAA2_FRAME_H
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/kassert.h>
+
+#include "dpaa2_types.h"
+#include "dpaa2_buf.h"
+
+/*
+ * Helper routines for the DPAA2 frames (e.g. descriptors, software/hardware
+ * annotations, etc.).
+ */
+
+/*
+ * DPAA2 frame descriptor size, field offsets and masks.
+ *
+ * See 3.1.1 Frame descriptor format,
+ * 4.2.1.2.2 Structure of Frame Descriptors (FDs),
+ * LX2160A DPAA2 Low-Level Hardware Reference Manual, Rev. 0, 06/2020
+ */
+#define DPAA2_FD_SIZE 32u
+#define DPAA2_FD_FMT_MASK (0x3u)
+#define DPAA2_FD_FMT_SHIFT (12)
+#define DPAA2_FD_ERR_MASK (0xFFu)
+#define DPAA2_FD_ERR_SHIFT (0)
+#define DPAA2_FD_SL_MASK (0x1u)
+#define DPAA2_FD_SL_SHIFT (14)
+#define DPAA2_FD_LEN_MASK (0x3FFFFu)
+#define DPAA2_FD_OFFSET_MASK (0x0FFFu)
+#define DPAA2_FD_PTAC_MASK (0x7u)
+#define DPAA2_FD_PTAC_SHIFT (21)
+
+/*
+ * DPAA2 frame annotation sizes
+ *
+ * NOTE: Accelerator-specific (HWA) annotation length is described in the 64-byte
+ * units by the FD[ASAL] bits and can be as big as 960 bytes. Current
+ * values describe what is actually supported by the DPAA2 drivers.
+ *
+ * See 3.1.1 Frame descriptor format,
+ * LX2160A DPAA2 Low-Level Hardware Reference Manual, Rev. 0
+ */
+#define DPAA2_FA_SIZE 192u /* DPAA2 frame annotation */
+#define DPAA2_FA_SWA_SIZE 64u /* SW frame annotation */
+#define DPAA2_FA_HWA_SIZE 128u /* HW frame annotation */
+#define DPAA2_FA_WRIOP_SIZE 128u /* WRIOP HW annotation */
+
+/**
+ * @brief DPAA2 frame descriptor.
+ *
+ * addr: Memory address of the start of the buffer holding the
+ * frame data or the buffer containing the scatter/gather
+ * list.
+ * data_length: Length of the frame data (in bytes).
+ * bpid_ivp_bmt: Buffer pool ID (14 bit + BMT bit + IVP bit)
+ * offset_fmt_sl: Frame data offset, frame format and short-length fields.
+ * frame_ctx: Frame context. This field allows the sender of a frame
+ * to communicate some out-of-band information to the
+ * receiver of the frame.
+ * ctrl: Control bits (ERR, CBMT, ASAL, PTAC, DROPP, SC, DD).
+ * flow_ctx: Frame flow context. Associates the frame with a flow
+ * structure. QMan may use the FLC field for 3 purposes:
+ * stashing control, order definition point identification,
+ * and enqueue replication control.
+ *
+ * See 3.1.1 Frame descriptor format,
+ * 4.2.1.2.2 Structure of Frame Descriptors (FDs),
+ * LX2160A DPAA2 Low-Level Hardware Reference Manual, Rev. 0, 06/2020
+ */
+struct dpaa2_fd {
+ uint64_t addr;
+ uint32_t data_length;
+ uint16_t bpid_ivp_bmt;
+ uint16_t offset_fmt_sl;
+ uint32_t frame_ctx;
+ uint32_t ctrl;
+ uint64_t flow_ctx;
+} __packed;
+CTASSERT(sizeof(struct dpaa2_fd) == DPAA2_FD_SIZE);
+
+/**
+ * @brief WRIOP hardware frame annotation.
+ *
+ * See 7.34.2 WRIOP hardware frame annotation (FA),
+ * LX2160A DPAA2 Low-Level Hardware Reference Manual, Rev. 0, 06/2020
+ */
+struct dpaa2_hwa_wriop {
+ union {
+ struct {
+ uint64_t fas;
+ uint64_t timestamp;
+ /* XXX-DSL: more to add here... */
+ } __packed;
+ uint8_t raw[128];
+ };
+} __packed;
+CTASSERT(sizeof(struct dpaa2_hwa_wriop) == DPAA2_FA_WRIOP_SIZE);
+
+/**
+ * @brief DPAA2 hardware frame annotation (accelerator-specific annotation).
+ *
+ * See 3.4.1.2 Accelerator-specific annotation,
+ * LX2160A DPAA2 Low-Level Hardware Reference Manual, Rev. 0, 06/2020
+ */
+struct dpaa2_hwa {
+ union {
+ struct dpaa2_hwa_wriop wriop;
+ };
+} __packed;
+CTASSERT(sizeof(struct dpaa2_hwa) == DPAA2_FA_HWA_SIZE);
+
+/**
+ * @brief DPAA2 software frame annotation (pass-through annotation).
+ *
+ * See 3.4.1.1 Pass-through annotation,
+ * LX2160A DPAA2 Low-Level Hardware Reference Manual, Rev. 0, 06/2020
+ */
+struct dpaa2_swa {
+ union {
+ struct {
+ uint32_t magic;
+ struct dpaa2_buf *buf;
+ };
+ struct {
+ uint8_t pta1[32];
+ uint8_t pta2[32];
+ };
+ uint8_t raw[64];
+ };
+} __packed;
+CTASSERT(sizeof(struct dpaa2_swa) == DPAA2_FA_SWA_SIZE);
+
+int dpaa2_fd_build(device_t, const uint16_t, struct dpaa2_buf *,
+ bus_dma_segment_t *, const int, struct dpaa2_fd *);
+
+int dpaa2_fd_err(struct dpaa2_fd *);
+uint32_t dpaa2_fd_data_len(struct dpaa2_fd *);
+int dpaa2_fd_format(struct dpaa2_fd *);
+bool dpaa2_fd_short_len(struct dpaa2_fd *);
+int dpaa2_fd_offset(struct dpaa2_fd *);
+
+int dpaa2_fa_get_swa(struct dpaa2_fd *, struct dpaa2_swa **);
+int dpaa2_fa_get_hwa(struct dpaa2_fd *, struct dpaa2_hwa **);
+
+#endif /* _DPAA2_FRAME_H */
diff --git a/sys/dev/dpaa2/dpaa2_ni.c b/sys/dev/dpaa2/dpaa2_ni.c
index 49e72c8ee14f..5017b5113109 100644
--- a/sys/dev/dpaa2/dpaa2_ni.c
+++ b/sys/dev/dpaa2/dpaa2_ni.c
@@ -96,6 +96,7 @@
#include "dpaa2_ni.h"
#include "dpaa2_channel.h"
#include "dpaa2_buf.h"
+#include "dpaa2_frame.h"
#define BIT(x) (1ul << (x))
#define WRIOP_VERSION(x, y, z) ((x) << 10 | (y) << 5 | (z) << 0)
@@ -156,10 +157,6 @@ MALLOC_DEFINE(M_DPAA2_TXB, "dpaa2_txb", "DPAA2 DMA-mapped buffer (Tx)");
#define DPAA2_RX_BUFRING_SZ (4096u)
#define DPAA2_RXE_BUFRING_SZ (1024u)
#define DPAA2_TXC_BUFRING_SZ (4096u)
-#define DPAA2_TX_SEGLIMIT (16u) /* arbitrary number */
-#define DPAA2_TX_SEG_SZ (PAGE_SIZE)
-#define DPAA2_TX_SEGS_MAXSZ (DPAA2_TX_SEGLIMIT * DPAA2_TX_SEG_SZ)
-#define DPAA2_TX_SGT_SZ (PAGE_SIZE) /* bytes */
/* Size of a buffer to keep a QoS table key configuration. */
#define ETH_QOS_KCFG_BUF_SIZE (PAGE_SIZE)
@@ -186,15 +183,6 @@ MALLOC_DEFINE(M_DPAA2_TXB, "dpaa2_txb", "DPAA2 DMA-mapped buffer (Tx)");
#define DPAA2_NI_TXBUF_IDX_MASK (0xFFu)
#define DPAA2_NI_TXBUF_IDX_SHIFT (49)
-#define DPAA2_NI_FD_FMT_MASK (0x3u)
-#define DPAA2_NI_FD_FMT_SHIFT (12)
-#define DPAA2_NI_FD_ERR_MASK (0xFFu)
-#define DPAA2_NI_FD_ERR_SHIFT (0)
-#define DPAA2_NI_FD_SL_MASK (0x1u)
-#define DPAA2_NI_FD_SL_SHIFT (14)
-#define DPAA2_NI_FD_LEN_MASK (0x3FFFFu)
-#define DPAA2_NI_FD_OFFSET_MASK (0x0FFFu)
-
/* Enables TCAM for Flow Steering and QoS look-ups. */
#define DPNI_OPT_HAS_KEY_MASKING 0x10
@@ -424,15 +412,6 @@ static int dpaa2_ni_set_mac_addr(device_t);
static int dpaa2_ni_set_hash(device_t, uint64_t);
static int dpaa2_ni_set_dist_key(device_t, enum dpaa2_ni_dist_mode, uint64_t);
-/* Frame descriptor routines */
-static int dpaa2_ni_build_fd(struct dpaa2_ni_softc *, struct dpaa2_ni_tx_ring *,
- struct dpaa2_buf *, bus_dma_segment_t *, int, struct dpaa2_fd *);
-static int dpaa2_ni_fd_err(struct dpaa2_fd *);
-static uint32_t dpaa2_ni_fd_data_len(struct dpaa2_fd *);
-static int dpaa2_ni_fd_format(struct dpaa2_fd *);
-static bool dpaa2_ni_fd_short_len(struct dpaa2_fd *);
-static int dpaa2_ni_fd_offset(struct dpaa2_fd *);
-
/* Various subroutines */
static int dpaa2_ni_cmp_api_version(struct dpaa2_ni_softc *, uint16_t, uint16_t);
static int dpaa2_ni_prepare_key_cfg(struct dpkg_profile_cfg *, uint8_t *);
@@ -2995,14 +2974,15 @@ dpaa2_ni_tx(struct dpaa2_ni_softc *sc, struct dpaa2_channel *ch,
}
}
- error = dpaa2_ni_build_fd(sc, tx, buf, segs, nsegs, &fd);
+ error = dpaa2_fd_build(dev, sc->tx_data_off, buf, segs, nsegs, &fd);
if (__predict_false(error != 0)) {
device_printf(dev, "%s: failed to build frame descriptor: "
"error=%d\n", __func__, error);
fq->chan->tx_dropped++;
if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
goto err_unload;
- }
+ } else
+ sc->tx_sg_frames++; /* for sysctl(9) */
bus_dmamap_sync(buf->dmat, buf->dmap, BUS_DMASYNC_PREWRITE);
bus_dmamap_sync(sgt->dmat, sgt->dmap, BUS_DMASYNC_PREWRITE);
@@ -3130,14 +3110,14 @@ dpaa2_ni_consume_frames(struct dpaa2_channel *chan, struct dpaa2_ni_fq **src,
* @brief Receive frames.
*/
static int
-dpaa2_ni_rx(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq, struct dpaa2_fd *fd,
- struct dpaa2_ni_rx_ctx *ctx)
+dpaa2_ni_rx(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq,
+ struct dpaa2_fd *fd, struct dpaa2_ni_rx_ctx *ctx)
{
- bus_addr_t paddr = (bus_addr_t)fd->addr;
- struct dpaa2_fa *fa = (struct dpaa2_fa *)PHYS_TO_DMAP(paddr);
- struct dpaa2_buf *buf = fa->buf;
- struct dpaa2_channel *bch = (struct dpaa2_channel *)buf->opt;
- struct dpaa2_ni_softc *sc = device_get_softc(bch->ni_dev);
+ bus_addr_t paddr;
+ struct dpaa2_swa *swa;
+ struct dpaa2_buf *buf;
+ struct dpaa2_channel *bch;
+ struct dpaa2_ni_softc *sc;
struct dpaa2_bp_softc *bpsc;
struct mbuf *m;
device_t bpdev;
@@ -3145,7 +3125,17 @@ dpaa2_ni_rx(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq, struct dpaa2_fd *f
void *buf_data;
int buf_len, error, released_n = 0;
- KASSERT(fa->magic == DPAA2_MAGIC, ("%s: wrong magic", __func__));
+ error = dpaa2_fa_get_swa(fd, &swa);
+ if (__predict_false(error != 0))
+ panic("%s: frame has no software annotation: error=%d",
+ __func__, error);
+
+ paddr = (bus_addr_t)fd->addr;
+ buf = swa->buf;
+ bch = (struct dpaa2_channel *)buf->opt;
+ sc = device_get_softc(bch->ni_dev);
+
+ KASSERT(swa->magic == DPAA2_MAGIC, ("%s: wrong magic", __func__));
/*
* NOTE: Current channel might not be the same as the "buffer" channel
* and it's fine. It must not be NULL though.
@@ -3157,7 +3147,7 @@ dpaa2_ni_rx(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq, struct dpaa2_fd *f
__func__, paddr, buf->paddr);
}
- switch (dpaa2_ni_fd_err(fd)) {
+ switch (dpaa2_fd_err(fd)) {
case 1: /* Enqueue rejected by QMan */
sc->rx_enq_rej_frames++;
break;
@@ -3167,7 +3157,7 @@ dpaa2_ni_rx(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq, struct dpaa2_fd *f
default:
break;
}
- switch (dpaa2_ni_fd_format(fd)) {
+ switch (dpaa2_fd_format(fd)) {
case DPAA2_FD_SINGLE:
sc->rx_single_buf_frames++;
break;
@@ -3183,9 +3173,11 @@ dpaa2_ni_rx(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq, struct dpaa2_fd *f
bus_dmamap_sync(buf->dmat, buf->dmap, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(buf->dmat, buf->dmap);
+
m = buf->m;
- buf_len = dpaa2_ni_fd_data_len(fd);
- buf_data = (uint8_t *)buf->vaddr + dpaa2_ni_fd_offset(fd);
+ buf_len = dpaa2_fd_data_len(fd);
+ buf_data = (uint8_t *)buf->vaddr + dpaa2_fd_offset(fd);
+
/* Prepare buffer to be re-cycled */
buf->m = NULL;
buf->paddr = 0;
@@ -3273,16 +3265,26 @@ static int
dpaa2_ni_rx_err(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq,
struct dpaa2_fd *fd)
{
- bus_addr_t paddr = (bus_addr_t)fd->addr;
- struct dpaa2_fa *fa = (struct dpaa2_fa *)PHYS_TO_DMAP(paddr);
- struct dpaa2_buf *buf = fa->buf;
- struct dpaa2_channel *bch = (struct dpaa2_channel *)buf->opt;
- struct dpaa2_ni_softc *sc = device_get_softc(bch->ni_dev);
+ bus_addr_t paddr;
+ struct dpaa2_swa *swa;
+ struct dpaa2_buf *buf;
+ struct dpaa2_channel *bch;
+ struct dpaa2_ni_softc *sc;
device_t bpdev;
struct dpaa2_bp_softc *bpsc;
int error;
- KASSERT(fa->magic == DPAA2_MAGIC, ("%s: wrong magic", __func__));
+ error = dpaa2_fa_get_swa(fd, &swa);
+ if (__predict_false(error != 0))
+ panic("%s: frame has no software annotation: error=%d",
+ __func__, error);
+
+ paddr = (bus_addr_t)fd->addr;
+ buf = swa->buf;
+ bch = (struct dpaa2_channel *)buf->opt;
+ sc = device_get_softc(bch->ni_dev);
+
+ KASSERT(swa->magic == DPAA2_MAGIC, ("%s: wrong magic", __func__));
/*
* NOTE: Current channel might not be the same as the "buffer" channel
* and it's fine. It must not be NULL though.
@@ -3316,14 +3318,26 @@ static int
dpaa2_ni_tx_conf(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq,
struct dpaa2_fd *fd)
{
- bus_addr_t paddr = (bus_addr_t)fd->addr;
- struct dpaa2_fa *fa = (struct dpaa2_fa *)PHYS_TO_DMAP(paddr);
- struct dpaa2_buf *buf = fa->buf;
- struct dpaa2_buf *sgt = buf->sgt;
- struct dpaa2_ni_tx_ring *tx = (struct dpaa2_ni_tx_ring *)buf->opt;
- struct dpaa2_channel *bch = tx->fq->chan;
-
- KASSERT(fa->magic == DPAA2_MAGIC, ("%s: wrong magic", __func__));
+ bus_addr_t paddr;
+ struct dpaa2_swa *swa;
+ struct dpaa2_buf *buf;
+ struct dpaa2_buf *sgt;
+ struct dpaa2_ni_tx_ring *tx;
+ struct dpaa2_channel *bch;
+ int error;
+
+ error = dpaa2_fa_get_swa(fd, &swa);
+ if (__predict_false(error != 0))
+ panic("%s: frame has no software annotation: error=%d",
+ __func__, error);
+
+ paddr = (bus_addr_t)fd->addr;
+ buf = swa->buf;
+ sgt = buf->sgt;
+ tx = (struct dpaa2_ni_tx_ring *)buf->opt;
+ bch = tx->fq->chan;
+
+ KASSERT(swa->magic == DPAA2_MAGIC, ("%s: wrong magic", __func__));
KASSERT(tx != NULL, ("%s: Tx ring is NULL", __func__));
KASSERT(sgt != NULL, ("%s: S/G table is NULL", __func__));
/*
@@ -3371,102 +3385,6 @@ dpaa2_ni_cmp_api_version(struct dpaa2_ni_softc *sc, uint16_t major,
return sc->api_major - major;
}
-/**
- * @brief Build a DPAA2 frame descriptor.
- */
-static int
-dpaa2_ni_build_fd(struct dpaa2_ni_softc *sc, struct dpaa2_ni_tx_ring *tx,
- struct dpaa2_buf *buf, bus_dma_segment_t *segs, int nsegs, struct dpaa2_fd *fd)
-{
- struct dpaa2_buf *sgt = buf->sgt;
- struct dpaa2_sg_entry *sge;
- struct dpaa2_fa *fa;
- int i, error;
-
- KASSERT(nsegs <= DPAA2_TX_SEGLIMIT, ("%s: too many segments", __func__));
- KASSERT(buf->opt != NULL, ("%s: no Tx ring?", __func__));
- KASSERT(sgt != NULL, ("%s: no S/G table?", __func__));
- KASSERT(sgt->vaddr != NULL, ("%s: no S/G vaddr?", __func__));
-
- memset(fd, 0, sizeof(*fd));
-
- /* Populate and map S/G table */
- if (__predict_true(nsegs <= DPAA2_TX_SEGLIMIT)) {
- sge = (struct dpaa2_sg_entry *)sgt->vaddr + sc->tx_data_off;
- for (i = 0; i < nsegs; i++) {
- sge[i].addr = (uint64_t)segs[i].ds_addr;
- sge[i].len = (uint32_t)segs[i].ds_len;
- sge[i].offset_fmt = 0u;
- }
- sge[i-1].offset_fmt |= 0x8000u; /* set final entry flag */
-
- KASSERT(sgt->paddr == 0, ("%s: paddr(%#jx) != 0", __func__,
- sgt->paddr));
-
- error = bus_dmamap_load(sgt->dmat, sgt->dmap, sgt->vaddr,
- DPAA2_TX_SGT_SZ, dpaa2_dmamap_oneseg_cb, &sgt->paddr,
- BUS_DMA_NOWAIT);
- if (__predict_false(error != 0)) {
- device_printf(sc->dev, "%s: bus_dmamap_load() failed: "
- "error=%d\n", __func__, error);
- return (error);
- }
-
- buf->paddr = sgt->paddr;
- buf->vaddr = sgt->vaddr;
- sc->tx_sg_frames++; /* for sysctl(9) */
- } else {
- return (EINVAL);
- }
-
- fa = (struct dpaa2_fa *)sgt->vaddr;
- fa->magic = DPAA2_MAGIC;
- fa->buf = buf;
-
- fd->addr = buf->paddr;
- fd->data_length = (uint32_t)buf->m->m_pkthdr.len;
- fd->bpid_ivp_bmt = 0;
- fd->offset_fmt_sl = 0x2000u | sc->tx_data_off;
- fd->ctrl = 0x00800000u;
-
- return (0);
-}
-
-static int
-dpaa2_ni_fd_err(struct dpaa2_fd *fd)
-{
- return ((fd->ctrl >> DPAA2_NI_FD_ERR_SHIFT) & DPAA2_NI_FD_ERR_MASK);
-}
-
-static uint32_t
-dpaa2_ni_fd_data_len(struct dpaa2_fd *fd)
-{
- if (dpaa2_ni_fd_short_len(fd)) {
- return (fd->data_length & DPAA2_NI_FD_LEN_MASK);
- }
- return (fd->data_length);
-}
-
-static int
-dpaa2_ni_fd_format(struct dpaa2_fd *fd)
-{
- return ((enum dpaa2_fd_format)((fd->offset_fmt_sl >>
- DPAA2_NI_FD_FMT_SHIFT) & DPAA2_NI_FD_FMT_MASK));
-}
-
-static bool
-dpaa2_ni_fd_short_len(struct dpaa2_fd *fd)
-{
- return (((fd->offset_fmt_sl >> DPAA2_NI_FD_SL_SHIFT)
- & DPAA2_NI_FD_SL_MASK) == 1);
-}
-
-static int
-dpaa2_ni_fd_offset(struct dpaa2_fd *fd)
-{
- return (fd->offset_fmt_sl & DPAA2_NI_FD_OFFSET_MASK);
-}
-
/**
* @brief Collect statistics of the network interface.
*/
diff --git a/sys/dev/dpaa2/dpaa2_ni.h b/sys/dev/dpaa2/dpaa2_ni.h
index 6fb0673fac09..fcd37501ebd0 100644
--- a/sys/dev/dpaa2/dpaa2_ni.h
+++ b/sys/dev/dpaa2/dpaa2_ni.h
@@ -490,8 +490,9 @@ struct dpaa2_ni_softc {
struct dpaa2_channel *channels[DPAA2_MAX_CHANNELS];
struct dpaa2_ni_fq rxe_queue; /* one per DPNI */
+ /* sysctl(9) */
struct dpaa2_atomic buf_num;
- struct dpaa2_atomic buf_free; /* for sysctl(9) only */
+ struct dpaa2_atomic buf_free;
int irq_rid[DPAA2_NI_MSI_COUNT];
struct resource *irq_res;
diff --git a/sys/dev/dpaa2/dpaa2_swp.h b/sys/dev/dpaa2/dpaa2_swp.h
index 1b1383b4241f..20980c6b71b7 100644
--- a/sys/dev/dpaa2/dpaa2_swp.h
+++ b/sys/dev/dpaa2/dpaa2_swp.h
@@ -35,6 +35,7 @@
#include "dpaa2_types.h"
#include "dpaa2_buf.h"
#include "dpaa2_bp.h"
+#include "dpaa2_frame.h"
/*
* DPAA2 QBMan software portal.
@@ -200,10 +201,8 @@
#define DPAA2_EQ_DESC_SIZE 32u /* Enqueue Command Descriptor */
#define DPAA2_FDR_DESC_SIZE 32u /* Descriptor of the FDR */
-#define DPAA2_FD_SIZE 32u /* Frame Descriptor */
#define DPAA2_FDR_SIZE 64u /* Frame Dequeue Response */
#define DPAA2_SCN_SIZE 16u /* State Change Notification */
-#define DPAA2_FA_SIZE 64u /* SW Frame Annotation */
#define DPAA2_SGE_SIZE 16u /* S/G table entry */
#define DPAA2_DQ_SIZE 64u /* Dequeue Response */
#define DPAA2_SWP_CMD_SIZE 64u /* SWP Command */
@@ -284,54 +283,6 @@ struct dpaa2_scn {
} __packed;
CTASSERT(sizeof(struct dpaa2_scn) == DPAA2_SCN_SIZE);
-/**
- * @brief DPAA2 frame descriptor.
- *
- * addr: Memory address of the start of the buffer holding the
- * frame data or the buffer containing the scatter/gather
- * list.
- * data_length: Length of the frame data (in bytes).
- * bpid_ivp_bmt: Buffer pool ID (14 bit + BMT bit + IVP bit)
- * offset_fmt_sl: Frame data offset, frame format and short-length fields.
- * frame_ctx: Frame context. This field allows the sender of a frame
- * to communicate some out-of-band information to the
- * receiver of the frame.
- * ctrl: Control bits (ERR, CBMT, ASAL, PTAC, DROPP, SC, DD).
- * flow_ctx: Frame flow context. Associates the frame with a flow
- * structure. QMan may use the FLC field for 3 purposes:
- * stashing control, order definition point identification,
- * and enqueue replication control.
- */
-struct dpaa2_fd {
- uint64_t addr;
- uint32_t data_length;
- uint16_t bpid_ivp_bmt;
- uint16_t offset_fmt_sl;
- uint32_t frame_ctx;
- uint32_t ctrl;
- uint64_t flow_ctx;
-} __packed;
-CTASSERT(sizeof(struct dpaa2_fd) == DPAA2_FD_SIZE);
-
-/**
- * @brief DPAA2 frame annotation.
- */
-struct dpaa2_fa {
- uint32_t magic;
- struct dpaa2_buf *buf;
-#ifdef __notyet__
- union {
- struct { /* Tx frame annotation */
- struct dpaa2_ni_tx_ring *tx;
- };
- struct { /* Rx frame annotation */
- uint64_t _notused;
- };
- };
-#endif
-} __packed;
-CTASSERT(sizeof(struct dpaa2_fa) <= DPAA2_FA_SIZE);
-
/**
* @brief DPAA2 scatter/gather entry.
*/
diff --git a/sys/dev/dpaa2/dpaa2_types.h b/sys/dev/dpaa2/dpaa2_types.h
index dbfac9ce0a40..dc1c232c09c2 100644
--- a/sys/dev/dpaa2/dpaa2_types.h
+++ b/sys/dev/dpaa2/dpaa2_types.h
@@ -40,6 +40,11 @@
#define DPAA2_MAX_CHANNELS 16 /* CPU cores */
#define DPAA2_MAX_TCS 8 /* Traffic classes */
+#define DPAA2_TX_SEGLIMIT (16u) /* for 64 KiB frames */
+#define DPAA2_TX_SEG_SZ (PAGE_SIZE)
+#define DPAA2_TX_SEGS_MAXSZ (DPAA2_TX_SEGLIMIT * DPAA2_TX_SEG_SZ)
+#define DPAA2_TX_SGT_SZ (PAGE_SIZE) /* in bytes */
+
/**
* @brief Types of the DPAA2 devices.
*/
diff --git a/sys/modules/dpaa2/Makefile b/sys/modules/dpaa2/Makefile
index 816d6fa5cf4a..388303eed0c7 100644
--- a/sys/modules/dpaa2/Makefile
+++ b/sys/modules/dpaa2/Makefile
@@ -14,6 +14,7 @@ SRCS+= dpaa2_con.c
SRCS+= dpaa2_buf.c
SRCS+= dpaa2_channel.c
SRCS+= dpaa2_types.c
+SRCS+= dpaa2_frame.c
SRCS+= dpaa2_cmd_if.c dpaa2_cmd_if.h
SRCS+= dpaa2_swp_if.c dpaa2_swp_if.h