From: Feifei Wang <[email protected]> For new SPx NIC, the way flow rules created is different from previous SPx NIC, so use different callback func to split them.
Signed-off-by: Feifei Wang <[email protected]> --- drivers/net/hinic3/base/hinic3_nic_cfg.c | 55 +- drivers/net/hinic3/base/hinic3_nic_cfg.h | 19 +- drivers/net/hinic3/hinic3_ethdev.c | 41 +- drivers/net/hinic3/hinic3_fdir.c | 657 +++++++++++++----- drivers/net/hinic3/hinic3_fdir.h | 361 ++++++++-- drivers/net/hinic3/hinic3_nic_io.h | 16 - drivers/net/hinic3/hinic3_rx.c | 26 +- drivers/net/hinic3/hinic3_tx.c | 16 +- .../net/hinic3/htn_adapt/hinic3_htn_cmdq.h | 8 + drivers/net/hinic3/meson.build | 8 +- .../net/hinic3/stn_adapt/hinic3_stn_cmdq.c | 2 +- .../net/hinic3/stn_adapt/hinic3_stn_cmdq.h | 8 + 12 files changed, 877 insertions(+), 340 deletions(-) diff --git a/drivers/net/hinic3/base/hinic3_nic_cfg.c b/drivers/net/hinic3/base/hinic3_nic_cfg.c index 22caac0457..5387626b98 100644 --- a/drivers/net/hinic3/base/hinic3_nic_cfg.c +++ b/drivers/net/hinic3/base/hinic3_nic_cfg.c @@ -970,7 +970,7 @@ hinic3_set_vlan_filter(struct hinic3_hwdev *hwdev, uint32_t vlan_filter_ctrl) static int hinic3_set_rx_lro(struct hinic3_hwdev *hwdev, uint8_t ipv4_en, - uint8_t ipv6_en, uint8_t lro_max_pkt_len) + uint8_t ipv6_en, uint8_t lro_max_pkt_len) { struct hinic3_cmd_lro_config lro_cfg = {0}; uint16_t out_size = sizeof(lro_cfg); @@ -1029,7 +1029,7 @@ hinic3_set_rx_lro_timer(struct hinic3_hwdev *hwdev, uint32_t timer_value) } int -hinic3_set_rx_lro_state(struct hinic3_hwdev *hwdev, uint8_t lro_en, uint32_t lro_timer, +hinic3_set_rx_lro_state(struct hinic3_hwdev *hwdev, bool lro_en, uint32_t lro_timer, uint32_t lro_max_pkt_len) { uint8_t ipv4_en = 0, ipv6_en = 0; @@ -1468,54 +1468,6 @@ hinic3_vf_get_default_cos(struct hinic3_hwdev *hwdev, uint8_t *cos_id) return 0; } -/** - * Set the Ethernet type filtering rule for the FDIR of a NIC. - * - * @param[in] hwdev - * Pointer to hardware device structure. - * @param[in] pkt_type - * Indicate the packet type. - * @param[in] queue_id - * Indicate the queue id. - * @param[in] en - * Indicate whether to add or delete an operation. 1 - add; 0 - delete. - * - * @return - * 0 on success, non-zero on failure. - */ -int -hinic3_set_fdir_ethertype_filter(struct hinic3_hwdev *hwdev, - uint8_t pkt_type, uint16_t queue_id, uint8_t en) -{ - struct hinic3_set_fdir_ethertype_rule ethertype_cmd; - uint16_t out_size = sizeof(ethertype_cmd); - int err; - - if (!hwdev) - return -EINVAL; - - memset(ðertype_cmd, 0, - sizeof(struct hinic3_set_fdir_ethertype_rule)); - ethertype_cmd.func_id = hinic3_global_func_id(hwdev); - ethertype_cmd.pkt_type = pkt_type; - ethertype_cmd.pkt_type_en = en; - ethertype_cmd.qid = (uint8_t)queue_id; - - err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_L2NIC, - HINIC3_NIC_CMD_SET_FDIR_STATUS, - ðertype_cmd, sizeof(ethertype_cmd), - ðertype_cmd, &out_size); - if (err || ethertype_cmd.head.status || !out_size) { - PMD_DRV_LOG(ERR, - "set fdir ethertype rule failed, err: %d, status: 0x%x, out size: 0x%x, func_id %d", - err, ethertype_cmd.head.status, out_size, - ethertype_cmd.func_id); - return -EIO; - } - - return 0; -} - int hinic3_add_tcam_rule(struct hinic3_hwdev *hwdev, struct hinic3_tcam_cfg_rule *tcam_rule, uint8_t tcam_rule_type) @@ -1543,8 +1495,7 @@ hinic3_add_tcam_rule(struct hinic3_hwdev *hwdev, struct hinic3_tcam_cfg_rule *tc &tcam_cmd, sizeof(tcam_cmd), &tcam_cmd, &out_size); if (err || tcam_cmd.msg_head.status || !out_size) { - PMD_DRV_LOG(ERR, - "Add tcam rule failed, err: %d, status: 0x%x, out size: 0x%x", + PMD_DRV_LOG(ERR, "Add tcam rule failed, err: %d, status: 0x%x, out size: 0x%x", err, tcam_cmd.msg_head.status, out_size); return -EIO; } diff --git a/drivers/net/hinic3/base/hinic3_nic_cfg.h b/drivers/net/hinic3/base/hinic3_nic_cfg.h index 06d5bc7d1b..6d3eb433bd 100644 --- a/drivers/net/hinic3/base/hinic3_nic_cfg.h +++ b/drivers/net/hinic3/base/hinic3_nic_cfg.h @@ -1203,7 +1203,7 @@ int hinic3_set_rx_vlan_offload(struct hinic3_hwdev *hwdev, uint8_t en); * @return * 0 on success, non-zero on failure. */ -int hinic3_set_rx_lro_state(struct hinic3_hwdev *hwdev, uint8_t lro_en, uint32_t lro_timer, +int hinic3_set_rx_lro_state(struct hinic3_hwdev *hwdev, bool lro_en, uint32_t lro_timer, uint32_t lro_max_pkt_len); /** @@ -1522,8 +1522,21 @@ int hinic3_get_feature_from_hw(struct hinic3_hwdev *hwdev, uint64_t *s_feature, */ int hinic3_set_feature_to_hw(struct hinic3_hwdev *hwdev, uint64_t *s_feature, uint16_t size); -int hinic3_set_fdir_ethertype_filter(struct hinic3_hwdev *hwdev, - uint8_t pkt_type, uint16_t queue_id, uint8_t en); +/** + * Set the Ethernet type filtering rule for the FDIR of a NIC. + * + * @param[in] hwdev + * Pointer to hardware device structure. + * @param[in] pkt_type + * Indicate the packet type. + * @param[in] ethertype_filter + * Pointer to ethertype_filter structure. + * @param[in] en + * Indicate whether to add or delete an operation. 1 - add; 0 - delete. + * + * @return + * 0 on success, non-zero on failure. + */ int hinic3_set_link_status_follow(struct hinic3_hwdev *hwdev, enum hinic3_link_follow_status status); diff --git a/drivers/net/hinic3/hinic3_ethdev.c b/drivers/net/hinic3/hinic3_ethdev.c index 1010773ac1..adeae07f27 100644 --- a/drivers/net/hinic3/hinic3_ethdev.c +++ b/drivers/net/hinic3/hinic3_ethdev.c @@ -975,8 +975,8 @@ hinic3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qid, uint16_t nb_desc, "RX queue depth is out of range from %d to %d", HINIC3_MIN_QUEUE_DEPTH, HINIC3_MAX_QUEUE_DEPTH); PMD_DRV_LOG(ERR, - "nb_desc: %d, q_depth: %d, port: %d queue: %d", - nb_desc, rq_depth, dev->data->port_id, qid); + "nb_desc: %d, q_depth: %d, port: %d queue: %d", + nb_desc, rq_depth, dev->data->port_id, qid); return -EINVAL; } @@ -2158,8 +2158,7 @@ hinic3_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) } /* Update max frame size. */ - HINIC3_MAX_RX_PKT_LEN(dev->data->dev_conf.rxmode) = - HINIC3_MTU_TO_PKTLEN(mtu); + HINIC3_MAX_RX_PKT_LEN(dev->data->dev_conf.rxmode) = HINIC3_MTU_TO_PKTLEN(mtu); nic_dev->mtu_size = mtu; return err; } @@ -2357,6 +2356,12 @@ hinic3_dev_promiscuous_enable(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); @@ -2527,20 +2532,22 @@ hinic3_rss_hash_update(struct rte_eth_dev *dev, } rss_type.ipv4 = (rss_hf & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 | - RTE_ETH_RSS_NONFRAG_IPV4_OTHER)) - ? 1 - : 0; + RTE_ETH_RSS_NONFRAG_IPV4_OTHER)) ? 1 : 0; rss_type.tcp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ? 1 : 0; rss_type.ipv6 = (rss_hf & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | - RTE_ETH_RSS_NONFRAG_IPV6_OTHER)) - ? 1 - : 0; - rss_type.ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_EX) ? 1 : 0; + RTE_ETH_RSS_NONFRAG_IPV6_OTHER)) ? 1 : 0; rss_type.tcp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ? 1 : 0; - rss_type.tcp_ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) ? 1 : 0; rss_type.udp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ? 1 : 0; rss_type.udp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ? 1 : 0; + if (nic_dev->feature_cap & NIC_F_HTN_CMDQ) { + rss_type.ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_EX) ? 1 : 0; + rss_type.tcp_ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) ? 1 : 0; + } else { + rss_type.ipv6_ext = 0; + rss_type.tcp_ipv6_ext = 0; + } + err = hinic3_set_rss_type(nic_dev->hwdev, rss_type); if (err) PMD_DRV_LOG(ERR, "Set RSS type failed"); @@ -2597,12 +2604,16 @@ hinic3_rss_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) rss_conf->rss_hf |= rss_type.ipv6 ? (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_OTHER) : 0; - rss_conf->rss_hf |= rss_type.ipv6_ext ? RTE_ETH_RSS_IPV6_EX : 0; rss_conf->rss_hf |= rss_type.tcp_ipv6 ? RTE_ETH_RSS_NONFRAG_IPV6_TCP : 0; - rss_conf->rss_hf |= rss_type.tcp_ipv6_ext ? RTE_ETH_RSS_IPV6_TCP_EX : 0; rss_conf->rss_hf |= rss_type.udp_ipv4 ? RTE_ETH_RSS_NONFRAG_IPV4_UDP : 0; rss_conf->rss_hf |= rss_type.udp_ipv6 ? RTE_ETH_RSS_NONFRAG_IPV6_UDP : 0; - + if (nic_dev->feature_cap & NIC_F_HTN_CMDQ) { + rss_conf->rss_hf |= rss_type.ipv6_ext ? RTE_ETH_RSS_IPV6_EX : 0; + rss_conf->rss_hf |= rss_type.tcp_ipv6_ext ? RTE_ETH_RSS_IPV6_TCP_EX : 0; + } else { + rss_conf->rss_hf |= 0; + rss_conf->rss_hf |= 0; + } return 0; } diff --git a/drivers/net/hinic3/hinic3_fdir.c b/drivers/net/hinic3/hinic3_fdir.c index 263a281729..37a4f0cf52 100644 --- a/drivers/net/hinic3/hinic3_fdir.c +++ b/drivers/net/hinic3/hinic3_fdir.c @@ -2,15 +2,15 @@ * Copyright(c) 2025 Huawei Technologies Co., Ltd */ +#include "base/hinic3_cmd.h" #include "base/hinic3_compat.h" #include "base/hinic3_hwdev.h" #include "base/hinic3_hwif.h" #include "base/hinic3_nic_cfg.h" #include "hinic3_ethdev.h" +#include "hinic3_nic_io.h" -#define HINIC3_UINT1_MAX 0x1 -#define HINIC3_UINT4_MAX 0xf -#define HINIC3_UINT15_MAX 0x7fff +#define HINIC3_INVALID_INDEX -1 #define HINIC3_DEV_PRIVATE_TO_TCAM_INFO(nic_dev) \ (&((struct hinic3_nic_dev *)(nic_dev))->tcam) @@ -77,6 +77,8 @@ hinic3_fdir_tcam_ipv4_init(struct hinic3_fdir_filter *rule, /* Fill type of ip. */ tcam_key->key_mask.ip_type = HINIC3_UINT1_MAX; tcam_key->key_info.ip_type = HINIC3_FDIR_IP_TYPE_IPV4; + tcam_key->key_mask.vlan_flag = HINIC3_UINT1_MAX; + tcam_key->key_info.vlan_flag = 0; /* Fill src IPv4. */ tcam_key->key_mask.sipv4_h = @@ -99,15 +101,9 @@ hinic3_fdir_tcam_ipv4_init(struct hinic3_fdir_filter *rule, HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv4.dst_ip); } -static void -hinic3_fdir_tcam_ipv6_init(struct hinic3_fdir_filter *rule, - struct hinic3_tcam_key *tcam_key) +static void hinic3_fdir_ipv6_tcam_key_init_sip(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) { - /* Fill type of ip. */ - tcam_key->key_mask_ipv6.ip_type = HINIC3_UINT1_MAX; - tcam_key->key_info_ipv6.ip_type = HINIC3_FDIR_IP_TYPE_IPV6; - - /* Fill src IPv6. */ tcam_key->key_mask_ipv6.sipv6_key0 = HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0]); tcam_key->key_mask_ipv6.sipv6_key1 = @@ -140,8 +136,11 @@ hinic3_fdir_tcam_ipv6_init(struct hinic3_fdir_filter *rule, HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0x3]); tcam_key->key_info_ipv6.sipv6_key7 = HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x3]); +} - /* Fill dst IPv6. */ +static void hinic3_fdir_ipv6_tcam_key_init_dip(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ tcam_key->key_mask_ipv6.dipv6_key0 = HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0]); tcam_key->key_mask_ipv6.dipv6_key1 = @@ -176,6 +175,26 @@ hinic3_fdir_tcam_ipv6_init(struct hinic3_fdir_filter *rule, HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x3]); } +static void hinic3_fdir_ipv6_tcam_key_init(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ + hinic3_fdir_ipv6_tcam_key_init_sip(rule, tcam_key); + hinic3_fdir_ipv6_tcam_key_init_dip(rule, tcam_key); +} + +static void +hinic3_fdir_tcam_ipv6_init(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ + /* Fill type of ip. */ + tcam_key->key_mask_ipv6.ip_type = HINIC3_UINT1_MAX; + tcam_key->key_info_ipv6.ip_type = HINIC3_FDIR_IP_TYPE_IPV6; + tcam_key->key_mask_ipv6.vlan_flag = HINIC3_UINT1_MAX; + tcam_key->key_info_ipv6.vlan_flag = 0; + + hinic3_fdir_ipv6_tcam_key_init(rule, tcam_key); +} + /** * Set the TCAM information in notunnel scenario. * @@ -204,6 +223,10 @@ hinic3_fdir_tcam_notunnel_init(struct rte_eth_dev *dev, tcam_key->key_info.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_NORMAL; tcam_key->key_mask.function_id = HINIC3_UINT15_MAX; + + tcam_key->key_mask.vlan_flag = 1; + tcam_key->key_info.vlan_flag = 0; + tcam_key->key_info.function_id = hinic3_global_func_id(nic_dev->hwdev) & HINIC3_UINT15_MAX; @@ -223,6 +246,8 @@ hinic3_fdir_tcam_vxlan_ipv4_init(struct hinic3_fdir_filter *rule, /* Fill type of ip. */ tcam_key->key_mask.ip_type = HINIC3_UINT1_MAX; tcam_key->key_info.ip_type = HINIC3_FDIR_IP_TYPE_IPV4; + tcam_key->key_mask.vlan_flag = HINIC3_UINT1_MAX; + tcam_key->key_info.vlan_flag = 0; /* Fill src ipv4. */ tcam_key->key_mask.sipv4_h = @@ -252,6 +277,8 @@ hinic3_fdir_tcam_vxlan_ipv6_init(struct hinic3_fdir_filter *rule, /* Fill type of ip. */ tcam_key->key_mask_vxlan_ipv6.ip_type = HINIC3_UINT1_MAX; tcam_key->key_info_vxlan_ipv6.ip_type = HINIC3_FDIR_IP_TYPE_IPV6; + tcam_key->key_mask_vxlan_ipv6.vlan_flag = HINIC3_UINT1_MAX; + tcam_key->key_info_vxlan_ipv6.vlan_flag = 0; /* Use inner dst ipv6 to fill the dst ipv6 of tcam_key. */ tcam_key->key_mask_vxlan_ipv6.dipv6_key0 = @@ -288,77 +315,6 @@ hinic3_fdir_tcam_vxlan_ipv6_init(struct hinic3_fdir_filter *rule, HINIC3_32_LOWER_16_BITS(rule->key_spec.inner_ipv6.dst_ip[0x3]); } -static void -hinic3_fdir_tcam_outer_ipv6_init(struct hinic3_fdir_filter *rule, - struct hinic3_tcam_key *tcam_key) -{ - tcam_key->key_mask_ipv6.sipv6_key0 = - HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0]); - tcam_key->key_mask_ipv6.sipv6_key1 = - HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0]); - tcam_key->key_mask_ipv6.sipv6_key2 = - HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0x1]); - tcam_key->key_mask_ipv6.sipv6_key3 = - HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0x1]); - tcam_key->key_mask_ipv6.sipv6_key4 = - HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0x2]); - tcam_key->key_mask_ipv6.sipv6_key5 = - HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0x2]); - tcam_key->key_mask_ipv6.sipv6_key6 = - HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0x3]); - tcam_key->key_mask_ipv6.sipv6_key7 = - HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0x3]); - tcam_key->key_info_ipv6.sipv6_key0 = - HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0]); - tcam_key->key_info_ipv6.sipv6_key1 = - HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0]); - tcam_key->key_info_ipv6.sipv6_key2 = - HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0x1]); - tcam_key->key_info_ipv6.sipv6_key3 = - HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x1]); - tcam_key->key_info_ipv6.sipv6_key4 = - HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0x2]); - tcam_key->key_info_ipv6.sipv6_key5 = - HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x2]); - tcam_key->key_info_ipv6.sipv6_key6 = - HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0x3]); - tcam_key->key_info_ipv6.sipv6_key7 = - HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x3]); - - tcam_key->key_mask_ipv6.dipv6_key0 = - HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0]); - tcam_key->key_mask_ipv6.dipv6_key1 = - HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0]); - tcam_key->key_mask_ipv6.dipv6_key2 = - HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0x1]); - tcam_key->key_mask_ipv6.dipv6_key3 = - HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0x1]); - tcam_key->key_mask_ipv6.dipv6_key4 = - HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0x2]); - tcam_key->key_mask_ipv6.dipv6_key5 = - HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0x2]); - tcam_key->key_mask_ipv6.dipv6_key6 = - HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0x3]); - tcam_key->key_mask_ipv6.dipv6_key7 = - HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0x3]); - tcam_key->key_info_ipv6.dipv6_key0 = - HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0]); - tcam_key->key_info_ipv6.dipv6_key1 = - HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0]); - tcam_key->key_info_ipv6.dipv6_key2 = - HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0x1]); - tcam_key->key_info_ipv6.dipv6_key3 = - HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x1]); - tcam_key->key_info_ipv6.dipv6_key4 = - HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0x2]); - tcam_key->key_info_ipv6.dipv6_key5 = - HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x2]); - tcam_key->key_info_ipv6.dipv6_key6 = - HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0x3]); - tcam_key->key_info_ipv6.dipv6_key7 = - HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x3]); -} - static void hinic3_fdir_tcam_ipv6_vxlan_init(struct rte_eth_dev *dev, struct hinic3_fdir_filter *rule, @@ -370,11 +326,14 @@ hinic3_fdir_tcam_ipv6_vxlan_init(struct rte_eth_dev *dev, tcam_key->key_info_ipv6.ip_proto = rule->key_spec.proto; tcam_key->key_mask_ipv6.tunnel_type = HINIC3_UINT4_MAX; - tcam_key->key_info_ipv6.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_VXLAN; + tcam_key->key_info_ipv6.tunnel_type = rule->tunnel_type; tcam_key->key_mask_ipv6.outer_ip_type = HINIC3_UINT1_MAX; tcam_key->key_info_ipv6.outer_ip_type = HINIC3_FDIR_IP_TYPE_IPV6; + tcam_key->key_mask_ipv6.vlan_flag = HINIC3_UINT1_MAX; + tcam_key->key_info_ipv6.vlan_flag = 0; + tcam_key->key_mask_ipv6.function_id = HINIC3_UINT15_MAX; tcam_key->key_info_ipv6.function_id = hinic3_global_func_id(nic_dev->hwdev) & HINIC3_UINT15_MAX; @@ -386,7 +345,7 @@ hinic3_fdir_tcam_ipv6_vxlan_init(struct rte_eth_dev *dev, tcam_key->key_info_ipv6.sport = rule->key_spec.src_port; if (rule->ip_type == HINIC3_FDIR_IP_TYPE_ANY) - hinic3_fdir_tcam_outer_ipv6_init(rule, tcam_key); + hinic3_fdir_ipv6_tcam_key_init(rule, tcam_key); } /** @@ -448,9 +407,11 @@ hinic3_fdir_tcam_vxlan_init(struct rte_eth_dev *dev, HINIC3_32_LOWER_16_BITS(rule->key_spec.tunnel.tunnel_id); tcam_key->key_mask.tunnel_type = HINIC3_UINT4_MAX; - tcam_key->key_info.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_VXLAN; + tcam_key->key_info.tunnel_type = rule->tunnel_type; + tcam_key->key_mask.vlan_flag = 1; tcam_key->key_mask.function_id = HINIC3_UINT15_MAX; + tcam_key->key_info.vlan_flag = 0; tcam_key->key_info.function_id = hinic3_global_func_id(nic_dev->hwdev) & HINIC3_UINT15_MAX; @@ -479,6 +440,259 @@ hinic3_fdir_tcam_info_init(struct rte_eth_dev *dev, tcam_key_calculate(tcam_key, fdir_tcam_rule); } +static void +hinic3_fdir_tcam_key_set_ipv4_sip_dip(struct rte_eth_ipv4_flow *ipv4_mask, + struct rte_eth_ipv4_flow *ipv4_spec, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_htn.sipv4_h = + HINIC3_32_UPPER_16_BITS(ipv4_mask->src_ip); + tcam_key->key_mask_htn.sipv4_l = + HINIC3_32_LOWER_16_BITS(ipv4_mask->src_ip); + tcam_key->key_info_htn.sipv4_h = + HINIC3_32_UPPER_16_BITS(ipv4_spec->src_ip); + tcam_key->key_info_htn.sipv4_l = + HINIC3_32_LOWER_16_BITS(ipv4_spec->src_ip); + + tcam_key->key_mask_htn.dipv4_h = + HINIC3_32_UPPER_16_BITS(ipv4_mask->dst_ip); + tcam_key->key_mask_htn.dipv4_l = + HINIC3_32_LOWER_16_BITS(ipv4_mask->dst_ip); + tcam_key->key_info_htn.dipv4_h = + HINIC3_32_UPPER_16_BITS(ipv4_spec->dst_ip); + tcam_key->key_info_htn.dipv4_l = + HINIC3_32_LOWER_16_BITS(ipv4_spec->dst_ip); +} + +static void +hinic3_fdir_tcam_key_set_ipv6_sip(struct rte_eth_ipv6_flow *ipv6_mask, + struct rte_eth_ipv6_flow *ipv6_spec, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_ipv6_htn.sipv6_key0 = + HINIC3_32_UPPER_16_BITS(ipv6_mask->src_ip[0]); + tcam_key->key_mask_ipv6_htn.sipv6_key1 = + HINIC3_32_LOWER_16_BITS(ipv6_mask->src_ip[0]); + tcam_key->key_mask_ipv6_htn.sipv6_key2 = + HINIC3_32_UPPER_16_BITS(ipv6_mask->src_ip[0x1]); + tcam_key->key_mask_ipv6_htn.sipv6_key3 = + HINIC3_32_LOWER_16_BITS(ipv6_mask->src_ip[0x1]); + tcam_key->key_mask_ipv6_htn.sipv6_key4 = + HINIC3_32_UPPER_16_BITS(ipv6_mask->src_ip[0x2]); + tcam_key->key_mask_ipv6_htn.sipv6_key5 = + HINIC3_32_LOWER_16_BITS(ipv6_mask->src_ip[0x2]); + tcam_key->key_mask_ipv6_htn.sipv6_key6 = + HINIC3_32_UPPER_16_BITS(ipv6_mask->src_ip[0x3]); + tcam_key->key_mask_ipv6_htn.sipv6_key7 = + HINIC3_32_LOWER_16_BITS(ipv6_mask->src_ip[0x3]); + tcam_key->key_info_ipv6_htn.sipv6_key0 = + HINIC3_32_UPPER_16_BITS(ipv6_spec->src_ip[0]); + tcam_key->key_info_ipv6_htn.sipv6_key1 = + HINIC3_32_LOWER_16_BITS(ipv6_spec->src_ip[0]); + tcam_key->key_info_ipv6_htn.sipv6_key2 = + HINIC3_32_UPPER_16_BITS(ipv6_spec->src_ip[0x1]); + tcam_key->key_info_ipv6_htn.sipv6_key3 = + HINIC3_32_LOWER_16_BITS(ipv6_spec->src_ip[0x1]); + tcam_key->key_info_ipv6_htn.sipv6_key4 = + HINIC3_32_UPPER_16_BITS(ipv6_spec->src_ip[0x2]); + tcam_key->key_info_ipv6_htn.sipv6_key5 = + HINIC3_32_LOWER_16_BITS(ipv6_spec->src_ip[0x2]); + tcam_key->key_info_ipv6_htn.sipv6_key6 = + HINIC3_32_UPPER_16_BITS(ipv6_spec->src_ip[0x3]); + tcam_key->key_info_ipv6_htn.sipv6_key7 = + HINIC3_32_LOWER_16_BITS(ipv6_spec->src_ip[0x3]); +} + +static void +hinic3_fdir_tcam_key_set_ipv6_dip(struct rte_eth_ipv6_flow *ipv6_mask, + struct rte_eth_ipv6_flow *ipv6_spec, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_ipv6_htn.dipv6_key0 = + HINIC3_32_UPPER_16_BITS(ipv6_mask->dst_ip[0]); + tcam_key->key_mask_ipv6_htn.dipv6_key1 = + HINIC3_32_LOWER_16_BITS(ipv6_mask->dst_ip[0]); + tcam_key->key_mask_ipv6_htn.dipv6_key2 = + HINIC3_32_UPPER_16_BITS(ipv6_mask->dst_ip[0x1]); + tcam_key->key_mask_ipv6_htn.dipv6_key3 = + HINIC3_32_LOWER_16_BITS(ipv6_mask->dst_ip[0x1]); + tcam_key->key_mask_ipv6_htn.dipv6_key4 = + HINIC3_32_UPPER_16_BITS(ipv6_mask->dst_ip[0x2]); + tcam_key->key_mask_ipv6_htn.dipv6_key5 = + HINIC3_32_LOWER_16_BITS(ipv6_mask->dst_ip[0x2]); + tcam_key->key_mask_ipv6_htn.dipv6_key6 = + HINIC3_32_UPPER_16_BITS(ipv6_mask->dst_ip[0x3]); + tcam_key->key_mask_ipv6_htn.dipv6_key7 = + HINIC3_32_LOWER_16_BITS(ipv6_mask->dst_ip[0x3]); + tcam_key->key_info_ipv6_htn.dipv6_key0 = + HINIC3_32_UPPER_16_BITS(ipv6_spec->dst_ip[0]); + tcam_key->key_info_ipv6_htn.dipv6_key1 = + HINIC3_32_LOWER_16_BITS(ipv6_spec->dst_ip[0]); + tcam_key->key_info_ipv6_htn.dipv6_key2 = + HINIC3_32_UPPER_16_BITS(ipv6_spec->dst_ip[0x1]); + tcam_key->key_info_ipv6_htn.dipv6_key3 = + HINIC3_32_LOWER_16_BITS(ipv6_spec->dst_ip[0x1]); + tcam_key->key_info_ipv6_htn.dipv6_key4 = + HINIC3_32_UPPER_16_BITS(ipv6_spec->dst_ip[0x2]); + tcam_key->key_info_ipv6_htn.dipv6_key5 = + HINIC3_32_LOWER_16_BITS(ipv6_spec->dst_ip[0x2]); + tcam_key->key_info_ipv6_htn.dipv6_key6 = + HINIC3_32_UPPER_16_BITS(ipv6_spec->dst_ip[0x3]); + tcam_key->key_info_ipv6_htn.dipv6_key7 = + HINIC3_32_LOWER_16_BITS(ipv6_spec->dst_ip[0x3]); +} + +static void +hinic3_fdir_tcam_key_set_outer_ipv4_sip_dip(struct rte_eth_ipv4_flow *ipv4_mask, + struct rte_eth_ipv4_flow *ipv4_spec, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_htn.outer_sipv4_h = + HINIC3_32_UPPER_16_BITS(ipv4_mask->src_ip); + tcam_key->key_mask_htn.outer_sipv4_l = + HINIC3_32_LOWER_16_BITS(ipv4_mask->src_ip); + tcam_key->key_info_htn.outer_sipv4_h = + HINIC3_32_UPPER_16_BITS(ipv4_spec->src_ip); + tcam_key->key_info_htn.outer_sipv4_l = + HINIC3_32_LOWER_16_BITS(ipv4_spec->src_ip); + + tcam_key->key_mask_htn.outer_dipv4_h = + HINIC3_32_UPPER_16_BITS(ipv4_mask->dst_ip); + tcam_key->key_mask_htn.outer_dipv4_l = + HINIC3_32_LOWER_16_BITS(ipv4_mask->dst_ip); + tcam_key->key_info_htn.outer_dipv4_h = + HINIC3_32_UPPER_16_BITS(ipv4_spec->dst_ip); + tcam_key->key_info_htn.outer_dipv4_l = + HINIC3_32_LOWER_16_BITS(ipv4_spec->dst_ip); +} + +static void +hinic3_fdir_tcam_key_set_ipv4_info(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_htn.ip_type = HINIC3_UINT2_MAX; + tcam_key->key_info_htn.ip_type = HINIC3_FDIR_IP_TYPE_IPV4; + + hinic3_fdir_tcam_key_set_ipv4_sip_dip(&rule->key_mask.ipv4, + &rule->key_spec.ipv4, tcam_key); +} + +static void hinic3_fdir_tcam_key_set_ipv6_info(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_ipv6_htn.ip_type = HINIC3_UINT2_MAX; + tcam_key->key_info_ipv6_htn.ip_type = HINIC3_FDIR_IP_TYPE_IPV6; + + hinic3_fdir_tcam_key_set_ipv6_sip(&rule->key_mask.ipv6, + &rule->key_spec.ipv6, tcam_key); + hinic3_fdir_tcam_key_set_ipv6_dip(&rule->key_mask.ipv6, + &rule->key_spec.ipv6, tcam_key); +} + +static void +hinic3_fdir_tcam_notunnel_htn_init(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_htn.tunnel_type = HINIC3_UINT3_MAX; + tcam_key->key_info_htn.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_NORMAL; + + if (rule->ip_type == HINIC3_FDIR_IP_TYPE_IPV4) + hinic3_fdir_tcam_key_set_ipv4_info(rule, tcam_key); + else if (rule->ip_type == HINIC3_FDIR_IP_TYPE_IPV6) + hinic3_fdir_tcam_key_set_ipv6_info(rule, tcam_key); +} + +static void +hinic3_fdir_tcam_key_set_outer_ipv4_info(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_ipv6_htn.outer_ip_type = HINIC3_UINT1_MAX; + tcam_key->key_info_ipv6_htn.outer_ip_type = HINIC3_FDIR_IP_TYPE_IPV4; + + hinic3_fdir_tcam_key_set_outer_ipv4_sip_dip(&rule->key_mask.ipv4, + &rule->key_spec.ipv4, tcam_key); +} + +static void +hinic3_fdir_tcam_key_set_inner_ipv4_info(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_htn.ip_type = HINIC3_UINT2_MAX; + tcam_key->key_info_htn.ip_type = HINIC3_FDIR_IP_TYPE_IPV4; + + hinic3_fdir_tcam_key_set_ipv4_sip_dip(&rule->key_mask.inner_ipv4, + &rule->key_spec.inner_ipv4, tcam_key); +} + +static void +hinic3_fdir_tcam_key_set_inner_ipv6_info(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_vxlan_ipv6_htn.ip_type = HINIC3_UINT2_MAX; + tcam_key->key_info_vxlan_ipv6_htn.ip_type = HINIC3_FDIR_IP_TYPE_IPV6; + + hinic3_fdir_tcam_key_set_ipv6_dip(&rule->key_mask.inner_ipv6, + &rule->key_spec.inner_ipv6, tcam_key); +} + +static void +hinic3_fdir_tcam_tunnel_htn_init(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ + tcam_key->key_mask_htn.tunnel_type = HINIC3_UINT3_MAX; + tcam_key->key_info_htn.tunnel_type = rule->tunnel_type; + + tcam_key->key_mask_htn.vni_h = + HINIC3_32_UPPER_16_BITS(rule->key_mask.tunnel.tunnel_id); + tcam_key->key_mask_htn.vni_l = + HINIC3_32_LOWER_16_BITS(rule->key_mask.tunnel.tunnel_id); + tcam_key->key_info_htn.vni_h = + HINIC3_32_UPPER_16_BITS(rule->key_spec.tunnel.tunnel_id); + tcam_key->key_info_htn.vni_l = + HINIC3_32_LOWER_16_BITS(rule->key_spec.tunnel.tunnel_id); + + if (rule->outer_ip_type == HINIC3_FDIR_IP_TYPE_IPV4) + hinic3_fdir_tcam_key_set_outer_ipv4_info(rule, tcam_key); + + if (rule->ip_type == HINIC3_FDIR_IP_TYPE_IPV4) + hinic3_fdir_tcam_key_set_inner_ipv4_info(rule, tcam_key); + else if (rule->ip_type == HINIC3_FDIR_IP_TYPE_IPV6) + hinic3_fdir_tcam_key_set_inner_ipv6_info(rule, tcam_key); +} + +static void +hinic3_fdir_tcam_info_htn_init(struct rte_eth_dev *dev, + struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key, + struct hinic3_tcam_cfg_rule *fdir_tcam_rule) +{ + struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + + tcam_key->key_mask_htn.function_id_h = HINIC3_UINT5_MAX; + tcam_key->key_mask_htn.function_id_l = HINIC3_UINT5_MAX; + tcam_key->key_info_htn.function_id_l = + hinic3_global_func_id(nic_dev->hwdev) & HINIC3_UINT5_MAX; + tcam_key->key_info_htn.function_id_h = + (hinic3_global_func_id(nic_dev->hwdev) >> HINIC3_UINT5_WIDTH) & HINIC3_UINT5_MAX; + + tcam_key->key_mask_htn.ip_proto = rule->key_mask.proto; + tcam_key->key_info_htn.ip_proto = rule->key_spec.proto; + + tcam_key->key_mask_htn.sport = rule->key_mask.src_port; + tcam_key->key_info_htn.sport = rule->key_spec.src_port; + + tcam_key->key_mask_htn.dport = rule->key_mask.dst_port; + tcam_key->key_info_htn.dport = rule->key_spec.dst_port; + if (rule->tunnel_type == HINIC3_FDIR_TUNNEL_MODE_NORMAL) + hinic3_fdir_tcam_notunnel_htn_init(rule, tcam_key); + else + hinic3_fdir_tcam_tunnel_htn_init(rule, tcam_key); + + fdir_tcam_rule->data.qid = rule->rq_index; + + tcam_key_calculate(tcam_key, fdir_tcam_rule); +} + /** * Find filter in given ethertype filter list. * @@ -513,19 +727,30 @@ hinic3_ethertype_filter_lookup(struct hinic3_ethertype_filter_list *ethertype_li * Point to the tcam filter list. * @param[in] key * The tcam key to find. + * @param[in] action_type + * The type of action. + * @param[in] tcam_index + * The index of tcam. * @return * If a matching filter is found, the filter is returned, otherwise NULL. */ static inline struct hinic3_tcam_filter * hinic3_tcam_filter_lookup(struct hinic3_tcam_filter_list *filter_list, - struct hinic3_tcam_key *key) + struct hinic3_tcam_key *key, + uint8_t action_type, uint16_t tcam_index) { struct hinic3_tcam_filter *it; - TAILQ_FOREACH(it, filter_list, entries) { - if (memcmp(key, &it->tcam_key, - sizeof(struct hinic3_tcam_key)) == 0) { - return it; + if (action_type == HINIC3_ACTION_ADD) { + TAILQ_FOREACH(it, filter_list, entries) { + if (memcmp(key, &it->tcam_key, sizeof(struct hinic3_tcam_key)) == 0) + return it; + } + } else { + TAILQ_FOREACH(it, filter_list, entries) { + if (tcam_index == + (it->index + HINIC3_PKT_TCAM_DYNAMIC_INDEX_START(it->dynamic_block_id))) + return it; } } @@ -588,25 +813,18 @@ hinic3_free_dynamic_block_resource(struct hinic3_tcam_info *tcam_info, * * @param[in] dev * Pointer to ethernet device structure. - * @param[in] fdir_tcam_rule - * Indicate the filtering rule to be searched for. * @param[in] tcam_info * Ternary Content-Addressable Memory (TCAM) information. - * @param[in] tcam_filter - * Point to the TCAM filter. * @param[out] tcam_index * Indicate the TCAM index to be searched for. * @result * Pointer to the TCAM dynamic block. If the search fails, NULL is returned. */ static struct hinic3_tcam_dynamic_block * -hinic3_dynamic_lookup_tcam_filter(struct rte_eth_dev *dev, - struct hinic3_tcam_cfg_rule *fdir_tcam_rule, +hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev, struct hinic3_tcam_info *tcam_info, - struct hinic3_tcam_filter *tcam_filter, uint16_t *tcam_index) { - struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); uint16_t block_cnt = tcam_info->tcam_dynamic_info.dynamic_block_cnt; struct hinic3_tcam_dynamic_block *dynamic_block_ptr = NULL; struct hinic3_tcam_dynamic_block *tmp = NULL; @@ -616,6 +834,8 @@ hinic3_dynamic_lookup_tcam_filter(struct rte_eth_dev *dev, uint16_t index; int err; + if ((hinic3_get_driver_feature(nic_dev) & NIC_F_HTN_FDIR) != 0) + rule_nums += nic_dev->ethertype_rule_nums; /* * Check whether the number of filtering rules reaches the maximum * capacity of dynamic TCAM blocks. @@ -662,8 +882,7 @@ hinic3_dynamic_lookup_tcam_filter(struct rte_eth_dev *dev, if (tmp == NULL || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) { - PMD_DRV_LOG(ERR, - "Fdir filter dynamic lookup for index failed!"); + PMD_DRV_LOG(ERR, "Fdir filter dynamic lookup for index failed!"); goto look_up_failed; } @@ -674,20 +893,13 @@ hinic3_dynamic_lookup_tcam_filter(struct rte_eth_dev *dev, /* Find the first free position. */ if (index == HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) { - PMD_DRV_LOG(ERR, - "tcam block 0x%x supports filter rules is full!", + PMD_DRV_LOG(ERR, "tcam block 0x%x supports filter rules is full!", tmp->dynamic_block_id); goto look_up_failed; } - tcam_filter->dynamic_block_id = tmp->dynamic_block_id; - tcam_filter->index = index; *tcam_index = index; - fdir_tcam_rule->index = - HINIC3_PKT_TCAM_DYNAMIC_INDEX_START(tmp->dynamic_block_id) + - index; - return tmp; look_up_failed: @@ -702,6 +914,107 @@ hinic3_dynamic_lookup_tcam_filter(struct rte_eth_dev *dev, return NULL; } +static void +hinic3_tcam_index_free(struct hinic3_nic_dev *nic_dev, uint16_t index, uint16_t block_id) +{ + struct hinic3_tcam_info *tcam_info = HINIC3_DEV_PRIVATE_TO_TCAM_INFO(nic_dev); + struct hinic3_tcam_dynamic_block *tmp = NULL; + + TAILQ_FOREACH(tmp, &tcam_info->tcam_dynamic_info.tcam_dynamic_list, entries) { + if (tmp->dynamic_block_id == block_id) + break; + } + + if (tmp == NULL || tmp->dynamic_block_id != block_id) { + PMD_DRV_LOG(ERR, "Fdir filter del dynamic lookup for block failed!"); + return; + } + + tmp->dynamic_index[index] = 0; + tmp->dynamic_index_cnt--; + if (tmp->dynamic_index_cnt == 0) { + hinic3_free_tcam_block(nic_dev->hwdev, &block_id); + hinic3_free_dynamic_block_resource(tcam_info, tmp); + } +} + +static uint16_t +hinic3_tcam_alloc_index(void *dev, uint16_t *block_id) +{ + struct hinic3_nic_dev *nic_dev = (struct hinic3_nic_dev *)dev; + struct hinic3_tcam_info *tcam_info = HINIC3_DEV_PRIVATE_TO_TCAM_INFO(nic_dev); + struct hinic3_tcam_dynamic_block *tmp = NULL; + uint16_t index = 0; + + tmp = hinic3_dynamic_lookup_tcam_filter(nic_dev, tcam_info, &index); + if (tmp == NULL) { + PMD_DRV_LOG(ERR, "Dynamic lookup tcam filter failed!"); + return HINIC3_TCAM_INVALID_INDEX; + } + + tmp->dynamic_index[index] = 1; + tmp->dynamic_index_cnt++; + + *block_id = tmp->dynamic_block_id; + + return index; +} + +static int +hinic3_set_fdir_ethertype_filter(void *hwdev, uint8_t pkt_type, void *filter, uint8_t en) +{ + struct hinic3_set_fdir_ethertype_rule ethertype_cmd; + struct hinic3_ethertype_filter *ethertype_filter = (struct hinic3_ethertype_filter *)filter; + uint16_t out_size = sizeof(ethertype_cmd); + uint16_t block_id; + uint32_t index = 0; + int err; + + if (!hwdev) + return -EINVAL; + struct hinic3_nic_dev *nic_dev = + (struct hinic3_nic_dev *)((struct hinic3_hwdev *)hwdev)->dev_handle; + + if ((hinic3_get_driver_feature(nic_dev) & NIC_F_HTN_FDIR) != 0) { + if (en != 0) { + index = hinic3_tcam_alloc_index(nic_dev, &block_id); + if (index == HINIC3_TCAM_INVALID_INDEX) + return -ENOMEM; + index += HINIC3_PKT_TCAM_DYNAMIC_INDEX_START(block_id); + } else { + index = ethertype_filter->tcam_index[pkt_type]; + } + } + + memset(ðertype_cmd, 0, sizeof(struct hinic3_set_fdir_ethertype_rule)); + ethertype_cmd.func_id = hinic3_global_func_id(hwdev); + ethertype_cmd.pkt_type = pkt_type; + ethertype_cmd.pkt_type_en = en; + ethertype_cmd.index = index; + ethertype_cmd.qid = (uint8_t)ethertype_filter->queue; + + err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_L2NIC, + HINIC3_NIC_CMD_SET_FDIR_STATUS, + ðertype_cmd, sizeof(ethertype_cmd), + ðertype_cmd, &out_size); + if (err || ethertype_cmd.head.status || !out_size) { + PMD_DRV_LOG(ERR, + "set fdir ethertype rule failed, err: %d, status: 0x%x, out size: 0x%x, func_id %d", + err, ethertype_cmd.head.status, out_size, ethertype_cmd.func_id); + return -EIO; + } + if ((hinic3_get_driver_feature(nic_dev) & NIC_F_HTN_FDIR) != 0) { + if (en == 0) { + hinic3_tcam_index_free(nic_dev, HINIC3_TCAM_GET_INDEX_IN_BLOCK(index), + HINIC3_TCAM_GET_DYNAMIC_BLOCK_INDEX(index)); + } else { + ethertype_filter->tcam_index[pkt_type] = index; + } + } + + return 0; +} + /** * Add a TCAM filter. * @@ -722,11 +1035,7 @@ hinic3_add_tcam_filter(struct rte_eth_dev *dev, struct hinic3_tcam_info *tcam_info = HINIC3_DEV_PRIVATE_TO_TCAM_INFO(dev->data->dev_private); struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); - struct hinic3_tcam_dynamic_block *dynamic_block_ptr = NULL; - struct hinic3_tcam_dynamic_block *tmp = NULL; struct hinic3_tcam_filter *tcam_filter; - uint16_t tcam_block_index = 0; - uint16_t index = 0; int err; /* Alloc TCAM filter memory. */ @@ -737,39 +1046,14 @@ hinic3_add_tcam_filter(struct rte_eth_dev *dev, tcam_filter->tcam_key = *tcam_key; tcam_filter->queue = (uint16_t)(fdir_tcam_rule->data.qid); - - /* Add new TCAM rules. */ - if (nic_dev->tcam_rule_nums == 0) { - err = hinic3_alloc_tcam_block(nic_dev->hwdev, &tcam_block_index); - if (err) { - PMD_DRV_LOG(ERR, - "Fdir filter tcam alloc block failed!"); - goto failed; - } - - dynamic_block_ptr = - hinic3_alloc_dynamic_block_resource(tcam_info, - tcam_block_index); - if (dynamic_block_ptr == NULL) { - PMD_DRV_LOG(ERR, "Fdir filter alloc dynamic first block memory failed!"); - goto alloc_block_failed; - } - } - - /* - * Look for an available index in the dynamic block to store the new - * TCAM filter. - */ - tmp = hinic3_dynamic_lookup_tcam_filter(dev, fdir_tcam_rule, tcam_info, - tcam_filter, &index); - if (tmp == NULL) { - PMD_DRV_LOG(ERR, "Dynamic lookup tcam filter failed!"); - goto lookup_tcam_index_failed; - } + tcam_filter->index = hinic3_tcam_alloc_index(nic_dev, &tcam_filter->dynamic_block_id); + if (tcam_filter->index == HINIC3_TCAM_INVALID_INDEX) + goto failed; + fdir_tcam_rule->index = HINIC3_PKT_TCAM_DYNAMIC_INDEX_START(tcam_filter->dynamic_block_id) + + tcam_filter->index; /* Add a new TCAM rule to the network device. */ - err = hinic3_add_tcam_rule(nic_dev->hwdev, fdir_tcam_rule, - TCAM_RULE_FDIR_TYPE); + err = hinic3_add_tcam_rule(nic_dev->hwdev, fdir_tcam_rule, TCAM_RULE_FDIR_TYPE); if (err) { PMD_DRV_LOG(ERR, "Fdir_tcam_rule add failed!"); goto add_tcam_rules_failed; @@ -785,10 +1069,6 @@ hinic3_add_tcam_filter(struct rte_eth_dev *dev, /* Add a filter to the end of the queue. */ TAILQ_INSERT_TAIL(&tcam_info->tcam_list, tcam_filter, entries); - /* Update dynamic index. */ - tmp->dynamic_index[index] = 1; - tmp->dynamic_index_cnt++; - nic_dev->tcam_rule_nums++; PMD_DRV_LOG(INFO, @@ -796,7 +1076,7 @@ hinic3_add_tcam_filter(struct rte_eth_dev *dev, hinic3_global_func_id(nic_dev->hwdev)); PMD_DRV_LOG(INFO, "tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d", - tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index, + tcam_filter->dynamic_block_id, tcam_filter->index, fdir_tcam_rule->index, fdir_tcam_rule->data.qid, nic_dev->tcam_rule_nums); return 0; @@ -806,14 +1086,7 @@ hinic3_add_tcam_filter(struct rte_eth_dev *dev, TCAM_RULE_FDIR_TYPE); add_tcam_rules_failed: -lookup_tcam_index_failed: - if (nic_dev->tcam_rule_nums == 0 && dynamic_block_ptr != NULL) - hinic3_free_dynamic_block_resource(tcam_info, - dynamic_block_ptr); - -alloc_block_failed: - if (nic_dev->tcam_rule_nums == 0) - hinic3_free_tcam_block(nic_dev->hwdev, &tcam_block_index); + hinic3_tcam_index_free(nic_dev, tcam_filter->index, tcam_filter->dynamic_block_id); failed: rte_free(tcam_filter); @@ -850,8 +1123,7 @@ hinic3_del_dynamic_tcam_filter(struct rte_eth_dev *dev, } if (tmp == NULL || tmp->dynamic_block_id != dynamic_block_id) { - PMD_DRV_LOG(ERR, - "Fdir filter del dynamic lookup for block failed!"); + PMD_DRV_LOG(ERR, "Fdir filter del dynamic lookup for block failed!"); return -EINVAL; } /* Calculate TCAM index. */ @@ -873,14 +1145,9 @@ hinic3_del_dynamic_tcam_filter(struct rte_eth_dev *dev, dynamic_block_id, tcam_filter->index, index, tmp->dynamic_index_cnt - 1, nic_dev->tcam_rule_nums - 1); - tmp->dynamic_index[tcam_filter->index] = 0; - tmp->dynamic_index_cnt--; - nic_dev->tcam_rule_nums--; - if (tmp->dynamic_index_cnt == 0) { - hinic3_free_tcam_block(nic_dev->hwdev, &dynamic_block_id); + hinic3_tcam_index_free(nic_dev, tcam_filter->index, tmp->dynamic_block_id); - hinic3_free_dynamic_block_resource(tcam_info, tmp); - } + nic_dev->tcam_rule_nums--; /* If the number of rules is 0, the TCAM filter is disabled. */ if (!(nic_dev->ethertype_rule_nums + nic_dev->tcam_rule_nums)) @@ -930,6 +1197,7 @@ hinic3_flow_add_del_fdir_filter(struct rte_eth_dev *dev, struct hinic3_fdir_filter *fdir_filter, bool add) { + struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); struct hinic3_tcam_info *tcam_info = HINIC3_DEV_PRIVATE_TO_TCAM_INFO(dev->data->dev_private); struct hinic3_tcam_filter *tcam_filter; @@ -940,11 +1208,15 @@ hinic3_flow_add_del_fdir_filter(struct rte_eth_dev *dev, memset(&fdir_tcam_rule, 0, sizeof(struct hinic3_tcam_cfg_rule)); memset((void *)&tcam_key, 0, sizeof(struct hinic3_tcam_key)); - hinic3_fdir_tcam_info_init(dev, fdir_filter, &tcam_key, - &fdir_tcam_rule); + if ((hinic3_get_driver_feature(nic_dev) & NIC_F_HTN_FDIR) == 0) + hinic3_fdir_tcam_info_init(dev, fdir_filter, &tcam_key, &fdir_tcam_rule); + else + hinic3_fdir_tcam_info_htn_init(dev, fdir_filter, &tcam_key, &fdir_tcam_rule); + /* Search for a filter. */ tcam_filter = - hinic3_tcam_filter_lookup(&tcam_info->tcam_list, &tcam_key); + hinic3_tcam_filter_lookup(&tcam_info->tcam_list, &tcam_key, + HINIC3_ACTION_ADD, HINIC3_INVALID_INDEX); if (tcam_filter != NULL && add) { PMD_DRV_LOG(ERR, "Filter exists."); return -EEXIST; @@ -965,6 +1237,13 @@ hinic3_flow_add_del_fdir_filter(struct rte_eth_dev *dev, fdir_filter->tcam_index = (int)(fdir_tcam_rule.index); } else { + tcam_filter = hinic3_tcam_filter_lookup(&tcam_info->tcam_list, &tcam_key, + HINIC3_ACTION_NOT_ADD, + fdir_filter->tcam_index); + if (tcam_filter == NULL) { + PMD_DRV_LOG(ERR, "Filter doesn't exist."); + return -ENOENT; + } PMD_DRV_LOG(INFO, "begin to del tcam filter"); ret = hinic3_del_tcam_filter(dev, tcam_filter); if (ret) @@ -1088,7 +1367,7 @@ hinic3_free_fdir_filter(struct rte_eth_dev *dev) static int hinic3_flow_set_arp_filter(struct rte_eth_dev *dev, - struct rte_eth_ethertype_filter *ethertype_filter, + struct hinic3_ethertype_filter *ethertype_filter, bool add) { struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); @@ -1097,7 +1376,7 @@ hinic3_flow_set_arp_filter(struct rte_eth_dev *dev, /* Setting the ARP Filter. */ ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_ARP, - ethertype_filter->queue, add); + ethertype_filter, add); if (ret) { PMD_DRV_LOG(ERR, "%s fdir ethertype rule failed, err: %d", add ? "Add" : "Del", ret); @@ -1107,7 +1386,7 @@ hinic3_flow_set_arp_filter(struct rte_eth_dev *dev, /* Setting the ARP Request Filter. */ ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_ARP_REQ, - ethertype_filter->queue, add); + ethertype_filter, add); if (ret) { PMD_DRV_LOG(ERR, "%s arp request rule failed, err: %d", add ? "Add" : "Del", ret); @@ -1117,7 +1396,7 @@ hinic3_flow_set_arp_filter(struct rte_eth_dev *dev, /* Setting the ARP Response Filter. */ ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_ARP_REP, - ethertype_filter->queue, add); + ethertype_filter, add); if (ret) { PMD_DRV_LOG(ERR, "%s arp response rule failed, err: %d", add ? "Add" : "Del", ret); @@ -1129,19 +1408,19 @@ hinic3_flow_set_arp_filter(struct rte_eth_dev *dev, set_arp_rep_failed: hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_ARP_REQ, - ethertype_filter->queue, !add); + ethertype_filter, !add); set_arp_req_failed: hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_ARP, - ethertype_filter->queue, !add); + ethertype_filter, !add); return ret; } static int hinic3_flow_set_slow_filter(struct rte_eth_dev *dev, - struct rte_eth_ethertype_filter *ethertype_filter, + struct hinic3_ethertype_filter *ethertype_filter, bool add) { struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); @@ -1150,7 +1429,7 @@ hinic3_flow_set_slow_filter(struct rte_eth_dev *dev, /* Setting the LACP Filter. */ ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_LACP, - ethertype_filter->queue, add); + ethertype_filter, add); if (ret) { PMD_DRV_LOG(ERR, "%s lacp fdir rule failed, err: %d", add ? "Add" : "Del", ret); @@ -1160,7 +1439,7 @@ hinic3_flow_set_slow_filter(struct rte_eth_dev *dev, /* Setting the OAM Filter. */ ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_OAM, - ethertype_filter->queue, add); + ethertype_filter, add); if (ret) { PMD_DRV_LOG(ERR, "%s oam rule failed, err: %d", add ? "Add" : "Del", ret); @@ -1172,14 +1451,14 @@ hinic3_flow_set_slow_filter(struct rte_eth_dev *dev, set_arp_oam_failed: hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_LACP, - ethertype_filter->queue, !add); + ethertype_filter, !add); return ret; } static int hinic3_flow_set_lldp_filter(struct rte_eth_dev *dev, - struct rte_eth_ethertype_filter *ethertype_filter, + struct hinic3_ethertype_filter *ethertype_filter, bool add) { struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); @@ -1188,7 +1467,7 @@ hinic3_flow_set_lldp_filter(struct rte_eth_dev *dev, /* Setting the LLDP Filter. */ ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_LLDP, - ethertype_filter->queue, add); + ethertype_filter, add); if (ret) { PMD_DRV_LOG(ERR, "%s lldp fdir rule failed, err: %d", add ? "Add" : "Del", ret); @@ -1198,7 +1477,7 @@ hinic3_flow_set_lldp_filter(struct rte_eth_dev *dev, /* Setting the CDCP Filter. */ ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_CDCP, - ethertype_filter->queue, add); + ethertype_filter, add); if (ret) { PMD_DRV_LOG(ERR, "%s cdcp fdir rule failed, err: %d", add ? "Add" : "Del", ret); @@ -1210,14 +1489,14 @@ hinic3_flow_set_lldp_filter(struct rte_eth_dev *dev, set_arp_cdcp_failed: hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, HINIC3_PKT_TYPE_LLDP, - ethertype_filter->queue, !add); + ethertype_filter, !add); return ret; } static int hinic3_flow_add_del_ethertype_filter_rule(struct rte_eth_dev *dev, - struct rte_eth_ethertype_filter *ethertype_filter, + struct hinic3_ethertype_filter *ethertype_filter, bool add) { struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); @@ -1245,7 +1524,7 @@ hinic3_flow_add_del_ethertype_filter_rule(struct rte_eth_dev *dev, return hinic3_flow_set_arp_filter(dev, ethertype_filter, add); case RTE_ETHER_TYPE_RARP: return hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, - HINIC3_PKT_TYPE_RARP, ethertype_filter->queue, add); + HINIC3_PKT_TYPE_RARP, ethertype_filter, add); case RTE_ETHER_TYPE_SLOW: return hinic3_flow_set_slow_filter(dev, ethertype_filter, add); @@ -1255,11 +1534,11 @@ hinic3_flow_add_del_ethertype_filter_rule(struct rte_eth_dev *dev, case RTE_ETHER_TYPE_CNM: return hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, - HINIC3_PKT_TYPE_CNM, ethertype_filter->queue, add); + HINIC3_PKT_TYPE_CNM, ethertype_filter, add); case RTE_ETHER_TYPE_ECP: return hinic3_set_fdir_ethertype_filter(nic_dev->hwdev, - HINIC3_PKT_TYPE_ECP, ethertype_filter->queue, add); + HINIC3_PKT_TYPE_ECP, ethertype_filter, add); default: PMD_DRV_LOG(ERR, "Unknown ethertype %d queue_id %d", @@ -1270,7 +1549,7 @@ hinic3_flow_add_del_ethertype_filter_rule(struct rte_eth_dev *dev, } static int -hinic3_flow_ethertype_rule_nums(struct rte_eth_ethertype_filter *ethertype_filter) +hinic3_flow_ethertype_rule_nums(struct hinic3_ethertype_filter *ethertype_filter) { switch (ethertype_filter->ether_type) { case RTE_ETHER_TYPE_ARP: @@ -1309,7 +1588,7 @@ hinic3_flow_ethertype_rule_nums(struct rte_eth_ethertype_filter *ethertype_filte */ int hinic3_flow_add_del_ethertype_filter(struct rte_eth_dev *dev, - struct rte_eth_ethertype_filter *ethertype_filter, + struct hinic3_ethertype_filter *ethertype_filter, bool add) { /* Get dev private info. */ diff --git a/drivers/net/hinic3/hinic3_fdir.h b/drivers/net/hinic3/hinic3_fdir.h index 8659f588d9..277d89d4fd 100644 --- a/drivers/net/hinic3/hinic3_fdir.h +++ b/drivers/net/hinic3/hinic3_fdir.h @@ -14,6 +14,30 @@ #define HINIC3_PKT_TCAM_DYNAMIC_INDEX_START(block_index) \ (HINIC3_TCAM_DYNAMIC_BLOCK_SIZE * (block_index)) +#define HINIC3_TCAM_GET_DYNAMIC_BLOCK_INDEX(index) \ + ((index) / HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) + +#define HINIC3_TCAM_GET_INDEX_IN_BLOCK(index) \ + ((index) % HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) + +#define HINIC3_TCAM_INVALID_INDEX 0xFFFF + +enum hinic3_ether_type { + HINIC3_PKT_TYPE_ARP = 1, + HINIC3_PKT_TYPE_ARP_REQ, + HINIC3_PKT_TYPE_ARP_REP, + HINIC3_PKT_TYPE_RARP, + HINIC3_PKT_TYPE_LACP, + HINIC3_PKT_TYPE_LLDP, + HINIC3_PKT_TYPE_OAM, + HINIC3_PKT_TYPE_CDCP, + HINIC3_PKT_TYPE_CNM, + HINIC3_PKT_TYPE_ECP = 10, + HINIC3_PKT_TYPE_BUTT, + + HINIC3_PKT_UNKNOWN = 31, +}; + /* Indicate a traffic filtering rule. */ struct rte_flow { TAILQ_ENTRY(rte_flow) node; @@ -30,6 +54,8 @@ struct hinic3_fdir_rule_key { uint16_t src_port; uint16_t dst_port; uint8_t proto; + uint8_t vlan_flag; + uint16_t ether_type; }; struct hinic3_fdir_filter { @@ -42,17 +68,34 @@ struct hinic3_fdir_filter { uint32_t rq_index; /**< Queue assigned when matched. */ }; +struct hinic3_ethertype_filter { + int tcam_index[HINIC3_PKT_TYPE_BUTT]; + uint16_t ether_type; /**< Ether type to match */ + uint16_t queue; /**< Queue assigned to when match*/ +}; + /* This structure is used to describe a basic filter type. */ struct hinic3_filter_t { uint16_t filter_rule_nums; enum rte_filter_type filter_type; - struct rte_eth_ethertype_filter ethertype_filter; + struct hinic3_ethertype_filter ethertype_filter; struct hinic3_fdir_filter fdir_filter; }; +enum hinic3_action_type { + HINIC3_ACTION_ADD, + HINIC3_ACTION_NOT_ADD, +}; + enum hinic3_fdir_tunnel_mode { HINIC3_FDIR_TUNNEL_MODE_NORMAL = 0, - HINIC3_FDIR_TUNNEL_MODE_VXLAN = 1, + HINIC3_FDIR_TUNNEL_MODE_VXLAN = 1, + HINIC3_FDIR_TUNNEL_MODE_NVGRE = 2, + HINIC3_FDIR_TUNNEL_MODE_FC = 3, + HINIC3_FDIR_TUNNEL_MODE_GPE = 4, + HINIC3_FDIR_TUNNEL_MODE_GENEVE = 5, + HINIC3_FDIR_TUNNEL_MODE_NSH = 6, + HINIC3_FDIR_TUNNEL_MODE_IPIP = 7, }; enum hinic3_fdir_ip_type { @@ -61,7 +104,6 @@ enum hinic3_fdir_ip_type { HINIC3_FDIR_IP_TYPE_ANY = 2, }; -/* Describe the key structure of the TCAM. */ struct hinic3_tcam_key_mem { #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) uint32_t rsvd0 : 16; @@ -77,11 +119,13 @@ struct hinic3_tcam_key_mem { uint32_t dipv4_h : 16; uint32_t dipv4_l : 16; - uint32_t rsvd2 : 16; + + uint32_t vlan_flag : 1; + uint32_t rsvd2 : 15; uint32_t rsvd3; - uint32_t rsvd4 : 16; + uint32_t ether_type : 16; uint32_t dport : 16; uint32_t sport : 16; @@ -89,9 +133,10 @@ struct hinic3_tcam_key_mem { uint32_t rsvd6 : 16; uint32_t outer_sipv4_h : 16; - uint32_t outer_sipv4_l : 16; + uint32_t outer_sipv4_l : 16; uint32_t outer_dipv4_h : 16; + uint32_t outer_dipv4_l : 16; uint32_t vni_h : 16; @@ -110,13 +155,14 @@ struct hinic3_tcam_key_mem { uint32_t dipv4_h : 16; uint32_t sipv4_l : 16; - uint32_t rsvd2 : 16; + uint32_t rsvd2 : 15; + uint32_t vlan_flag : 1; uint32_t dipv4_l : 16; uint32_t rsvd3; uint32_t dport : 16; - uint32_t rsvd4 : 16; + uint32_t ether_type : 16; uint32_t rsvd5 : 16; uint32_t sport : 16; @@ -135,18 +181,90 @@ struct hinic3_tcam_key_mem { #endif }; -/* - * Define the IPv6-related TCAM key data structure in common - * scenarios or IPv6 tunnel scenarios. - */ +struct hinic3_tcam_key_mem_htn { +#if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) + uint32_t rsvd0 : 16; + uint32_t ip_proto : 8; + uint32_t tunnel_type : 3; + uint32_t function_id_h: 5; + + uint32_t function_id_l : 5; + uint32_t ip_type : 2; + uint32_t outer_ip_type : 1; + uint32_t rsvd1 : 8; + uint32_t outer_sipv4_h : 16; + + uint32_t outer_sipv4_l : 16; + uint32_t outer_dipv4_h : 16; + + uint32_t outer_dipv4_l : 16; + uint32_t rsvd2 : 8; + uint32_t vni_h : 8; + + uint32_t vni_l : 16; + uint32_t sipv4_h : 16; + + uint32_t sipv4_l : 16; + uint32_t rsvd5 : 16; + + uint32_t rsvd6; + uint32_t rsvd7; + + uint32_t rsvd8 : 16; + uint32_t dipv4_h : 16; + + uint32_t dipv4_l : 16; + uint32_t sport : 16; + + uint32_t dport : 16; + uint32_t rsvd5 : 16; +#else + uint32_t function_id_h : 5; + uint32_t tunnel_type : 3; + uint32_t ip_proto : 8; + uint32_t rsvd0 : 16; + + uint32_t outer_sipv4_h : 16; + uint32_t rsvd1 : 8; + uint32_t outer_ip_type : 1; + uint32_t ip_type : 2; + uint32_t function_id_l : 5; + + uint32_t outer_dipv4_h : 16; + uint32_t outer_sipv4_l : 16; + + uint32_t vni_h : 8; + uint32_t rsvd2 : 8; + uint32_t outer_dipv4_l : 16; + + uint32_t sipv4_h : 16; + uint32_t vni_l : 16; + + uint32_t rsvd5 : 16; + uint32_t sipv4_l : 16; + + uint32_t rsvd6; + uint32_t rsvd7; + + uint32_t dipv4_h : 16; + uint32_t rsvd8 : 16; + + uint32_t sport : 16; + uint32_t dipv4_l :16; + + uint32_t rsvd9 : 16; + uint32_t dport : 16; +#endif +}; + struct hinic3_tcam_key_ipv6_mem { #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) uint32_t rsvd0 : 16; - /* Indicates the normal IPv6 nextHdr or inner IPv4/IPv6 next proto. */ uint32_t ip_proto : 8; uint32_t tunnel_type : 4; uint32_t outer_ip_type : 1; - uint32_t rsvd1 : 3; + uint32_t vlan_flag : 1; + uint32_t rsvd1 : 2; uint32_t function_id : 15; uint32_t ip_type : 1; @@ -179,7 +297,9 @@ struct hinic3_tcam_key_ipv6_mem { uint32_t dipv6_key7 : 16; uint32_t rsvd2 : 16; #else - uint32_t rsvd1 : 3; + uint32_t rsvd1 : 2; + uint32_t vlan_flag : 1; + uint32_t outer_ip_type : 1; uint32_t tunnel_type : 4; uint32_t ip_proto : 8; @@ -218,10 +338,86 @@ struct hinic3_tcam_key_ipv6_mem { #endif }; -/* - * Define the tcam key value data structure related to IPv6 in - * the VXLAN scenario. - */ +struct hinic3_tcam_key_ipv6_mem_htn { +#if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) + uint32_t rsvd0 : 16; + uint32_t ip_proto : 8; + uint32_t tunnel_type : 3; + uint32_t function_id_h : 5; + + uint32_t function_id_l : 5; + uint32_t ip_type : 2; + uint32_t outer_ip_type : 1; + uint32_t rsvd1 : 8; + uint32_t sipv6_key0 : 16; + + uint32_t sipv6_key1 : 16; + uint32_t sipv6_key2 : 16; + + uint32_t sipv6_key3 : 16; + uint32_t sipv6_key4 : 16; + + uint32_t sipv6_key5 : 16; + uint32_t sipv6_key6 : 16; + + uint32_t sipv6_key7 : 16; + uint32_t dipv6_key0 : 16; + + uint32_t dipv6_key1 : 16; + uint32_t dipv6_key2 : 16; + + uint32_t dipv6_key3 : 16; + uint32_t dipv6_key4 : 16; + + uint32_t dipv6_key5 : 16; + uint32_t dipv6_key6 : 16; + + uint32_t dipv6_key7 : 16; + uint32_t sport : 16; + + uint32_t dport : 16; + uint32_t rsvd2 : 16; +#else + uint32_t function_id_h : 5; + uint32_t tunnel_type : 3; + uint32_t ip_proto : 8; + uint32_t rsvd0 : 16; + + uint32_t sipv6_key0 : 16; + uint32_t rsvd1 : 8; + uint32_t outer_ip_type : 1; + uint32_t ip_type : 2; + uint32_t function_id_l : 5; + + uint32_t sipv6_key2 : 16; + uint32_t sipv6_key1 : 16; + + uint32_t sipv6_key4 : 16; + uint32_t sipv6_key3 : 16; + + uint32_t sipv6_key6 : 16; + uint32_t sipv6_key5 : 16; + + uint32_t dipv6_key0 : 16; + uint32_t sipv6_key7 : 16; + + uint32_t dipv6_key2 : 16; + uint32_t dipv6_key1 : 16; + + uint32_t dipv6_key4 : 16; + uint32_t dipv6_key3 : 16; + + uint32_t dipv6_key6 : 16; + uint32_t dipv6_key5 : 16; + + uint32_t sport : 16; + uint32_t dipv6_key7 : 16; + + uint32_t rsvd2 : 16; + uint32_t dport : 16; +#endif +}; + struct hinic3_tcam_key_vxlan_ipv6_mem { #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) uint32_t rsvd0 : 16; @@ -246,7 +442,8 @@ struct hinic3_tcam_key_vxlan_ipv6_mem { uint32_t dport : 16; uint32_t sport : 16; - uint32_t rsvd2 : 16; + uint32_t vlan_flag : 1; + uint32_t rsvd2 : 15; uint32_t rsvd3 : 16; uint32_t outer_sipv4_h : 16; @@ -281,7 +478,8 @@ struct hinic3_tcam_key_vxlan_ipv6_mem { uint32_t dport : 16; uint32_t dipv6_key7 : 16; - uint32_t rsvd2 : 16; + uint32_t rsvd2 : 15; + uint32_t vlan_flag : 1; uint32_t sport : 16; uint32_t outer_sipv4_h : 16; @@ -298,6 +496,88 @@ struct hinic3_tcam_key_vxlan_ipv6_mem { #endif }; +struct hinic3_tcam_key_vxlan_ipv6_mem_htn { +#if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) + uint32_t rsvd0 : 16; + uint32_t ip_proto : 8; + uint32_t tunnel_type : 3; + uint32_t function_id_h : 5; + + uint32_t function_id_l : 5; + uint32_t ip_type : 2; + uint32_t outer_ip_type : 1; + uint32_t rsvd1 : 8; + uint32_t outer_sipv4_h : 16; + + uint32_t outer_sipv4_l : 16; + uint32_t outer_dipv4_h : 16; + + uint32_t outer_dipv4_l : 16; + uint32_t rsvd2 : 8; + uint32_t vni_h : 8; + + uint32_t vni_l : 16; + uint32_t rsvd3 : 16; + + uint32_t rsvd4 : 16; + uint32_t dipv6_key0 : 16; + + uint32_t dipv6_key1 : 16; + uint32_t dipv6_key2 : 16; + + uint32_t dipv6_key3 : 16; + uint32_t dipv6_key4 : 16; + + uint32_t dipv6_key5 : 16; + uint32_t dipv6_key6 : 16; + + uint32_t dipv6_key7 : 16; + uint32_t sport : 16; + + uint32_t dport : 16; + uint32_t rsvd2 : 16; +#else + uint32_t function_id_h : 5; + uint32_t tunnel_type : 3; + uint32_t ip_proto : 8; + uint32_t rsvd0 : 16; + + uint32_t outer_sipv4_h : 16; + uint32_t rsvd1 : 8; + uint32_t outer_ip_type : 1; + uint32_t ip_type : 2; + uint32_t function_id_l : 5; + + uint32_t outer_dipv4_h : 16; + uint32_t outer_sipv4_l : 16; + + uint32_t vni_h : 8; + uint32_t rsvd2 : 8; + uint32_t outer_dipv4_l : 16; + + uint32_t rsvd3 : 16; + uint32_t vni_l : 16; + + uint32_t dipv6_key0 : 16; + uint32_t rsvd4 : 16; + + uint32_t dipv6_key2 : 16; + uint32_t dipv6_key1 : 16; + + uint32_t dipv6_key4 : 16; + uint32_t dipv6_key3 : 16; + + uint32_t dipv6_key6 : 16; + uint32_t dipv6_key5 : 16; + + uint32_t sport : 16; + uint32_t dipv6_key7 : 16; + + uint32_t rsvd5 : 16; + uint32_t dport : 16; +#endif +}; + /* * TCAM key structure. The two unions indicate the key and mask respectively. * The TCAM key is consistent with the TCAM entry. @@ -307,18 +587,26 @@ struct hinic3_tcam_key { struct hinic3_tcam_key_mem key_info; struct hinic3_tcam_key_ipv6_mem key_info_ipv6; struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6; + + struct hinic3_tcam_key_mem_htn key_info_htn; + struct hinic3_tcam_key_ipv6_mem_htn key_info_ipv6_htn; + struct hinic3_tcam_key_vxlan_ipv6_mem_htn key_info_vxlan_ipv6_htn; }; union { struct hinic3_tcam_key_mem key_mask; struct hinic3_tcam_key_ipv6_mem key_mask_ipv6; struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6; + + struct hinic3_tcam_key_mem_htn key_mask_htn; + struct hinic3_tcam_key_ipv6_mem_htn key_mask_ipv6_htn; + struct hinic3_tcam_key_vxlan_ipv6_mem_htn key_mask_vxlan_ipv6_htn; }; }; /* Structure indicates the TCAM filter. */ struct hinic3_tcam_filter { - TAILQ_ENTRY(hinic3_tcam_filter) - entries; /**< Filter entry, used for linked list operations. */ + /** Filter entry, used for linked list operations. */ + TAILQ_ENTRY(hinic3_tcam_filter) entries; uint16_t dynamic_block_id; /**< Dynamic block ID. */ uint16_t index; /**< TCAM index. */ struct hinic3_tcam_key tcam_key; /**< Indicate TCAM key. */ @@ -362,33 +650,24 @@ struct hinic3_tcam_info { #define HINIC3_CNM_RULE_NUM 1 #define HINIC3_ECP_RULE_NUM 2 +#define HINIC3_UINT1_MAX 0x1 +#define HINIC3_UINT2_MAX 0x3 +#define HINIC3_UINT3_MAX 0x7 +#define HINIC3_UINT4_MAX 0xf +#define HINIC3_UINT5_WIDTH 0x5 +#define HINIC3_UINT5_MAX 0x1f +#define HINIC3_UINT15_MAX 0x7fff + /* Define Ethernet type. */ #define RTE_ETHER_TYPE_CNM 0x22e7 #define RTE_ETHER_TYPE_ECP 0x8940 -/* Protocol type of the data packet. */ -enum hinic3_ether_type { - HINIC3_PKT_TYPE_ARP = 1, - HINIC3_PKT_TYPE_ARP_REQ, - HINIC3_PKT_TYPE_ARP_REP, - HINIC3_PKT_TYPE_RARP, - HINIC3_PKT_TYPE_LACP, - HINIC3_PKT_TYPE_LLDP, - HINIC3_PKT_TYPE_OAM, - HINIC3_PKT_TYPE_CDCP, - HINIC3_PKT_TYPE_CNM, - HINIC3_PKT_TYPE_ECP = 10, - - HINIC3_PKT_UNKNOWN = 31, -}; - int hinic3_flow_add_del_fdir_filter(struct rte_eth_dev *dev, struct hinic3_fdir_filter *fdir_filter, bool add); int hinic3_flow_add_del_ethertype_filter(struct rte_eth_dev *dev, - struct rte_eth_ethertype_filter *ethertype_filter, + struct hinic3_ethertype_filter *ethertype_filter, bool add); - void hinic3_free_fdir_filter(struct rte_eth_dev *dev); int hinic3_enable_rxq_fdir_filter(struct rte_eth_dev *dev, uint32_t queue_id, uint32_t able); diff --git a/drivers/net/hinic3/hinic3_nic_io.h b/drivers/net/hinic3/hinic3_nic_io.h index d0acba4cf4..e1741d1156 100644 --- a/drivers/net/hinic3/hinic3_nic_io.h +++ b/drivers/net/hinic3/hinic3_nic_io.h @@ -277,22 +277,6 @@ int hinic3_init_qp_ctxts(struct hinic3_nic_dev *nic_dev); */ void hinic3_free_qp_ctxts(struct hinic3_hwdev *hwdev); -/** - * Get cmdq ops software tile NIC(stn) supported. - * - * @return - * Pointer to ops. - */ -struct hinic3_nic_cmdq_ops *hinic3_cmdq_get_stn_ops(void); - -/** - * Get cmdq ops hardware tile NIC(htn) supported. - * - * @return - * Pointer to ops. - */ -struct hinic3_nic_cmdq_ops *hinic3_cmdq_get_htn_ops(void); - /** * Update driver feature capabilities. * diff --git a/drivers/net/hinic3/hinic3_rx.c b/drivers/net/hinic3/hinic3_rx.c index 9e2c80f759..4c12943a05 100644 --- a/drivers/net/hinic3/hinic3_rx.c +++ b/drivers/net/hinic3/hinic3_rx.c @@ -22,8 +22,7 @@ * Current pi. */ static inline void -hinic3_get_rq_wqe(struct hinic3_rxq *rxq, struct hinic3_rq_wqe **rq_wqe, - uint16_t *pi) +hinic3_get_rq_wqe(struct hinic3_rxq *rxq, struct hinic3_rq_wqe **rq_wqe, uint16_t *pi) { *pi = MASKED_QUEUE_IDX(rxq, rxq->prod_idx); @@ -84,8 +83,7 @@ hinic3_rx_fill_wqe(struct hinic3_rxq *rxq) if (rxq->wqe_type == HINIC3_EXTEND_RQ_WQE) { /* Unit of cqe length is 16B. */ - hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge, - cqe_dma, + hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge, cqe_dma, HINIC3_CQE_LEN >> HINIC3_CQE_SIZE_SHIFT); /* Use fixed len. */ rq_wqe->extend_wqe.buf_desc.sge.len = nic_dev->rx_buff_len; @@ -436,12 +434,18 @@ hinic3_init_rss_type(struct hinic3_nic_dev *nic_dev, rss_type.ipv4 = (rss_hf & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4)) ? 1 : 0; rss_type.tcp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ? 1 : 0; rss_type.ipv6 = (rss_hf & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6)) ? 1 : 0; - rss_type.ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_EX) ? 1 : 0; rss_type.tcp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ? 1 : 0; - rss_type.tcp_ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) ? 1 : 0; rss_type.udp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ? 1 : 0; rss_type.udp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ? 1 : 0; + if (nic_dev->feature_cap & NIC_F_HTN_CMDQ) { + rss_type.ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_EX) ? 1 : 0; + rss_type.tcp_ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) ? 1 : 0; + } else { + rss_type.ipv6_ext = 0; + rss_type.ipv6_ext = 0; + } + err = hinic3_set_rss_type(nic_dev->hwdev, rss_type); return err; } @@ -488,8 +492,7 @@ hinic3_update_rss_config(struct rte_eth_dev *dev, goto init_rss_fail; } - err = hinic3_rss_cfg(nic_dev->hwdev, HINIC3_RSS_ENABLE, num_tc, - prio_tc); + err = hinic3_rss_cfg(nic_dev->hwdev, HINIC3_RSS_ENABLE, num_tc, prio_tc); if (err) { PMD_DRV_LOG(ERR, "Enable rss failed, err: %d", err); goto init_rss_fail; @@ -797,7 +800,7 @@ hinic3_start_rq(struct rte_eth_dev *eth_dev, struct hinic3_rxq *rxq) } } - hinic3_rearm_rxq_mbuf(rxq); + (void)hinic3_rearm_rxq_mbuf(rxq); if (rxq->nic_dev->num_rss == 1) { err = hinic3_set_vport_enable(nic_dev->hwdev, true); if (err) @@ -813,7 +816,6 @@ hinic3_start_rq(struct rte_eth_dev *eth_dev, struct hinic3_rxq *rxq) return err; } - static inline uint64_t hinic3_rx_vlan(uint8_t vlan_offload, uint16_t vlan_tag, uint16_t *vlan_tci) { @@ -1018,8 +1020,8 @@ hinic3_rx_get_cqe_info(struct hinic3_rxq *rxq __rte_unused, volatile struct hini uint32_t dw2 = hinic3_hw_cpu32(rx_cqe->offload_type); uint32_t dw3 = hinic3_hw_cpu32(rx_cqe->hash_val); - cqe_info->lro_num = RQ_CQE_STATUS_GET(dw0, NUM_LRO); - cqe_info->csum_err = RQ_CQE_STATUS_GET(dw0, CSUM_ERR); + cqe_info->lro_num = RQ_CQE_STATUS_GET(dw0, NUM_LRO); + cqe_info->csum_err = RQ_CQE_STATUS_GET(dw0, CSUM_ERR); cqe_info->pkt_len = RQ_CQE_SGE_GET(dw1, LEN); cqe_info->vlan_tag = RQ_CQE_SGE_GET(dw1, VLAN); diff --git a/drivers/net/hinic3/hinic3_tx.c b/drivers/net/hinic3/hinic3_tx.c index e0ff095c04..6b2bffb14e 100644 --- a/drivers/net/hinic3/hinic3_tx.c +++ b/drivers/net/hinic3/hinic3_tx.c @@ -393,7 +393,7 @@ static int hinic3_set_tx_offload(struct hinic3_nic_dev *nic_dev, struct rte_mbuf *mbuf, struct hinic3_sq_wqe_combo *wqe_combo, - struct hinic3_wqe_info *wqe_info) + struct hinic3_wqe_info *wqe_info) { uint64_t ol_flags = mbuf->ol_flags; struct hinic3_offload_info *offload_info = &wqe_info->offload_info; @@ -409,7 +409,7 @@ hinic3_set_tx_offload(struct hinic3_nic_dev *nic_dev, /* Tso offload. */ if (ol_flags & HINIC3_PKT_TX_TCP_SEG) { - wqe_info->queue_info.payload_offset = wqe_info->payload_offset; + wqe_info->queue_info.payload_offset = wqe_info->payload_offset >> 1; if ((wqe_info->payload_offset >> 1) > MAX_PAYLOAD_OFFSET) return -EINVAL; @@ -457,7 +457,7 @@ hinic3_set_tx_offload(struct hinic3_nic_dev *nic_dev, offload_info->out_l4_en = 1; set_tx_wqe_offload: - nic_dev->tx_ops->tx_set_wqe_offload(wqe_info, wqe_combo); + nic_dev->tx_ops->nic_tx_set_wqe_offload(wqe_info, wqe_combo); return 0; } @@ -627,9 +627,8 @@ hinic3_get_tx_offload(struct hinic3_nic_dev *nic_dev, struct rte_mbuf *mbuf, return err; /* Non-tso mbuf only check sge num. */ - if (likely(!(mbuf->ol_flags & HINIC3_PKT_TX_TCP_SEG))) { + if (likely(!(mbuf->ol_flags & HINIC3_PKT_TX_TCP_SEG))) return hinic3_non_tso_pkt_pre_process(mbuf, wqe_info); - } /* Tso mbuf. */ wqe_info->payload_offset = @@ -647,8 +646,7 @@ hinic3_get_tx_offload(struct hinic3_nic_dev *nic_dev, struct rte_mbuf *mbuf, } static inline void -hinic3_set_buf_desc(struct hinic3_sq_bufdesc *buf_descs, rte_iova_t addr, - uint32_t len) +hinic3_set_buf_desc(struct hinic3_sq_bufdesc *buf_descs, rte_iova_t addr, uint32_t len) { buf_descs->hi_addr = hinic3_hw_be32(upper_32_bits(addr)); buf_descs->lo_addr = hinic3_hw_be32(lower_32_bits(addr)); @@ -832,14 +830,14 @@ hinic3_prepare_sq_ctrl(struct hinic3_sq_wqe_combo *wqe_combo, if (wqe_combo->wqe_type == SQ_WQE_EXTENDED_TYPE) { wqe_desc->ctrl_len |= SQ_CTRL_SET(wqe_info->sge_cnt, BUFDESC_NUM) | SQ_CTRL_SET(wqe_combo->task_type, TASKSECT_LEN) | - SQ_CTRL_SET(SQ_WQE_SGL, DATA_FORMAT); + SQ_CTRL_SET(SQ_NORMAL_WQE, DATA_FORMAT); *qsf = SQ_CTRL_QUEUE_INFO_SET(1, UC) | SQ_CTRL_QUEUE_INFO_SET(queue_info->sctp, SCTP) | SQ_CTRL_QUEUE_INFO_SET(queue_info->udp_dp_en, TCPUDP_CS) | SQ_CTRL_QUEUE_INFO_SET(queue_info->tso, TSO) | SQ_CTRL_QUEUE_INFO_SET(queue_info->ufo, UFO) | - SQ_CTRL_QUEUE_INFO_SET(queue_info->payload_offset >> 1, PLDOFF) | + SQ_CTRL_QUEUE_INFO_SET(queue_info->payload_offset, PLDOFF) | SQ_CTRL_QUEUE_INFO_SET(queue_info->pkt_type, PKT_TYPE) | SQ_CTRL_QUEUE_INFO_SET(queue_info->mss, MSS); diff --git a/drivers/net/hinic3/htn_adapt/hinic3_htn_cmdq.h b/drivers/net/hinic3/htn_adapt/hinic3_htn_cmdq.h index ffafe39fb5..73f4922734 100644 --- a/drivers/net/hinic3/htn_adapt/hinic3_htn_cmdq.h +++ b/drivers/net/hinic3/htn_adapt/hinic3_htn_cmdq.h @@ -52,4 +52,12 @@ struct hinic3_htn_vlan_ctx { uint16_t dest_func_id; }; +/** + * Get cmdq ops hardware tile NIC(htn) supported. + * + * @return + * Pointer to ops. + */ +struct hinic3_nic_cmdq_ops *hinic3_nic_cmdq_get_htn_ops(void); + #endif /* _HINIC3_HTN_CMDQ_H_ */ diff --git a/drivers/net/hinic3/meson.build b/drivers/net/hinic3/meson.build index b79b753716..b286cdb79c 100644 --- a/drivers/net/hinic3/meson.build +++ b/drivers/net/hinic3/meson.build @@ -16,8 +16,6 @@ endif cflags += ['-DHW_CONVERT_ENDIAN'] -subdir('base') - sources = files( 'hinic3_ethdev.c', 'hinic3_nic_io.c', @@ -28,3 +26,9 @@ sources = files( ) includes += include_directories('base') +includes += include_directories('stn_adapt') +includes += include_directories('stn_adapt') + +subdir('base') +subdir('htn_adapt') +subdir('stn_adapt') \ No newline at end of file diff --git a/drivers/net/hinic3/stn_adapt/hinic3_stn_cmdq.c b/drivers/net/hinic3/stn_adapt/hinic3_stn_cmdq.c index dfe8598f78..f41f060d17 100644 --- a/drivers/net/hinic3/stn_adapt/hinic3_stn_cmdq.c +++ b/drivers/net/hinic3/stn_adapt/hinic3_stn_cmdq.c @@ -94,7 +94,7 @@ static uint8_t prepare_cmd_buf_modify_svlan(struct hinic3_cmd_buf *cmd_buf, uint return HINIC3_UCODE_CMD_MODIFY_VLAN_CTX; } -static uint8_t prepare_cmd_buf_set_rss_indir_table(struct hinic3_nic_dev *nic_dev, +static uint8_t prepare_cmd_buf_set_rss_indir_table(struct hinic3_nic_dev *nic_dev __rte_unused, const uint32_t *indir_table, struct hinic3_cmd_buf *cmd_buf) { diff --git a/drivers/net/hinic3/stn_adapt/hinic3_stn_cmdq.h b/drivers/net/hinic3/stn_adapt/hinic3_stn_cmdq.h index a40c4faa89..f1720c29c7 100644 --- a/drivers/net/hinic3/stn_adapt/hinic3_stn_cmdq.h +++ b/drivers/net/hinic3/stn_adapt/hinic3_stn_cmdq.h @@ -35,4 +35,12 @@ struct hinic3_stn_vlan_ctx { uint32_t vlan_sel; }; +/** + * Get cmdq ops software tile NIC(stn) supported. + * + * @return + * Pointer to ops. + */ +struct hinic3_nic_cmdq_ops *hinic3_nic_cmdq_get_stn_ops(void); + #endif /* _HINIC3_STN_CMDQ_H_ */ -- 2.45.1.windows.1

