aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/mana
diff options
context:
space:
mode:
authorWei Hu <whu@FreeBSD.org>2025-12-23 07:00:38 +0000
committerWei Hu <whu@FreeBSD.org>2025-12-23 07:00:38 +0000
commitd0a2bd2765b365c4be9b17c29306f848953e55a5 (patch)
tree8121c9e6c91ab9d417a117421a244c79cb7ffb51 /sys/dev/mana
parent44f656641c238cb3db31026f3e3bef36cd5231a8 (diff)
Diffstat (limited to 'sys/dev/mana')
-rw-r--r--sys/dev/mana/gdma.h6
-rw-r--r--sys/dev/mana/mana.h11
-rw-r--r--sys/dev/mana/mana_en.c79
3 files changed, 65 insertions, 31 deletions
diff --git a/sys/dev/mana/gdma.h b/sys/dev/mana/gdma.h
index 9e32d58dbfdc..90cd908055af 100644
--- a/sys/dev/mana/gdma.h
+++ b/sys/dev/mana/gdma.h
@@ -193,6 +193,9 @@ struct gdma_general_req {
}; /* HW DATA */
#define GDMA_MESSAGE_V1 1
+#define GDMA_MESSAGE_V2 2
+#define GDMA_MESSAGE_V3 3
+#define GDMA_MESSAGE_V4 4
struct gdma_general_resp {
struct gdma_resp_hdr hdr;
@@ -409,6 +412,9 @@ struct gdma_context {
struct gdma_resource msix_resource;
struct gdma_irq_context *irq_contexts;
+ /* L2 MTU */
+ uint16_t adapter_mtu;
+
/* This maps a CQ index to the queue structure. */
unsigned int max_num_cqs;
struct gdma_queue **cq_table;
diff --git a/sys/dev/mana/mana.h b/sys/dev/mana/mana.h
index a037eb3f05c7..de34f8a82c6a 100644
--- a/sys/dev/mana/mana.h
+++ b/sys/dev/mana/mana.h
@@ -102,9 +102,6 @@ enum TRI_STATE {
#define COMP_ENTRY_SIZE 64
#define MIN_FRAME_SIZE 146
-#define ADAPTER_MTU_SIZE 1500
-#define DEFAULT_FRAME_SIZE (ADAPTER_MTU_SIZE + 14)
-#define MAX_FRAME_SIZE 4096
/* Unit number of RX buffers. Must be power of two
* Higher number could fail at allocation.
@@ -534,6 +531,9 @@ struct mana_port_context {
uint16_t port_idx;
uint16_t frame_size;
+ uint16_t max_mtu;
+ uint16_t min_mtu;
+ uint16_t mtu;
bool port_is_up;
bool port_st_save; /* Saved port state */
@@ -613,6 +613,11 @@ struct mana_query_device_cfg_resp {
uint16_t max_num_vports;
uint16_t reserved;
uint32_t max_num_eqs;
+
+ /* response v2: */
+ uint16_t adapter_mtu;
+ uint16_t reserved2;
+ uint32_t reserved3;
}; /* HW DATA */
/* Query vPort Configuration */
diff --git a/sys/dev/mana/mana_en.c b/sys/dev/mana/mana_en.c
index 949b498ceadc..bc8c172bab69 100644
--- a/sys/dev/mana/mana_en.c
+++ b/sys/dev/mana/mana_en.c
@@ -181,18 +181,19 @@ mana_ioctl(if_t ifp, u_long command, caddr_t data)
new_mtu = ifr->ifr_mtu;
if (if_getmtu(ifp) == new_mtu)
break;
- if ((new_mtu + 18 > MAX_FRAME_SIZE) ||
- (new_mtu + 18 < MIN_FRAME_SIZE)) {
+ if ((new_mtu > apc->max_mtu) ||
+ (new_mtu < apc->min_mtu)) {
if_printf(ifp, "Invalid MTU. new_mtu: %d, "
"max allowed: %d, min allowed: %d\n",
- new_mtu, MAX_FRAME_SIZE - 18, MIN_FRAME_SIZE - 18);
+ new_mtu, apc->max_mtu, apc->min_mtu);
return EINVAL;
}
MANA_APC_LOCK_LOCK(apc);
if (apc->port_is_up)
mana_down(apc);
- apc->frame_size = new_mtu + 18;
+ apc->frame_size = new_mtu + ETHER_HDR_LEN;
+ apc->mtu = new_mtu;
if_setmtu(ifp, new_mtu);
mana_dbg(NULL, "Set MTU to %d\n", new_mtu);
@@ -421,17 +422,11 @@ mana_load_rx_mbuf(struct mana_port_context *apc, struct mana_rxq *rxq,
if (alloc_mbuf) {
mbuf = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, rxq->datasize);
- if (unlikely(mbuf == NULL)) {
- mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
- if (unlikely(mbuf == NULL)) {
- return ENOMEM;
- }
- mlen = MCLBYTES;
- } else {
- mlen = rxq->datasize;
- }
+ if (unlikely(mbuf == NULL))
+ return ENOMEM;
- mbuf->m_pkthdr.len = mbuf->m_len = mlen;
+ mbuf->m_pkthdr.len = mbuf->m_len = rxq->datasize;
+ mlen = rxq->datasize;
} else {
if (rx_oob->mbuf) {
mbuf = rx_oob->mbuf;
@@ -911,9 +906,9 @@ mana_init_port_context(struct mana_port_context *apc)
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
- MJUMPAGESIZE, /* maxsize */
+ MJUM16BYTES, /* maxsize */
1, /* nsegments */
- MJUMPAGESIZE, /* maxsegsize */
+ MJUM16BYTES, /* maxsegsize */
0, /* flags */
NULL, NULL, /* lockfunc, lockfuncarg*/
&apc->rx_buf_tag);
@@ -994,6 +989,9 @@ mana_query_device_cfg(struct mana_context *ac, uint32_t proto_major_ver,
mana_gd_init_req_hdr(&req.hdr, MANA_QUERY_DEV_CONFIG,
sizeof(req), sizeof(resp));
+
+ req.hdr.resp.msg_version = GDMA_MESSAGE_V2;
+
req.proto_major_ver = proto_major_ver;
req.proto_minor_ver = proto_minor_ver;
req.proto_micro_ver = proto_micro_ver;
@@ -1016,8 +1014,14 @@ mana_query_device_cfg(struct mana_context *ac, uint32_t proto_major_ver,
*max_num_vports = resp.max_num_vports;
- mana_dbg(NULL, "mana max_num_vports from device = %d\n",
- *max_num_vports);
+ if (resp.hdr.response.msg_version >= GDMA_MESSAGE_V2)
+ gc->adapter_mtu = resp.adapter_mtu;
+ else
+ gc->adapter_mtu = ETHERMTU + ETHER_HDR_LEN;
+
+ mana_dbg(NULL, "mana max_num_vports from device = %d, "
+ "adapter_mtu = %u\n",
+ *max_num_vports, gc->adapter_mtu);
return 0;
}
@@ -2295,7 +2299,7 @@ mana_alloc_rx_wqe(struct mana_port_context *apc,
uint32_t buf_idx;
int err;
- if (rxq->datasize == 0 || rxq->datasize > PAGE_SIZE) {
+ if (rxq->datasize == 0) {
mana_err(NULL,
"WARNING: Invalid rxq datasize %u\n", rxq->datasize);
}
@@ -2359,6 +2363,28 @@ mana_push_wqe(struct mana_rxq *rxq)
return 0;
}
+static uint32_t
+mana_calc_rx_datasize(struct mana_port_context *apc)
+{
+ uint32_t effective_mtu = 0;
+
+ if (apc->frame_size > MJUM16BYTES) {
+ mana_err(NULL, "mana frame_size %u is too big\n",
+ apc->frame_size);
+ effective_mtu = MJUM16BYTES;
+ } else if (apc->frame_size > MJUM9BYTES) {
+ effective_mtu = MJUM16BYTES;
+ } else if (apc->frame_size > MJUMPAGESIZE) {
+ effective_mtu = MJUM9BYTES;
+ } else if (apc->frame_size > MCLBYTES) {
+ effective_mtu = MJUMPAGESIZE;
+ } else {
+ effective_mtu = MCLBYTES;
+ }
+
+ return effective_mtu;
+}
+
static struct mana_rxq *
mana_create_rxq(struct mana_port_context *apc, uint32_t rxq_idx,
struct mana_eq *eq, if_t ndev)
@@ -2381,14 +2407,8 @@ mana_create_rxq(struct mana_port_context *apc, uint32_t rxq_idx,
rxq->ndev = ndev;
rxq->num_rx_buf = apc->rx_queue_size;
rxq->rxq_idx = rxq_idx;
- /*
- * Minimum size is MCLBYTES(2048) bytes for a mbuf cluster.
- * Now we just allow maximum size of 4096.
- */
- rxq->datasize = ALIGN(apc->frame_size, MCLBYTES);
- if (rxq->datasize > MAX_FRAME_SIZE)
- rxq->datasize = MAX_FRAME_SIZE;
+ rxq->datasize = mana_calc_rx_datasize(apc);
mana_dbg(NULL, "Setting rxq %d datasize %d\n",
rxq_idx, rxq->datasize);
@@ -2914,10 +2934,13 @@ mana_probe_port(struct mana_context *ac, int port_idx,
mana_rx_req_size);
apc->port_handle = INVALID_MANA_HANDLE;
apc->port_idx = port_idx;
- apc->frame_size = DEFAULT_FRAME_SIZE;
apc->last_tx_cq_bind_cpu = -1;
apc->last_rx_cq_bind_cpu = -1;
apc->vport_use_count = 0;
+ apc->max_mtu = gc->adapter_mtu - ETHER_HDR_LEN;
+ apc->min_mtu = MIN_FRAME_SIZE;
+ apc->mtu = ETHERMTU;
+ apc->frame_size = apc->mtu + ETHER_HDR_LEN;
MANA_APC_LOCK_INIT(apc);
@@ -2932,7 +2955,7 @@ mana_probe_port(struct mana_context *ac, int port_idx,
if_setioctlfn(ndev, mana_ioctl);
if_setgetcounterfn(ndev, mana_get_counter);
- if_setmtu(ndev, ETHERMTU);
+ if_setmtu(ndev, apc->mtu);
if_setbaudrate(ndev, IF_Gbps(100));
mana_rss_key_fill(apc->hashkey, MANA_HASH_KEY_SIZE);