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