Currently, the driver does not support FLOW_DISSECTOR_KEY_IP and FLOW_DISSECTOR_KEY_ENC_KEYID. But the hardware supports ip_tos (FLOW_DISSECTOR_KEY_IP) and outer_tun_vni (FLOW_DISSECTOR_KEY_ENC_KEYID). This patch adds support for FLOW_DISSECTOR_KEY_IP and FLOW_DISSECTOR_KEY_ENC_KEYID. Additionally, since tc flow cannot effectively support l2_user_def, l3_user_def, and l4_user_def, this patch explicitly sets them to not be used. Signed-off-by: Jijie Shao --- .../hisilicon/hns3/hns3pf/hclge_main.c | 79 +++++++++++++++++-- .../hisilicon/hns3/hns3pf/hclge_main.h | 4 + 2 files changed, 77 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index bbbc017a0fb7..a7320eca41d3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -16,7 +16,7 @@ #include #include - +#include #include "hclge_cmd.h" #include "hclge_dcb.h" #include "hclge_main.h" @@ -337,7 +337,9 @@ static const struct key_info tuple_key_info[] = { { OUTER_SRC_PORT, 16, KEY_OPT_LE16, -1, -1 }, { OUTER_DST_PORT, 16, KEY_OPT_LE16, -1, -1 }, { OUTER_L4_RSV, 32, KEY_OPT_LE32, -1, -1 }, - { OUTER_TUN_VNI, 24, KEY_OPT_VNI, -1, -1 }, + { OUTER_TUN_VNI, 24, KEY_OPT_VNI, + offsetof(struct hclge_fd_rule, tuples.outer_tun_vni), + offsetof(struct hclge_fd_rule, tuples_mask.outer_tun_vni) }, { OUTER_TUN_FLOW_ID, 8, KEY_OPT_U8, -1, -1 }, { INNER_DST_MAC, 48, KEY_OPT_MAC, offsetof(struct hclge_fd_rule, tuples.dst_mac), @@ -5590,8 +5592,9 @@ static int hclge_init_fd_config(struct hclge_dev *hdev) /* If use max 400bit key, we can support tuples for ether type */ if (hdev->fd_cfg.fd_mode == HCLGE_FD_MODE_DEPTH_2K_WIDTH_400B_STAGE_1) { - key_cfg->tuple_active |= - BIT(INNER_DST_MAC) | BIT(INNER_SRC_MAC); + key_cfg->tuple_active |= BIT(INNER_DST_MAC) | + BIT(INNER_SRC_MAC) | + BIT(OUTER_TUN_VNI); if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) key_cfg->tuple_active |= HCLGE_FD_TUPLE_USER_DEF_TUPLES; } @@ -5760,6 +5763,17 @@ static bool hclge_fd_convert_tuple(u32 tuple_bit, u8 *key_x, u8 *key_y, *(__le32 *)key_x = cpu_to_le32(tmp_x_l); *(__le32 *)key_y = cpu_to_le32(tmp_y_l); + return true; + case KEY_OPT_VNI: + calc_x(tmp_x_l, *(u32 *)(&p[offset]), *(u32 *)(&p[moffset])); + calc_y(tmp_y_l, *(u32 *)(&p[offset]), *(u32 *)(&p[moffset])); + for (i = 0; i < HCLGE_VNI_LENGTH; i++) { + key_x[i] = ((__force u32)cpu_to_le32(tmp_x_l) >> + (i * BITS_PER_BYTE)) & 0xFF; + key_y[i] = ((__force u32)cpu_to_le32(tmp_y_l) >> + (i * BITS_PER_BYTE)) & 0xFF; + } + return true; default: return false; @@ -7340,6 +7354,53 @@ static void hclge_get_cls_key_port(const struct flow_rule *flow, } } +static int hclge_get_cls_enc_keyid(struct hclge_dev *hdev, + const struct flow_rule *flow, + struct hclge_fd_rule *rule) +{ + if (flow_rule_match_key(flow, FLOW_DISSECTOR_KEY_ENC_KEYID)) { + struct flow_match_enc_keyid match; + + flow_rule_match_enc_keyid(flow, &match); + + /* vni is only 24 bits and must be greater than 0, + * and it can not be masked. + */ + if (be32_to_cpu(match.mask->keyid) != + HCLGE_FD_VXLAN_VNI_UNMASK || + be32_to_cpu(match.key->keyid) >= VXLAN_N_VID || + !match.key->keyid) { + dev_err(&hdev->pdev->dev, "invalid enc_keyid\n"); + return -EINVAL; + } + + rule->tuples.outer_tun_vni = be32_to_cpu(match.key->keyid); + rule->tuples_mask.outer_tun_vni = + be32_to_cpu(match.mask->keyid); + } else { + rule->unused_tuple |= BIT(OUTER_TUN_VNI); + } + + return 0; +} + +static void hclge_get_cls_key_ip_tos(const struct flow_rule *flow, + struct hclge_fd_rule *rule) +{ + if (flow_rule_match_key(flow, FLOW_DISSECTOR_KEY_IP)) { + struct flow_match_ip match; + + flow_rule_match_ip(flow, &match); + + rule->tuples.ip_tos = match.key->tos; + rule->tuples_mask.ip_tos = match.mask->tos; + if (!rule->tuples.ip_tos) + rule->unused_tuple |= BIT(INNER_IP_TOS); + } else { + rule->unused_tuple |= BIT(INNER_IP_TOS); + } +} + static int hclge_get_tc_flower_action(struct hclge_dev *hdev, struct flow_cls_offload *cls_flower, struct hclge_fd_rule *rule) @@ -7393,6 +7454,9 @@ static int hclge_parse_cls_flower(struct hclge_dev *hdev, struct netlink_ext_ack *extack = cls_flower->common.extack; int ret; + /* not support any user def tuples */ + rule->unused_tuple |= HCLGE_FD_TUPLE_USER_DEF_TUPLES; + hclge_get_cls_key_basic(flow, rule); hclge_get_cls_key_mac(flow, rule); hclge_get_cls_key_vlan(flow, rule); @@ -7402,8 +7466,9 @@ static int hclge_parse_cls_flower(struct hclge_dev *hdev, return ret; hclge_get_cls_key_port(flow, rule); + hclge_get_cls_key_ip_tos(flow, rule); - return 0; + return hclge_get_cls_enc_keyid(hdev, flow, rule); } static int hclge_check_cls_flower(struct hclge_dev *hdev, @@ -7433,7 +7498,9 @@ static int hclge_check_cls_flower(struct hclge_dev *hdev, BIT_ULL(FLOW_DISSECTOR_KEY_VLAN) | BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS) | BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | - BIT_ULL(FLOW_DISSECTOR_KEY_PORTS))) { + BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) | + BIT_ULL(FLOW_DISSECTOR_KEY_IP) | + BIT_ULL(FLOW_DISSECTOR_KEY_ENC_KEYID))) { dev_err(&hdev->pdev->dev, "unsupported key set: %#llx\n", dissector->used_keys); return -EOPNOTSUPP; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 032b472d2368..ccb19d960690 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -645,6 +645,9 @@ struct key_info { #define HCLGE_FD_USER_DEF_DATA GENMASK(15, 0) #define HCLGE_FD_USER_DEF_OFFSET GENMASK(15, 0) #define HCLGE_FD_USER_DEF_OFFSET_UNMASK GENMASK(15, 0) +#define HCLGE_FD_VXLAN_VNI_UNMASK GENMASK(31, 0) + +#define HCLGE_VNI_LENGTH 3 /* assigned by firmware, the real filter number for each pf may be less */ #define MAX_FD_FILTER_NUM 4096 @@ -738,6 +741,7 @@ struct hclge_fd_rule_tuples { u32 l4_user_def; u8 ip_tos; u8 ip_proto; + u32 outer_tun_vni; }; struct hclge_fd_rule { -- 2.33.0