Provide CIR drop counters and VF LAG configuration so that packets dropped for exceeding the committed information rate are visible and VFs can select the correct queue on an aggregated link.
Signed-off-by: Jiacheng Ye <[email protected]> --- doc/guides/rel_notes/release_26_11.rst | 4 ++ drivers/net/hinic3/base/hinic3_cmd.h | 2 + drivers/net/hinic3/base/hinic3_nic_cfg.c | 63 ++++++++++++++++++++++ drivers/net/hinic3/base/hinic3_nic_cfg.h | 45 +++++++++++++++- drivers/net/hinic3/hinic3_ethdev.c | 68 +++++++++++++++++++++++- drivers/net/hinic3/hinic3_ethdev.h | 3 ++ 6 files changed, 182 insertions(+), 3 deletions(-) diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst index e282fa5581..0c02cbf67f 100644 --- a/doc/guides/rel_notes/release_26_11.rst +++ b/doc/guides/rel_notes/release_26_11.rst @@ -92,6 +92,10 @@ New Features ``xdp_meta_rx_ts_valid_mask``. * Added ``read_clock`` operation to query the PTP hardware clock. +* **Updated Huawei hinic3 ethernet driver.** + + * Added CIR drop statistics and VF link aggregation (LAG) support. + * **Updated Intel iavf driver.** * Runtime Rx/Tx queue setup is now automatically disabled diff --git a/drivers/net/hinic3/base/hinic3_cmd.h b/drivers/net/hinic3/base/hinic3_cmd.h index f2d5d47522..ecce94690e 100644 --- a/drivers/net/hinic3/base/hinic3_cmd.h +++ b/drivers/net/hinic3/base/hinic3_cmd.h @@ -94,6 +94,8 @@ enum hinic3_nic_cmd { /* PORT CFG */ HINIC3_NIC_CMD_CFG_PAUSE_INFO = 101, HINIC3_NIC_CMD_VF_COS = 104, + HINIC3_NIC_CMD_GET_CIR_DROP = 115, + HINIC3_NIC_CMD_CFG_VF_LAG = 243, }; /* COMM commands between driver to MPU. */ diff --git a/drivers/net/hinic3/base/hinic3_nic_cfg.c b/drivers/net/hinic3/base/hinic3_nic_cfg.c index bd3c39730f..48dee29750 100644 --- a/drivers/net/hinic3/base/hinic3_nic_cfg.c +++ b/drivers/net/hinic3/base/hinic3_nic_cfg.c @@ -600,6 +600,33 @@ hinic3_get_pause_info(struct hinic3_hwdev *hwdev, struct nic_pause_config *nic_p return hinic3_cfg_hw_pause(hwdev, HINIC3_CMD_OP_GET, nic_pause); } +int +hinic3_get_cir_drop(void *hwdev, struct hinic3_cir_drop *stats) +{ + struct hinic3_port_stats_info stats_info = { 0 }; + struct hinic3_cmd_get_dp_info_resp vport_stats = { 0 }; + uint16_t out_size = sizeof(vport_stats); + int err; + + if (!hwdev || !stats) + return -EINVAL; + + stats_info.func_id = hinic3_global_func_id(hwdev); + err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_L2NIC, + HINIC3_NIC_CMD_GET_CIR_DROP, + &stats_info, sizeof(stats_info), + &vport_stats, &out_size); + if (err || !out_size || vport_stats.msg_head.status) { + PMD_DRV_LOG(ERR, "Get port stats failed, err: %d, status: 0x%x, out size: 0x%x", + err, vport_stats.msg_head.status, out_size); + return -EIO; + } + + memcpy(stats, vport_stats.value, sizeof(*stats)); + + return 0; +} + int hinic3_get_vport_stats(struct hinic3_hwdev *hwdev, struct hinic3_vport_stats *stats) { @@ -1724,3 +1751,39 @@ hinic3_set_link_status_follow(struct hinic3_hwdev *hwdev, return follow.head.status; } + +uint8_t +hinic3_cmd_vf_lag(void *hwdev, uint16_t func_id, uint8_t opcode) +{ + struct hinic3_vf_lag_cmd vf_lag_info = {0}; + uint16_t out_size = sizeof(struct hinic3_vf_lag_cmd); + uint8_t lag_en = 0; + int err; + + if (!hwdev || func_id >= MAX_FUNCTION_NUM) + return 0; + vf_lag_info.func_id = func_id; + vf_lag_info.opcode = opcode; + vf_lag_info.en_flag = 0; + + err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_L2NIC, + HINIC3_NIC_CMD_CFG_VF_LAG, + &vf_lag_info, sizeof(vf_lag_info), + &vf_lag_info, &out_size); + if (vf_lag_info.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED) + return 0; + + if (err || vf_lag_info.msg_head.status || !out_size) { + PMD_DRV_LOG(ERR, + "Get vf_lag failed, err: %d, status: 0x%x, out size: 0x%x", + err, vf_lag_info.msg_head.status, out_size); + return 0; + } + + if (opcode == HINIC3_CMD_OPCODE_GET) { + lag_en = (vf_lag_info.vf_lag_bitmap.vf_bit_map[func_id / VF_LAG_VF_NUM_PER_GROUP] & + ((0x1ULL) << (func_id % VF_LAG_VF_NUM_PER_GROUP))); + } + + return lag_en; +} diff --git a/drivers/net/hinic3/base/hinic3_nic_cfg.h b/drivers/net/hinic3/base/hinic3_nic_cfg.h index 6d3eb433bd..5f08d49a72 100644 --- a/drivers/net/hinic3/base/hinic3_nic_cfg.h +++ b/drivers/net/hinic3/base/hinic3_nic_cfg.h @@ -17,6 +17,7 @@ #define HINIC3_DCB_UP_MAX 0x8 #define HINIC3_MAX_NUM_RQ 256 +#define MAX_FUNCTION_NUM 4096 #define HINIC3_MAX_MTU_SIZE 9600 #define HINIC3_MIN_MTU_SIZE 256 @@ -371,6 +372,18 @@ struct hinic3_port_stats_info { uint16_t rsvd1; }; +#define HINIC3_CMD_MAX_DP_DATA_NUM 50 +struct hinic3_cir_drop { + uint64_t rx_discard_phy; +}; + +struct hinic3_cmd_get_dp_info_resp { + struct mgmt_msg_head msg_head; + uint16_t length; + uint16_t rsvd; + uint64_t value[HINIC3_CMD_MAX_DP_DATA_NUM]; +}; + struct hinic3_vport_stats { uint64_t tx_unicast_pkts_vport; uint64_t tx_unicast_bytes_vport; @@ -390,6 +403,8 @@ struct hinic3_vport_stats { uint64_t rx_discard_vport; uint64_t tx_err_vport; uint64_t rx_err_vport; + uint64_t rx_mtu_err_vport; + uint64_t rx_out_of_buffer; /* fw: rx_nowqe */ }; struct hinic3_cmd_vport_stats { @@ -398,7 +413,7 @@ struct hinic3_cmd_vport_stats { uint32_t stats_size; uint32_t rsvd1; struct hinic3_vport_stats stats; - uint64_t rsvd2[6]; + uint64_t rsvd2[4]; }; struct hinic3_phy_port_stats { @@ -1540,4 +1555,32 @@ int hinic3_set_feature_to_hw(struct hinic3_hwdev *hwdev, uint64_t *s_feature, ui int hinic3_set_link_status_follow(struct hinic3_hwdev *hwdev, enum hinic3_link_follow_status status); + +/* VF LAG definitions */ +#define VF_LAG_VF_NUM_GROUP_NUM 128 +#define VF_LAG_VF_NUM_PER_GROUP 32 +#define HINIC3_CMD_OPCODE_SET 0 +#define HINIC3_CMD_OPCODE_GET 1 + +typedef struct hinic3_vf_lag_bitmap_s { + uint32_t vf_bit_map[VF_LAG_VF_NUM_GROUP_NUM]; +} hinic3_vf_lag_bitmap; + +struct hinic3_vf_lag_cmd { + struct mgmt_msg_head msg_head; + + uint16_t func_id; + uint8_t opcode; /* 0 -> set, 1 -> get */ + uint8_t en_flag; /* 0 -> disable, 1 -> enable */ + uint8_t bond_active_num; + uint8_t bond_active_bitmap; + uint8_t mac_sync_flag; + uint8_t rsvd; + hinic3_vf_lag_bitmap vf_lag_bitmap; +}; + +int hinic3_get_cir_drop(void *hwdev, struct hinic3_cir_drop *stats); + +uint8_t hinic3_cmd_vf_lag(void *hwdev, uint16_t func_id, uint8_t opcode); + #endif /* _HINIC3_NIC_CFG_H_ */ diff --git a/drivers/net/hinic3/hinic3_ethdev.c b/drivers/net/hinic3/hinic3_ethdev.c index 623c836a3b..ecf7df3ec0 100644 --- a/drivers/net/hinic3/hinic3_ethdev.c +++ b/drivers/net/hinic3/hinic3_ethdev.c @@ -80,12 +80,25 @@ struct hinic3_xstats_name_off { uint32_t offset; }; +#define HINIC3_CIR_DROP_STAT(_stat_item) \ + { \ + .name = #_stat_item, \ + .offset = offsetof(struct hinic3_cir_drop, _stat_item), \ + } + #define HINIC3_FUNC_STAT(_stat_item) \ { \ .name = #_stat_item, \ .offset = offsetof(struct hinic3_vport_stats, _stat_item), \ } + +static struct hinic3_xstats_name_off hinic3_cir_drop_stats_strings[] = { + HINIC3_CIR_DROP_STAT(rx_discard_phy), +}; + +#define HINIC3_CIR_DROP_XSTATS_NUM RTE_DIM(hinic3_cir_drop_stats_strings) + static const struct hinic3_xstats_name_off hinic3_vport_stats_strings[] = { HINIC3_FUNC_STAT(tx_unicast_pkts_vport), HINIC3_FUNC_STAT(tx_unicast_bytes_vport), @@ -105,6 +118,8 @@ static const struct hinic3_xstats_name_off hinic3_vport_stats_strings[] = { HINIC3_FUNC_STAT(rx_discard_vport), HINIC3_FUNC_STAT(tx_err_vport), HINIC3_FUNC_STAT(rx_err_vport), + HINIC3_FUNC_STAT(rx_mtu_err_vport), + HINIC3_FUNC_STAT(rx_out_of_buffer), }; #define HINIC3_VPORT_XSTATS_NUM RTE_DIM(hinic3_vport_stats_strings) @@ -285,11 +300,13 @@ static uint32_t hinic3_xstats_calc_num(struct hinic3_nic_dev *nic_dev) { if (HINIC3_IS_VF(nic_dev->hwdev)) { - return (HINIC3_VPORT_XSTATS_NUM + + return (HINIC3_VPORT_XSTATS_NUM + HINIC3_PHYPORT_XSTATS_NUM + + HINIC3_CIR_DROP_XSTATS_NUM + HINIC3_RXQ_XSTATS_NUM * nic_dev->num_rqs + HINIC3_TXQ_XSTATS_NUM * nic_dev->num_sqs); } else { return (HINIC3_VPORT_XSTATS_NUM + HINIC3_PHYPORT_XSTATS_NUM + + HINIC3_CIR_DROP_XSTATS_NUM + HINIC3_RXQ_XSTATS_NUM * nic_dev->num_rqs + HINIC3_TXQ_XSTATS_NUM * nic_dev->num_sqs); } @@ -1250,7 +1267,14 @@ hinic3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qid, uint16_t nb_desc, txq->wqebb_size = (uint16_t)RTE_BIT32(txq->wqebb_shift); txq->tx_free_thresh = tx_free_thresh; txq->owner = 1; - txq->cos = nic_dev->default_cos; + + if (!ODD_NUMBER_QUEUE_ID(qid) && + hinic3_cmd_vf_lag(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev), + HINIC3_CMD_OPCODE_GET) == 1) + txq->cos = SELECT_OTHER_COS_ID(nic_dev->default_cos); + else + txq->cos = nic_dev->default_cos; + txq->tx_deferred_start = tx_conf->tx_deferred_start; txq->tx_wqe_compact_task = HINIC3_SUPPORT_TX_WQE_COMPACT_TASK(nic_dev); @@ -2850,6 +2874,35 @@ hinic3_dev_stats_reset(struct rte_eth_dev *dev) return 0; } +static uint16_t +get_port_cir_drop(struct hinic3_nic_dev *nic_dev, + struct rte_eth_xstat *xstats) +{ + struct hinic3_cir_drop port_stats; + uint16_t i; + int err = 0; + + memset(&port_stats, 0, sizeof(port_stats)); + + err = hinic3_get_cir_drop(nic_dev->hwdev, &port_stats); + if (err) { + PMD_DRV_LOG(ERR, "Failed to get CPB cir drops from fw."); + + for (i = 0; i < RTE_DIM(hinic3_cir_drop_stats_strings); i++) + xstats[i].value = 0; + + return RTE_DIM(hinic3_cir_drop_stats_strings); + } + + for (i = 0; i < RTE_DIM(hinic3_cir_drop_stats_strings); i++) { + memcpy(&xstats[i].value, + (const char *)&port_stats + hinic3_cir_drop_stats_strings[i].offset, + sizeof(uint64_t)); + } + + return RTE_DIM(hinic3_cir_drop_stats_strings); +} + /** * Get device extended statistics. * @@ -2938,6 +2991,9 @@ hinic3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, count++; } + /* Get stats from cir drop stats structure */ + count += get_port_cir_drop(nic_dev, &xstats[count]); + if (HINIC3_IS_VF(nic_dev->hwdev)) return count; @@ -3038,6 +3094,14 @@ hinic3_dev_xstats_get_names(struct rte_eth_dev *dev, count++; } + /* Get cir drop stats name. */ + for (i = 0; i < HINIC3_CIR_DROP_XSTATS_NUM; i++) { + strlcpy(xstats_names[count].name, + hinic3_cir_drop_stats_strings[i].name, + sizeof(xstats_names[count].name)); + count++; + } + if (HINIC3_IS_VF(nic_dev->hwdev)) return count; diff --git a/drivers/net/hinic3/hinic3_ethdev.h b/drivers/net/hinic3/hinic3_ethdev.h index 9061e2b217..6e21672a4d 100644 --- a/drivers/net/hinic3/hinic3_ethdev.h +++ b/drivers/net/hinic3/hinic3_ethdev.h @@ -155,6 +155,9 @@ struct hinic3_nic_dev { }; +#define SELECT_OTHER_COS_ID(cos_id) ((cos_id) ^ 4) +#define ODD_NUMBER_QUEUE_ID(q_id) ((q_id) & 1) + extern const struct rte_flow_ops hinic3_flow_ops; /** -- 2.33.0

