From: David Marchand <david.marchand@redhat.com>
To: dev@dpdk.org
Cc: rjarry@redhat.com, cfontain@redhat.com,
Vladimir Medvedkin <vladimir.medvedkin@intel.com>
Subject: [PATCH v3 4/5] net/iavf: accept up to 32k unicast MAC addresses
Date: Sun, 10 May 2026 19:03:04 +0200 [thread overview]
Message-ID: <20260510170306.3406045-5-david.marchand@redhat.com> (raw)
In-Reply-To: <20260510170306.3406045-1-david.marchand@redhat.com>
E810 hardware provides 32k switch lookups.
Thanks to this, it is possible to allow a lot more secondary mac
addresses than what is possible today.
In practice, the maximum number of macs available per port may be lower
and depends on usage by other (trusted?) VFs on the same PF.
There is no way to figure out this limit but to try adding a mac address
and get an error from the PF driver.
Mailbox exchanges are limited to IAVF_AQ_BUF_SZ, segment messages
accordingly.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
Changes since v2:
- added an entry in release notes,
- removed unneeded temp variable,
Changes since v1:
- fixed buffer overflow on mailbox messages during port restart/VF reset,
---
doc/guides/rel_notes/release_26_07.rst | 4 +
drivers/net/intel/iavf/iavf.h | 5 +-
drivers/net/intel/iavf/iavf_ethdev.c | 12 +--
drivers/net/intel/iavf/iavf_vchnl.c | 113 ++++++++++++++++++-------
4 files changed, 94 insertions(+), 40 deletions(-)
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index b425e6f8cd..9d461f2837 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -63,6 +63,10 @@ New Features
``rte_eal_init`` and the application is responsible for probing each device,
* ``--auto-probing`` enables the initial bus probing, which is the current default behavior.
+* **Updated IAVF ethernet driver.**
+
+ * Increased the maximum number of secondary MAC addresses from 64 to 32k.
+ This increases a VF port memory footprint by ~192kB.
Removed Items
-------------
diff --git a/drivers/net/intel/iavf/iavf.h b/drivers/net/intel/iavf/iavf.h
index 403c61e2e8..f1dede0694 100644
--- a/drivers/net/intel/iavf/iavf.h
+++ b/drivers/net/intel/iavf/iavf.h
@@ -31,7 +31,8 @@
#define IAVF_IRQ_MAP_NUM_PER_BUF 128
#define IAVF_RXTX_QUEUE_CHUNKS_NUM 2
-#define IAVF_NUM_MACADDR_MAX 64
+#define IAVF_UC_MACADDR_MAX 32768
+#define IAVF_MC_MACADDR_MAX 64
#define IAVF_DEV_WATCHDOG_PERIOD 2000 /* microseconds, set 0 to disable*/
@@ -253,7 +254,7 @@ struct iavf_info {
uint32_t link_speed;
/* Multicast addrs */
- struct rte_ether_addr mc_addrs[IAVF_NUM_MACADDR_MAX];
+ struct rte_ether_addr mc_addrs[IAVF_MC_MACADDR_MAX];
uint16_t mc_addrs_num; /* Multicast mac addresses number */
struct iavf_vsi vsi;
diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c
index 1eca20bc9a..edbbc34cc5 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -379,10 +379,10 @@ iavf_set_mc_addr_list(struct rte_eth_dev *dev,
IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
int err, ret;
- if (mc_addrs_num > IAVF_NUM_MACADDR_MAX) {
+ if (mc_addrs_num > IAVF_MC_MACADDR_MAX) {
PMD_DRV_LOG(ERR,
"can't add more than a limited number (%u) of addresses.",
- (uint32_t)IAVF_NUM_MACADDR_MAX);
+ (uint32_t)IAVF_MC_MACADDR_MAX);
return -EINVAL;
}
@@ -1120,7 +1120,7 @@ iavf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->hash_key_size = vf->vf_res->rss_key_size;
dev_info->reta_size = vf->vf_res->rss_lut_size;
dev_info->flow_type_rss_offloads = IAVF_RSS_OFFLOAD_ALL;
- dev_info->max_mac_addrs = IAVF_NUM_MACADDR_MAX;
+ dev_info->max_mac_addrs = IAVF_UC_MACADDR_MAX;
dev_info->dev_capa =
RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
@@ -2821,12 +2821,12 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
iavf_set_default_ptype_table(eth_dev);
/* copy mac addr */
- eth_dev->data->mac_addrs = rte_zmalloc(
- "iavf_mac", RTE_ETHER_ADDR_LEN * IAVF_NUM_MACADDR_MAX, 0);
+ eth_dev->data->mac_addrs = rte_calloc("iavf_mac", IAVF_UC_MACADDR_MAX,
+ RTE_ETHER_ADDR_LEN, 0);
if (!eth_dev->data->mac_addrs) {
PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to"
" store MAC addresses",
- RTE_ETHER_ADDR_LEN * IAVF_NUM_MACADDR_MAX);
+ RTE_ETHER_ADDR_LEN * IAVF_UC_MACADDR_MAX);
ret = -ENOMEM;
goto init_vf_err;
}
diff --git a/drivers/net/intel/iavf/iavf_vchnl.c b/drivers/net/intel/iavf/iavf_vchnl.c
index 08dd6f2d7f..d0fc8dd54b 100644
--- a/drivers/net/intel/iavf/iavf_vchnl.c
+++ b/drivers/net/intel/iavf/iavf_vchnl.c
@@ -1437,48 +1437,97 @@ iavf_config_irq_map_lv(struct iavf_adapter *adapter, uint16_t num)
return 0;
}
-void
-iavf_add_del_all_mac_addr(struct iavf_adapter *adapter, bool add)
+static int
+iavf_add_del_uc_addr_bulk(struct iavf_adapter *adapter, struct rte_ether_addr *addrs,
+ uint32_t nb_addrs, bool add)
{
+#define IAVF_ETH_ADDR_PER_REQ \
+ ((IAVF_AQ_BUF_SZ - sizeof(struct virtchnl_ether_addr_list)) / \
+ sizeof(struct virtchnl_ether_addr))
struct {
struct virtchnl_ether_addr_list list;
- struct virtchnl_ether_addr addr[IAVF_NUM_MACADDR_MAX];
- } list_req = {0};
- struct virtchnl_ether_addr_list *list = &list_req.list;
+ struct virtchnl_ether_addr addr[IAVF_ETH_ADDR_PER_REQ];
+ } cmd_buffer;
+#undef IAVF_ETH_ADDR_PER_REQ
+ struct virtchnl_ether_addr_list *list = &cmd_buffer.list;
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
- struct iavf_cmd_info args = {0};
- int err, i;
- size_t buf_len;
- for (i = 0; i < IAVF_NUM_MACADDR_MAX; i++) {
- struct rte_ether_addr *addr = &adapter->dev_data->mac_addrs[i];
- struct virtchnl_ether_addr *vc_addr = &list->list[list->num_elements];
+ for (uint32_t i = 0; i < nb_addrs; i++) {
+ struct iavf_cmd_info args;
+ uint32_t batch;
+ int err;
- /* ignore empty addresses */
- if (rte_is_zero_ether_addr(addr))
- continue;
+ batch = i % RTE_DIM(cmd_buffer.addr);
+
+ if (batch == 0) {
+ memset(&cmd_buffer, 0, sizeof(cmd_buffer));
+ list->vsi_id = vf->vsi_res->vsi_id;
+ list->num_elements = 0;
+ }
+
+ rte_memcpy(list->list[batch].addr, addrs[i].addr_bytes,
+ sizeof(list->list[batch].addr));
+ list->list[batch].type = VIRTCHNL_ETHER_ADDR_EXTRA;
list->num_elements++;
- memcpy(vc_addr->addr, addr->addr_bytes, sizeof(addr->addr_bytes));
- vc_addr->type = (list->num_elements == 1) ?
- VIRTCHNL_ETHER_ADDR_PRIMARY :
- VIRTCHNL_ETHER_ADDR_EXTRA;
+ if (batch != RTE_DIM(cmd_buffer.addr) - 1 && i != nb_addrs - 1)
+ continue;
+
+ memset(&args, 0, sizeof(args));
+ args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR;
+ args.in_args = (uint8_t *)list;
+ args.in_args_size = sizeof(struct virtchnl_ether_addr_list) +
+ sizeof(struct virtchnl_ether_addr) * list->num_elements;
+ args.out_buffer = vf->aq_resp;
+ args.out_size = IAVF_AQ_BUF_SZ;
+ err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
+ if (err != 0) {
+ PMD_DRV_LOG(ERR, "fail to execute command %s for %u macs",
+ add ? "VIRTCHNL_OP_ADD_ETH_ADDR" : "VIRTCHNL_OP_DEL_ETH_ADDR",
+ list->num_elements);
+ return err;
+ }
+
+ PMD_DRV_LOG(DEBUG, "executed command %s for %u macs",
+ add ? "VIRTCHNL_OP_ADD_ETH_ADDR" : "VIRTCHNL_OP_DEL_ETH_ADDR",
+ list->num_elements);
}
- /* for some reason PF side checks for buffer being too big, so adjust it down */
- buf_len = sizeof(struct virtchnl_ether_addr_list) +
- sizeof(struct virtchnl_ether_addr) * list->num_elements;
+ return 0;
+}
- list->vsi_id = vf->vsi_res->vsi_id;
- args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR;
- args.in_args = (uint8_t *)list;
- args.in_args_size = buf_len;
- args.out_buffer = vf->aq_resp;
- args.out_size = IAVF_AQ_BUF_SZ;
- err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
- if (err)
- PMD_DRV_LOG(ERR, "fail to execute command %s",
- add ? "OP_ADD_ETHER_ADDRESS" : "OP_DEL_ETHER_ADDRESS");
+void
+iavf_add_del_all_mac_addr(struct iavf_adapter *adapter, bool add)
+{
+ int start = -1;
+ int i;
+
+ /* Handle primary address (index 0) separately */
+ if (!rte_is_zero_ether_addr(&adapter->dev_data->mac_addrs[0]))
+ iavf_add_del_eth_addr(adapter, &adapter->dev_data->mac_addrs[0], add,
+ VIRTCHNL_ETHER_ADDR_PRIMARY);
+
+ /* Process secondary addresses in contiguous blocks */
+ for (i = 1; i < IAVF_UC_MACADDR_MAX; i++) {
+ struct rte_ether_addr *addr = &adapter->dev_data->mac_addrs[i];
+
+ if (!rte_is_zero_ether_addr(addr)) {
+ if (start == -1)
+ start = i;
+ continue;
+ }
+
+ if (start != -1) {
+ iavf_add_del_uc_addr_bulk(adapter, &adapter->dev_data->mac_addrs[start],
+ i - start, add);
+ start = -1;
+ }
+ }
+
+ if (start != -1) {
+ iavf_add_del_uc_addr_bulk(adapter, &adapter->dev_data->mac_addrs[start],
+ i - start, add);
+ }
}
int
@@ -2060,7 +2109,7 @@ iavf_add_del_mc_addr_list(struct iavf_adapter *adapter,
{
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) +
- (IAVF_NUM_MACADDR_MAX * sizeof(struct virtchnl_ether_addr))];
+ (IAVF_MC_MACADDR_MAX * sizeof(struct virtchnl_ether_addr))];
struct virtchnl_ether_addr_list *list;
struct iavf_cmd_info args;
uint32_t i;
--
2.53.0
next prev parent reply other threads:[~2026-05-10 17:03 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-03 9:18 [PATCH 0/4] Remove limitations coming from legacy VMDq David Marchand
2026-04-03 9:18 ` [PATCH 1/4] ethdev: skip VMDq pools unless configured David Marchand
2026-04-03 9:18 ` [PATCH 2/4] ethdev: announce VMDq capability David Marchand
2026-04-06 22:22 ` Kishore Padmanabha
2026-04-29 14:18 ` David Marchand
2026-04-03 9:18 ` [PATCH 3/4] ethdev: hide VMDq internal sizes David Marchand
2026-04-03 9:18 ` [PATCH 4/4] net/iavf: accept up to 32k unicast MAC addresses David Marchand
2026-04-05 18:47 ` [PATCH 0/4] Remove limitations coming from legacy VMDq Stephen Hemminger
2026-04-29 14:22 ` David Marchand
2026-05-06 12:35 ` [PATCH v2 0/5] " David Marchand
2026-05-06 12:35 ` [PATCH v2 1/5] ethdev: skip VMDq pools unless configured David Marchand
2026-05-06 12:35 ` [PATCH v2 2/5] ethdev: announce VMDq capability David Marchand
2026-05-06 12:35 ` [PATCH v2 3/5] ethdev: hide VMDq internal sizes David Marchand
2026-05-06 12:35 ` [PATCH v2 4/5] net/iavf: accept up to 32k unicast MAC addresses David Marchand
2026-05-06 12:35 ` [PATCH v2 5/5] net/iavf: fix duplicate MAC addresses install David Marchand
2026-05-07 2:51 ` [PATCH v2 0/5] Remove limitations coming from legacy VMDq Stephen Hemminger
2026-05-10 15:03 ` David Marchand
2026-05-10 17:03 ` [PATCH v3 " David Marchand
2026-05-10 17:03 ` [PATCH v3 1/5] ethdev: check VMDq availability David Marchand
2026-05-10 17:03 ` [PATCH v3 2/5] ethdev: skip VMDq pools unless configured David Marchand
2026-05-10 17:03 ` [PATCH v3 3/5] ethdev: hide VMDq internal sizes David Marchand
2026-05-10 17:03 ` David Marchand [this message]
2026-05-12 14:41 ` [PATCH v3 4/5] net/iavf: accept up to 32k unicast MAC addresses Stephen Hemminger
2026-05-10 17:03 ` [PATCH v3 5/5] net/iavf: fix duplicate MAC addresses install David Marchand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260510170306.3406045-5-david.marchand@redhat.com \
--to=david.marchand@redhat.com \
--cc=cfontain@redhat.com \
--cc=dev@dpdk.org \
--cc=rjarry@redhat.com \
--cc=vladimir.medvedkin@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox