[PATCH v1 06/17] net/hinic3: add VF link state and promiscuous support
Jiacheng Ye
yejiacheng4 at h-partners.com
Sat Oct 10 16:44:57 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 and add the
symmetric feature-capability check to the disable path 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 | 5 ++-
drivers/net/hinic3/base/hinic3_nic_event.c | 6 +++
drivers/net/hinic3/hinic3_ethdev.c | 47 +++++++++++++++++++++-
4 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/drivers/net/hinic3/base/hinic3_hwdev.h b/drivers/net/hinic3/base/hinic3_hwdev.h
index 5601f93190..04487f9b42 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 : 1;
+ uint8_t vf_valid_status : 1; /* vport_enable: 1, vport_disable: 0 */
uint32_t speed;
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 0a0c7e74e0..2241908004 100644
--- a/drivers/net/hinic3/base/hinic3_nic_cfg.c
+++ b/drivers/net/hinic3/base/hinic3_nic_cfg.c
@@ -443,12 +443,13 @@ int
hinic3_set_vport_enable(struct hinic3_hwdev *hwdev, bool enable)
{
struct hinic3_vport_state en_state;
- struct hinic3_nic_dev *nic_dev = hwdev->dev_handle;
+ struct hinic3_nic_dev *nic_dev;
uint16_t out_size = sizeof(en_state);
int err;
if (!hwdev)
return -EINVAL;
+ nic_dev = hwdev->dev_handle;
memset(&en_state, 0, sizeof(en_state));
en_state.func_id = hinic3_global_func_id(hwdev);
@@ -467,6 +468,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 be8a1fc576..2f2d6aa75b 100644
--- a/drivers/net/hinic3/base/hinic3_nic_event.c
+++ b/drivers/net/hinic3/base/hinic3_nic_event.c
@@ -112,6 +112,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 5a0e93ed8a..f4be6cdc06 100644
--- a/drivers/net/hinic3/hinic3_ethdev.c
+++ b/drivers/net/hinic3/hinic3_ethdev.c
@@ -820,6 +820,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;
/*
@@ -844,6 +845,23 @@ 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;
+ if (link.link_status == RTE_ETH_LINK_DOWN) {
+ PMD_DRV_LOG(ERR,
+ "Set VF link up failed, dev_name: %s, port_id: %d,"
+ " link_status: %d, vf_valid_status: %d",
+ nic_dev->dev_name, dev->data->port_id,
+ nic_dev->hwdev->link_status,
+ nic_dev->hwdev->vf_valid_status);
+ return -EAGAIN;
+ }
+
+ (void)rte_eth_linkstatus_set(dev, &link);
+ }
+
return 0;
}
@@ -860,6 +878,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);
@@ -873,11 +892,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;
}
@@ -925,6 +952,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);
}
@@ -2470,6 +2503,12 @@ hinic3_dev_promiscuous_disable(struct rte_eth_dev *dev)
uint32_t rx_mode;
int err;
+ if (!(nic_dev->feature_cap & NIC_F_PROMISC)) {
+ PMD_DRV_LOG(ERR, "nic_dev: %s, port_id: %d, do not support vf promisc: %" PRIu64,
+ nic_dev->dev_name, dev->data->port_id, nic_dev->feature_cap);
+ return -ENOTSUP;
+ }
+
rx_mode = nic_dev->rx_mode & (~HINIC3_RX_MODE_PROMISC);
err = hinic3_set_rx_mode(nic_dev->hwdev, rx_mode);
@@ -3522,6 +3561,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,
@@ -3543,6 +3584,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