* [PATCH 0/4] Remove limitations coming from legacy VMDq
@ 2026-04-03 9:18 David Marchand
2026-04-03 9:18 ` [PATCH 1/4] ethdev: skip VMDq pools unless configured David Marchand
` (6 more replies)
0 siblings, 7 replies; 24+ messages in thread
From: David Marchand @ 2026-04-03 9:18 UTC (permalink / raw)
To: dev; +Cc: rjarry, cfontain
Since the commit 88ac4396ad29 ("ethdev: add VMDq support"),
VMDq has been imposing a maximum number of mac addresses in the
mac_addr_add/del API.
Nowadays, new Intel drivers do not support the feature and few other
drivers implement this feature.
This series proposes to flag drivers that support the feature, and
remove the limit of number of mac addresses for others.
Next step could be to remove the VMDq pool notion from the generic API.
However I have some concern about this, as changing the quite stable
mac_addr_add/del API now seems a lot of noise for not much benefit.
--
David Marchand
David Marchand (4):
ethdev: skip VMDq pools unless configured
ethdev: announce VMDq capability
ethdev: hide VMDq internal sizes
net/iavf: accept up to 32k unicast MAC addresses
drivers/net/bnxt/bnxt_ethdev.c | 3 +-
drivers/net/bnxt/bnxt_reps.c | 1 +
drivers/net/cnxk/cnxk_ethdev_ops.c | 1 -
drivers/net/intel/e1000/em_ethdev.c | 1 +
drivers/net/intel/e1000/igb_ethdev.c | 1 +
drivers/net/intel/fm10k/fm10k_ethdev.c | 1 +
drivers/net/intel/i40e/i40e_ethdev.c | 3 +-
drivers/net/intel/i40e/i40e_vf_representor.c | 1 +
drivers/net/intel/iavf/iavf.h | 5 ++-
drivers/net/intel/iavf/iavf_ethdev.c | 10 ++---
drivers/net/intel/iavf/iavf_vchnl.c | 6 +--
drivers/net/intel/ipn3ke/ipn3ke_representor.c | 3 +-
drivers/net/intel/ixgbe/ixgbe_ethdev.c | 2 +
drivers/net/txgbe/txgbe_ethdev.c | 1 +
drivers/net/txgbe/txgbe_ethdev_vf.c | 1 +
lib/ethdev/ethdev_driver.h | 8 +++-
lib/ethdev/rte_ethdev.c | 45 ++++++++++++++++---
lib/ethdev/rte_ethdev.h | 8 +---
18 files changed, 73 insertions(+), 28 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 24+ messages in thread* [PATCH 1/4] ethdev: skip VMDq pools unless configured 2026-04-03 9:18 [PATCH 0/4] Remove limitations coming from legacy VMDq David Marchand @ 2026-04-03 9:18 ` David Marchand 2026-04-03 9:18 ` [PATCH 2/4] ethdev: announce VMDq capability David Marchand ` (5 subsequent siblings) 6 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-04-03 9:18 UTC (permalink / raw) To: dev Cc: rjarry, cfontain, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao, Harman Kalra, Thomas Monjalon, Andrew Rybchenko The mac_addr_add API describes that only the 0 pool should be passed unless VMDq has been enabled, though there was no validation so far. Add such a check, then cleanup the related operations (adding, removing, restoring). As a side effect, the net/cnxk does not need to manually reset the mac_pool_sel[] array. Signed-off-by: David Marchand <david.marchand@redhat.com> --- drivers/net/cnxk/cnxk_ethdev_ops.c | 1 - lib/ethdev/rte_ethdev.c | 28 +++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/net/cnxk/cnxk_ethdev_ops.c b/drivers/net/cnxk/cnxk_ethdev_ops.c index 49e77e49a6..75decf7098 100644 --- a/drivers/net/cnxk/cnxk_ethdev_ops.c +++ b/drivers/net/cnxk/cnxk_ethdev_ops.c @@ -1240,7 +1240,6 @@ cnxk_nix_mc_addr_list_configure(struct rte_eth_dev *eth_dev, struct rte_ether_ad /* Update address in NIC data structure */ rte_ether_addr_copy(&mc_addr_set[i], &data->mac_addrs[j]); rte_ether_addr_copy(&mc_addr_set[i], &dev->dmac_addrs[j]); - data->mac_pool_sel[j] = RTE_BIT64(0); } roc_nix_npc_promisc_ena_dis(nix, true); diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 2edc7a362e..9577b7d848 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -1680,7 +1680,10 @@ eth_dev_mac_restore(struct rte_eth_dev *dev, continue; pool = 0; - pool_mask = dev->data->mac_pool_sel[i]; + if ((dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0) + pool_mask = dev->data->mac_pool_sel[i]; + else + pool_mask = 1; do { if (pool_mask & UINT64_C(1)) @@ -5390,8 +5393,9 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, uint32_t pool) { struct rte_eth_dev *dev; - int index; uint64_t pool_mask; + bool vmdq; + int index; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -5416,6 +5420,12 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, RTE_ETHDEV_LOG_LINE(ERR, "Pool ID must be 0-%d", RTE_ETH_64_POOLS - 1); return -EINVAL; } + vmdq = (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0; + if (!vmdq && pool != 0) { + RTE_ETHDEV_LOG_LINE(ERR, "Port %u: VMDq is not configured (pool %d)", + port_id, pool); + return -EINVAL; + } index = eth_dev_get_mac_addr_index(port_id, addr); if (index < 0) { @@ -5425,7 +5435,7 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, port_id); return -ENOSPC; } - } else { + } else if (vmdq) { pool_mask = dev->data->mac_pool_sel[index]; /* Check if both MAC address and pool is already there, and do nothing */ @@ -5440,8 +5450,10 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, /* Update address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]); - /* Update pool bitmap in NIC data structure */ - dev->data->mac_pool_sel[index] |= RTE_BIT64(pool); + if (vmdq) { + /* Update pool bitmap in NIC data structure */ + dev->data->mac_pool_sel[index] |= RTE_BIT64(pool); + } } ret = eth_err(port_id, ret); @@ -5486,8 +5498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) /* Update address in NIC data structure */ rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]); - /* reset pool bitmap */ - dev->data->mac_pool_sel[index] = 0; + if ((dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0) { + /* reset pool bitmap */ + dev->data->mac_pool_sel[index] = 0; + } rte_ethdev_trace_mac_addr_remove(port_id, addr); -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 2/4] ethdev: announce VMDq capability 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 ` David Marchand 2026-04-06 22:22 ` Kishore Padmanabha 2026-04-03 9:18 ` [PATCH 3/4] ethdev: hide VMDq internal sizes David Marchand ` (4 subsequent siblings) 6 siblings, 1 reply; 24+ messages in thread From: David Marchand @ 2026-04-03 9:18 UTC (permalink / raw) To: dev Cc: rjarry, cfontain, Kishore Padmanabha, Ajit Khaparde, Bruce Richardson, Rosen Xu, Anatoly Burakov, Vladimir Medvedkin, Jiawen Wu, Zaiyu Wang, Thomas Monjalon, Andrew Rybchenko Let's mark VMDq feature availability as a per device capability. We can then enforce API calls related to this feature are done on device with such capability. Signed-off-by: David Marchand <david.marchand@redhat.com> --- drivers/net/bnxt/bnxt_ethdev.c | 3 ++- drivers/net/bnxt/bnxt_reps.c | 1 + drivers/net/intel/e1000/em_ethdev.c | 1 + drivers/net/intel/e1000/igb_ethdev.c | 1 + drivers/net/intel/fm10k/fm10k_ethdev.c | 1 + drivers/net/intel/i40e/i40e_ethdev.c | 3 ++- drivers/net/intel/i40e/i40e_vf_representor.c | 1 + drivers/net/intel/ipn3ke/ipn3ke_representor.c | 3 ++- drivers/net/intel/ixgbe/ixgbe_ethdev.c | 2 ++ drivers/net/txgbe/txgbe_ethdev.c | 1 + drivers/net/txgbe/txgbe_ethdev_vf.c | 1 + lib/ethdev/rte_ethdev.c | 17 +++++++++++++++++ lib/ethdev/rte_ethdev.h | 2 ++ 13 files changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index b677f9491d..0f783b9e98 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -1214,7 +1214,8 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, dev_info->speed_capa = bnxt_get_speed_capabilities(bp); dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | - RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP | + RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; dev_info->default_rxconf = (struct rte_eth_rxconf) { diff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c index e26a086f41..5e834830e2 100644 --- a/drivers/net/bnxt/bnxt_reps.c +++ b/drivers/net/bnxt/bnxt_reps.c @@ -649,6 +649,7 @@ int bnxt_rep_dev_info_get_op(struct rte_eth_dev *eth_dev, dev_info->max_tx_queues = max_rx_rings; dev_info->reta_size = bnxt_rss_hash_tbl_size(parent_bp); dev_info->hash_key_size = 40; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; /* MTU specifics */ diff --git a/drivers/net/intel/e1000/em_ethdev.c b/drivers/net/intel/e1000/em_ethdev.c index 9e15e882b9..389744ad5e 100644 --- a/drivers/net/intel/e1000/em_ethdev.c +++ b/drivers/net/intel/e1000/em_ethdev.c @@ -1175,6 +1175,7 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) RTE_ETH_LINK_SPEED_100M_HD | RTE_ETH_LINK_SPEED_100M | RTE_ETH_LINK_SPEED_1G; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; /* Preferred queue parameters */ diff --git a/drivers/net/intel/e1000/igb_ethdev.c b/drivers/net/intel/e1000/igb_ethdev.c index ef1599ac38..fe68c18417 100644 --- a/drivers/net/intel/e1000/igb_ethdev.c +++ b/drivers/net/intel/e1000/igb_ethdev.c @@ -2324,6 +2324,7 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->tx_queue_offload_capa = igb_get_tx_queue_offloads_capa(dev); dev_info->tx_offload_capa = igb_get_tx_port_offloads_capa(dev) | dev_info->tx_queue_offload_capa; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; switch (hw->mac.type) { diff --git a/drivers/net/intel/fm10k/fm10k_ethdev.c b/drivers/net/intel/fm10k/fm10k_ethdev.c index 97f61afec2..037d2206fd 100644 --- a/drivers/net/intel/fm10k/fm10k_ethdev.c +++ b/drivers/net/intel/fm10k/fm10k_ethdev.c @@ -1444,6 +1444,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev, dev_info->speed_capa = RTE_ETH_LINK_SPEED_1G | RTE_ETH_LINK_SPEED_2_5G | RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G | RTE_ETH_LINK_SPEED_40G | RTE_ETH_LINK_SPEED_100G; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; return 0; } diff --git a/drivers/net/intel/i40e/i40e_ethdev.c b/drivers/net/intel/i40e/i40e_ethdev.c index 100a751225..64c29c6e85 100644 --- a/drivers/net/intel/i40e/i40e_ethdev.c +++ b/drivers/net/intel/i40e/i40e_ethdev.c @@ -3878,7 +3878,8 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | - RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP | + RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) * diff --git a/drivers/net/intel/i40e/i40e_vf_representor.c b/drivers/net/intel/i40e/i40e_vf_representor.c index e8f0bb62a0..d31148acb5 100644 --- a/drivers/net/intel/i40e/i40e_vf_representor.c +++ b/drivers/net/intel/i40e/i40e_vf_representor.c @@ -33,6 +33,7 @@ i40e_vf_representor_dev_infos_get(struct rte_eth_dev *ethdev, /* get dev info for the vdev */ dev_info->device = ethdev->device; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; dev_info->max_rx_queues = ethdev->data->nb_rx_queues; diff --git a/drivers/net/intel/ipn3ke/ipn3ke_representor.c b/drivers/net/intel/ipn3ke/ipn3ke_representor.c index cd34d08055..d581ee3c37 100644 --- a/drivers/net/intel/ipn3ke/ipn3ke_representor.c +++ b/drivers/net/intel/ipn3ke/ipn3ke_representor.c @@ -95,7 +95,8 @@ ipn3ke_rpst_dev_infos_get(struct rte_eth_dev *ethdev, dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | - RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP | + RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; dev_info->switch_info.name = ethdev->device->name; diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c b/drivers/net/intel/ixgbe/ixgbe_ethdev.c index 57d929cf2c..5d886b3e28 100644 --- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c @@ -3997,6 +3997,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->max_mtu = dev_info->max_rx_pktlen - IXGBE_ETH_OVERHEAD; dev_info->min_mtu = RTE_ETHER_MIN_MTU; dev_info->vmdq_queue_num = dev_info->max_rx_queues; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->rx_queue_offload_capa = ixgbe_get_rx_queue_offloads(dev); dev_info->rx_offload_capa = (ixgbe_get_rx_port_offloads(dev) | dev_info->rx_queue_offload_capa); @@ -4115,6 +4116,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev, dev_info->max_vmdq_pools = RTE_ETH_16_POOLS; else dev_info->max_vmdq_pools = RTE_ETH_64_POOLS; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->rx_queue_offload_capa = ixgbe_get_rx_queue_offloads(dev); dev_info->rx_offload_capa = (ixgbe_get_rx_port_offloads(dev) | dev_info->rx_queue_offload_capa); diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c index 5d360f8305..bd818e8269 100644 --- a/drivers/net/txgbe/txgbe_ethdev.c +++ b/drivers/net/txgbe/txgbe_ethdev.c @@ -2836,6 +2836,7 @@ txgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->max_vfs = pci_dev->max_vfs; dev_info->max_vmdq_pools = RTE_ETH_64_POOLS; dev_info->vmdq_queue_num = dev_info->max_rx_queues; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; dev_info->rx_queue_offload_capa = txgbe_get_rx_queue_offloads(dev); dev_info->rx_offload_capa = (txgbe_get_rx_port_offloads(dev) | diff --git a/drivers/net/txgbe/txgbe_ethdev_vf.c b/drivers/net/txgbe/txgbe_ethdev_vf.c index 39a5fff65c..934763574c 100644 --- a/drivers/net/txgbe/txgbe_ethdev_vf.c +++ b/drivers/net/txgbe/txgbe_ethdev_vf.c @@ -572,6 +572,7 @@ txgbevf_dev_info_get(struct rte_eth_dev *dev, dev_info->max_hash_mac_addrs = TXGBE_VMDQ_NUM_UC_MAC; dev_info->max_vfs = pci_dev->max_vfs; dev_info->max_vmdq_pools = RTE_ETH_64_POOLS; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; dev_info->rx_queue_offload_capa = txgbe_get_rx_queue_offloads(dev); dev_info->rx_offload_capa = (txgbe_get_rx_port_offloads(dev) | diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 9577b7d848..7ba539e796 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -158,6 +158,7 @@ static const struct { {RTE_ETH_DEV_CAPA_RXQ_SHARE, "RXQ_SHARE"}, {RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP, "FLOW_RULE_KEEP"}, {RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"}, + {RTE_ETH_DEV_CAPA_VMDQ, "VMDQ"}, }; enum { @@ -1581,6 +1582,22 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, goto rollback; } + if (!(dev_info.dev_capa & RTE_ETH_DEV_CAPA_VMDQ)) { + if ((dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0) { + RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does not support VMDq rx mode", + port_id); + ret = -EINVAL; + goto rollback; + } + if (dev_conf->txmode.mq_mode == RTE_ETH_MQ_TX_VMDQ_DCB || + dev_conf->txmode.mq_mode == RTE_ETH_MQ_TX_VMDQ_ONLY) { + RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does not support VMDq tx mode", + port_id); + ret = -EINVAL; + goto rollback; + } + } + /* * Setup new number of Rx/Tx queues and reconfigure device. */ diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index 0d8e2d0236..62c72de0e5 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -1696,6 +1696,8 @@ struct rte_eth_conf { #define RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP RTE_BIT64(3) /** Device supports keeping shared flow objects across restart. */ #define RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP RTE_BIT64(4) +/** Device supports VMDq. */ +#define RTE_ETH_DEV_CAPA_VMDQ RTE_BIT64(5) /**@}*/ /* -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 2/4] ethdev: announce VMDq capability 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 0 siblings, 1 reply; 24+ messages in thread From: Kishore Padmanabha @ 2026-04-06 22:22 UTC (permalink / raw) To: David Marchand Cc: dev, rjarry, cfontain, Ajit Khaparde, Bruce Richardson, Rosen Xu, Anatoly Burakov, Vladimir Medvedkin, Jiawen Wu, Zaiyu Wang, Thomas Monjalon, Andrew Rybchenko [-- Attachment #1.1: Type: text/plain, Size: 11777 bytes --] On Fri, Apr 3, 2026 at 5:19 AM David Marchand <david.marchand@redhat.com> wrote: > Let's mark VMDq feature availability as a per device capability. > We can then enforce API calls related to this feature are done on device > with such capability. > > Signed-off-by: David Marchand <david.marchand@redhat.com> > --- > drivers/net/bnxt/bnxt_ethdev.c | 3 ++- > drivers/net/bnxt/bnxt_reps.c | 1 + > drivers/net/intel/e1000/em_ethdev.c | 1 + > drivers/net/intel/e1000/igb_ethdev.c | 1 + > drivers/net/intel/fm10k/fm10k_ethdev.c | 1 + > drivers/net/intel/i40e/i40e_ethdev.c | 3 ++- > drivers/net/intel/i40e/i40e_vf_representor.c | 1 + > drivers/net/intel/ipn3ke/ipn3ke_representor.c | 3 ++- > drivers/net/intel/ixgbe/ixgbe_ethdev.c | 2 ++ > drivers/net/txgbe/txgbe_ethdev.c | 1 + > drivers/net/txgbe/txgbe_ethdev_vf.c | 1 + > lib/ethdev/rte_ethdev.c | 17 +++++++++++++++++ > lib/ethdev/rte_ethdev.h | 2 ++ > 13 files changed, 34 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/bnxt/bnxt_ethdev.c > b/drivers/net/bnxt/bnxt_ethdev.c > index b677f9491d..0f783b9e98 100644 > --- a/drivers/net/bnxt/bnxt_ethdev.c > +++ b/drivers/net/bnxt/bnxt_ethdev.c > @@ -1214,7 +1214,8 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev > *eth_dev, > > dev_info->speed_capa = bnxt_get_speed_capabilities(bp); > dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | > - RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; > + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP | > + RTE_ETH_DEV_CAPA_VMDQ; > We have not been testing the VMDq feature for sometime, planning to deprecate this feature. Please remove this change. > dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; > > dev_info->default_rxconf = (struct rte_eth_rxconf) { > diff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c > index e26a086f41..5e834830e2 100644 > --- a/drivers/net/bnxt/bnxt_reps.c > +++ b/drivers/net/bnxt/bnxt_reps.c > @@ -649,6 +649,7 @@ int bnxt_rep_dev_info_get_op(struct rte_eth_dev > *eth_dev, > dev_info->max_tx_queues = max_rx_rings; > dev_info->reta_size = bnxt_rss_hash_tbl_size(parent_bp); > dev_info->hash_key_size = 40; > + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; > dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; > > We have not been testing the VMDq feature for sometime, planning to deprecate this feature. Please remove this change. > /* MTU specifics */ > diff --git a/drivers/net/intel/e1000/em_ethdev.c > b/drivers/net/intel/e1000/em_ethdev.c > index 9e15e882b9..389744ad5e 100644 > --- a/drivers/net/intel/e1000/em_ethdev.c > +++ b/drivers/net/intel/e1000/em_ethdev.c > @@ -1175,6 +1175,7 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct > rte_eth_dev_info *dev_info) > RTE_ETH_LINK_SPEED_100M_HD | > RTE_ETH_LINK_SPEED_100M | > RTE_ETH_LINK_SPEED_1G; > > + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; > dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; > > /* Preferred queue parameters */ > diff --git a/drivers/net/intel/e1000/igb_ethdev.c > b/drivers/net/intel/e1000/igb_ethdev.c > index ef1599ac38..fe68c18417 100644 > --- a/drivers/net/intel/e1000/igb_ethdev.c > +++ b/drivers/net/intel/e1000/igb_ethdev.c > @@ -2324,6 +2324,7 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct > rte_eth_dev_info *dev_info) > dev_info->tx_queue_offload_capa = > igb_get_tx_queue_offloads_capa(dev); > dev_info->tx_offload_capa = igb_get_tx_port_offloads_capa(dev) | > dev_info->tx_queue_offload_capa; > + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; > dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; > > switch (hw->mac.type) { > diff --git a/drivers/net/intel/fm10k/fm10k_ethdev.c > b/drivers/net/intel/fm10k/fm10k_ethdev.c > index 97f61afec2..037d2206fd 100644 > --- a/drivers/net/intel/fm10k/fm10k_ethdev.c > +++ b/drivers/net/intel/fm10k/fm10k_ethdev.c > @@ -1444,6 +1444,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev, > dev_info->speed_capa = RTE_ETH_LINK_SPEED_1G | > RTE_ETH_LINK_SPEED_2_5G | > RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G | > RTE_ETH_LINK_SPEED_40G | RTE_ETH_LINK_SPEED_100G; > + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; > > return 0; > } > diff --git a/drivers/net/intel/i40e/i40e_ethdev.c > b/drivers/net/intel/i40e/i40e_ethdev.c > index 100a751225..64c29c6e85 100644 > --- a/drivers/net/intel/i40e/i40e_ethdev.c > +++ b/drivers/net/intel/i40e/i40e_ethdev.c > @@ -3878,7 +3878,8 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct > rte_eth_dev_info *dev_info) > > dev_info->dev_capa = > RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | > - RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; > + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP | > + RTE_ETH_DEV_CAPA_VMDQ; > dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; > > dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) * > diff --git a/drivers/net/intel/i40e/i40e_vf_representor.c > b/drivers/net/intel/i40e/i40e_vf_representor.c > index e8f0bb62a0..d31148acb5 100644 > --- a/drivers/net/intel/i40e/i40e_vf_representor.c > +++ b/drivers/net/intel/i40e/i40e_vf_representor.c > @@ -33,6 +33,7 @@ i40e_vf_representor_dev_infos_get(struct rte_eth_dev > *ethdev, > /* get dev info for the vdev */ > dev_info->device = ethdev->device; > > + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; > dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; > > dev_info->max_rx_queues = ethdev->data->nb_rx_queues; > diff --git a/drivers/net/intel/ipn3ke/ipn3ke_representor.c > b/drivers/net/intel/ipn3ke/ipn3ke_representor.c > index cd34d08055..d581ee3c37 100644 > --- a/drivers/net/intel/ipn3ke/ipn3ke_representor.c > +++ b/drivers/net/intel/ipn3ke/ipn3ke_representor.c > @@ -95,7 +95,8 @@ ipn3ke_rpst_dev_infos_get(struct rte_eth_dev *ethdev, > > dev_info->dev_capa = > RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | > - RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; > + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP | > + RTE_ETH_DEV_CAPA_VMDQ; > dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; > > dev_info->switch_info.name = ethdev->device->name; > diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c > b/drivers/net/intel/ixgbe/ixgbe_ethdev.c > index 57d929cf2c..5d886b3e28 100644 > --- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c > +++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c > @@ -3997,6 +3997,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct > rte_eth_dev_info *dev_info) > dev_info->max_mtu = dev_info->max_rx_pktlen - IXGBE_ETH_OVERHEAD; > dev_info->min_mtu = RTE_ETHER_MIN_MTU; > dev_info->vmdq_queue_num = dev_info->max_rx_queues; > + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; > dev_info->rx_queue_offload_capa = ixgbe_get_rx_queue_offloads(dev); > dev_info->rx_offload_capa = (ixgbe_get_rx_port_offloads(dev) | > dev_info->rx_queue_offload_capa); > @@ -4115,6 +4116,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev, > dev_info->max_vmdq_pools = RTE_ETH_16_POOLS; > else > dev_info->max_vmdq_pools = RTE_ETH_64_POOLS; > + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; > dev_info->rx_queue_offload_capa = ixgbe_get_rx_queue_offloads(dev); > dev_info->rx_offload_capa = (ixgbe_get_rx_port_offloads(dev) | > dev_info->rx_queue_offload_capa); > diff --git a/drivers/net/txgbe/txgbe_ethdev.c > b/drivers/net/txgbe/txgbe_ethdev.c > index 5d360f8305..bd818e8269 100644 > --- a/drivers/net/txgbe/txgbe_ethdev.c > +++ b/drivers/net/txgbe/txgbe_ethdev.c > @@ -2836,6 +2836,7 @@ txgbe_dev_info_get(struct rte_eth_dev *dev, struct > rte_eth_dev_info *dev_info) > dev_info->max_vfs = pci_dev->max_vfs; > dev_info->max_vmdq_pools = RTE_ETH_64_POOLS; > dev_info->vmdq_queue_num = dev_info->max_rx_queues; > + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; > dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; > dev_info->rx_queue_offload_capa = txgbe_get_rx_queue_offloads(dev); > dev_info->rx_offload_capa = (txgbe_get_rx_port_offloads(dev) | > diff --git a/drivers/net/txgbe/txgbe_ethdev_vf.c > b/drivers/net/txgbe/txgbe_ethdev_vf.c > index 39a5fff65c..934763574c 100644 > --- a/drivers/net/txgbe/txgbe_ethdev_vf.c > +++ b/drivers/net/txgbe/txgbe_ethdev_vf.c > @@ -572,6 +572,7 @@ txgbevf_dev_info_get(struct rte_eth_dev *dev, > dev_info->max_hash_mac_addrs = TXGBE_VMDQ_NUM_UC_MAC; > dev_info->max_vfs = pci_dev->max_vfs; > dev_info->max_vmdq_pools = RTE_ETH_64_POOLS; > + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; > dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; > dev_info->rx_queue_offload_capa = txgbe_get_rx_queue_offloads(dev); > dev_info->rx_offload_capa = (txgbe_get_rx_port_offloads(dev) | > diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c > index 9577b7d848..7ba539e796 100644 > --- a/lib/ethdev/rte_ethdev.c > +++ b/lib/ethdev/rte_ethdev.c > @@ -158,6 +158,7 @@ static const struct { > {RTE_ETH_DEV_CAPA_RXQ_SHARE, "RXQ_SHARE"}, > {RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP, "FLOW_RULE_KEEP"}, > {RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, > "FLOW_SHARED_OBJECT_KEEP"}, > + {RTE_ETH_DEV_CAPA_VMDQ, "VMDQ"}, > }; > > enum { > @@ -1581,6 +1582,22 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t > nb_rx_q, uint16_t nb_tx_q, > goto rollback; > } > > + if (!(dev_info.dev_capa & RTE_ETH_DEV_CAPA_VMDQ)) { > + if ((dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) > != 0) { > + RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does > not support VMDq rx mode", > + port_id); > + ret = -EINVAL; > + goto rollback; > + } > + if (dev_conf->txmode.mq_mode == RTE_ETH_MQ_TX_VMDQ_DCB || > + dev_conf->txmode.mq_mode == > RTE_ETH_MQ_TX_VMDQ_ONLY) { > + RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does > not support VMDq tx mode", > + port_id); > + ret = -EINVAL; > + goto rollback; > + } > + } > + > /* > * Setup new number of Rx/Tx queues and reconfigure device. > */ > diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h > index 0d8e2d0236..62c72de0e5 100644 > --- a/lib/ethdev/rte_ethdev.h > +++ b/lib/ethdev/rte_ethdev.h > @@ -1696,6 +1696,8 @@ struct rte_eth_conf { > #define RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP RTE_BIT64(3) > /** Device supports keeping shared flow objects across restart. */ > #define RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP RTE_BIT64(4) > +/** Device supports VMDq. */ > +#define RTE_ETH_DEV_CAPA_VMDQ RTE_BIT64(5) > /**@}*/ > > /* > -- > 2.53.0 > > [-- Attachment #1.2: Type: text/html, Size: 13987 bytes --] [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 5493 bytes --] ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 2/4] ethdev: announce VMDq capability 2026-04-06 22:22 ` Kishore Padmanabha @ 2026-04-29 14:18 ` David Marchand 0 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-04-29 14:18 UTC (permalink / raw) To: Kishore Padmanabha Cc: dev, rjarry, cfontain, Ajit Khaparde, Bruce Richardson, Rosen Xu, Anatoly Burakov, Vladimir Medvedkin, Jiawen Wu, Zaiyu Wang, Thomas Monjalon, Andrew Rybchenko On Tue, 7 Apr 2026 at 00:22, Kishore Padmanabha <kishore.padmanabha@broadcom.com> wrote: >> diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c >> index b677f9491d..0f783b9e98 100644 >> --- a/drivers/net/bnxt/bnxt_ethdev.c >> +++ b/drivers/net/bnxt/bnxt_ethdev.c >> @@ -1214,7 +1214,8 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, >> >> dev_info->speed_capa = bnxt_get_speed_capabilities(bp); >> dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | >> - RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; >> + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP | >> + RTE_ETH_DEV_CAPA_VMDQ; > > We have not been testing the VMDq feature for sometime, planning to deprecate this feature. Please remove this change. Currently, the driver supports VMDq: $ git grep -i vmdq doc/guides/nics/features/bnxt.ini doc/guides/nics/features/bnxt.ini:VMDq = Y I don't intend to own this feature drop with my series :-). Please announce such a deprecation and flag it properly. -- David Marchand ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 3/4] ethdev: hide VMDq internal sizes 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-03 9:18 ` David Marchand 2026-04-03 9:18 ` [PATCH 4/4] net/iavf: accept up to 32k unicast MAC addresses David Marchand ` (3 subsequent siblings) 6 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-04-03 9:18 UTC (permalink / raw) To: dev; +Cc: rjarry, cfontain, Thomas Monjalon, Andrew Rybchenko Hide RTE_ETH_NUM_RECEIVE_MAC_ADDR and RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY in the driver API as those (ambiguous) macros are only a driver concern. In practice, this is only used by the bnxt and ixgbe (+ clones) drivers. Signed-off-by: David Marchand <david.marchand@redhat.com> --- lib/ethdev/ethdev_driver.h | 8 +++++++- lib/ethdev/rte_ethdev.h | 6 ------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index 1255cd6f2c..a4e9cf5b90 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -119,6 +119,12 @@ struct __rte_cache_aligned rte_eth_dev { struct rte_eth_dev_sriov; struct rte_eth_dev_owner; +/* Definitions used for receive MAC address */ +#define RTE_ETH_NUM_RECEIVE_MAC_ADDR 128 /**< Maximum nb. of receive mac addr. */ + +/* Definitions used for unicast hash */ +#define RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY 128 /**< Maximum nb. of UC hash array. */ + /** * @internal * The data part, with no function pointers, associated with each Ethernet @@ -153,7 +159,7 @@ struct __rte_cache_aligned rte_eth_dev_data { * The first entry (index zero) is the default address. */ struct rte_ether_addr *mac_addrs; - /** Bitmap associating MAC addresses to pools */ + /** Bitmap associating MAC addresses to VMDq pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; /** * Device Ethernet MAC addresses of hash filtering. diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index 62c72de0e5..6c1984e679 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -903,12 +903,6 @@ rte_eth_rss_hf_refine(uint64_t rss_hf) #define RTE_ETH_VLAN_ID_MAX 0x0FFF /**< VLAN ID is in lower 12 bits*/ /**@}*/ -/* Definitions used for receive MAC address */ -#define RTE_ETH_NUM_RECEIVE_MAC_ADDR 128 /**< Maximum nb. of receive mac addr. */ - -/* Definitions used for unicast hash */ -#define RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY 128 /**< Maximum nb. of UC hash array. */ - /**@{@name VMDq Rx mode * @see rte_eth_vmdq_rx_conf.rx_mode */ -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 4/4] net/iavf: accept up to 32k unicast MAC addresses 2026-04-03 9:18 [PATCH 0/4] Remove limitations coming from legacy VMDq David Marchand ` (2 preceding siblings ...) 2026-04-03 9:18 ` [PATCH 3/4] ethdev: hide VMDq internal sizes David Marchand @ 2026-04-03 9:18 ` David Marchand 2026-04-05 18:47 ` [PATCH 0/4] Remove limitations coming from legacy VMDq Stephen Hemminger ` (2 subsequent siblings) 6 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-04-03 9:18 UTC (permalink / raw) To: dev; +Cc: rjarry, cfontain, Vladimir Medvedkin 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 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. Signed-off-by: David Marchand <david.marchand@redhat.com> --- drivers/net/intel/iavf/iavf.h | 5 +++-- drivers/net/intel/iavf/iavf_ethdev.c | 10 +++++----- drivers/net/intel/iavf/iavf_vchnl.c | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) 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..c69a012d50 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; @@ -2822,11 +2822,11 @@ iavf_dev_init(struct rte_eth_dev *eth_dev) /* copy mac addr */ eth_dev->data->mac_addrs = rte_zmalloc( - "iavf_mac", RTE_ETHER_ADDR_LEN * IAVF_NUM_MACADDR_MAX, 0); + "iavf_mac", RTE_ETHER_ADDR_LEN * IAVF_UC_MACADDR_MAX, 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..c70f2fbbc0 100644 --- a/drivers/net/intel/iavf/iavf_vchnl.c +++ b/drivers/net/intel/iavf/iavf_vchnl.c @@ -1442,7 +1442,7 @@ iavf_add_del_all_mac_addr(struct iavf_adapter *adapter, bool add) { struct { struct virtchnl_ether_addr_list list; - struct virtchnl_ether_addr addr[IAVF_NUM_MACADDR_MAX]; + struct virtchnl_ether_addr addr[IAVF_UC_MACADDR_MAX]; } list_req = {0}; struct virtchnl_ether_addr_list *list = &list_req.list; struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); @@ -1450,7 +1450,7 @@ iavf_add_del_all_mac_addr(struct iavf_adapter *adapter, bool add) int err, i; size_t buf_len; - for (i = 0; i < IAVF_NUM_MACADDR_MAX; i++) { + for (i = 0; i < IAVF_UC_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]; @@ -2060,7 +2060,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 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 0/4] Remove limitations coming from legacy VMDq 2026-04-03 9:18 [PATCH 0/4] Remove limitations coming from legacy VMDq David Marchand ` (3 preceding siblings ...) 2026-04-03 9:18 ` [PATCH 4/4] net/iavf: accept up to 32k unicast MAC addresses David Marchand @ 2026-04-05 18:47 ` Stephen Hemminger 2026-04-29 14:22 ` David Marchand 2026-05-06 12:35 ` [PATCH v2 0/5] " David Marchand 2026-05-10 17:03 ` [PATCH v3 " David Marchand 6 siblings, 1 reply; 24+ messages in thread From: Stephen Hemminger @ 2026-04-05 18:47 UTC (permalink / raw) To: David Marchand; +Cc: dev, rjarry, cfontain On Fri, 3 Apr 2026 11:18:31 +0200 David Marchand <david.marchand@redhat.com> wrote: > Since the commit 88ac4396ad29 ("ethdev: add VMDq support"), > VMDq has been imposing a maximum number of mac addresses in the > mac_addr_add/del API. > > Nowadays, new Intel drivers do not support the feature and few other > drivers implement this feature. > > This series proposes to flag drivers that support the feature, and > remove the limit of number of mac addresses for others. > > Next step could be to remove the VMDq pool notion from the generic API. > However I have some concern about this, as changing the quite stable > mac_addr_add/del API now seems a lot of noise for not much benefit. > > Make sense. The AI review found a couple of things. Had to poke at it to make a good description Subject: Re: [PATCH 1/4] ethdev: skip VMDq pools unless configured Patches 1/4 and 3/4 look good to me. Patch 2/4 has two issues: 1) In bnxt_reps.c, the new line: dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; overwrites any default capabilities that were previously set before the driver callback. The other drivers in this patch had the same pre-existing pattern (plain assignment before &= ~FLOW_RULE_KEEP), so for them it's no worse. But bnxt_reps.c previously only did the &= ~ clear, so this is a new regression. Should be |= instead of =. 2) Several drivers that receive RTE_ETH_DEV_CAPA_VMDQ don't actually support VMDq: e1000/em, bnxt representors, and i40e VF representors have no max_vmdq_pools or VMDq configuration. Marking them as VMDq-capable seems incorrect and would allow users to attempt VMDq configuration on devices that can't handle it. Patch 4/4 has a stack overflow: iavf_add_del_all_mac_addr() allocates list_req on the stack with addr[IAVF_UC_MACADDR_MAX]. At 32768 entries of ~8 bytes each, that's roughly 256 KiB on the stack. This will blow the stack on most configurations. Needs to be heap-allocated. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 0/4] Remove limitations coming from legacy VMDq 2026-04-05 18:47 ` [PATCH 0/4] Remove limitations coming from legacy VMDq Stephen Hemminger @ 2026-04-29 14:22 ` David Marchand 0 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-04-29 14:22 UTC (permalink / raw) To: Stephen Hemminger; +Cc: dev, rjarry, cfontain On Sun, 5 Apr 2026 at 20:47, Stephen Hemminger <stephen@networkplumber.org> wrote: > > On Fri, 3 Apr 2026 11:18:31 +0200 > David Marchand <david.marchand@redhat.com> wrote: > > > Since the commit 88ac4396ad29 ("ethdev: add VMDq support"), > > VMDq has been imposing a maximum number of mac addresses in the > > mac_addr_add/del API. > > > > Nowadays, new Intel drivers do not support the feature and few other > > drivers implement this feature. > > > > This series proposes to flag drivers that support the feature, and > > remove the limit of number of mac addresses for others. > > > > Next step could be to remove the VMDq pool notion from the generic API. > > However I have some concern about this, as changing the quite stable > > mac_addr_add/del API now seems a lot of noise for not much benefit. > > > > > > Make sense. The AI review found a couple of things. > Had to poke at it to make a good description > > Subject: Re: [PATCH 1/4] ethdev: skip VMDq pools unless configured > > Patches 1/4 and 3/4 look good to me. > > Patch 2/4 has two issues: > > 1) In bnxt_reps.c, the new line: > > dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; > > overwrites any default capabilities that were previously set before > the driver callback. The other drivers in this patch had the same > pre-existing pattern (plain assignment before &= ~FLOW_RULE_KEEP), > so for them it's no worse. But bnxt_reps.c previously only did the > &= ~ clear, so this is a new regression. Should be |= instead of =. The explicit &= ~FLOW_RULE_KEEP was added as a "documentation" hint for maintainers. 2fe6f1b76279 ("drivers/net: advertise no support for keeping flow rules") Though I don't see much activity on the topic, so this hint probably missed the target. In any case, dev_capa is set to 0 from ethdev before calling the driver op, so nothing is broken with an explicit =. > > 2) Several drivers that receive RTE_ETH_DEV_CAPA_VMDQ don't actually > support VMDq: e1000/em, bnxt representors, and i40e VF representors > have no max_vmdq_pools or VMDq configuration. Marking them as > VMDq-capable seems incorrect and would allow users to attempt VMDq > configuration on devices that can't handle it. This one is interesting and it seems to make sense, I'll double check. > > Patch 4/4 has a stack overflow: > > iavf_add_del_all_mac_addr() allocates list_req on the stack with > addr[IAVF_UC_MACADDR_MAX]. At 32768 entries of ~8 bytes each, > that's roughly 256 KiB on the stack. This will blow the stack > on most configurations. Needs to be heap-allocated. The heap allocations were removed recently, I'll see how I can rework. -- David Marchand ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 0/5] Remove limitations coming from legacy VMDq 2026-04-03 9:18 [PATCH 0/4] Remove limitations coming from legacy VMDq David Marchand ` (4 preceding siblings ...) 2026-04-05 18:47 ` [PATCH 0/4] Remove limitations coming from legacy VMDq Stephen Hemminger @ 2026-05-06 12:35 ` David Marchand 2026-05-06 12:35 ` [PATCH v2 1/5] ethdev: skip VMDq pools unless configured David Marchand ` (5 more replies) 2026-05-10 17:03 ` [PATCH v3 " David Marchand 6 siblings, 6 replies; 24+ messages in thread From: David Marchand @ 2026-05-06 12:35 UTC (permalink / raw) To: dev Since the commit 88ac4396ad29 ("ethdev: add VMDq support"), VMDq has been imposing a maximum number of mac addresses in the mac_addr_add/del API. Nowadays, new Intel drivers do not support the feature and few other drivers implement this feature. This series proposes to flag drivers that support the feature, and remove the limit of number of mac addresses for others. Next step could be to remove the VMDq pool notion from the generic API. However I have some concern about this, as changing the quite stable mac_addr_add/del API now seems a lot of noise for not much benefit. -- David Marchand Changes since v1: - dropped incorrect VMDq feature announce for bnxt representors, em, i40e representors, ipn3ke representors, - fixed buffer overflow on mailbox messages during port restart/VF reset, - fixed duplicate MAC address installation on port start/restart, David Marchand (5): ethdev: skip VMDq pools unless configured ethdev: announce VMDq capability ethdev: hide VMDq internal sizes net/iavf: accept up to 32k unicast MAC addresses net/iavf: fix duplicate MAC addresses install drivers/net/bnxt/bnxt_ethdev.c | 3 +- drivers/net/cnxk/cnxk_ethdev_ops.c | 1 - drivers/net/intel/e1000/igb_ethdev.c | 1 + drivers/net/intel/fm10k/fm10k_ethdev.c | 1 + drivers/net/intel/i40e/i40e_ethdev.c | 3 +- drivers/net/intel/iavf/iavf.h | 5 +- drivers/net/intel/iavf/iavf_ethdev.c | 41 ++++++--- drivers/net/intel/iavf/iavf_vchnl.c | 117 ++++++++++++++++++------- drivers/net/intel/ixgbe/ixgbe_ethdev.c | 2 + drivers/net/txgbe/txgbe_ethdev.c | 1 + drivers/net/txgbe/txgbe_ethdev_vf.c | 1 + lib/ethdev/ethdev_driver.h | 8 +- lib/ethdev/rte_ethdev.c | 45 ++++++++-- lib/ethdev/rte_ethdev.h | 8 +- 14 files changed, 172 insertions(+), 65 deletions(-) -- 2.53.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 1/5] ethdev: skip VMDq pools unless configured 2026-05-06 12:35 ` [PATCH v2 0/5] " David Marchand @ 2026-05-06 12:35 ` David Marchand 2026-05-06 12:35 ` [PATCH v2 2/5] ethdev: announce VMDq capability David Marchand ` (4 subsequent siblings) 5 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-05-06 12:35 UTC (permalink / raw) To: dev Cc: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao, Harman Kalra, Thomas Monjalon, Andrew Rybchenko The mac_addr_add API describes that only the 0 pool should be passed unless VMDq has been enabled, though there was no validation so far. Add such a check, then cleanup the related operations (adding, removing, restoring). As a side effect, the net/cnxk does not need to manually reset the mac_pool_sel[] array. Signed-off-by: David Marchand <david.marchand@redhat.com> --- drivers/net/cnxk/cnxk_ethdev_ops.c | 1 - lib/ethdev/rte_ethdev.c | 28 +++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/net/cnxk/cnxk_ethdev_ops.c b/drivers/net/cnxk/cnxk_ethdev_ops.c index 49e77e49a6..75decf7098 100644 --- a/drivers/net/cnxk/cnxk_ethdev_ops.c +++ b/drivers/net/cnxk/cnxk_ethdev_ops.c @@ -1240,7 +1240,6 @@ cnxk_nix_mc_addr_list_configure(struct rte_eth_dev *eth_dev, struct rte_ether_ad /* Update address in NIC data structure */ rte_ether_addr_copy(&mc_addr_set[i], &data->mac_addrs[j]); rte_ether_addr_copy(&mc_addr_set[i], &dev->dmac_addrs[j]); - data->mac_pool_sel[j] = RTE_BIT64(0); } roc_nix_npc_promisc_ena_dis(nix, true); diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 2edc7a362e..9577b7d848 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -1680,7 +1680,10 @@ eth_dev_mac_restore(struct rte_eth_dev *dev, continue; pool = 0; - pool_mask = dev->data->mac_pool_sel[i]; + if ((dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0) + pool_mask = dev->data->mac_pool_sel[i]; + else + pool_mask = 1; do { if (pool_mask & UINT64_C(1)) @@ -5390,8 +5393,9 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, uint32_t pool) { struct rte_eth_dev *dev; - int index; uint64_t pool_mask; + bool vmdq; + int index; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -5416,6 +5420,12 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, RTE_ETHDEV_LOG_LINE(ERR, "Pool ID must be 0-%d", RTE_ETH_64_POOLS - 1); return -EINVAL; } + vmdq = (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0; + if (!vmdq && pool != 0) { + RTE_ETHDEV_LOG_LINE(ERR, "Port %u: VMDq is not configured (pool %d)", + port_id, pool); + return -EINVAL; + } index = eth_dev_get_mac_addr_index(port_id, addr); if (index < 0) { @@ -5425,7 +5435,7 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, port_id); return -ENOSPC; } - } else { + } else if (vmdq) { pool_mask = dev->data->mac_pool_sel[index]; /* Check if both MAC address and pool is already there, and do nothing */ @@ -5440,8 +5450,10 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, /* Update address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]); - /* Update pool bitmap in NIC data structure */ - dev->data->mac_pool_sel[index] |= RTE_BIT64(pool); + if (vmdq) { + /* Update pool bitmap in NIC data structure */ + dev->data->mac_pool_sel[index] |= RTE_BIT64(pool); + } } ret = eth_err(port_id, ret); @@ -5486,8 +5498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) /* Update address in NIC data structure */ rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]); - /* reset pool bitmap */ - dev->data->mac_pool_sel[index] = 0; + if ((dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0) { + /* reset pool bitmap */ + dev->data->mac_pool_sel[index] = 0; + } rte_ethdev_trace_mac_addr_remove(port_id, addr); -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 2/5] ethdev: announce VMDq capability 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 ` David Marchand 2026-05-06 12:35 ` [PATCH v2 3/5] ethdev: hide VMDq internal sizes David Marchand ` (3 subsequent siblings) 5 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-05-06 12:35 UTC (permalink / raw) To: dev Cc: Kishore Padmanabha, Ajit Khaparde, Bruce Richardson, Anatoly Burakov, Vladimir Medvedkin, Jiawen Wu, Zaiyu Wang, Thomas Monjalon, Andrew Rybchenko Let's mark VMDq feature availability as a per device capability. We can then enforce API calls related to this feature are done on device with such capability. Signed-off-by: David Marchand <david.marchand@redhat.com> --- Changes since v1: - dropped incorrect VMDq feature announce for bnxt representors, em, i40e representors, ipn3ke representors, --- drivers/net/bnxt/bnxt_ethdev.c | 3 ++- drivers/net/intel/e1000/igb_ethdev.c | 1 + drivers/net/intel/fm10k/fm10k_ethdev.c | 1 + drivers/net/intel/i40e/i40e_ethdev.c | 3 ++- drivers/net/intel/ixgbe/ixgbe_ethdev.c | 2 ++ drivers/net/txgbe/txgbe_ethdev.c | 1 + drivers/net/txgbe/txgbe_ethdev_vf.c | 1 + lib/ethdev/rte_ethdev.c | 17 +++++++++++++++++ lib/ethdev/rte_ethdev.h | 2 ++ 9 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index b677f9491d..0f783b9e98 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -1214,7 +1214,8 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, dev_info->speed_capa = bnxt_get_speed_capabilities(bp); dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | - RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP | + RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; dev_info->default_rxconf = (struct rte_eth_rxconf) { diff --git a/drivers/net/intel/e1000/igb_ethdev.c b/drivers/net/intel/e1000/igb_ethdev.c index ef1599ac38..fe68c18417 100644 --- a/drivers/net/intel/e1000/igb_ethdev.c +++ b/drivers/net/intel/e1000/igb_ethdev.c @@ -2324,6 +2324,7 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->tx_queue_offload_capa = igb_get_tx_queue_offloads_capa(dev); dev_info->tx_offload_capa = igb_get_tx_port_offloads_capa(dev) | dev_info->tx_queue_offload_capa; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; switch (hw->mac.type) { diff --git a/drivers/net/intel/fm10k/fm10k_ethdev.c b/drivers/net/intel/fm10k/fm10k_ethdev.c index 97f61afec2..037d2206fd 100644 --- a/drivers/net/intel/fm10k/fm10k_ethdev.c +++ b/drivers/net/intel/fm10k/fm10k_ethdev.c @@ -1444,6 +1444,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev, dev_info->speed_capa = RTE_ETH_LINK_SPEED_1G | RTE_ETH_LINK_SPEED_2_5G | RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G | RTE_ETH_LINK_SPEED_40G | RTE_ETH_LINK_SPEED_100G; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; return 0; } diff --git a/drivers/net/intel/i40e/i40e_ethdev.c b/drivers/net/intel/i40e/i40e_ethdev.c index 100a751225..64c29c6e85 100644 --- a/drivers/net/intel/i40e/i40e_ethdev.c +++ b/drivers/net/intel/i40e/i40e_ethdev.c @@ -3878,7 +3878,8 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | - RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP | + RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) * diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c b/drivers/net/intel/ixgbe/ixgbe_ethdev.c index 57d929cf2c..5d886b3e28 100644 --- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c @@ -3997,6 +3997,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->max_mtu = dev_info->max_rx_pktlen - IXGBE_ETH_OVERHEAD; dev_info->min_mtu = RTE_ETHER_MIN_MTU; dev_info->vmdq_queue_num = dev_info->max_rx_queues; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->rx_queue_offload_capa = ixgbe_get_rx_queue_offloads(dev); dev_info->rx_offload_capa = (ixgbe_get_rx_port_offloads(dev) | dev_info->rx_queue_offload_capa); @@ -4115,6 +4116,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev, dev_info->max_vmdq_pools = RTE_ETH_16_POOLS; else dev_info->max_vmdq_pools = RTE_ETH_64_POOLS; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->rx_queue_offload_capa = ixgbe_get_rx_queue_offloads(dev); dev_info->rx_offload_capa = (ixgbe_get_rx_port_offloads(dev) | dev_info->rx_queue_offload_capa); diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c index 5d360f8305..bd818e8269 100644 --- a/drivers/net/txgbe/txgbe_ethdev.c +++ b/drivers/net/txgbe/txgbe_ethdev.c @@ -2836,6 +2836,7 @@ txgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->max_vfs = pci_dev->max_vfs; dev_info->max_vmdq_pools = RTE_ETH_64_POOLS; dev_info->vmdq_queue_num = dev_info->max_rx_queues; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; dev_info->rx_queue_offload_capa = txgbe_get_rx_queue_offloads(dev); dev_info->rx_offload_capa = (txgbe_get_rx_port_offloads(dev) | diff --git a/drivers/net/txgbe/txgbe_ethdev_vf.c b/drivers/net/txgbe/txgbe_ethdev_vf.c index 39a5fff65c..934763574c 100644 --- a/drivers/net/txgbe/txgbe_ethdev_vf.c +++ b/drivers/net/txgbe/txgbe_ethdev_vf.c @@ -572,6 +572,7 @@ txgbevf_dev_info_get(struct rte_eth_dev *dev, dev_info->max_hash_mac_addrs = TXGBE_VMDQ_NUM_UC_MAC; dev_info->max_vfs = pci_dev->max_vfs; dev_info->max_vmdq_pools = RTE_ETH_64_POOLS; + dev_info->dev_capa = RTE_ETH_DEV_CAPA_VMDQ; dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; dev_info->rx_queue_offload_capa = txgbe_get_rx_queue_offloads(dev); dev_info->rx_offload_capa = (txgbe_get_rx_port_offloads(dev) | diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 9577b7d848..7ba539e796 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -158,6 +158,7 @@ static const struct { {RTE_ETH_DEV_CAPA_RXQ_SHARE, "RXQ_SHARE"}, {RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP, "FLOW_RULE_KEEP"}, {RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"}, + {RTE_ETH_DEV_CAPA_VMDQ, "VMDQ"}, }; enum { @@ -1581,6 +1582,22 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, goto rollback; } + if (!(dev_info.dev_capa & RTE_ETH_DEV_CAPA_VMDQ)) { + if ((dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0) { + RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does not support VMDq rx mode", + port_id); + ret = -EINVAL; + goto rollback; + } + if (dev_conf->txmode.mq_mode == RTE_ETH_MQ_TX_VMDQ_DCB || + dev_conf->txmode.mq_mode == RTE_ETH_MQ_TX_VMDQ_ONLY) { + RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does not support VMDq tx mode", + port_id); + ret = -EINVAL; + goto rollback; + } + } + /* * Setup new number of Rx/Tx queues and reconfigure device. */ diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index 0d8e2d0236..62c72de0e5 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -1696,6 +1696,8 @@ struct rte_eth_conf { #define RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP RTE_BIT64(3) /** Device supports keeping shared flow objects across restart. */ #define RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP RTE_BIT64(4) +/** Device supports VMDq. */ +#define RTE_ETH_DEV_CAPA_VMDQ RTE_BIT64(5) /**@}*/ /* -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 3/5] ethdev: hide VMDq internal sizes 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 ` David Marchand 2026-05-06 12:35 ` [PATCH v2 4/5] net/iavf: accept up to 32k unicast MAC addresses David Marchand ` (2 subsequent siblings) 5 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-05-06 12:35 UTC (permalink / raw) To: dev; +Cc: Thomas Monjalon, Andrew Rybchenko Hide RTE_ETH_NUM_RECEIVE_MAC_ADDR and RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY in the driver API as those (ambiguous) macros are only a driver concern. In practice, this is only used by the bnxt and ixgbe (+ clones) drivers. Signed-off-by: David Marchand <david.marchand@redhat.com> --- lib/ethdev/ethdev_driver.h | 8 +++++++- lib/ethdev/rte_ethdev.h | 6 ------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index 1255cd6f2c..a4e9cf5b90 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -119,6 +119,12 @@ struct __rte_cache_aligned rte_eth_dev { struct rte_eth_dev_sriov; struct rte_eth_dev_owner; +/* Definitions used for receive MAC address */ +#define RTE_ETH_NUM_RECEIVE_MAC_ADDR 128 /**< Maximum nb. of receive mac addr. */ + +/* Definitions used for unicast hash */ +#define RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY 128 /**< Maximum nb. of UC hash array. */ + /** * @internal * The data part, with no function pointers, associated with each Ethernet @@ -153,7 +159,7 @@ struct __rte_cache_aligned rte_eth_dev_data { * The first entry (index zero) is the default address. */ struct rte_ether_addr *mac_addrs; - /** Bitmap associating MAC addresses to pools */ + /** Bitmap associating MAC addresses to VMDq pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; /** * Device Ethernet MAC addresses of hash filtering. diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index 62c72de0e5..6c1984e679 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -903,12 +903,6 @@ rte_eth_rss_hf_refine(uint64_t rss_hf) #define RTE_ETH_VLAN_ID_MAX 0x0FFF /**< VLAN ID is in lower 12 bits*/ /**@}*/ -/* Definitions used for receive MAC address */ -#define RTE_ETH_NUM_RECEIVE_MAC_ADDR 128 /**< Maximum nb. of receive mac addr. */ - -/* Definitions used for unicast hash */ -#define RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY 128 /**< Maximum nb. of UC hash array. */ - /**@{@name VMDq Rx mode * @see rte_eth_vmdq_rx_conf.rx_mode */ -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 4/5] net/iavf: accept up to 32k unicast MAC addresses 2026-05-06 12:35 ` [PATCH v2 0/5] " David Marchand ` (2 preceding siblings ...) 2026-05-06 12:35 ` [PATCH v2 3/5] ethdev: hide VMDq internal sizes David Marchand @ 2026-05-06 12:35 ` 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 5 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-05-06 12:35 UTC (permalink / raw) To: dev; +Cc: Vladimir Medvedkin 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 v1: - fixed buffer overflow on mailbox messages during port restart/VF reset, --- drivers/net/intel/iavf/iavf.h | 5 +- drivers/net/intel/iavf/iavf_ethdev.c | 10 +-- drivers/net/intel/iavf/iavf_vchnl.c | 117 +++++++++++++++++++-------- 3 files changed, 93 insertions(+), 39 deletions(-) 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..c69a012d50 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; @@ -2822,11 +2822,11 @@ iavf_dev_init(struct rte_eth_dev *eth_dev) /* copy mac addr */ eth_dev->data->mac_addrs = rte_zmalloc( - "iavf_mac", RTE_ETHER_ADDR_LEN * IAVF_NUM_MACADDR_MAX, 0); + "iavf_mac", RTE_ETHER_ADDR_LEN * IAVF_UC_MACADDR_MAX, 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..144968db35 100644 --- a/drivers/net/intel/iavf/iavf_vchnl.c +++ b/drivers/net/intel/iavf/iavf_vchnl.c @@ -1437,48 +1437,101 @@ 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++) { + size_t buf_len = sizeof(struct virtchnl_ether_addr_list) + + sizeof(struct virtchnl_ether_addr) * list->num_elements; + 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; + + buf_len = sizeof(struct virtchnl_ether_addr_list) + + sizeof(struct virtchnl_ether_addr) * list->num_elements; + + 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 = 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 != 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 +2113,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 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 5/5] net/iavf: fix duplicate MAC addresses install 2026-05-06 12:35 ` [PATCH v2 0/5] " David Marchand ` (3 preceding siblings ...) 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 ` David Marchand 2026-05-07 2:51 ` [PATCH v2 0/5] Remove limitations coming from legacy VMDq Stephen Hemminger 5 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-05-06 12:35 UTC (permalink / raw) To: dev; +Cc: stable, Vladimir Medvedkin, Bruce Richardson On port restart, all MAC addresses get pushed *twice* to the hardware, once by the driver and once by the eth_dev_mac_restore() in ethdev. On the other hand, MAC address filters are reset in the hardware by the PF only when a VF reset is triggered. Strictly speaking, the mac restore on port (re)start is unneeded, if no VF reset happened, so we can announce to ethdev that no mac restoration is needed via a get_restore_flags callback. Then, move the mac restoration to the VF reset handler. Fixes: 3d42086def30 ("net/iavf: preserve MAC address with i40e PF Linux driver") Cc: stable@dpdk.org Signed-off-by: David Marchand <david.marchand@redhat.com> --- drivers/net/intel/iavf/iavf_ethdev.c | 31 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c index c69a012d50..5871ed3539 100644 --- a/drivers/net/intel/iavf/iavf_ethdev.c +++ b/drivers/net/intel/iavf/iavf_ethdev.c @@ -126,6 +126,8 @@ static void iavf_dev_del_mac_addr(struct rte_eth_dev *dev, uint32_t index); static int iavf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on); static int iavf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask); +static uint64_t iavf_get_restore_flags(struct rte_eth_dev *dev, + enum rte_eth_dev_operation op); static int iavf_dev_rss_reta_update(struct rte_eth_dev *dev, struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size); @@ -249,6 +251,7 @@ static const struct eth_dev_ops iavf_eth_dev_ops = { .tx_done_cleanup = iavf_dev_tx_done_cleanup, .get_monitor_addr = iavf_get_monitor_addr, .tm_ops_get = iavf_tm_ops_get, + .get_restore_flags = iavf_get_restore_flags, }; static int @@ -269,6 +272,13 @@ iavf_tm_ops_get(struct rte_eth_dev *dev, return 0; } +static uint64_t +iavf_get_restore_flags(__rte_unused struct rte_eth_dev *dev, + __rte_unused enum rte_eth_dev_operation op) +{ + return RTE_ETH_RESTORE_ALL & ~RTE_ETH_RESTORE_MAC_ADDR; +} + __rte_unused static int iavf_vfr_inprogress(struct iavf_hw *hw) @@ -1039,15 +1049,14 @@ iavf_dev_start(struct rte_eth_dev *dev) rte_intr_enable(intr_handle); } - /* Set all mac addrs */ - iavf_add_del_all_mac_addr(adapter, true); - - if (!adapter->mac_primary_set) - adapter->mac_primary_set = true; - - /* Set all multicast addresses */ - iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num, - true); + if (!adapter->mac_primary_set) { + if (iavf_add_del_eth_addr(adapter, &dev->data->mac_addrs[0], true, + VIRTCHNL_ETHER_ADDR_PRIMARY) != 0) + PMD_DRV_LOG(ERR, "failed to add primary MAC:" RTE_ETHER_ADDR_PRT_FMT, + RTE_ETHER_ADDR_BYTES(&dev->data->mac_addrs[0])); + else + adapter->mac_primary_set = true; + } rte_spinlock_init(&vf->phc_time_aq_lock); @@ -3144,6 +3153,10 @@ iavf_handle_hw_reset(struct rte_eth_dev *dev, bool vf_initiated_reset) if (ret) goto error; + /* after a VF reset, all mac addresses got flushed, restore them */ + iavf_add_del_all_mac_addr(adapter, true); + iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num, true); + dev->data->dev_started = 1; } goto exit; -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 0/5] Remove limitations coming from legacy VMDq 2026-05-06 12:35 ` [PATCH v2 0/5] " David Marchand ` (4 preceding siblings ...) 2026-05-06 12:35 ` [PATCH v2 5/5] net/iavf: fix duplicate MAC addresses install David Marchand @ 2026-05-07 2:51 ` Stephen Hemminger 2026-05-10 15:03 ` David Marchand 5 siblings, 1 reply; 24+ messages in thread From: Stephen Hemminger @ 2026-05-07 2:51 UTC (permalink / raw) To: David Marchand; +Cc: dev On Wed, 6 May 2026 14:35:48 +0200 David Marchand <david.marchand@redhat.com> wrote: > Since the commit 88ac4396ad29 ("ethdev: add VMDq support"), > VMDq has been imposing a maximum number of mac addresses in the > mac_addr_add/del API. > > Nowadays, new Intel drivers do not support the feature and few other > drivers implement this feature. > > This series proposes to flag drivers that support the feature, and > remove the limit of number of mac addresses for others. > > Next step could be to remove the VMDq pool notion from the generic API. > However I have some concern about this, as changing the quite stable > mac_addr_add/del API now seems a lot of noise for not much benefit. > AI review (manual not automated) saw these: On Wed, 6 May 2026 14:35:49 +0200 David Marchand <david.marchand@redhat.com> wrote: [PATCH v2 1/5] ethdev: skip VMDq pools unless configured -------------------------------------------------------- Warning: duplicate-add no longer returns 0 in non-VMDq mode } else if (vmdq) { pool_mask = dev->data->mac_pool_sel[index]; /* Check if both MAC address and pool is already there, and do nothing */ if (pool_mask & RTE_BIT64(pool)) return 0; } When index >= 0 (MAC already present) and VMDq is not configured, the early "already there" return that existed before is now skipped entirely. The driver's mac_addr_add op gets re-invoked and mac_pool_sel is no longer updated for !vmdq, so subsequent calls keep re-invoking it. Pre-patch behaviour was idempotent (return 0). Suggested fix: } else if (vmdq) { pool_mask = dev->data->mac_pool_sel[index]; if (pool_mask & RTE_BIT64(pool)) return 0; } else { return 0; /* MAC already installed, only one pool */ } [PATCH v2 2/5] ethdev: announce VMDq capability ----------------------------------------------- Warning: capability advertised even when max_vmdq_pools may be 0 The capability bit is set unconditionally in several drivers where VMDq availability is conditional on hardware variant or runtime configuration: - net/intel/e1000/igb_ethdev.c: max_vmdq_pools = 0 for e1000_82575, e1000_i354 (no setting), e1000_i210, e1000_i211. - net/intel/i40e/i40e_ethdev.c: max_vmdq_pools is gated on (pf->flags & I40E_FLAG_VMDQ). - net/bnxt/bnxt_ethdev.c: max_vmdq_pools is set to 0 when there are not enough resources (see "Not enough resources to support VMDq" path). With this patch a user can pass mq_mode |= RTE_ETH_MQ_RX_VMDQ_FLAG through rte_eth_dev_configure() because the new capability check passes, but the driver has no pools to honour the request. Suggested fix: gate the capa bit on max_vmdq_pools > 0, or set it per-MAC-type / per-flag in each driver. Warning: VMDq capability advertised on VFs that do not configure VMDq ixgbevf_dev_info_get() and txgbevf_dev_info_get() now advertise RTE_ETH_DEV_CAPA_VMDQ, but ixgbevf_dev_configure() and txgbevf_dev_configure() only handle RTE_ETH_MQ_RX_RSS_FLAG. The feature matrices doc/guides/nics/features/ixgbe_vf.ini and txgbe_vf.ini do not list "VMDq = Y". A VF is itself a member of a PF VMDq pool; advertising the capa from the VF is misleading. Warning: ipn3ke advertises VMDq=Y in its features file but is not updated by the patch doc/guides/nics/features/ipn3ke.ini has "VMDq = Y" but the patch does not add RTE_ETH_DEV_CAPA_VMDQ to ipn3ke. Either update the driver or correct the feature matrix. Warning: missing release note The new RTE_ETH_DEV_CAPA_VMDQ public bit and the new rejection in rte_eth_dev_configure() (returning -EINVAL when an application sets a VMDq mq_mode on a non-VMDq device) are user-visible API and behavioural changes. release_26_07.rst should mention them under "API Changes". [PATCH v2 3/5] ethdev: hide VMDq internal sizes ----------------------------------------------- Warning: public defines removed without deprecation cycle RTE_ETH_NUM_RECEIVE_MAC_ADDR and RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY were declared in the application-facing rte_ethdev.h. Moving them to ethdev_driver.h removes them from the public API. Per the DPDK API/ABI policy this normally needs a prior deprecation notice; at minimum it warrants a release_26_07.rst "API Changes" entry. [PATCH v2 4/5] net/iavf: accept up to 32k unicast MAC addresses --------------------------------------------------------------- Warning: dead store in iavf_add_del_uc_addr_bulk() for (uint32_t i = 0; i < nb_addrs; i++) { size_t buf_len = sizeof(struct virtchnl_ether_addr_list) + sizeof(struct virtchnl_ether_addr) * list->num_elements; ... buf_len = sizeof(struct virtchnl_ether_addr_list) + sizeof(struct virtchnl_ether_addr) * list->num_elements; The first initialiser is unconditionally overwritten by the second assignment before any read. Drop the initialiser (or move the declaration to the use site). Warning: missing release note for max_mac_addrs jump max_mac_addrs goes from 64 to 32768 and dev_data->mac_addrs is now allocated at RTE_ETHER_ADDR_LEN * 32768 = 192 KiB per VF port. This is a notable behaviour change for iavf users and worth a release_26_07.rst entry. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 0/5] Remove limitations coming from legacy VMDq 2026-05-07 2:51 ` [PATCH v2 0/5] Remove limitations coming from legacy VMDq Stephen Hemminger @ 2026-05-10 15:03 ` David Marchand 0 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-05-10 15:03 UTC (permalink / raw) To: Stephen Hemminger; +Cc: dev Hello Stephen, On Thu, 7 May 2026 at 04:51, Stephen Hemminger <stephen@networkplumber.org> wrote: > > On Wed, 6 May 2026 14:35:48 +0200 > David Marchand <david.marchand@redhat.com> wrote: > > > Since the commit 88ac4396ad29 ("ethdev: add VMDq support"), > > VMDq has been imposing a maximum number of mac addresses in the > > mac_addr_add/del API. > > > > Nowadays, new Intel drivers do not support the feature and few other > > drivers implement this feature. > > > > This series proposes to flag drivers that support the feature, and > > remove the limit of number of mac addresses for others. > > > > Next step could be to remove the VMDq pool notion from the generic API. > > However I have some concern about this, as changing the quite stable > > mac_addr_add/del API now seems a lot of noise for not much benefit. > > > > > AI review (manual not automated) saw these: > > On Wed, 6 May 2026 14:35:49 +0200 > David Marchand <david.marchand@redhat.com> wrote: > > [PATCH v2 1/5] ethdev: skip VMDq pools unless configured > -------------------------------------------------------- > > Warning: duplicate-add no longer returns 0 in non-VMDq mode > > } else if (vmdq) { > pool_mask = dev->data->mac_pool_sel[index]; > /* Check if both MAC address and pool is already there, and do nothing */ > if (pool_mask & RTE_BIT64(pool)) > return 0; > } > > When index >= 0 (MAC already present) and VMDq is not configured, > the early "already there" return that existed before is now skipped > entirely. The driver's mac_addr_add op gets re-invoked and > mac_pool_sel is no longer updated for !vmdq, so subsequent calls > keep re-invoking it. Pre-patch behaviour was idempotent (return 0). > > Suggested fix: > > } else if (vmdq) { > pool_mask = dev->data->mac_pool_sel[index]; > if (pool_mask & RTE_BIT64(pool)) > return 0; > } else { > return 0; /* MAC already installed, only one pool */ > } Yes, good catch. > > > [PATCH v2 2/5] ethdev: announce VMDq capability > ----------------------------------------------- > > Warning: capability advertised even when max_vmdq_pools may be 0 > > The capability bit is set unconditionally in several drivers where > VMDq availability is conditional on hardware variant or runtime > configuration: > > - net/intel/e1000/igb_ethdev.c: max_vmdq_pools = 0 for e1000_82575, > e1000_i354 (no setting), e1000_i210, e1000_i211. > - net/intel/i40e/i40e_ethdev.c: max_vmdq_pools is gated on > (pf->flags & I40E_FLAG_VMDQ). > - net/bnxt/bnxt_ethdev.c: max_vmdq_pools is set to 0 when there > are not enough resources (see "Not enough resources to support > VMDq" path). > > With this patch a user can pass mq_mode |= RTE_ETH_MQ_RX_VMDQ_FLAG > through rte_eth_dev_configure() because the new capability check > passes, but the driver has no pools to honour the request. > > Suggested fix: gate the capa bit on max_vmdq_pools > 0, or set it > per-MAC-type / per-flag in each driver. I realise now that this new device capability would also break VMDQ with failsafe on top of VMDQ-capable ports. In the end, as suggested here, max_vmdq_pools is already a gate and no new capability is needed. > > Warning: VMDq capability advertised on VFs that do not configure VMDq > > ixgbevf_dev_info_get() and txgbevf_dev_info_get() now advertise > RTE_ETH_DEV_CAPA_VMDQ, but ixgbevf_dev_configure() and > txgbevf_dev_configure() only handle RTE_ETH_MQ_RX_RSS_FLAG. The > feature matrices doc/guides/nics/features/ixgbe_vf.ini and > txgbe_vf.ini do not list "VMDq = Y". A VF is itself a member of a > PF VMDq pool; advertising the capa from the VF is misleading. > > Warning: ipn3ke advertises VMDq=Y in its features file but is not > updated by the patch > > doc/guides/nics/features/ipn3ke.ini has "VMDq = Y" but the patch > does not add RTE_ETH_DEV_CAPA_VMDQ to ipn3ke. Either update the > driver or correct the feature matrix. > > Warning: missing release note > > The new RTE_ETH_DEV_CAPA_VMDQ public bit and the new rejection in > rte_eth_dev_configure() (returning -EINVAL when an application sets > a VMDq mq_mode on a non-VMDq device) are user-visible API and > behavioural changes. release_26_07.rst should mention them under > "API Changes". > > [PATCH v2 3/5] ethdev: hide VMDq internal sizes > ----------------------------------------------- > > Warning: public defines removed without deprecation cycle > > RTE_ETH_NUM_RECEIVE_MAC_ADDR and RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY > were declared in the application-facing rte_ethdev.h. Moving them > to ethdev_driver.h removes them from the public API. Per the DPDK > API/ABI policy this normally needs a prior deprecation notice; at > minimum it warrants a release_26_07.rst "API Changes" entry. Mixed feeling about it. I can add a note, but I think it is noise. > > > [PATCH v2 4/5] net/iavf: accept up to 32k unicast MAC addresses > --------------------------------------------------------------- > > Warning: dead store in iavf_add_del_uc_addr_bulk() > > for (uint32_t i = 0; i < nb_addrs; i++) { > size_t buf_len = sizeof(struct virtchnl_ether_addr_list) + > sizeof(struct virtchnl_ether_addr) * list->num_elements; > ... > buf_len = sizeof(struct virtchnl_ether_addr_list) + > sizeof(struct virtchnl_ether_addr) * list->num_elements; > > The first initialiser is unconditionally overwritten by the second > assignment before any read. Drop the initialiser (or move the > declaration to the use site). Good catch.. rebase damage on my side, I dropped some experiments/changes but forgot to update after. > > Warning: missing release note for max_mac_addrs jump > > max_mac_addrs goes from 64 to 32768 and dev_data->mac_addrs is now > allocated at RTE_ETHER_ADDR_LEN * 32768 = 192 KiB per VF port. This > is a notable behaviour change for iavf users and worth a > release_26_07.rst entry. > -- David Marchand ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 0/5] Remove limitations coming from legacy VMDq 2026-04-03 9:18 [PATCH 0/4] Remove limitations coming from legacy VMDq David Marchand ` (5 preceding siblings ...) 2026-05-06 12:35 ` [PATCH v2 0/5] " David Marchand @ 2026-05-10 17:03 ` David Marchand 2026-05-10 17:03 ` [PATCH v3 1/5] ethdev: check VMDq availability David Marchand ` (4 more replies) 6 siblings, 5 replies; 24+ messages in thread From: David Marchand @ 2026-05-10 17:03 UTC (permalink / raw) To: dev; +Cc: rjarry, cfontain Since the commit 88ac4396ad29 ("ethdev: add VMDq support"), VMDq has been imposing a maximum number of mac addresses in the mac_addr_add/del API. Nowadays, new Intel drivers do not support the feature and few other drivers implement this feature. This series enforces that the driver announces VMDq pools before using VMDq related features, then remove the limit of number of mac addresses for others. Next step could be to remove the VMDq pool notion from the generic API. However I have some concern about this, as changing the quite stable mac_addr_add/del API now seems a lot of noise for not much benefit. -- David Marchand Changes since v2: - changed approach: did not introduce a new device capability, relied on already existing dev_info->max_vmdq_pools, - fixed duplicate mac addition without VMDq, - updated documentation, Changes since v1: - dropped incorrect VMDq feature announce for bnxt representors, em, i40e representors, ipn3ke representors, - fixed buffer overflow on mailbox messages during port restart/VF reset, - fixed duplicate MAC address installation on port start/restart, David Marchand (5): ethdev: check VMDq availability ethdev: skip VMDq pools unless configured ethdev: hide VMDq internal sizes net/iavf: accept up to 32k unicast MAC addresses net/iavf: fix duplicate MAC addresses install doc/guides/rel_notes/release_26_07.rst | 15 ++++ drivers/net/cnxk/cnxk_ethdev_ops.c | 1 - drivers/net/intel/iavf/iavf.h | 5 +- drivers/net/intel/iavf/iavf_ethdev.c | 43 ++++++---- drivers/net/intel/iavf/iavf_vchnl.c | 113 ++++++++++++++++++------- lib/ethdev/ethdev_driver.h | 8 +- lib/ethdev/rte_ethdev.c | 68 +++++++++++---- lib/ethdev/rte_ethdev.h | 6 -- 8 files changed, 186 insertions(+), 73 deletions(-) -- 2.53.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 1/5] ethdev: check VMDq availability 2026-05-10 17:03 ` [PATCH v3 " David Marchand @ 2026-05-10 17:03 ` David Marchand 2026-05-10 17:03 ` [PATCH v3 2/5] ethdev: skip VMDq pools unless configured David Marchand ` (3 subsequent siblings) 4 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-05-10 17:03 UTC (permalink / raw) To: dev; +Cc: rjarry, cfontain, Thomas Monjalon, Andrew Rybchenko Refuse VMDq related Rx/Tx modes when the driver do not announce VMDq pools availability. This will used later as a gate to ignore/reject VMDq related matters. Signed-off-by: David Marchand <david.marchand@redhat.com> --- Changes since v2: - added an entry in release notes, - changed approach: relied on pre-existing dev_info->max_vmdq_pools rather than introduce a new device capability, Changes since v1: - dropped incorrect VMDq feature announce for bnxt representors, em, i40e representors, ipn3ke representors, --- doc/guides/rel_notes/release_26_07.rst | 6 ++++++ lib/ethdev/rte_ethdev.c | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst index f012d47a4b..b59793f177 100644 --- a/doc/guides/rel_notes/release_26_07.rst +++ b/doc/guides/rel_notes/release_26_07.rst @@ -92,6 +92,12 @@ API Changes Also, make sure to start the actual text at the margin. ======================================================= +* **Updated VMDq related API in ethdev.** + + * At port configuration time, the number of VMDq pools advertised by a driver is now used to + validate VMDq related Rx and Tx modes (``RTE_ETH_MQ_RX_VMDQ_FLAG``, ``RTE_ETH_MQ_TX_VMDQ_DCB``, + ``RTE_ETH_MQ_TX_VMDQ_ONLY``). + ABI Changes ----------- diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 2edc7a362e..eae34954e2 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -1581,6 +1581,22 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, goto rollback; } + if (dev_info.max_vmdq_pools == 0) { + if ((dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0) { + RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does not support VMDq rx mode", + port_id); + ret = -EINVAL; + goto rollback; + } + if (dev_conf->txmode.mq_mode == RTE_ETH_MQ_TX_VMDQ_DCB || + dev_conf->txmode.mq_mode == RTE_ETH_MQ_TX_VMDQ_ONLY) { + RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does not support VMDq tx mode", + port_id); + ret = -EINVAL; + goto rollback; + } + } + /* * Setup new number of Rx/Tx queues and reconfigure device. */ -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 2/5] ethdev: skip VMDq pools unless configured 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 ` David Marchand 2026-05-10 17:03 ` [PATCH v3 3/5] ethdev: hide VMDq internal sizes David Marchand ` (2 subsequent siblings) 4 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-05-10 17:03 UTC (permalink / raw) To: dev Cc: rjarry, cfontain, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao, Harman Kalra, Thomas Monjalon, Andrew Rybchenko The mac_addr_add API describes that only the 0 pool should be passed unless VMDq has been enabled, though there was no validation so far. Add such a check, then cleanup the MAC related operations (adding, removing, restoring). As a side effect, the net/cnxk does not need to manually reset the mac_pool_sel[] array. Signed-off-by: David Marchand <david.marchand@redhat.com> --- Changes since v2: - added an entry in release notes, - fixed duplicate mac address handling for !vmdq, - rewrote update of eth_dev_mac_restore to isolate the !vmdq case, --- doc/guides/rel_notes/release_26_07.rst | 2 + drivers/net/cnxk/cnxk_ethdev_ops.c | 1 - lib/ethdev/rte_ethdev.c | 52 ++++++++++++++++++-------- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst index b59793f177..3d2e71102b 100644 --- a/doc/guides/rel_notes/release_26_07.rst +++ b/doc/guides/rel_notes/release_26_07.rst @@ -97,6 +97,8 @@ API Changes * At port configuration time, the number of VMDq pools advertised by a driver is now used to validate VMDq related Rx and Tx modes (``RTE_ETH_MQ_RX_VMDQ_FLAG``, ``RTE_ETH_MQ_TX_VMDQ_DCB``, ``RTE_ETH_MQ_TX_VMDQ_ONLY``). + * A check was added in ``rte_eth_dev_mac_addr_add`` to validate that the ``pool`` parameter is 0 + when VMDq is not configured. ABI Changes diff --git a/drivers/net/cnxk/cnxk_ethdev_ops.c b/drivers/net/cnxk/cnxk_ethdev_ops.c index 49e77e49a6..75decf7098 100644 --- a/drivers/net/cnxk/cnxk_ethdev_ops.c +++ b/drivers/net/cnxk/cnxk_ethdev_ops.c @@ -1240,7 +1240,6 @@ cnxk_nix_mc_addr_list_configure(struct rte_eth_dev *eth_dev, struct rte_ether_ad /* Update address in NIC data structure */ rte_ether_addr_copy(&mc_addr_set[i], &data->mac_addrs[j]); rte_ether_addr_copy(&mc_addr_set[i], &dev->dmac_addrs[j]); - data->mac_pool_sel[j] = RTE_BIT64(0); } roc_nix_npc_promisc_ena_dis(nix, true); diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index eae34954e2..a628a7661a 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -1677,7 +1677,7 @@ eth_dev_mac_restore(struct rte_eth_dev *dev, { struct rte_ether_addr *addr; uint16_t i; - uint32_t pool = 0; + uint32_t pool; uint64_t pool_mask; /* replay MAC address configuration including default MAC */ @@ -1685,9 +1685,11 @@ eth_dev_mac_restore(struct rte_eth_dev *dev, if (dev->dev_ops->mac_addr_set != NULL) dev->dev_ops->mac_addr_set(dev, addr); else if (dev->dev_ops->mac_addr_add != NULL) - dev->dev_ops->mac_addr_add(dev, addr, 0, pool); + dev->dev_ops->mac_addr_add(dev, addr, 0, 0); if (dev->dev_ops->mac_addr_add != NULL) { + bool vmdq = (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0; + for (i = 1; i < dev_info->max_mac_addrs; i++) { addr = &dev->data->mac_addrs[i]; @@ -1695,15 +1697,19 @@ eth_dev_mac_restore(struct rte_eth_dev *dev, if (rte_is_zero_ether_addr(addr)) continue; - pool = 0; - pool_mask = dev->data->mac_pool_sel[i]; - - do { - if (pool_mask & UINT64_C(1)) - dev->dev_ops->mac_addr_add(dev, addr, i, pool); - pool_mask >>= 1; - pool++; - } while (pool_mask); + if (!vmdq) { + dev->dev_ops->mac_addr_add(dev, addr, i, 0); + } else { + pool = 0; + pool_mask = dev->data->mac_pool_sel[i]; + + do { + if (pool_mask & UINT64_C(1)) + dev->dev_ops->mac_addr_add(dev, addr, i, pool); + pool_mask >>= 1; + pool++; + } while (pool_mask); + } } } } @@ -5406,8 +5412,9 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, uint32_t pool) { struct rte_eth_dev *dev; - int index; uint64_t pool_mask; + bool vmdq; + int index; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -5432,6 +5439,12 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, RTE_ETHDEV_LOG_LINE(ERR, "Pool ID must be 0-%d", RTE_ETH_64_POOLS - 1); return -EINVAL; } + vmdq = (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0; + if (!vmdq && pool != 0) { + RTE_ETHDEV_LOG_LINE(ERR, "Port %u: VMDq is not configured (pool %d)", + port_id, pool); + return -EINVAL; + } index = eth_dev_get_mac_addr_index(port_id, addr); if (index < 0) { @@ -5442,6 +5455,9 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, return -ENOSPC; } } else { + if (!vmdq) + return 0; + pool_mask = dev->data->mac_pool_sel[index]; /* Check if both MAC address and pool is already there, and do nothing */ @@ -5456,8 +5472,10 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, /* Update address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]); - /* Update pool bitmap in NIC data structure */ - dev->data->mac_pool_sel[index] |= RTE_BIT64(pool); + if (vmdq) { + /* Update pool bitmap in NIC data structure */ + dev->data->mac_pool_sel[index] |= RTE_BIT64(pool); + } } ret = eth_err(port_id, ret); @@ -5502,8 +5520,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) /* Update address in NIC data structure */ rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]); - /* reset pool bitmap */ - dev->data->mac_pool_sel[index] = 0; + if ((dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) != 0) { + /* reset pool bitmap */ + dev->data->mac_pool_sel[index] = 0; + } rte_ethdev_trace_mac_addr_remove(port_id, addr); -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 3/5] ethdev: hide VMDq internal sizes 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 ` David Marchand 2026-05-10 17:03 ` [PATCH v3 4/5] net/iavf: accept up to 32k unicast MAC addresses David Marchand 2026-05-10 17:03 ` [PATCH v3 5/5] net/iavf: fix duplicate MAC addresses install David Marchand 4 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-05-10 17:03 UTC (permalink / raw) To: dev; +Cc: rjarry, cfontain, Thomas Monjalon, Andrew Rybchenko Hide RTE_ETH_NUM_RECEIVE_MAC_ADDR and RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY in the driver API as those (ambiguous) macros are only a driver concern. In practice, this is only used by the bnxt and ixgbe (+ clones) drivers. Signed-off-by: David Marchand <david.marchand@redhat.com> --- Changes since v2: - added an entry in release notes, --- doc/guides/rel_notes/release_26_07.rst | 3 +++ lib/ethdev/ethdev_driver.h | 8 +++++++- lib/ethdev/rte_ethdev.h | 6 ------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst index 3d2e71102b..b425e6f8cd 100644 --- a/doc/guides/rel_notes/release_26_07.rst +++ b/doc/guides/rel_notes/release_26_07.rst @@ -99,6 +99,9 @@ API Changes ``RTE_ETH_MQ_TX_VMDQ_ONLY``). * A check was added in ``rte_eth_dev_mac_addr_add`` to validate that the ``pool`` parameter is 0 when VMDq is not configured. + * The ``RTE_ETH_NUM_RECEIVE_MAC_ADDR`` and ``RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY`` macros are VMDq + related and are sizes of internal arrays in ethdev that only drivers need to care about. + Those macros are moved to the driver only ethdev API. ABI Changes diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index 1255cd6f2c..a4e9cf5b90 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -119,6 +119,12 @@ struct __rte_cache_aligned rte_eth_dev { struct rte_eth_dev_sriov; struct rte_eth_dev_owner; +/* Definitions used for receive MAC address */ +#define RTE_ETH_NUM_RECEIVE_MAC_ADDR 128 /**< Maximum nb. of receive mac addr. */ + +/* Definitions used for unicast hash */ +#define RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY 128 /**< Maximum nb. of UC hash array. */ + /** * @internal * The data part, with no function pointers, associated with each Ethernet @@ -153,7 +159,7 @@ struct __rte_cache_aligned rte_eth_dev_data { * The first entry (index zero) is the default address. */ struct rte_ether_addr *mac_addrs; - /** Bitmap associating MAC addresses to pools */ + /** Bitmap associating MAC addresses to VMDq pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; /** * Device Ethernet MAC addresses of hash filtering. diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index 0d8e2d0236..27d2ddc0c1 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -903,12 +903,6 @@ rte_eth_rss_hf_refine(uint64_t rss_hf) #define RTE_ETH_VLAN_ID_MAX 0x0FFF /**< VLAN ID is in lower 12 bits*/ /**@}*/ -/* Definitions used for receive MAC address */ -#define RTE_ETH_NUM_RECEIVE_MAC_ADDR 128 /**< Maximum nb. of receive mac addr. */ - -/* Definitions used for unicast hash */ -#define RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY 128 /**< Maximum nb. of UC hash array. */ - /**@{@name VMDq Rx mode * @see rte_eth_vmdq_rx_conf.rx_mode */ -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 4/5] net/iavf: accept up to 32k unicast MAC addresses 2026-05-10 17:03 ` [PATCH v3 " David Marchand ` (2 preceding siblings ...) 2026-05-10 17:03 ` [PATCH v3 3/5] ethdev: hide VMDq internal sizes David Marchand @ 2026-05-10 17:03 ` David Marchand 2026-05-12 14:41 ` Stephen Hemminger 2026-05-10 17:03 ` [PATCH v3 5/5] net/iavf: fix duplicate MAC addresses install David Marchand 4 siblings, 1 reply; 24+ messages in thread From: David Marchand @ 2026-05-10 17:03 UTC (permalink / raw) To: dev; +Cc: rjarry, cfontain, Vladimir Medvedkin 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 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v3 4/5] net/iavf: accept up to 32k unicast MAC addresses 2026-05-10 17:03 ` [PATCH v3 4/5] net/iavf: accept up to 32k unicast MAC addresses David Marchand @ 2026-05-12 14:41 ` Stephen Hemminger 0 siblings, 0 replies; 24+ messages in thread From: Stephen Hemminger @ 2026-05-12 14:41 UTC (permalink / raw) To: David Marchand; +Cc: dev, rjarry, cfontain, Vladimir Medvedkin On Sun, 10 May 2026 19:03:04 +0200 David Marchand <david.marchand@redhat.com> wrote: > 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 AI review feedback; nothing major but worth a look Series: ethdev: VMDq cleanup and iavf: 32k MACs / duplicate install fix Tree: dpdk main (DPDK 26.07) Patch 2 - ethdev: skip VMDq pools unless configured Info Doxygen of rte_eth_dev_mac_addr_add() is not updated to describe the new constraint that pool must be 0 when VMDq is not configured. The function-level @param documentation and @return list should mention that -EINVAL is now returned when VMDq is disabled and pool != 0. Subtle behavior change: when VMDq is not configured, mac_pool_sel[index] is no longer set to RTE_BIT64(0) on add. Before this patch every added MAC ended up with bit 0 set; afterwards the array stays at 0. This is consistent with the new restore path (which now uses the VMDq flag rather than walking pool_mask in the !vmdq case), but the change in observable state of dev->data->mac_pool_sel[] could surprise an out-of- tree consumer. Worth a sentence in the API change note. Patch 4 - net/iavf: accept up to 32k unicast MAC addresses Info Release notes wording: "secondary MAC addresses from 64 to 32k" is slightly imprecise. IAVF_NUM_MACADDR_MAX (64) was the total cap including the primary MAC; IAVF_UC_MACADDR_MAX (32768) is also a total cap including index 0. Either drop "secondary" or say "secondary MAC addresses from 63 to 32767". iavf_add_del_uc_addr_bulk() returns an int but the only caller (iavf_add_del_all_mac_addr) discards it. The pre-existing function was already void so this is no regression, but having the helper return an error code that is unconditionally dropped is misleading. Either propagate the error to the caller (and make iavf_add_del_all_mac_addr return int) or make the helper void. eth_dev_mac_restore() now iterates dev_info->max_mac_addrs which for iavf becomes 32768. With patch 5 applied this path is skipped via get_restore_flags, but any driver that increases max_mac_addrs into the thousands without setting RTE_ETH_RESTORE_MAC_ADDR off will pay a 32k rte_is_zero_ether_addr() scan on every dev_start. Not a bug here, but worth keeping in mind. sizeof(struct virtchnl_ether_addr_list) already accounts for the embedded list[1] slot, so in_args_size = sizeof(struct virtchnl_ether_addr_list) + sizeof(struct virtchnl_ether_addr) * list->num_elements overcounts by sizeof(struct virtchnl_ether_addr). This matches what iavf_add_del_eth_addr() already does, and the buffer is sized to hold it, so it's not a bug -- noting it for completeness. Patch 5 - net/iavf: fix duplicate MAC addresses install Info Recovery edge case: if iavf_add_del_eth_addr() for the primary fails during the first iavf_dev_start(), mac_primary_set stays false. On a subsequent VF reset, iavf_dev_start() (called from iavf_handle_hw_reset) will re-attempt the primary add, and the new iavf_add_del_all_mac_addr() call right after will add the primary again via VIRTCHNL_ETHER_ADDR_PRIMARY. This re-introduces a single-MAC double-install in a narrow failure path. Could be avoided by skipping the primary in iavf_add_del_all_mac_addr() when mac_primary_set is already true, or by having iavf_dev_start() skip the primary add when in_reset_recovery is set. No release notes entry. With Fixes: + Cc: stable this is acceptable as a bug fix, but the patch also introduces a new dev_op (get_restore_flags) for the driver and changes when MC addresses are re-pushed (only on VF reset, not on every dev_start). A one-line note in the iavf section of the release notes would help users tracking behaviour changes between stop/start cycles. Patches 1 and 3 have no findings. ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 5/5] net/iavf: fix duplicate MAC addresses install 2026-05-10 17:03 ` [PATCH v3 " David Marchand ` (3 preceding siblings ...) 2026-05-10 17:03 ` [PATCH v3 4/5] net/iavf: accept up to 32k unicast MAC addresses David Marchand @ 2026-05-10 17:03 ` David Marchand 4 siblings, 0 replies; 24+ messages in thread From: David Marchand @ 2026-05-10 17:03 UTC (permalink / raw) To: dev; +Cc: rjarry, cfontain, stable, Vladimir Medvedkin, Bruce Richardson On port restart, all MAC addresses get pushed *twice* to the hardware, once by the driver and once by the eth_dev_mac_restore() in ethdev. On the other hand, MAC address filters are reset in the hardware by the PF only when a VF reset is triggered. Strictly speaking, the mac restore on port (re)start is unneeded, if no VF reset happened, so we can announce to ethdev that no mac restoration is needed via a get_restore_flags callback. Then, move the mac restoration to the VF reset handler. Fixes: 3d42086def30 ("net/iavf: preserve MAC address with i40e PF Linux driver") Cc: stable@dpdk.org Signed-off-by: David Marchand <david.marchand@redhat.com> --- drivers/net/intel/iavf/iavf_ethdev.c | 31 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c index edbbc34cc5..504eabebe7 100644 --- a/drivers/net/intel/iavf/iavf_ethdev.c +++ b/drivers/net/intel/iavf/iavf_ethdev.c @@ -126,6 +126,8 @@ static void iavf_dev_del_mac_addr(struct rte_eth_dev *dev, uint32_t index); static int iavf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on); static int iavf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask); +static uint64_t iavf_get_restore_flags(struct rte_eth_dev *dev, + enum rte_eth_dev_operation op); static int iavf_dev_rss_reta_update(struct rte_eth_dev *dev, struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size); @@ -249,6 +251,7 @@ static const struct eth_dev_ops iavf_eth_dev_ops = { .tx_done_cleanup = iavf_dev_tx_done_cleanup, .get_monitor_addr = iavf_get_monitor_addr, .tm_ops_get = iavf_tm_ops_get, + .get_restore_flags = iavf_get_restore_flags, }; static int @@ -269,6 +272,13 @@ iavf_tm_ops_get(struct rte_eth_dev *dev, return 0; } +static uint64_t +iavf_get_restore_flags(__rte_unused struct rte_eth_dev *dev, + __rte_unused enum rte_eth_dev_operation op) +{ + return RTE_ETH_RESTORE_ALL & ~RTE_ETH_RESTORE_MAC_ADDR; +} + __rte_unused static int iavf_vfr_inprogress(struct iavf_hw *hw) @@ -1039,15 +1049,14 @@ iavf_dev_start(struct rte_eth_dev *dev) rte_intr_enable(intr_handle); } - /* Set all mac addrs */ - iavf_add_del_all_mac_addr(adapter, true); - - if (!adapter->mac_primary_set) - adapter->mac_primary_set = true; - - /* Set all multicast addresses */ - iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num, - true); + if (!adapter->mac_primary_set) { + if (iavf_add_del_eth_addr(adapter, &dev->data->mac_addrs[0], true, + VIRTCHNL_ETHER_ADDR_PRIMARY) != 0) + PMD_DRV_LOG(ERR, "failed to add primary MAC:" RTE_ETHER_ADDR_PRT_FMT, + RTE_ETHER_ADDR_BYTES(&dev->data->mac_addrs[0])); + else + adapter->mac_primary_set = true; + } rte_spinlock_init(&vf->phc_time_aq_lock); @@ -3144,6 +3153,10 @@ iavf_handle_hw_reset(struct rte_eth_dev *dev, bool vf_initiated_reset) if (ret) goto error; + /* after a VF reset, all mac addresses got flushed, restore them */ + iavf_add_del_all_mac_addr(adapter, true); + iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num, true); + dev->data->dev_started = 1; } goto exit; -- 2.53.0 ^ permalink raw reply related [flat|nested] 24+ messages in thread
end of thread, other threads:[~2026-05-12 14:42 UTC | newest] Thread overview: 24+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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 ` [PATCH v3 4/5] net/iavf: accept up to 32k unicast MAC addresses David Marchand 2026-05-12 14:41 ` Stephen Hemminger 2026-05-10 17:03 ` [PATCH v3 5/5] net/iavf: fix duplicate MAC addresses install David Marchand
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox