On Tue, Sep 08, 2026 at 11:27:43AM +0200, David Marchand wrote:
> Starting firmware version 22.49.1014, the number of mac addresses
> per VF is not capped to 128 anymore.
> 
> The value can be increased via devlink:
> $ devlink dev param set pci/0000:3b:00.2 name max_macs value 4096 \
>       cmode driverinit
> $ devlink dev reload pci/0000:3b:00.2
> 
> On the DPDK side, we must retrieve the maximum number of unicast
> and multicast addresses supported with a query to the firmware.
> 
> Then, dynamically allocate the mac addresses arrays and report the
> limit instead of the previous hardcoded value.
> 
> Signed-off-by: David Marchand <[email protected]>
> ---
> Changes since v4:
> - added RN update,
> - fixed types of fields added to mlx5_hca_attr and mlx5_dev_cap,
> - used RTE_BIT32,
> - fixed mlx5_nl_mac_addr_sync inverted arguments,
> 
> ---
>  doc/guides/rel_notes/release_26_11.rst |  5 +++
>  drivers/common/mlx5/mlx5_devx_cmds.c   |  4 +++
>  drivers/common/mlx5/mlx5_devx_cmds.h   |  2 ++
>  drivers/net/mlx5/linux/mlx5_os.c       | 42 ++++++++++++++++++++------
>  drivers/net/mlx5/mlx5.c                |  9 ++----
>  drivers/net/mlx5/mlx5.h                |  8 +++--
>  drivers/net/mlx5/mlx5_ethdev.c         |  2 +-
>  drivers/net/mlx5/mlx5_mac.c            | 22 +++++++++-----
>  drivers/net/mlx5/mlx5_trigger.c        | 10 +++---
>  drivers/net/mlx5/windows/mlx5_os.c     | 40 +++++++++++++++++++-----
>  10 files changed, 104 insertions(+), 40 deletions(-)
> 
> diff --git a/doc/guides/rel_notes/release_26_11.rst 
> b/doc/guides/rel_notes/release_26_11.rst
> index 87c7e81bde..43043cd579 100644
> --- a/doc/guides/rel_notes/release_26_11.rst
> +++ b/doc/guides/rel_notes/release_26_11.rst
> @@ -55,6 +55,11 @@ New Features
>       Also, make sure to start the actual text at the margin.
>       =======================================================
>  
> +* **Updated NVIDIA mlx5 ethernet driver.**
> +
> +  * Increased the maximum number of secondary unicast MAC addresses from 128 
> to up to 4096
> +    (depending on devlink configuration on the associated kernel netdevice).
> +
>  
>  Removed Items
>  -------------
> diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c 
> b/drivers/common/mlx5/mlx5_devx_cmds.c
> index 140b057ab4..e5d9c92779 100644
> --- a/drivers/common/mlx5/mlx5_devx_cmds.c
> +++ b/drivers/common/mlx5/mlx5_devx_cmds.c
> @@ -1110,6 +1110,10 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
>       attr->log_max_pd = MLX5_GET(cmd_hca_cap, hcattr, log_max_pd);
>       attr->log_max_srq = MLX5_GET(cmd_hca_cap, hcattr, log_max_srq);
>       attr->log_max_srq_sz = MLX5_GET(cmd_hca_cap, hcattr, log_max_srq_sz);
> +     attr->log_max_current_uc_list = MLX5_GET(cmd_hca_cap, hcattr,
> +                                              log_max_current_uc_list);
> +     attr->log_max_current_mc_list = MLX5_GET(cmd_hca_cap, hcattr,
> +                                              log_max_current_mc_list);
>       attr->reg_c_preserve =
>               MLX5_GET(cmd_hca_cap, hcattr, reg_c_preserve);
>       attr->mmo_regex_qp_en = MLX5_GET(cmd_hca_cap, hcattr, regexp_mmo_qp);
> diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h 
> b/drivers/common/mlx5/mlx5_devx_cmds.h
> index 90beb2e9e6..504b4a4f64 100644
> --- a/drivers/common/mlx5/mlx5_devx_cmds.h
> +++ b/drivers/common/mlx5/mlx5_devx_cmds.h
> @@ -356,6 +356,8 @@ struct mlx5_hca_attr {
>       uint8_t tx_sw_owner_v2:1;
>       uint8_t esw_sw_owner:1;
>       uint8_t esw_sw_owner_v2:1;
> +     uint8_t log_max_current_uc_list:5;
> +     uint8_t log_max_current_mc_list:5;
>  };
>  
>  /* LAG Context. */
> diff --git a/drivers/net/mlx5/linux/mlx5_os.c 
> b/drivers/net/mlx5/linux/mlx5_os.c
> index 7d8ea4acba..35efb1d572 100644
> --- a/drivers/net/mlx5/linux/mlx5_os.c
> +++ b/drivers/net/mlx5/linux/mlx5_os.c
> @@ -389,6 +389,16 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared 
> *sh)
>       sh->dev_cap.esw_info.regc_mask = 0;
>  #endif
>       sh->dev_cap.esw_info.is_set = 1;
> +     if (hca_attr->log_max_current_uc_list > 0)
> +             sh->dev_cap.max_uc_mac_addrs = 
> RTE_BIT32(hca_attr->log_max_current_uc_list);
> +     else
> +             sh->dev_cap.max_uc_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES;
> +     if (hca_attr->log_max_current_mc_list > 0)
> +             sh->dev_cap.max_mc_mac_addrs = 
> RTE_BIT32(hca_attr->log_max_current_mc_list);
> +     else
> +             sh->dev_cap.max_mc_mac_addrs = MLX5_MAX_MC_MAC_ADDRESSES;
> +     sh->dev_cap.max_mac_addrs =
> +             sh->dev_cap.max_uc_mac_addrs + sh->dev_cap.max_mc_mac_addrs;
>       return 0;
>  }
>  
> @@ -1464,6 +1474,22 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
>       priv->sh = sh;
>       priv->dev_port = spawn->phys_port;
>       priv->pci_dev = spawn->pci_dev;
> +     priv->mac = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
> +                             sizeof(*priv->mac) * sh->dev_cap.max_mac_addrs,
> +                             RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
> +     if (priv->mac == NULL) {
> +             DRV_LOG(ERR, "Failed to allocate MAC address array.");
> +             err = ENOMEM;
> +             goto error;
> +     }
> +     priv->mac_own = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
> +                                 RTE_BITSET_SIZE(sh->dev_cap.max_mac_addrs),
> +                                 RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
> +     if (priv->mac_own == NULL) {
> +             DRV_LOG(ERR, "Failed to allocate MAC ownership bitmap.");
> +             err = ENOMEM;
> +             goto error;
> +     }
>       /* Some internal functions rely on Netlink sockets, open them now. */
>       priv->nl_socket_rdma = nl_rdma;
>       priv->nl_socket_route = mlx5_nl_init(NETLINK_ROUTE, 0);
> @@ -1762,8 +1788,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
>               mlx5_nl_mac_addr_sync(priv->nl_socket_route,
>                                     mlx5_ifindex(eth_dev),
>                                     eth_dev->data->mac_addrs,
> -                                   MLX5_MAX_UC_MAC_ADDRESSES,
> -                                   MLX5_MAX_MAC_ADDRESSES);
> +                                   sh->dev_cap.max_uc_mac_addrs,
> +                                   sh->dev_cap.max_mac_addrs);
>       priv->ctrl_flows = 0;
>       rte_spinlock_init(&priv->flow_list_lock);
>       TAILQ_INIT(&priv->flow_meters);
> @@ -1963,17 +1989,15 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
>                       mlx5_flex_item_port_cleanup(eth_dev);
>               mlx5_free(priv->ext_rxqs);
>               mlx5_free(priv->ext_txqs);
> +             mlx5_free(priv->mac);
> +             eth_dev->data->mac_addrs = NULL;

