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 <[email protected]> --- 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

