by QMan */ sc->rx_enq_rej_frames++; break; @@ -3164,7 +3154,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; @@ -3180,9 +3170,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; @@ -3269,16 +3261,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. @@ -3312,14 +3314,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__)); /* @@ -3367,102 +3381,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