This can segfault because eth_dev is allocated later than priv.
Previous version of the error rollback accounted for that
(where mac_addrs was reset only if eth_dev != NULL).
The same logic applies in Windows code.

Could you please revert that?

> +             mlx5_free(priv->mac_own);
>               mlx5_free(priv);
>               if (eth_dev != NULL)
>                       eth_dev->data->dev_private = NULL;
>       }
> -     if (eth_dev != NULL) {
> -             /* mac_addrs must not be freed alone because part of
> -              * dev_private
> -              **/
> -             eth_dev->data->mac_addrs = NULL;
> +     if (eth_dev != NULL)
>               rte_eth_dev_release_port(eth_dev);
> -     }
>       if (sh)
>               mlx5_free_shared_dev_ctx(sh);
>       if (nl_rdma >= 0)
> @@ -3531,7 +3555,7 @@ mlx5_os_mac_addr_flush(struct rte_eth_dev *dev)
>       const int vf = priv->sh->dev_cap.vf;
>       int i;
>  
> -     for (i = MLX5_MAX_MAC_ADDRESSES - 1; i >= 0; --i) {
> +     for (i = priv->sh->dev_cap.max_mac_addrs - 1; i >= 0; --i) {
>               if (rte_bitset_test(priv->mac_own, i)) {
>                       if (vf)
>                               mlx5_nl_mac_addr_remove(priv->nl_socket_route,
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
> index c7b0d3ef8b..4bd1c6d1c0 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -2556,6 +2556,9 @@ mlx5_dev_close(struct rte_eth_dev *dev)
>               mlx5_list_destroy(priv->hrxqs);
>       mlx5_free(priv->ext_rxqs);
>       mlx5_free(priv->ext_txqs);
> +     mlx5_free(priv->mac);
> +     dev->data->mac_addrs = NULL;
> +     mlx5_free(priv->mac_own);
>       sh->port[priv->dev_port - 1].nl_ih_port_id = RTE_MAX_ETHPORTS;
>       /*
>        * The interrupt handler port id must be reset before priv is reset
> @@ -2590,12 +2593,6 @@ mlx5_dev_close(struct rte_eth_dev *dev)
>       mlx5_flow_pools_destroy(priv);
>       memset(priv, 0, sizeof(*priv));
>       priv->domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
> -     /*
> -      * Reset mac_addrs to NULL such that it is not freed as part of
> -      * rte_eth_dev_release_port(). mac_addrs is part of dev_private so
> -      * it is freed when dev_private is freed.
> -      */
> -     dev->data->mac_addrs = NULL;
>       return 0;
>  }
>  
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
> index 7f20c811f3..70efcda9bb 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -217,6 +217,9 @@ struct mlx5_dev_cap {
>       } mprq; /* Capability for Multi-Packet RQ. */
>       char fw_ver[64]; /* Firmware version of this device. */
>       struct flow_hw_port_info esw_info; /* E-switch manager reg_c0. */
> +     uint32_t max_uc_mac_addrs; /* Maximum unicast MAC addresses. */
> +     uint32_t max_mc_mac_addrs; /* Maximum multicast MAC addresses. */
> +     uint32_t max_mac_addrs; /* Total maximum MAC addresses. */
>  };
>  
>  #define MLX5_MPESW_PORT_INVALID (-1)
> @@ -2018,9 +2021,8 @@ struct mlx5_priv {
>       struct mlx5_dev_ctx_shared *sh; /* Shared device context. */
>       uint32_t dev_port; /* Device port number. */
>       struct rte_pci_device *pci_dev; /* Backend PCI device. */
> -     struct rte_ether_addr mac[MLX5_MAX_MAC_ADDRESSES]; /* MAC addresses. */
> -     RTE_BITSET_DECLARE(mac_own, MLX5_MAX_MAC_ADDRESSES);
> -     /* Bit-field of MAC addresses owned by the PMD. */
> +     struct rte_ether_addr *mac; /* MAC addresses. */
> +     uint64_t *mac_own; /* Bit-field of MAC addresses owned by the PMD. */
>       uint16_t vlan_filter[MLX5_MAX_VLAN_IDS]; /* VLAN filters table. */
>       unsigned int vlan_filter_n; /* Number of configured VLAN filters. */
>       /* Device properties. */
> diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
> index 8160d10e7e..306c1cd734 100644
> --- a/drivers/net/mlx5/mlx5_ethdev.c
> +++ b/drivers/net/mlx5/mlx5_ethdev.c
> @@ -392,7 +392,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct 
> rte_eth_dev_info *info)
>       max = RTE_MIN(max, (unsigned int)UINT16_MAX);
>       info->max_rx_queues = max;
>       info->max_tx_queues = max;
> -     info->max_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES;
> +     info->max_mac_addrs = priv->sh->dev_cap.max_uc_mac_addrs;
>       info->rx_queue_offload_capa = mlx5_get_rx_queue_offloads(dev);
>       info->rx_seg_capa.max_nseg = MLX5_MAX_RXQ_NSEG;
>       info->rx_seg_capa.multi_pools = !priv->config.mprq.enabled;
> diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
> index 0e5d2be530..2ce7cfd407 100644
> --- a/drivers/net/mlx5/mlx5_mac.c
> +++ b/drivers/net/mlx5/mlx5_mac.c
> @@ -36,7 +36,9 @@ mlx5_internal_mac_addr_remove(struct rte_eth_dev *dev,
>                             uint32_t index,
>                             struct rte_ether_addr *addr)
>  {
> -     MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES);
> +     struct mlx5_priv *priv = dev->data->dev_private;
> +
> +     MLX5_ASSERT(index < priv->sh->dev_cap.max_mac_addrs);

Coverity in our internal CI reports the following:

        drivers/net/mlx5/mlx5_mac.c:39:20: CID 910875 (#1 of 1):
          Type: Parse warning (PW.SET_BUT_NOT_USED)
          Classification: Unclassified
          Severity: Unspecified
          Action: Undecided
          Owner: Unassigned
          Defect only exists locally.
        drivers/net/mlx5/mlx5_mac.c:39:20:
          1. set_but_not_used: variable "priv" was set but never used

priv variable can be removed using MLX5_SH macro:

        MLX5_ASSERT(index < MLX5_SH(dev)->dev_cap.max_mac_addrs);

>       if (rte_is_zero_ether_addr(&dev->data->mac_addrs[index]))
>               return false;
>       mlx5_os_mac_addr_remove(dev, index);
> @@ -63,16 +65,17 @@ static int
>  mlx5_internal_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr 
> *mac,
>                          uint32_t index)
>  {
> +     struct mlx5_priv *priv = dev->data->dev_private;
>       unsigned int i;
>       int ret;
>  
> -     MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES);
> +     MLX5_ASSERT(index < priv->sh->dev_cap.max_mac_addrs);
>       if (rte_is_zero_ether_addr(mac)) {
>               rte_errno = EINVAL;
>               return -rte_errno;
>       }
>       /* First, make sure this address isn't already configured. */
> -     for (i = 0; (i != MLX5_MAX_MAC_ADDRESSES); ++i) {
> +     for (i = 0; i != priv->sh->dev_cap.max_mac_addrs; ++i) {
>               /* Skip this index, it's going to be reconfigured. */
>               if (i == index)
>                       continue;
> @@ -101,10 +104,11 @@ mlx5_internal_mac_addr_add(struct rte_eth_dev *dev, 
> struct rte_ether_addr *mac,
>  void
>  mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
>  {
> +     struct mlx5_priv *priv = dev->data->dev_private;
>       struct rte_ether_addr addr = { 0 };
>       int ret;
>  
> -     if (index >= MLX5_MAX_UC_MAC_ADDRESSES)
> +     if (index >= priv->sh->dev_cap.max_uc_mac_addrs)
>               return;
>       if (mlx5_internal_mac_addr_remove(dev, index, &addr)) {
>               ret = mlx5_traffic_mac_remove(dev, &addr);
> @@ -133,9 +137,10 @@ int
>  mlx5_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
>                 uint32_t index, uint32_t vmdq __rte_unused)
>  {
> +     struct mlx5_priv *priv = dev->data->dev_private;
>       int ret;
>  
> -     if (index >= MLX5_MAX_UC_MAC_ADDRESSES) {
> +     if (index >= priv->sh->dev_cap.max_uc_mac_addrs) {
>               rte_errno = EINVAL;
>               return -rte_errno;
>       }
> @@ -217,16 +222,17 @@ int
>  mlx5_set_mc_addr_list(struct rte_eth_dev *dev,
>                     struct rte_ether_addr *mc_addr_set, uint32_t nb_mc_addr)
>  {
> +     struct mlx5_priv *priv = dev->data->dev_private;
>       uint32_t i;
>       int ret;
>  
> -     if (nb_mc_addr >= MLX5_MAX_MC_MAC_ADDRESSES) {
> +     if (nb_mc_addr >= priv->sh->dev_cap.max_mc_mac_addrs) {
>               rte_errno = ENOSPC;
>               return -rte_errno;
>       }
> -     for (i = MLX5_MAX_UC_MAC_ADDRESSES; i != MLX5_MAX_MAC_ADDRESSES; ++i)
> +     for (i = priv->sh->dev_cap.max_uc_mac_addrs; i != 
> priv->sh->dev_cap.max_mac_addrs; ++i)
>               mlx5_internal_mac_addr_remove(dev, i, NULL);
> -     i = MLX5_MAX_UC_MAC_ADDRESSES;
> +     i = priv->sh->dev_cap.max_uc_mac_addrs;
>       while (nb_mc_addr--) {
>               ret = mlx5_internal_mac_addr_add(dev, mc_addr_set++, i++);
>               if (ret)
> diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
> index 7f6148f4e1..c5f493117b 100644
> --- a/drivers/net/mlx5/mlx5_trigger.c
> +++ b/drivers/net/mlx5/mlx5_trigger.c
> @@ -1916,7 +1916,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
>               }
>       }
>       /* Add MAC address flows. */
> -     for (i = 0; i != MLX5_MAX_MAC_ADDRESSES; ++i) {
> +     for (i = 0; i != priv->sh->dev_cap.max_mac_addrs; ++i) {
>               struct rte_ether_addr *mac = &dev->data->mac_addrs[i];
>  
>               /* Add flows for unicast and multicast mac addresses added by 
> API. */
> @@ -2186,7 +2186,7 @@ mlx5_traffic_vlan_add(struct rte_eth_dev *dev, const 
> uint16_t vid)
>               return 0;
>  
>       /* Add all unicast DMAC flow rules with new VLAN attached. */
> -     for (i = 0; i != MLX5_MAX_MAC_ADDRESSES; ++i) {
> +     for (i = 0; i != priv->sh->dev_cap.max_mac_addrs; ++i) {
>               struct rte_ether_addr *mac = &dev->data->mac_addrs[i];
>  
>               if (rte_is_zero_ether_addr(mac))
> @@ -2203,7 +2203,7 @@ mlx5_traffic_vlan_add(struct rte_eth_dev *dev, const 
> uint16_t vid)
>                * Removing after creating VLAN rules so that traffic "gap" is 
> not introduced.
>                */
>  
> -             for (i = 0; i != MLX5_MAX_MAC_ADDRESSES; ++i) {
> +             for (i = 0; i != priv->sh->dev_cap.max_mac_addrs; ++i) {
>                       struct rte_ether_addr *mac = &dev->data->mac_addrs[i];
>  
>                       if (rte_is_zero_ether_addr(mac))
> @@ -2241,7 +2241,7 @@ mlx5_traffic_vlan_remove(struct rte_eth_dev *dev, const 
> uint16_t vid)
>                * Recreating first to ensure no traffic "gap".
>                */
>  
> -             for (i = 0; i != MLX5_MAX_MAC_ADDRESSES; ++i) {
> +             for (i = 0; i != priv->sh->dev_cap.max_mac_addrs; ++i) {
>                       struct rte_ether_addr *mac = &dev->data->mac_addrs[i];
>  
>                       if (rte_is_zero_ether_addr(mac))
> @@ -2254,7 +2254,7 @@ mlx5_traffic_vlan_remove(struct rte_eth_dev *dev, const 
> uint16_t vid)
>       }
>  
>       /* Remove all unicast DMAC flow rules with this VLAN. */
> -     for (i = 0; i != MLX5_MAX_MAC_ADDRESSES; ++i) {
> +     for (i = 0; i != priv->sh->dev_cap.max_mac_addrs; ++i) {
>               struct rte_ether_addr *mac = &dev->data->mac_addrs[i];
>  
>               if (rte_is_zero_ether_addr(mac))
> diff --git a/drivers/net/mlx5/windows/mlx5_os.c 
> b/drivers/net/mlx5/windows/mlx5_os.c
> index eaa6c25c09..fa429a824b 100644
> --- a/drivers/net/mlx5/windows/mlx5_os.c
> +++ b/drivers/net/mlx5/windows/mlx5_os.c
> @@ -261,6 +261,16 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared 
> *sh)
>                MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
>       DRV_LOG(DEBUG, "Packet pacing is not supported.");
>       mlx5_rt_timestamp_config(sh, hca_attr);
> +     if (hca_attr->log_max_current_uc_list > 0)
> +             sh->dev_cap.max_uc_mac_addrs = 
> RTE_BIT32(hca_attr->log_max_current_uc_list);
> +     else
> +             sh->dev_cap.max_uc_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES;
> +     if (hca_attr->log_max_current_mc_list > 0)
> +             sh->dev_cap.max_mc_mac_addrs = 
> RTE_BIT32(hca_attr->log_max_current_mc_list);
> +     else
> +             sh->dev_cap.max_mc_mac_addrs = MLX5_MAX_MC_MAC_ADDRESSES;
> +     sh->dev_cap.max_mac_addrs =
> +             sh->dev_cap.max_uc_mac_addrs + sh->dev_cap.max_mc_mac_addrs;
>       return 0;
>  }
>  
> @@ -396,6 +406,22 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
>       priv->sh = sh;
>       priv->dev_port = spawn->phys_port;
>       priv->pci_dev = spawn->pci_dev;
> +     priv->mac = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
> +                             sizeof(*priv->mac) * sh->dev_cap.max_mac_addrs,
> +                             RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
> +     if (priv->mac == NULL) {
> +             DRV_LOG(ERR, "Failed to allocate MAC address array.");
> +             err = ENOMEM;
> +             goto error;
> +     }
> +     priv->mac_own = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
> +                                 RTE_BITSET_SIZE(sh->dev_cap.max_mac_addrs),
> +                                 RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
> +     if (priv->mac_own == NULL) {
> +             DRV_LOG(ERR, "Failed to allocate MAC ownership bitmap.");
> +             err = ENOMEM;
> +             goto error;
> +     }
>       priv->mp_id.port_id = port_id;
>       strlcpy(priv->mp_id.name, MLX5_MP_NAME, RTE_MP_MAX_NAME_LEN);
>       priv->representor = !!switch_info->representor;
> @@ -612,17 +638,15 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
>                       mlx5_l3t_destroy(priv->mtr_profile_tbl);
>               if (own_domain_id)
>                       claim_zero(rte_eth_switch_domain_free(priv->domain_id));
> +             mlx5_free(priv->mac);
> +             eth_dev->data->mac_addrs = NULL;
> +             mlx5_free(priv->mac_own);
>               mlx5_free(priv);
>               if (eth_dev != NULL)
>                       eth_dev->data->dev_private = NULL;
>       }
> -     if (eth_dev != NULL) {
> -             /* mac_addrs must not be freed alone because part of
> -              * dev_private
> -              **/
> -             eth_dev->data->mac_addrs = NULL;
> +     if (eth_dev != NULL)
>               rte_eth_dev_release_port(eth_dev);
> -     }
>       if (sh)
>               mlx5_free_shared_dev_ctx(sh);
>       MLX5_ASSERT(err > 0);
> @@ -698,7 +722,7 @@ mlx5_os_mac_addr_flush(struct rte_eth_dev *dev)
>       struct mlx5_priv *priv = dev->data->dev_private;
>       int i;
>  
> -     for (i = MLX5_MAX_MAC_ADDRESSES - 1; i >= 0; --i) {
> +     for (i = priv->sh->dev_cap.max_mac_addrs - 1; i >= 0; --i) {
>               if (rte_bitset_test(priv->mac_own, i))
>                       rte_bitset_clear(priv->mac_own, i);
>       }
> @@ -718,7 +742,7 @@ mlx5_os_mac_addr_remove(struct rte_eth_dev *dev, uint32_t 
> index)
>  {
>       struct mlx5_priv *priv = dev->data->dev_private;
>  
> -     if (index < MLX5_MAX_MAC_ADDRESSES)
> +     if (index < priv->sh->dev_cap.max_mac_addrs)
>               rte_bitset_clear(priv->mac_own, index);
>  }
>  
> -- 
> 2.54.0
> 

Reply via email to