From: Chengwen Feng <fengcheng...@huawei.com> If VF has the multi-TCs capability, then application could configure the multi-TCs feature through the DCB interface. Because VF does not have its own ETS and PFC components, the constraints are as follows:
1. The DCB configuration (struct rte_eth_dcb_rx_conf and rte_eth_dcb_tx_conf) must be the same as that of the PF. 2. VF does not support RTE_ETH_DCB_PFC_SUPPORT configuration. Signed-off-by: Chengwen Feng <fengcheng...@huawei.com> Signed-off-by: Dengdui Huang <huangdeng...@huawei.com> --- drivers/net/hns3/hns3_dcb.c | 106 ++++++++++++ drivers/net/hns3/hns3_dcb.h | 4 + drivers/net/hns3/hns3_dump.c | 6 +- drivers/net/hns3/hns3_ethdev.c | 98 +----------- drivers/net/hns3/hns3_ethdev_vf.c | 257 ++++++++++++++++++++++++++++-- drivers/net/hns3/hns3_mbx.h | 41 +++++ 6 files changed, 404 insertions(+), 108 deletions(-) diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c index 9a1f4120d0..6d2945d9c5 100644 --- a/drivers/net/hns3/hns3_dcb.c +++ b/drivers/net/hns3/hns3_dcb.c @@ -1800,3 +1800,109 @@ hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) return ret; } + +int +hns3_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + enum rte_eth_rx_mq_mode mq_mode = dev->data->dev_conf.rxmode.mq_mode; + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + int i; + + if (hns->is_vf && !hns3_dev_get_support(hw, VF_MULTI_TCS)) + return -ENOTSUP; + + rte_spinlock_lock(&hw->lock); + if ((uint32_t)mq_mode & RTE_ETH_MQ_RX_DCB_FLAG) + dcb_info->nb_tcs = hw->dcb_info.local_max_tc; + else + dcb_info->nb_tcs = 1; + + for (i = 0; i < HNS3_MAX_USER_PRIO; i++) + dcb_info->prio_tc[i] = hw->dcb_info.prio_tc[i]; + for (i = 0; i < dcb_info->nb_tcs; i++) + dcb_info->tc_bws[i] = hw->dcb_info.pg_info[0].tc_dwrr[i]; + + for (i = 0; i < hw->dcb_info.num_tc; i++) { + dcb_info->tc_queue.tc_rxq[0][i].base = hw->alloc_rss_size * i; + dcb_info->tc_queue.tc_txq[0][i].base = + hw->tc_queue[i].tqp_offset; + dcb_info->tc_queue.tc_rxq[0][i].nb_queue = hw->alloc_rss_size; + dcb_info->tc_queue.tc_txq[0][i].nb_queue = + hw->tc_queue[i].tqp_count; + } + rte_spinlock_unlock(&hw->lock); + + return 0; +} + +int +hns3_check_dev_mq_mode(struct rte_eth_dev *dev) +{ + enum rte_eth_rx_mq_mode rx_mq_mode = dev->data->dev_conf.rxmode.mq_mode; + enum rte_eth_tx_mq_mode tx_mq_mode = dev->data->dev_conf.txmode.mq_mode; + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + struct rte_eth_dcb_rx_conf *dcb_rx_conf; + struct rte_eth_dcb_tx_conf *dcb_tx_conf; + uint8_t num_tc; + int max_tc = 0; + int i; + + if (((uint32_t)rx_mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) || + (tx_mq_mode == RTE_ETH_MQ_TX_VMDQ_DCB || + tx_mq_mode == RTE_ETH_MQ_TX_VMDQ_ONLY)) { + hns3_err(hw, "VMDQ is not supported, rx_mq_mode = %d, tx_mq_mode = %d.", + rx_mq_mode, tx_mq_mode); + return -EOPNOTSUPP; + } + + dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; + dcb_tx_conf = &dev->data->dev_conf.tx_adv_conf.dcb_tx_conf; + if ((uint32_t)rx_mq_mode & RTE_ETH_MQ_RX_DCB_FLAG) { + if (dcb_rx_conf->nb_tcs > hw->dcb_info.tc_max) { + hns3_err(hw, "nb_tcs(%u) > max_tc(%u) driver supported.", + dcb_rx_conf->nb_tcs, hw->dcb_info.tc_max); + return -EINVAL; + } + + /* + * The PF driver supports only four or eight TCs. But the + * number of TCs supported by the VF driver is flexible, + * therefore, only the number of TCs in the PF is verified. + */ + if (!hns->is_vf && !(dcb_rx_conf->nb_tcs == HNS3_4_TCS || + dcb_rx_conf->nb_tcs == HNS3_8_TCS)) { + hns3_err(hw, "on RTE_ETH_MQ_RX_DCB_RSS mode, " + "nb_tcs(%d) != %d or %d in rx direction.", + dcb_rx_conf->nb_tcs, HNS3_4_TCS, HNS3_8_TCS); + return -EINVAL; + } + + if (dcb_rx_conf->nb_tcs != dcb_tx_conf->nb_tcs) { + hns3_err(hw, "num_tcs(%d) of tx is not equal to rx(%d)", + dcb_tx_conf->nb_tcs, dcb_rx_conf->nb_tcs); + return -EINVAL; + } + + for (i = 0; i < HNS3_MAX_USER_PRIO; i++) { + if (dcb_rx_conf->dcb_tc[i] != dcb_tx_conf->dcb_tc[i]) { + hns3_err(hw, "dcb_tc[%d] = %u in rx direction, " + "is not equal to one in tx direction.", + i, dcb_rx_conf->dcb_tc[i]); + return -EINVAL; + } + if (dcb_rx_conf->dcb_tc[i] > max_tc) + max_tc = dcb_rx_conf->dcb_tc[i]; + } + + num_tc = max_tc + 1; + if (num_tc > dcb_rx_conf->nb_tcs) { + hns3_err(hw, "max num_tc(%u) mapped > nb_tcs(%u)", + num_tc, dcb_rx_conf->nb_tcs); + return -EINVAL; + } + } + + return 0; +} diff --git a/drivers/net/hns3/hns3_dcb.h b/drivers/net/hns3/hns3_dcb.h index d5bb5edf4d..552e9c3026 100644 --- a/drivers/net/hns3/hns3_dcb.h +++ b/drivers/net/hns3/hns3_dcb.h @@ -215,4 +215,8 @@ int hns3_update_queue_map_configure(struct hns3_adapter *hns); int hns3_port_shaper_update(struct hns3_hw *hw, uint32_t speed); uint8_t hns3_txq_mapped_tc_get(struct hns3_hw *hw, uint16_t txq_no); +int hns3_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info); + +int hns3_check_dev_mq_mode(struct rte_eth_dev *dev); + #endif /* HNS3_DCB_H */ diff --git a/drivers/net/hns3/hns3_dump.c b/drivers/net/hns3/hns3_dump.c index 678279e2ac..0e978dee60 100644 --- a/drivers/net/hns3/hns3_dump.c +++ b/drivers/net/hns3/hns3_dump.c @@ -210,7 +210,7 @@ hns3_get_device_basic_info(FILE *file, struct rte_eth_dev *dev) " - Device Base Info:\n" "\t -- name: %s\n" "\t -- adapter_state=%s\n" - "\t -- tc_max=%u tc_num=%u\n" + "\t -- tc_max=%u tc_num=%u dwrr[%u %u %u %u]\n" "\t -- nb_rx_queues=%u nb_tx_queues=%u\n" "\t -- total_tqps_num=%u tqps_num=%u intr_tqps_num=%u\n" "\t -- rss_size_max=%u alloc_rss_size=%u tx_qnum_per_tc=%u\n" @@ -224,6 +224,10 @@ hns3_get_device_basic_info(FILE *file, struct rte_eth_dev *dev) dev->data->name, hns3_get_adapter_state_name(hw->adapter_state), hw->dcb_info.tc_max, hw->dcb_info.num_tc, + hw->dcb_info.pg_info[0].tc_dwrr[0], + hw->dcb_info.pg_info[0].tc_dwrr[1], + hw->dcb_info.pg_info[0].tc_dwrr[2], + hw->dcb_info.pg_info[0].tc_dwrr[3], dev->data->nb_rx_queues, dev->data->nb_tx_queues, hw->total_tqps_num, hw->tqps_num, hw->intr_tqps_num, hw->rss_size_max, hw->alloc_rss_size, hw->tx_qnum_per_tc, diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index 5af11d9228..a809a47423 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -1870,71 +1870,6 @@ hns3_remove_mc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) return ret; } -static int -hns3_check_mq_mode(struct rte_eth_dev *dev) -{ - enum rte_eth_rx_mq_mode rx_mq_mode = dev->data->dev_conf.rxmode.mq_mode; - enum rte_eth_tx_mq_mode tx_mq_mode = dev->data->dev_conf.txmode.mq_mode; - struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); - struct rte_eth_dcb_rx_conf *dcb_rx_conf; - struct rte_eth_dcb_tx_conf *dcb_tx_conf; - uint8_t num_tc; - int max_tc = 0; - int i; - - if (((uint32_t)rx_mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) || - (tx_mq_mode == RTE_ETH_MQ_TX_VMDQ_DCB || - tx_mq_mode == RTE_ETH_MQ_TX_VMDQ_ONLY)) { - hns3_err(hw, "VMDQ is not supported, rx_mq_mode = %d, tx_mq_mode = %d.", - rx_mq_mode, tx_mq_mode); - return -EOPNOTSUPP; - } - - dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; - dcb_tx_conf = &dev->data->dev_conf.tx_adv_conf.dcb_tx_conf; - if ((uint32_t)rx_mq_mode & RTE_ETH_MQ_RX_DCB_FLAG) { - if (dcb_rx_conf->nb_tcs > hw->dcb_info.tc_max) { - hns3_err(hw, "nb_tcs(%u) > max_tc(%u) driver supported.", - dcb_rx_conf->nb_tcs, hw->dcb_info.tc_max); - return -EINVAL; - } - - if (!(dcb_rx_conf->nb_tcs == HNS3_4_TCS || - dcb_rx_conf->nb_tcs == HNS3_8_TCS)) { - hns3_err(hw, "on RTE_ETH_MQ_RX_DCB_RSS mode, " - "nb_tcs(%d) != %d or %d in rx direction.", - dcb_rx_conf->nb_tcs, HNS3_4_TCS, HNS3_8_TCS); - return -EINVAL; - } - - if (dcb_rx_conf->nb_tcs != dcb_tx_conf->nb_tcs) { - hns3_err(hw, "num_tcs(%d) of tx is not equal to rx(%d)", - dcb_tx_conf->nb_tcs, dcb_rx_conf->nb_tcs); - return -EINVAL; - } - - for (i = 0; i < HNS3_MAX_USER_PRIO; i++) { - if (dcb_rx_conf->dcb_tc[i] != dcb_tx_conf->dcb_tc[i]) { - hns3_err(hw, "dcb_tc[%d] = %u in rx direction, " - "is not equal to one in tx direction.", - i, dcb_rx_conf->dcb_tc[i]); - return -EINVAL; - } - if (dcb_rx_conf->dcb_tc[i] > max_tc) - max_tc = dcb_rx_conf->dcb_tc[i]; - } - - num_tc = max_tc + 1; - if (num_tc > dcb_rx_conf->nb_tcs) { - hns3_err(hw, "max num_tc(%u) mapped > nb_tcs(%u)", - num_tc, dcb_rx_conf->nb_tcs); - return -EINVAL; - } - } - - return 0; -} - static int hns3_bind_ring_with_vector(struct hns3_hw *hw, uint16_t vector_id, bool en, enum hns3_ring_type queue_type, uint16_t queue_id) @@ -2033,7 +1968,7 @@ hns3_check_dev_conf(struct rte_eth_dev *dev) struct rte_eth_conf *conf = &dev->data->dev_conf; int ret; - ret = hns3_check_mq_mode(dev); + ret = hns3_check_dev_mq_mode(dev); if (ret) return ret; @@ -5489,37 +5424,6 @@ hns3_priority_flow_ctrl_set(struct rte_eth_dev *dev, return ret; } -static int -hns3_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info) -{ - struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); - enum rte_eth_rx_mq_mode mq_mode = dev->data->dev_conf.rxmode.mq_mode; - int i; - - rte_spinlock_lock(&hw->lock); - if ((uint32_t)mq_mode & RTE_ETH_MQ_RX_DCB_FLAG) - dcb_info->nb_tcs = hw->dcb_info.local_max_tc; - else - dcb_info->nb_tcs = 1; - - for (i = 0; i < HNS3_MAX_USER_PRIO; i++) - dcb_info->prio_tc[i] = hw->dcb_info.prio_tc[i]; - for (i = 0; i < dcb_info->nb_tcs; i++) - dcb_info->tc_bws[i] = hw->dcb_info.pg_info[0].tc_dwrr[i]; - - for (i = 0; i < hw->dcb_info.num_tc; i++) { - dcb_info->tc_queue.tc_rxq[0][i].base = hw->alloc_rss_size * i; - dcb_info->tc_queue.tc_txq[0][i].base = - hw->tc_queue[i].tqp_offset; - dcb_info->tc_queue.tc_rxq[0][i].nb_queue = hw->alloc_rss_size; - dcb_info->tc_queue.tc_txq[0][i].nb_queue = - hw->tc_queue[i].tqp_count; - } - rte_spinlock_unlock(&hw->lock); - - return 0; -} - static int hns3_reinit_dev(struct hns3_adapter *hns) { diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c index 41d8252540..f9ef3dbb06 100644 --- a/drivers/net/hns3/hns3_ethdev_vf.c +++ b/drivers/net/hns3/hns3_ethdev_vf.c @@ -379,6 +379,236 @@ hns3vf_bind_ring_with_vector(struct hns3_hw *hw, uint16_t vector_id, return ret; } +static int +hns3vf_set_multi_tc(struct hns3_hw *hw, const struct hns3_mbx_tc_config *config) +{ + struct hns3_mbx_tc_config *payload; + struct hns3_vf_to_pf_msg req; + int ret; + + hns3vf_mbx_setup(&req, HNS3_MBX_SET_TC, 0); + payload = (struct hns3_mbx_tc_config *)req.data; + memcpy(payload, config, sizeof(*payload)); + payload->prio_tc_map = rte_cpu_to_le_32(config->prio_tc_map); + ret = hns3vf_mbx_send(hw, &req, true, NULL, 0); + if (ret) + hns3_err(hw, "failed to set multi-tc, ret = %d.", ret); + + return ret; +} + +static int +hns3vf_unset_multi_tc(struct hns3_hw *hw) +{ + struct hns3_mbx_tc_config *paylod; + struct hns3_vf_to_pf_msg req; + int ret; + + hns3vf_mbx_setup(&req, HNS3_MBX_SET_TC, 0); + paylod = (struct hns3_mbx_tc_config *)req.data; + paylod->tc_dwrr[0] = HNS3_ETS_DWRR_MAX; + paylod->num_tc = 1; + ret = hns3vf_mbx_send(hw, &req, true, NULL, 0); + if (ret) + hns3_err(hw, "failed to unset multi-tc, ret = %d.", ret); + + return ret; +} + +static int +hns3vf_check_multi_tc_config(struct rte_eth_dev *dev, const struct hns3_mbx_tc_config *info) +{ + struct rte_eth_dcb_rx_conf *rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t prio_tc_map = info->prio_tc_map; + uint8_t map; + int i; + + if (rx_conf->nb_tcs != info->num_tc) { + hns3_err(hw, "num_tcs(%d) is not equal to PF config(%u)!", + rx_conf->nb_tcs, info->num_tc); + return -EINVAL; + } + + for (i = 0; i < HNS3_MAX_USER_PRIO; i++) { + map = prio_tc_map & HNS3_MBX_PRIO_MASK; + prio_tc_map >>= HNS3_MBX_PRIO_SHIFT; + if (rx_conf->dcb_tc[i] != map) { + hns3_err(hw, "dcb_tc[%d] = %u is not equal to PF config(%u)!", + i, rx_conf->dcb_tc[i], map); + return -EINVAL; + } + } + + return 0; +} + +static int +hns3vf_get_multi_tc_info(struct hns3_hw *hw, struct hns3_mbx_tc_config *info) +{ + uint8_t resp_msg[HNS3_MBX_MAX_RESP_DATA_SIZE]; + struct hns3_mbx_tc_prio_map *map = (struct hns3_mbx_tc_prio_map *)resp_msg; + struct hns3_mbx_tc_ets_info *ets = (struct hns3_mbx_tc_ets_info *)resp_msg; + struct hns3_vf_to_pf_msg req; + int i, ret; + + memset(info, 0, sizeof(*info)); + + hns3vf_mbx_setup(&req, HNS3_MBX_GET_TC, HNS3_MBX_GET_PRIO_MAP); + ret = hns3vf_mbx_send(hw, &req, true, resp_msg, sizeof(resp_msg)); + if (ret) { + hns3_err(hw, "failed to get multi-tc prio map, ret = %d.", ret); + return ret; + } + info->prio_tc_map = rte_le_to_cpu_32(map->prio_tc_map); + + hns3vf_mbx_setup(&req, HNS3_MBX_GET_TC, HNS3_MBX_GET_ETS_INFO); + ret = hns3vf_mbx_send(hw, &req, true, resp_msg, sizeof(resp_msg)); + if (ret) { + hns3_err(hw, "failed to get multi-tc ETS info, ret = %d.", ret); + return ret; + } + for (i = 0; i < HNS3_MAX_TC_NUM; i++) { + if (ets->sch_mode[i] == HNS3_ETS_SCHED_MODE_INVALID) + continue; + info->tc_dwrr[i] = ets->sch_mode[i]; + info->num_tc++; + if (ets->sch_mode[i] > 0) + info->tc_sch_mode |= 1u << i; + } + + return 0; +} + +static void +hns3vf_update_dcb_info(struct hns3_hw *hw, const struct hns3_mbx_tc_config *info) +{ + uint32_t prio_tc_map; + uint8_t map; + int i; + + hw->dcb_info.local_max_tc = hw->dcb_info.num_tc; + hw->dcb_info.hw_tc_map = (1u << hw->dcb_info.num_tc) - 1u; + memset(hw->dcb_info.pg_info[0].tc_dwrr, 0, sizeof(hw->dcb_info.pg_info[0].tc_dwrr)); + + if (hw->dcb_info.num_tc == 1) { + memset(hw->dcb_info.prio_tc, 0, sizeof(hw->dcb_info.prio_tc)); + hw->dcb_info.pg_info[0].tc_dwrr[0] = HNS3_ETS_DWRR_MAX; + return; + } + + if (info == NULL) + return; + + prio_tc_map = info->prio_tc_map; + for (i = 0; i < HNS3_MAX_TC_NUM; i++) { + map = prio_tc_map & HNS3_MBX_PRIO_MASK; + prio_tc_map >>= HNS3_MBX_PRIO_SHIFT; + hw->dcb_info.prio_tc[i] = map; + } + for (i = 0; i < hw->dcb_info.num_tc; i++) + hw->dcb_info.pg_info[0].tc_dwrr[i] = info->tc_dwrr[i]; +} + +static int +hns3vf_setup_dcb(struct rte_eth_dev *dev) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_mbx_tc_config info; + int ret; + + if (!hns3_dev_get_support(hw, VF_MULTI_TCS)) { + hns3_err(hw, "this port does not support dcb configurations."); + return -ENOTSUP; + } + + if (dev->data->dev_conf.dcb_capability_en & RTE_ETH_DCB_PFC_SUPPORT) { + hns3_err(hw, "VF don't support PFC!"); + return -ENOTSUP; + } + + ret = hns3vf_get_multi_tc_info(hw, &info); + if (ret) + return ret; + + ret = hns3vf_check_multi_tc_config(dev, &info); + if (ret) + return ret; + + /* + * If multiple-TCs have been configured, cancel the configuration + * first. Otherwise, the configuration will fail. + */ + if (hw->dcb_info.num_tc > 1) { + ret = hns3vf_unset_multi_tc(hw); + if (ret) + return ret; + hw->dcb_info.num_tc = 1; + hns3vf_update_dcb_info(hw, NULL); + } + + ret = hns3vf_set_multi_tc(hw, &info); + if (ret) + return ret; + + hw->dcb_info.num_tc = info.num_tc; + hns3vf_update_dcb_info(hw, &info); + + return hns3_queue_to_tc_mapping(hw, hw->data->nb_rx_queues, hw->data->nb_rx_queues); +} + +static int +hns3vf_unset_dcb(struct rte_eth_dev *dev) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret; + + if (hw->dcb_info.num_tc > 1) { + ret = hns3vf_unset_multi_tc(hw); + if (ret) + return ret; + } + + hw->dcb_info.num_tc = 1; + hns3vf_update_dcb_info(hw, NULL); + + return hns3_queue_to_tc_mapping(hw, hw->data->nb_rx_queues, hw->data->nb_rx_queues); +} + +static int +hns3vf_config_dcb(struct rte_eth_dev *dev) +{ + struct rte_eth_conf *conf = &dev->data->dev_conf; + uint32_t rx_mq_mode = conf->rxmode.mq_mode; + int ret; + + if (rx_mq_mode & RTE_ETH_MQ_RX_DCB_FLAG) + ret = hns3vf_setup_dcb(dev); + else + ret = hns3vf_unset_dcb(dev); + + return ret; +} + +static int +hns3vf_check_dev_conf(struct rte_eth_dev *dev) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct rte_eth_conf *conf = &dev->data->dev_conf; + int ret; + + ret = hns3_check_dev_mq_mode(dev); + if (ret) + return ret; + + if (conf->link_speeds & RTE_ETH_LINK_SPEED_FIXED) { + hns3_err(hw, "setting link speed/duplex not supported"); + ret = -EINVAL; + } + + return ret; +} + static int hns3vf_dev_configure(struct rte_eth_dev *dev) { @@ -412,11 +642,13 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) } hw->adapter_state = HNS3_NIC_CONFIGURING; - if (conf->link_speeds & RTE_ETH_LINK_SPEED_FIXED) { - hns3_err(hw, "setting link speed/duplex not supported"); - ret = -EINVAL; + ret = hns3vf_check_dev_conf(dev); + if (ret) + goto cfg_err; + + ret = hns3vf_config_dcb(dev); + if (ret) goto cfg_err; - } /* When RSS is not configured, redirect the packet queue 0 */ if ((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) { @@ -1496,6 +1728,15 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) return ret; } +static void +hns3vf_notify_uninit(struct hns3_hw *hw) +{ + struct hns3_vf_to_pf_msg req; + + hns3vf_mbx_setup(&req, HNS3_MBX_VF_UNINIT, 0); + (void)hns3vf_mbx_send(hw, &req, false, NULL, 0); +} + static void hns3vf_uninit_vf(struct rte_eth_dev *eth_dev) { @@ -1515,6 +1756,7 @@ hns3vf_uninit_vf(struct rte_eth_dev *eth_dev) rte_intr_disable(pci_dev->intr_handle); hns3_intr_unregister(pci_dev->intr_handle, hns3vf_interrupt_handler, eth_dev); + (void)hns3vf_notify_uninit(hw); hns3_cmd_uninit(hw); hns3_cmd_destroy_queue(hw); hw->io_base = NULL; @@ -1652,14 +1894,8 @@ static int hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue) { struct hns3_hw *hw = &hns->hw; - uint16_t nb_rx_q = hw->data->nb_rx_queues; - uint16_t nb_tx_q = hw->data->nb_tx_queues; int ret; - ret = hns3_queue_to_tc_mapping(hw, nb_rx_q, nb_tx_q); - if (ret) - return ret; - hns3_enable_rxd_adv_layout(hw); ret = hns3_init_queues(hns, reset_queue); @@ -2240,6 +2476,7 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = { .vlan_filter_set = hns3vf_vlan_filter_set, .vlan_offload_set = hns3vf_vlan_offload_set, .get_reg = hns3_get_regs, + .get_dcb_info = hns3_get_dcb_info, .dev_supported_ptypes_get = hns3_dev_supported_ptypes_get, .tx_done_cleanup = hns3_tx_done_cleanup, .eth_dev_priv_dump = hns3_eth_dev_priv_dump, diff --git a/drivers/net/hns3/hns3_mbx.h b/drivers/net/hns3/hns3_mbx.h index eec3dd2c7e..73ff5020fe 100644 --- a/drivers/net/hns3/hns3_mbx.h +++ b/drivers/net/hns3/hns3_mbx.h @@ -9,6 +9,8 @@ #include <rte_spinlock.h> +#include "hns3_cmd.h" + enum HNS3_MBX_OPCODE { HNS3_MBX_RESET = 0x01, /* (VF -> PF) assert reset */ HNS3_MBX_ASSERTING_RESET, /* (PF -> VF) PF is asserting reset */ @@ -45,11 +47,13 @@ enum HNS3_MBX_OPCODE { HNS3_MBX_PUSH_VLAN_INFO = 34, /* (PF -> VF) push port base vlan */ HNS3_MBX_PUSH_PROMISC_INFO = 36, /* (PF -> VF) push vf promisc info */ + HNS3_MBX_VF_UNINIT, /* (VF -> PF) vf is unintializing */ HNS3_MBX_HANDLE_VF_TBL = 38, /* (VF -> PF) store/clear hw cfg tbl */ HNS3_MBX_GET_RING_VECTOR_MAP, /* (VF -> PF) get ring-to-vector map */ HNS3_MBX_GET_TC = 47, /* (VF -> PF) get tc info of PF configured */ + HNS3_MBX_SET_TC, /* (VF -> PF) set tc */ HNS3_MBX_PUSH_LINK_STATUS = 201, /* (IMP -> PF) get port link status */ }; @@ -64,7 +68,44 @@ struct hns3_basic_info { enum hns3_mbx_get_tc_subcode { HNS3_MBX_GET_PRIO_MAP = 0, /* query priority to tc map */ + HNS3_MBX_GET_ETS_INFO, /* query ets info */ +}; + +struct hns3_mbx_tc_prio_map { + /* + * Each four bits correspond to one priority's TC. + * Bit0-3 correspond to priority-0's TC, bit4-7 correspond to + * priority-1's TC, and so on. + */ + uint32_t prio_tc_map; +}; + +#define HNS3_ETS_SCHED_MODE_INVALID 255 +#define HNS3_ETS_DWRR_MAX 100 +struct hns3_mbx_tc_ets_info { + uint8_t sch_mode[HNS3_MAX_TC_NUM]; /* 1~100: DWRR, 0: SP; 255-invalid */ +}; + +#pragma pack(1) +#define HNS3_MBX_PRIO_SHIFT 4 +#define HNS3_MBX_PRIO_MASK 0xFu +struct hns3_mbx_tc_config { + /* + * Each four bits correspond to one priority's TC. + * Bit0-3 correspond to priority-0's TC, bit4-7 correspond to + * priority-1's TC, and so on. + */ + uint32_t prio_tc_map; + uint8_t tc_dwrr[HNS3_MAX_TC_NUM]; + uint8_t num_tc; + /* + * Each bit correspond to one TC's scheduling mode, 0 means SP + * scheduling mode, 1 means DWRR scheduling mode. + * Bit0 corresponds to TC0, bit1 corresponds to TC1, and so on. + */ + uint8_t tc_sch_mode; }; +#pragma pack() /* below are per-VF mac-vlan subcodes */ enum hns3_mbx_mac_vlan_subcode { -- 2.33.0