Acked-by: Chengwen Feng <[email protected] mailto:[email protected] 
>



November 4, 2026 at 8:40 PM, "Shuaisong Yang" <[email protected] 
mailto:[email protected]?to=%22Shuaisong%20Yang%22%20%3Cyangshuaisong%40h-partners.com%3E
 > wrote:


> 
> Currently, the driver obtains the PF's UMV (unicast MAC VLAN) table
> space from the board configuration, and falls back to the hard-coded
> default value HNS3_DEFAULT_UMV_SPACE_PER_PF (384 = 3072 / 8) when
> the firmware reports an empty umv_space field.
> 
> The hard-coded value is only accurate for chips with a 3072-entry UMV
> table. On chips whose total UMV table size is smaller than 3072, every
> PF still requests 384 entries: the first initialized PF occupies the
> whole table while the others get nothing, which makes adding unicast
> MAC or VLAN entries fail on those ports.
> 
> Fix this by obtaining the UMV size from the device specifications
> command, whose umv_size field is the default value allocated by the
> firmware policy. The requested size is determined at allocation time
> in hns3_init_umv_space(), in the following priority:
>  1. pf->cfg_umv_size, the user specified value from the board
>  configuration
>  2. pf->def_umv_size, the default value reported by the firmware
>  3. the hard-coded default, as the last fallback for old firmware
> 
> Fixes: d51867db65 ("net/hns3: add initialization")
> Cc: [email protected]
> 
> Signed-off-by: Shuaisong Yang <[email protected]>
> ---
>  drivers/net/hns3/hns3_cmd.h | 6 ++++--
>  drivers/net/hns3/hns3_common.c | 1 +
>  drivers/net/hns3/hns3_ethdev.c | 19 ++++++++++++-------
>  drivers/net/hns3/hns3_ethdev.h | 3 ++-
>  4 files changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
> index 2a2ec155ea..473c4f1ec4 100644
> --- a/drivers/net/hns3/hns3_cmd.h
> +++ b/drivers/net/hns3/hns3_cmd.h
> @@ -1008,9 +1008,11 @@ struct hns3_dev_specs_0_cmd {
>  };
>  
>  struct hns3_dev_specs_1_cmd {
> - uint8_t rsv0[12];
> + uint8_t rsv0[8];
> + uint16_t umv_size;
> + uint8_t rsv1[2];
>  uint8_t min_tx_pkt_len;
> - uint8_t rsv1[11];
> + uint8_t rsv2[11];
>  };
>  
>  struct hns3_query_rpu_cmd {
> diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c
> index 5e6fbd1f97..a2384ca6c9 100644
> --- a/drivers/net/hns3/hns3_common.c
> +++ b/drivers/net/hns3/hns3_common.c
> @@ -997,6 +997,7 @@ hns3_parse_dev_specifications(struct hns3_hw *hw, struct 
> hns3_cmd_desc *desc)
>  return;
>  
>  hw->max_tm_rate = rte_le_to_cpu_32(req0->max_tm_rate);
> + hns->pf.def_umv_size = rte_le_to_cpu_16(req1->umv_size);
>  }
>  
>  static int
> diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
> index 8a898422b1..e45e0d2b16 100644
> --- a/drivers/net/hns3/hns3_ethdev.c
> +++ b/drivers/net/hns3/hns3_ethdev.c
> @@ -1330,19 +1330,26 @@ hns3_init_umv_space(struct hns3_hw *hw)
>  struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
>  struct hns3_pf *pf = &hns->pf;
>  uint16_t allocated_size = 0;
> + uint16_t wanted_umv_size;
>  int ret;
>  
> - ret = hns3_set_umv_space(hw, pf->wanted_umv_size, &allocated_size,
> + wanted_umv_size = pf->cfg_umv_size;
> + if (wanted_umv_size == 0)
> + wanted_umv_size = pf->def_umv_size;
> + if (wanted_umv_size == 0)
> + wanted_umv_size = HNS3_DEFAULT_UMV_SPACE_PER_PF;
> +
> + ret = hns3_set_umv_space(hw, wanted_umv_size, &allocated_size,
>  true);
>  if (ret)
>  return ret;
>  
> - if (allocated_size < pf->wanted_umv_size)
> + if (allocated_size < wanted_umv_size)
>  PMD_INIT_LOG(WARNING, "Alloc umv space failed, want %u, get %u",
> - pf->wanted_umv_size, allocated_size);
> + wanted_umv_size, allocated_size);
>  
>  pf->max_umv_size = (!!allocated_size) ? allocated_size :
> - pf->wanted_umv_size;
> + wanted_umv_size;
>  pf->used_umv_size = 0;
>  return 0;
>  }
> @@ -2560,8 +2567,6 @@ hns3_parse_cfg(struct hns3_cfg *cfg, struct 
> hns3_cmd_desc *desc)
>  cfg->umv_space = hns3_get_field(rte_le_to_cpu_32(req->param[1]),
>  HNS3_CFG_UMV_TBL_SPACE_M,
>  HNS3_CFG_UMV_TBL_SPACE_S);
> - if (!cfg->umv_space)
> - cfg->umv_space = HNS3_DEFAULT_UMV_SPACE_PER_PF;
>  
>  ext_rss_size_max = hns3_get_field(rte_le_to_cpu_32(req->param[2]),
>  HNS3_CFG_EXT_RSS_SIZE_M,
> @@ -2792,7 +2797,7 @@ hns3_get_board_configuration(struct hns3_hw *hw)
>  hns3_set_bit(hw->dcb_info.hw_tc_map, 0, 1);
>  pf->tx_sch_mode = HNS3_FLAG_TC_BASE_SCH_MODE;
>  
> - pf->wanted_umv_size = cfg.umv_space;
> + pf->cfg_umv_size = cfg.umv_space;
>  
>  return ret;
>  }
> diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
> index fb1a3795cf..4df83e88eb 100644
> --- a/drivers/net/hns3/hns3_ethdev.h
> +++ b/drivers/net/hns3/hns3_ethdev.h
> @@ -841,7 +841,8 @@ struct hns3_pf {
>  bool support_fc_autoneg; /* support FC autonegotiate */
>  bool support_multi_tc_pause;
>  
> - uint16_t wanted_umv_size;
> + uint16_t cfg_umv_size;
> + uint16_t def_umv_size;
>  uint16_t max_umv_size;
>  uint16_t used_umv_size;
>  
> -- 
> 2.33.0
>

Reply via email to