git: ec68ff15bfa6 - main - mgb: support multi-segment packets in the DMA descriptor rings.

From: Ruslan Bukin <br_at_FreeBSD.org>
Date: Tue, 13 Oct 2026 16:30:41 UTC
The branch main has been updated by br:

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

commit ec68ff15bfa6aece12383ba408e9eec95f4b79cd
Author:     Ruslan Bukin <br@FreeBSD.org>
AuthorDate: 2026-10-13 16:26:10 +0000
Commit:     Ruslan Bukin <br@FreeBSD.org>
CommitDate: 2026-10-13 16:28:10 +0000

    mgb: support multi-segment packets in the DMA descriptor rings.
    
    Reviewed by:    emaste
    Sponsored by:   EPSRC ("UKRI3001: CHERI Research Centre")
    Differential Revision:  https://reviews.freebsd.org/D60705
---
 sys/dev/mgb/if_mgb.c | 22 ++++++++++------------
 sys/dev/mgb/if_mgb.h |  1 +
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/sys/dev/mgb/if_mgb.c b/sys/dev/mgb/if_mgb.c
index 60f93bb0615d..887d95dc457c 100644
--- a/sys/dev/mgb/if_mgb.c
+++ b/sys/dev/mgb/if_mgb.c
@@ -968,6 +968,7 @@ mgb_isc_txd_encap(void *xsc , if_pkt_info_t ipi)
 	struct mgb_ring_desc *txd;
 	bus_dma_segment_t *segs;
 	qidx_t pidx, nsegs;
+	uint32_t ctl;
 	int i;
 
 	KASSERT(ipi->ipi_qsidx == 0,
@@ -981,23 +982,20 @@ mgb_isc_txd_encap(void *xsc , if_pkt_info_t ipi)
 
 	/* For each seg, create a descriptor */
 	for (i = 0; i < nsegs; ++i) {
-		KASSERT(nsegs == 1, ("Multisegment packet !!!!!\n"));
 		txd = &rdata->ring[pidx];
-		txd->ctl = htole32(
-		    (segs[i].ds_len & MGB_DESC_CTL_BUFLEN_MASK ) |
-		    /*
-		     * XXX: This will be wrong in the multipacket case
-		     * I suspect FS should be for the first packet and
-		     * LS should be for the last packet
-		     */
-		    MGB_TX_DESC_CTL_FS | MGB_TX_DESC_CTL_LS |
-		    MGB_DESC_CTL_FCS);
+		ctl = (segs[i].ds_len & MGB_DESC_CTL_BUFLEN_MASK) |
+		    MGB_DESC_CTL_FCS;
+		if (i == 0)
+			ctl |= MGB_TX_DESC_CTL_FS;
+		if (i == (nsegs - 1))
+			ctl |= MGB_TX_DESC_CTL_LS | MGB_DESC_CTL_IOC;
+		txd->ctl = htole32(ctl);
 		txd->addr.low = htole32(CSR_TRANSLATE_ADDR_LOW32(
 		    segs[i].ds_addr));
 		txd->addr.high = htole32(CSR_TRANSLATE_ADDR_HIGH32(
 		    segs[i].ds_addr));
-		txd->sts = htole32(
-		    (segs[i].ds_len << 16) & MGB_DESC_FRAME_LEN_MASK);
+		txd->sts = htole32((ipi->ipi_len << MGB_DESC_FRAME_LEN_SHIFT) &
+		    MGB_DESC_FRAME_LEN_MASK);
 		pidx = MGB_NEXT_RING_IDX(pidx);
 	}
 	ipi->ipi_new_pidx = pidx;
diff --git a/sys/dev/mgb/if_mgb.h b/sys/dev/mgb/if_mgb.h
index 19f6d4a20cc7..ebae9bb29e55 100644
--- a/sys/dev/mgb/if_mgb.h
+++ b/sys/dev/mgb/if_mgb.h
@@ -173,6 +173,7 @@
 #define MGB_DESC_CTL_BUFLEN_MASK	(0x0000FFFF)
 #define MGB_DESC_STS_BUFLEN_MASK	(0x00003FFF)
 #define MGB_DESC_FRAME_LEN_MASK		(0x3FFF0000)
+#define MGB_DESC_FRAME_LEN_SHIFT	16
 #define MGB_DESC_GET_FRAME_LEN(_desc)	\
 	(((_desc)->ctl & MGB_DESC_FRAME_LEN_MASK) >> 16)