[PATCH v2 12/26] net/hinic3: add VF link state and promiscuous support

Jiacheng Ye yejiacheng4 at h-partners.com
Wed Oct 14 17:09:08 CEST 2026


Every VF link previously followed the PF, so a VF could not be brought down
while the PF stayed up. Track vf_valid_status and combine it with the
physical link so the VF link can be set down independently.

Register the promiscuous callbacks in the VF eth_dev_ops so a VF can enter
promiscuous mode independently as well.

Signed-off-by: Jiacheng Ye <yejiacheng4 at h-partners.com>
---
 drivers/net/hinic3/base/hinic3_hwdev.h     |  3 +-
 drivers/net/hinic3/base/hinic3_nic_cfg.c   |  2 ++
 drivers/net/hinic3/base/hinic3_nic_event.c |  6 ++++
 drivers/net/hinic3/hinic3_ethdev.c         | 32 ++++++++++++++++++++--
 4 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/net/hinic3/base/hinic3_hwdev.h b/drivers/net/hinic3/base/hinic3_hwdev.h
index c6661aa1a6..87ca18e571 100644
--- a/drivers/net/hinic3/base/hinic3_hwdev.h
+++ b/drivers/net/hinic3/base/hinic3_hwdev.h
@@ -157,7 +157,8 @@ struct hinic3_hwdev {
 	char mgmt_ver[MGMT_VERSION_MAX_LEN];
 
 	uint16_t max_vfs;
-	uint16_t link_status;
+	uint8_t link_status;
+	uint8_t vf_valid_status; /* vport_enable: 1, vport_disable: 0 */
 	uint64_t features[HINIC3_MAX_FEATURE_QWORD];
 };
 
diff --git a/drivers/net/hinic3/base/hinic3_nic_cfg.c b/drivers/net/hinic3/base/hinic3_nic_cfg.c
index 8f0309e44d..21177bb531 100644
--- a/drivers/net/hinic3/base/hinic3_nic_cfg.c
+++ b/drivers/net/hinic3/base/hinic3_nic_cfg.c
@@ -470,6 +470,8 @@ hinic3_set_vport_enable(struct hinic3_hwdev *hwdev, bool enable)
 		return -EIO;
 	}
 
+	hwdev->vf_valid_status = enable;
+
 	return 0;
 }
 
diff --git a/drivers/net/hinic3/base/hinic3_nic_event.c b/drivers/net/hinic3/base/hinic3_nic_event.c
index 981a5f5083..787b4b0739 100644
--- a/drivers/net/hinic3/base/hinic3_nic_event.c
+++ b/drivers/net/hinic3/base/hinic3_nic_event.c
@@ -111,6 +111,12 @@ link_status_event_handler(struct hinic3_hwdev *hwdev, struct hinic3_handler_info
 
 	/* Link event reported only after set vport enable. */
 	hinic3_get_link_port_info(hwdev, link_status->state, &link);
+
+	if (HINIC3_IS_VF(hwdev)) {
+		hwdev->link_status = link.link_status;
+		link.link_status = hwdev->link_status & hwdev->vf_valid_status;
+	}
+
 	err = rte_eth_linkstatus_set(hwdev->eth_dev, &link);
 	if (!err && hwdev->eth_dev->data->dev_conf.intr_conf.lsc != 0)
 		rte_eth_dev_callback_process(hwdev->eth_dev,
diff --git a/drivers/net/hinic3/hinic3_ethdev.c b/drivers/net/hinic3/hinic3_ethdev.c
index bffcff9569..6e6c8a3c08 100644
--- a/drivers/net/hinic3/hinic3_ethdev.c
+++ b/drivers/net/hinic3/hinic3_ethdev.c
@@ -836,6 +836,7 @@ static int
 hinic3_dev_set_link_up(struct rte_eth_dev *dev)
 {
 	struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+	struct rte_eth_link link = { 0 };
 	int err;
 
 	/*
@@ -860,6 +861,14 @@ hinic3_dev_set_link_up(struct rte_eth_dev *dev)
 		return err;
 	}
 
+	if (HINIC3_IS_VF(nic_dev->hwdev)) {
+		link = dev->data->dev_link;
+		link.link_status = nic_dev->hwdev->link_status &
+					nic_dev->hwdev->vf_valid_status;
+
+		(void)rte_eth_linkstatus_set(dev, &link);
+	}
+
 	return 0;
 }
 
@@ -876,6 +885,7 @@ static int
 hinic3_dev_set_link_down(struct rte_eth_dev *dev)
 {
 	struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+	struct rte_eth_link link = {0};
 	int err;
 
 	err = hinic3_set_vport_enable(nic_dev->hwdev, false);
@@ -889,11 +899,19 @@ hinic3_dev_set_link_down(struct rte_eth_dev *dev)
 	err = hinic3_set_port_enable(nic_dev->hwdev, false);
 	if (err) {
 		PMD_DRV_LOG(ERR,
-			"Set MAC link down failed, dev_name: %s, port_id: %d",
-			nic_dev->dev_name, dev->data->port_id);
+			    "Set MAC link down failed, dev_name: %s, port_id: %d",
+			    nic_dev->dev_name, dev->data->port_id);
 		return err;
 	}
 
+	if (HINIC3_IS_VF(nic_dev->hwdev)) {
+		link = dev->data->dev_link;
+		link.link_status = nic_dev->hwdev->link_status &
+					nic_dev->hwdev->vf_valid_status;
+
+		(void)rte_eth_linkstatus_set(dev, &link);
+	}
+
 	return 0;
 }
 
@@ -941,6 +959,12 @@ hinic3_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	} while (rep_cnt--);
 
 out:
+	if (HINIC3_IS_VF(nic_dev->hwdev)) {
+		nic_dev->hwdev->link_status = link.link_status;
+		link.link_status = nic_dev->hwdev->link_status &
+					nic_dev->hwdev->vf_valid_status;
+	}
+
 	return rte_eth_linkstatus_set(dev, &link);
 }
 
@@ -3571,6 +3595,8 @@ static const struct eth_dev_ops hinic3_pmd_vf_ops = {
 	.dev_configure                 = hinic3_dev_configure,
 	.dev_infos_get                 = hinic3_dev_infos_get,
 	.fw_version_get                = hinic3_fw_version_get,
+	.dev_set_link_up               = hinic3_dev_set_link_up,
+	.dev_set_link_down             = hinic3_dev_set_link_down,
 	.rx_queue_setup                = hinic3_rx_queue_setup,
 	.tx_queue_setup                = hinic3_tx_queue_setup,
 	.rx_queue_intr_enable          = hinic3_dev_rx_queue_intr_enable,
@@ -3592,6 +3618,8 @@ static const struct eth_dev_ops hinic3_pmd_vf_ops = {
 	.vlan_offload_set              = hinic3_vlan_offload_set,
 	.allmulticast_enable           = hinic3_dev_allmulticast_enable,
 	.allmulticast_disable          = hinic3_dev_allmulticast_disable,
+	.promiscuous_enable            = hinic3_dev_promiscuous_enable,
+	.promiscuous_disable           = hinic3_dev_promiscuous_disable,
 	.rss_hash_update               = hinic3_rss_hash_update,
 	.rss_hash_conf_get             = hinic3_rss_conf_get,
 	.reta_update                   = hinic3_rss_reta_update,
-- 
2.33.0



More information about the dev mailing list