The branch main has been updated by dsl:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=8e994533806d8aa0ae4582a52d811ede2b19bb26

commit 8e994533806d8aa0ae4582a52d811ede2b19bb26
Author:     Dmitry Salychev <[email protected]>
AuthorDate: 2026-01-25 16:53:57 +0000
Commit:     Dmitry Salychev <[email protected]>
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

Reply via email to