1fcba820dSWei Hu (Xavier) /* SPDX-License-Identifier: BSD-3-Clause 253e6f86cSMin Hu (Connor) * Copyright(c) 2018-2021 HiSilicon Limited. 3fcba820dSWei Hu (Xavier) */ 4fcba820dSWei Hu (Xavier) 5df96fd0dSBruce Richardson #include <ethdev_driver.h> 6fcba820dSWei Hu (Xavier) #include <rte_hash.h> 7fcba820dSWei Hu (Xavier) #include <rte_hash_crc.h> 8fcba820dSWei Hu (Xavier) #include <rte_io.h> 9fcba820dSWei Hu (Xavier) #include <rte_malloc.h> 10fcba820dSWei Hu (Xavier) 11fcba820dSWei Hu (Xavier) #include "hns3_ethdev.h" 12fcba820dSWei Hu (Xavier) #include "hns3_logs.h" 13fcba820dSWei Hu (Xavier) 14fcba820dSWei Hu (Xavier) #define HNS3_VLAN_TAG_TYPE_NONE 0 15fcba820dSWei Hu (Xavier) #define HNS3_VLAN_TAG_TYPE_TAG2 1 16fcba820dSWei Hu (Xavier) #define HNS3_VLAN_TAG_TYPE_TAG1 2 17fcba820dSWei Hu (Xavier) #define HNS3_VLAN_TAG_TYPE_TAG1_2 3 18fcba820dSWei Hu (Xavier) 19fcba820dSWei Hu (Xavier) #define HNS3_PF_ID_S 0 20fcba820dSWei Hu (Xavier) #define HNS3_PF_ID_M GENMASK(2, 0) 21fcba820dSWei Hu (Xavier) #define HNS3_VF_ID_S 3 22fcba820dSWei Hu (Xavier) #define HNS3_VF_ID_M GENMASK(10, 3) 23fcba820dSWei Hu (Xavier) #define HNS3_PORT_TYPE_B 11 24fcba820dSWei Hu (Xavier) #define HNS3_NETWORK_PORT_ID_S 0 25fcba820dSWei Hu (Xavier) #define HNS3_NETWORK_PORT_ID_M GENMASK(3, 0) 26fcba820dSWei Hu (Xavier) 27fcba820dSWei Hu (Xavier) #define HNS3_FD_EPORT_SW_EN_B 0 28fcba820dSWei Hu (Xavier) 29fcba820dSWei Hu (Xavier) #define HNS3_FD_AD_DATA_S 32 30fcba820dSWei Hu (Xavier) #define HNS3_FD_AD_DROP_B 0 31fcba820dSWei Hu (Xavier) #define HNS3_FD_AD_DIRECT_QID_B 1 32fcba820dSWei Hu (Xavier) #define HNS3_FD_AD_QID_S 2 33f8e7fcbfSChengwen Feng #define HNS3_FD_AD_QID_M GENMASK(11, 2) 34fcba820dSWei Hu (Xavier) #define HNS3_FD_AD_USE_COUNTER_B 12 35fcba820dSWei Hu (Xavier) #define HNS3_FD_AD_COUNTER_NUM_S 13 36f8e7fcbfSChengwen Feng #define HNS3_FD_AD_COUNTER_NUM_M GENMASK(19, 13) 37fcba820dSWei Hu (Xavier) #define HNS3_FD_AD_NXT_STEP_B 20 38fcba820dSWei Hu (Xavier) #define HNS3_FD_AD_NXT_KEY_S 21 39f8e7fcbfSChengwen Feng #define HNS3_FD_AD_NXT_KEY_M GENMASK(25, 21) 40fcba820dSWei Hu (Xavier) #define HNS3_FD_AD_WR_RULE_ID_B 0 41fcba820dSWei Hu (Xavier) #define HNS3_FD_AD_RULE_ID_S 1 42f8e7fcbfSChengwen Feng #define HNS3_FD_AD_RULE_ID_M GENMASK(12, 1) 43f8e7fcbfSChengwen Feng #define HNS3_FD_AD_QUEUE_REGION_EN_B 16 44f8e7fcbfSChengwen Feng #define HNS3_FD_AD_QUEUE_REGION_SIZE_S 17 45f8e7fcbfSChengwen Feng #define HNS3_FD_AD_QUEUE_REGION_SIZE_M GENMASK(20, 17) 4659200fd7SWei Hu (Xavier) #define HNS3_FD_AD_COUNTER_HIGH_BIT 7 4759200fd7SWei Hu (Xavier) #define HNS3_FD_AD_COUNTER_HIGH_BIT_B 26 4876d79456SWei Hu (Xavier) #define HNS3_FD_AD_QUEUE_ID_HIGH_BIT 10 4976d79456SWei Hu (Xavier) #define HNS3_FD_AD_QUEUE_ID_HIGH_BIT_B 21 50fcba820dSWei Hu (Xavier) 51fcba820dSWei Hu (Xavier) enum HNS3_PORT_TYPE { 52fcba820dSWei Hu (Xavier) HOST_PORT, 53fcba820dSWei Hu (Xavier) NETWORK_PORT 54fcba820dSWei Hu (Xavier) }; 55fcba820dSWei Hu (Xavier) 56fcba820dSWei Hu (Xavier) enum HNS3_FD_MODE { 57fcba820dSWei Hu (Xavier) HNS3_FD_MODE_DEPTH_2K_WIDTH_400B_STAGE_1, 58fcba820dSWei Hu (Xavier) HNS3_FD_MODE_DEPTH_1K_WIDTH_400B_STAGE_2, 59fcba820dSWei Hu (Xavier) HNS3_FD_MODE_DEPTH_4K_WIDTH_200B_STAGE_1, 60fcba820dSWei Hu (Xavier) HNS3_FD_MODE_DEPTH_2K_WIDTH_200B_STAGE_2, 61fcba820dSWei Hu (Xavier) }; 62fcba820dSWei Hu (Xavier) 63fcba820dSWei Hu (Xavier) enum HNS3_FD_KEY_TYPE { 64fcba820dSWei Hu (Xavier) HNS3_FD_KEY_BASE_ON_PTYPE, 65fcba820dSWei Hu (Xavier) HNS3_FD_KEY_BASE_ON_TUPLE, 66fcba820dSWei Hu (Xavier) }; 67fcba820dSWei Hu (Xavier) 68fcba820dSWei Hu (Xavier) enum HNS3_FD_META_DATA { 69fcba820dSWei Hu (Xavier) PACKET_TYPE_ID, 70fcba820dSWei Hu (Xavier) IP_FRAGEMENT, 71fcba820dSWei Hu (Xavier) ROCE_TYPE, 72fcba820dSWei Hu (Xavier) NEXT_KEY, 73fcba820dSWei Hu (Xavier) VLAN_NUMBER, 74fcba820dSWei Hu (Xavier) SRC_VPORT, 75fcba820dSWei Hu (Xavier) DST_VPORT, 76fcba820dSWei Hu (Xavier) TUNNEL_PACKET, 77fcba820dSWei Hu (Xavier) MAX_META_DATA, 78fcba820dSWei Hu (Xavier) }; 79fcba820dSWei Hu (Xavier) 80fcba820dSWei Hu (Xavier) struct key_info { 81fcba820dSWei Hu (Xavier) uint8_t key_type; 82fcba820dSWei Hu (Xavier) uint8_t key_length; 83fcba820dSWei Hu (Xavier) }; 84fcba820dSWei Hu (Xavier) 85fcba820dSWei Hu (Xavier) static const struct key_info meta_data_key_info[] = { 86fcba820dSWei Hu (Xavier) {PACKET_TYPE_ID, 6}, 87fcba820dSWei Hu (Xavier) {IP_FRAGEMENT, 1}, 88fcba820dSWei Hu (Xavier) {ROCE_TYPE, 1}, 89fcba820dSWei Hu (Xavier) {NEXT_KEY, 5}, 90fcba820dSWei Hu (Xavier) {VLAN_NUMBER, 2}, 91fcba820dSWei Hu (Xavier) {SRC_VPORT, 12}, 92fcba820dSWei Hu (Xavier) {DST_VPORT, 12}, 93fcba820dSWei Hu (Xavier) {TUNNEL_PACKET, 1}, 94fcba820dSWei Hu (Xavier) }; 95fcba820dSWei Hu (Xavier) 96fcba820dSWei Hu (Xavier) static const struct key_info tuple_key_info[] = { 97fcba820dSWei Hu (Xavier) {OUTER_DST_MAC, 48}, 98fcba820dSWei Hu (Xavier) {OUTER_SRC_MAC, 48}, 99fcba820dSWei Hu (Xavier) {OUTER_VLAN_TAG_FST, 16}, 100fcba820dSWei Hu (Xavier) {OUTER_VLAN_TAG_SEC, 16}, 101fcba820dSWei Hu (Xavier) {OUTER_ETH_TYPE, 16}, 102fcba820dSWei Hu (Xavier) {OUTER_L2_RSV, 16}, 103fcba820dSWei Hu (Xavier) {OUTER_IP_TOS, 8}, 104fcba820dSWei Hu (Xavier) {OUTER_IP_PROTO, 8}, 105fcba820dSWei Hu (Xavier) {OUTER_SRC_IP, 32}, 106fcba820dSWei Hu (Xavier) {OUTER_DST_IP, 32}, 107fcba820dSWei Hu (Xavier) {OUTER_L3_RSV, 16}, 108fcba820dSWei Hu (Xavier) {OUTER_SRC_PORT, 16}, 109fcba820dSWei Hu (Xavier) {OUTER_DST_PORT, 16}, 110fcba820dSWei Hu (Xavier) {OUTER_L4_RSV, 32}, 111fcba820dSWei Hu (Xavier) {OUTER_TUN_VNI, 24}, 112fcba820dSWei Hu (Xavier) {OUTER_TUN_FLOW_ID, 8}, 113fcba820dSWei Hu (Xavier) {INNER_DST_MAC, 48}, 114fcba820dSWei Hu (Xavier) {INNER_SRC_MAC, 48}, 115fcba820dSWei Hu (Xavier) {INNER_VLAN_TAG1, 16}, 116fcba820dSWei Hu (Xavier) {INNER_VLAN_TAG2, 16}, 117fcba820dSWei Hu (Xavier) {INNER_ETH_TYPE, 16}, 118fcba820dSWei Hu (Xavier) {INNER_L2_RSV, 16}, 119fcba820dSWei Hu (Xavier) {INNER_IP_TOS, 8}, 120fcba820dSWei Hu (Xavier) {INNER_IP_PROTO, 8}, 121fcba820dSWei Hu (Xavier) {INNER_SRC_IP, 32}, 122fcba820dSWei Hu (Xavier) {INNER_DST_IP, 32}, 123fcba820dSWei Hu (Xavier) {INNER_L3_RSV, 16}, 124fcba820dSWei Hu (Xavier) {INNER_SRC_PORT, 16}, 125fcba820dSWei Hu (Xavier) {INNER_DST_PORT, 16}, 126fcba820dSWei Hu (Xavier) {INNER_SCTP_TAG, 32}, 127fcba820dSWei Hu (Xavier) }; 128fcba820dSWei Hu (Xavier) 129fcba820dSWei Hu (Xavier) #define MAX_KEY_LENGTH 400 130fcba820dSWei Hu (Xavier) #define MAX_200B_KEY_LENGTH 200 131fcba820dSWei Hu (Xavier) #define MAX_META_DATA_LENGTH 16 132fcba820dSWei Hu (Xavier) #define MAX_KEY_DWORDS DIV_ROUND_UP(MAX_KEY_LENGTH / HNS3_BITS_PER_BYTE, 4) 133fcba820dSWei Hu (Xavier) #define MAX_KEY_BYTES (MAX_KEY_DWORDS * 4) 134fcba820dSWei Hu (Xavier) 135fcba820dSWei Hu (Xavier) enum HNS3_FD_PACKET_TYPE { 136fcba820dSWei Hu (Xavier) NIC_PACKET, 137fcba820dSWei Hu (Xavier) ROCE_PACKET, 138fcba820dSWei Hu (Xavier) }; 139fcba820dSWei Hu (Xavier) 140fcba820dSWei Hu (Xavier) /* For each bit of TCAM entry, it uses a pair of 'x' and 141fcba820dSWei Hu (Xavier) * 'y' to indicate which value to match, like below: 142fcba820dSWei Hu (Xavier) * ---------------------------------- 143fcba820dSWei Hu (Xavier) * | bit x | bit y | search value | 144fcba820dSWei Hu (Xavier) * ---------------------------------- 145fcba820dSWei Hu (Xavier) * | 0 | 0 | always hit | 146fcba820dSWei Hu (Xavier) * ---------------------------------- 147fcba820dSWei Hu (Xavier) * | 1 | 0 | match '0' | 148fcba820dSWei Hu (Xavier) * ---------------------------------- 149fcba820dSWei Hu (Xavier) * | 0 | 1 | match '1' | 150fcba820dSWei Hu (Xavier) * ---------------------------------- 151fcba820dSWei Hu (Xavier) * | 1 | 1 | invalid | 152fcba820dSWei Hu (Xavier) * ---------------------------------- 153fcba820dSWei Hu (Xavier) * Then for input key(k) and mask(v), we can calculate the value by 154fcba820dSWei Hu (Xavier) * the formulae: 155fcba820dSWei Hu (Xavier) * x = (~k) & v 156fcba820dSWei Hu (Xavier) * y = k & v 157fcba820dSWei Hu (Xavier) */ 158fcba820dSWei Hu (Xavier) #define calc_x(x, k, v) ((x) = (~(k) & (v))) 159fcba820dSWei Hu (Xavier) #define calc_y(y, k, v) ((y) = ((k) & (v))) 160fcba820dSWei Hu (Xavier) 161fcba820dSWei Hu (Xavier) struct hns3_fd_tcam_config_1_cmd { 162fcba820dSWei Hu (Xavier) uint8_t stage; 163fcba820dSWei Hu (Xavier) uint8_t xy_sel; 164fcba820dSWei Hu (Xavier) uint8_t port_info; 165fcba820dSWei Hu (Xavier) uint8_t rsv1[1]; 166fcba820dSWei Hu (Xavier) rte_le32_t index; 167fcba820dSWei Hu (Xavier) uint8_t entry_vld; 168fcba820dSWei Hu (Xavier) uint8_t rsv2[7]; 169fcba820dSWei Hu (Xavier) uint8_t tcam_data[8]; 170fcba820dSWei Hu (Xavier) }; 171fcba820dSWei Hu (Xavier) 172fcba820dSWei Hu (Xavier) struct hns3_fd_tcam_config_2_cmd { 173fcba820dSWei Hu (Xavier) uint8_t tcam_data[24]; 174fcba820dSWei Hu (Xavier) }; 175fcba820dSWei Hu (Xavier) 176fcba820dSWei Hu (Xavier) struct hns3_fd_tcam_config_3_cmd { 177fcba820dSWei Hu (Xavier) uint8_t tcam_data[20]; 178fcba820dSWei Hu (Xavier) uint8_t rsv[4]; 179fcba820dSWei Hu (Xavier) }; 180fcba820dSWei Hu (Xavier) 181fcba820dSWei Hu (Xavier) struct hns3_get_fd_mode_cmd { 182fcba820dSWei Hu (Xavier) uint8_t mode; 183fcba820dSWei Hu (Xavier) uint8_t enable; 184fcba820dSWei Hu (Xavier) uint8_t rsv[22]; 185fcba820dSWei Hu (Xavier) }; 186fcba820dSWei Hu (Xavier) 187fcba820dSWei Hu (Xavier) struct hns3_get_fd_allocation_cmd { 188fcba820dSWei Hu (Xavier) rte_le32_t stage1_entry_num; 189fcba820dSWei Hu (Xavier) rte_le32_t stage2_entry_num; 190fcba820dSWei Hu (Xavier) rte_le16_t stage1_counter_num; 191fcba820dSWei Hu (Xavier) rte_le16_t stage2_counter_num; 192fcba820dSWei Hu (Xavier) uint8_t rsv[12]; 193fcba820dSWei Hu (Xavier) }; 194fcba820dSWei Hu (Xavier) 195fcba820dSWei Hu (Xavier) struct hns3_set_fd_key_config_cmd { 196fcba820dSWei Hu (Xavier) uint8_t stage; 197fcba820dSWei Hu (Xavier) uint8_t key_select; 198fcba820dSWei Hu (Xavier) uint8_t inner_sipv6_word_en; 199fcba820dSWei Hu (Xavier) uint8_t inner_dipv6_word_en; 200fcba820dSWei Hu (Xavier) uint8_t outer_sipv6_word_en; 201fcba820dSWei Hu (Xavier) uint8_t outer_dipv6_word_en; 202fcba820dSWei Hu (Xavier) uint8_t rsv1[2]; 203fcba820dSWei Hu (Xavier) rte_le32_t tuple_mask; 204fcba820dSWei Hu (Xavier) rte_le32_t meta_data_mask; 205fcba820dSWei Hu (Xavier) uint8_t rsv2[8]; 206fcba820dSWei Hu (Xavier) }; 207fcba820dSWei Hu (Xavier) 208fcba820dSWei Hu (Xavier) struct hns3_fd_ad_config_cmd { 209fcba820dSWei Hu (Xavier) uint8_t stage; 210fcba820dSWei Hu (Xavier) uint8_t rsv1[3]; 211fcba820dSWei Hu (Xavier) rte_le32_t index; 212fcba820dSWei Hu (Xavier) rte_le64_t ad_data; 213fcba820dSWei Hu (Xavier) uint8_t rsv2[8]; 214fcba820dSWei Hu (Xavier) }; 215fcba820dSWei Hu (Xavier) 216fcba820dSWei Hu (Xavier) struct hns3_fd_get_cnt_cmd { 217fcba820dSWei Hu (Xavier) uint8_t stage; 218fcba820dSWei Hu (Xavier) uint8_t rsv1[3]; 219fcba820dSWei Hu (Xavier) rte_le16_t index; 220fcba820dSWei Hu (Xavier) uint8_t rsv2[2]; 221fcba820dSWei Hu (Xavier) rte_le64_t value; 222fcba820dSWei Hu (Xavier) uint8_t rsv3[8]; 223fcba820dSWei Hu (Xavier) }; 224fcba820dSWei Hu (Xavier) 225fcba820dSWei Hu (Xavier) static int hns3_get_fd_mode(struct hns3_hw *hw, uint8_t *fd_mode) 226fcba820dSWei Hu (Xavier) { 227fcba820dSWei Hu (Xavier) struct hns3_get_fd_mode_cmd *req; 228fcba820dSWei Hu (Xavier) struct hns3_cmd_desc desc; 229fcba820dSWei Hu (Xavier) int ret; 230fcba820dSWei Hu (Xavier) 231fcba820dSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FD_MODE_CTRL, true); 232fcba820dSWei Hu (Xavier) 233fcba820dSWei Hu (Xavier) req = (struct hns3_get_fd_mode_cmd *)desc.data; 234fcba820dSWei Hu (Xavier) 235fcba820dSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc, 1); 236fcba820dSWei Hu (Xavier) if (ret) { 237fcba820dSWei Hu (Xavier) hns3_err(hw, "Get fd mode fail, ret=%d", ret); 238fcba820dSWei Hu (Xavier) return ret; 239fcba820dSWei Hu (Xavier) } 240fcba820dSWei Hu (Xavier) 241fcba820dSWei Hu (Xavier) *fd_mode = req->mode; 242fcba820dSWei Hu (Xavier) 243fcba820dSWei Hu (Xavier) return ret; 244fcba820dSWei Hu (Xavier) } 245fcba820dSWei Hu (Xavier) 246fcba820dSWei Hu (Xavier) static int hns3_get_fd_allocation(struct hns3_hw *hw, 247fcba820dSWei Hu (Xavier) uint32_t *stage1_entry_num, 248fcba820dSWei Hu (Xavier) uint32_t *stage2_entry_num, 249fcba820dSWei Hu (Xavier) uint16_t *stage1_counter_num, 250fcba820dSWei Hu (Xavier) uint16_t *stage2_counter_num) 251fcba820dSWei Hu (Xavier) { 252fcba820dSWei Hu (Xavier) struct hns3_get_fd_allocation_cmd *req; 253fcba820dSWei Hu (Xavier) struct hns3_cmd_desc desc; 254fcba820dSWei Hu (Xavier) int ret; 255fcba820dSWei Hu (Xavier) 256fcba820dSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FD_GET_ALLOCATION, true); 257fcba820dSWei Hu (Xavier) 258fcba820dSWei Hu (Xavier) req = (struct hns3_get_fd_allocation_cmd *)desc.data; 259fcba820dSWei Hu (Xavier) 260fcba820dSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc, 1); 261fcba820dSWei Hu (Xavier) if (ret) { 262fcba820dSWei Hu (Xavier) hns3_err(hw, "Query fd allocation fail, ret=%d", ret); 263fcba820dSWei Hu (Xavier) return ret; 264fcba820dSWei Hu (Xavier) } 265fcba820dSWei Hu (Xavier) 266fcba820dSWei Hu (Xavier) *stage1_entry_num = rte_le_to_cpu_32(req->stage1_entry_num); 267fcba820dSWei Hu (Xavier) *stage2_entry_num = rte_le_to_cpu_32(req->stage2_entry_num); 268fcba820dSWei Hu (Xavier) *stage1_counter_num = rte_le_to_cpu_16(req->stage1_counter_num); 269fcba820dSWei Hu (Xavier) *stage2_counter_num = rte_le_to_cpu_16(req->stage2_counter_num); 270fcba820dSWei Hu (Xavier) 271fcba820dSWei Hu (Xavier) return ret; 272fcba820dSWei Hu (Xavier) } 273fcba820dSWei Hu (Xavier) 274fcba820dSWei Hu (Xavier) static int hns3_set_fd_key_config(struct hns3_adapter *hns) 275fcba820dSWei Hu (Xavier) { 276fcba820dSWei Hu (Xavier) struct hns3_set_fd_key_config_cmd *req; 277fcba820dSWei Hu (Xavier) struct hns3_fd_key_cfg *key_cfg; 278fcba820dSWei Hu (Xavier) struct hns3_pf *pf = &hns->pf; 279fcba820dSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 280fcba820dSWei Hu (Xavier) struct hns3_cmd_desc desc; 281fcba820dSWei Hu (Xavier) int ret; 282fcba820dSWei Hu (Xavier) 283fcba820dSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FD_KEY_CONFIG, false); 284fcba820dSWei Hu (Xavier) 285fcba820dSWei Hu (Xavier) req = (struct hns3_set_fd_key_config_cmd *)desc.data; 286fcba820dSWei Hu (Xavier) key_cfg = &pf->fdir.fd_cfg.key_cfg[HNS3_FD_STAGE_1]; 287fcba820dSWei Hu (Xavier) req->stage = HNS3_FD_STAGE_1; 288fcba820dSWei Hu (Xavier) req->key_select = key_cfg->key_sel; 289fcba820dSWei Hu (Xavier) req->inner_sipv6_word_en = key_cfg->inner_sipv6_word_en; 290fcba820dSWei Hu (Xavier) req->inner_dipv6_word_en = key_cfg->inner_dipv6_word_en; 291fcba820dSWei Hu (Xavier) req->outer_sipv6_word_en = key_cfg->outer_sipv6_word_en; 292fcba820dSWei Hu (Xavier) req->outer_dipv6_word_en = key_cfg->outer_dipv6_word_en; 293fcba820dSWei Hu (Xavier) req->tuple_mask = rte_cpu_to_le_32(~key_cfg->tuple_active); 294fcba820dSWei Hu (Xavier) req->meta_data_mask = rte_cpu_to_le_32(~key_cfg->meta_data_active); 295fcba820dSWei Hu (Xavier) 296fcba820dSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc, 1); 297fcba820dSWei Hu (Xavier) if (ret) 298fcba820dSWei Hu (Xavier) hns3_err(hw, "Set fd key fail, ret=%d", ret); 299fcba820dSWei Hu (Xavier) 300fcba820dSWei Hu (Xavier) return ret; 301fcba820dSWei Hu (Xavier) } 302fcba820dSWei Hu (Xavier) 303a4732847SChengwen Feng static void hns3_set_tuple_config(struct hns3_adapter *hns, 304a4732847SChengwen Feng struct hns3_fd_key_cfg *key_cfg) 305a4732847SChengwen Feng { 306a4732847SChengwen Feng enum hns3_fdir_tuple_config tuple_cfg = hns->pf.fdir.tuple_cfg; 307a4732847SChengwen Feng 308a4732847SChengwen Feng if (tuple_cfg == HNS3_FDIR_TUPLE_CONFIG_DEFAULT) 309a4732847SChengwen Feng return; 310a4732847SChengwen Feng 311a4732847SChengwen Feng if (hns->pf.fdir.fd_cfg.max_key_length != MAX_KEY_LENGTH) { 312a4732847SChengwen Feng hns3_warn(&hns->hw, "fdir tuple config only valid with 400bit key!"); 313a4732847SChengwen Feng return; 314a4732847SChengwen Feng } 315a4732847SChengwen Feng 316a4732847SChengwen Feng switch (tuple_cfg) { 317a4732847SChengwen Feng case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INSMAC: 318a4732847SChengwen Feng key_cfg->tuple_active &= ~BIT(INNER_SRC_MAC); 319a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); 320a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); 321a4732847SChengwen Feng break; 322a4732847SChengwen Feng case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INDMAC: 323a4732847SChengwen Feng key_cfg->tuple_active &= ~BIT(INNER_DST_MAC); 324a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); 325a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); 326a4732847SChengwen Feng break; 327a4732847SChengwen Feng case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INSIP: 328a4732847SChengwen Feng key_cfg->tuple_active &= ~BIT(INNER_SRC_IP); 329a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); 330a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); 331a4732847SChengwen Feng break; 332a4732847SChengwen Feng case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INDIP: 333a4732847SChengwen Feng key_cfg->tuple_active &= ~BIT(INNER_DST_IP); 334a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); 335a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); 336a4732847SChengwen Feng break; 337a4732847SChengwen Feng case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_SCTPTAG: 338a4732847SChengwen Feng key_cfg->tuple_active &= ~BIT(INNER_SCTP_TAG); 339a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); 340a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); 341a4732847SChengwen Feng break; 342a4732847SChengwen Feng case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_TUNVNI: 343a4732847SChengwen Feng key_cfg->tuple_active &= ~BIT(OUTER_TUN_VNI); 344a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); 345a4732847SChengwen Feng key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); 346a4732847SChengwen Feng break; 347a4732847SChengwen Feng default: 348a4732847SChengwen Feng hns3_err(&hns->hw, "invalid fdir tuple config %u!", tuple_cfg); 349a4732847SChengwen Feng return; 350a4732847SChengwen Feng } 351a4732847SChengwen Feng 352a4732847SChengwen Feng hns3_info(&hns->hw, "fdir tuple config %s!", hns3_tuple_config_name(tuple_cfg)); 353a4732847SChengwen Feng } 354a4732847SChengwen Feng 355fcba820dSWei Hu (Xavier) int hns3_init_fd_config(struct hns3_adapter *hns) 356fcba820dSWei Hu (Xavier) { 357fcba820dSWei Hu (Xavier) struct hns3_pf *pf = &hns->pf; 358fcba820dSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 359fcba820dSWei Hu (Xavier) struct hns3_fd_key_cfg *key_cfg; 360fcba820dSWei Hu (Xavier) int ret; 361fcba820dSWei Hu (Xavier) 362fcba820dSWei Hu (Xavier) ret = hns3_get_fd_mode(hw, &pf->fdir.fd_cfg.fd_mode); 363fcba820dSWei Hu (Xavier) if (ret) 364fcba820dSWei Hu (Xavier) return ret; 365fcba820dSWei Hu (Xavier) 366fcba820dSWei Hu (Xavier) switch (pf->fdir.fd_cfg.fd_mode) { 367fcba820dSWei Hu (Xavier) case HNS3_FD_MODE_DEPTH_2K_WIDTH_400B_STAGE_1: 368fcba820dSWei Hu (Xavier) pf->fdir.fd_cfg.max_key_length = MAX_KEY_LENGTH; 369fcba820dSWei Hu (Xavier) break; 370fcba820dSWei Hu (Xavier) case HNS3_FD_MODE_DEPTH_4K_WIDTH_200B_STAGE_1: 371fcba820dSWei Hu (Xavier) pf->fdir.fd_cfg.max_key_length = MAX_200B_KEY_LENGTH; 372fcba820dSWei Hu (Xavier) hns3_warn(hw, "Unsupported tunnel filter in 4K*200Bit"); 373fcba820dSWei Hu (Xavier) break; 374fcba820dSWei Hu (Xavier) default: 3752427c27eSHongbo Zheng hns3_err(hw, "Unsupported flow director mode %u", 376fcba820dSWei Hu (Xavier) pf->fdir.fd_cfg.fd_mode); 377fcba820dSWei Hu (Xavier) return -EOPNOTSUPP; 378fcba820dSWei Hu (Xavier) } 379fcba820dSWei Hu (Xavier) 380fcba820dSWei Hu (Xavier) key_cfg = &pf->fdir.fd_cfg.key_cfg[HNS3_FD_STAGE_1]; 381fcba820dSWei Hu (Xavier) key_cfg->key_sel = HNS3_FD_KEY_BASE_ON_TUPLE; 382fcba820dSWei Hu (Xavier) key_cfg->inner_sipv6_word_en = IPV6_ADDR_WORD_MASK; 383fcba820dSWei Hu (Xavier) key_cfg->inner_dipv6_word_en = IPV6_ADDR_WORD_MASK; 384fcba820dSWei Hu (Xavier) key_cfg->outer_sipv6_word_en = 0; 385fcba820dSWei Hu (Xavier) key_cfg->outer_dipv6_word_en = 0; 386fcba820dSWei Hu (Xavier) 387fcba820dSWei Hu (Xavier) key_cfg->tuple_active = BIT(INNER_VLAN_TAG1) | BIT(INNER_ETH_TYPE) | 388fcba820dSWei Hu (Xavier) BIT(INNER_IP_PROTO) | BIT(INNER_IP_TOS) | 389fcba820dSWei Hu (Xavier) BIT(INNER_SRC_IP) | BIT(INNER_DST_IP) | 390fcba820dSWei Hu (Xavier) BIT(INNER_SRC_PORT) | BIT(INNER_DST_PORT); 391cc9dbd9aSChengwen Feng hns3_dbg(hw, "fdir tuple: inner<vlan_tag1 eth_type ip_src ip_dst " 392cc9dbd9aSChengwen Feng "ip_proto ip_tos l4_src_port l4_dst_port>"); 393fcba820dSWei Hu (Xavier) 394fcba820dSWei Hu (Xavier) /* If use max 400bit key, we can support tuples for ether type */ 395fcba820dSWei Hu (Xavier) if (pf->fdir.fd_cfg.max_key_length == MAX_KEY_LENGTH) { 396fcba820dSWei Hu (Xavier) key_cfg->tuple_active |= 397fcba820dSWei Hu (Xavier) BIT(INNER_DST_MAC) | BIT(INNER_SRC_MAC) | 398fcba820dSWei Hu (Xavier) BIT(OUTER_SRC_PORT) | BIT(INNER_SCTP_TAG) | 399fcba820dSWei Hu (Xavier) BIT(OUTER_DST_PORT) | BIT(INNER_VLAN_TAG2) | 400fcba820dSWei Hu (Xavier) BIT(OUTER_TUN_VNI) | BIT(OUTER_TUN_FLOW_ID) | 401fcba820dSWei Hu (Xavier) BIT(OUTER_ETH_TYPE) | BIT(OUTER_IP_PROTO); 402cc9dbd9aSChengwen Feng hns3_dbg(hw, "fdir tuple more: inner<dst_mac src_mac " 403cc9dbd9aSChengwen Feng "vlan_tag2 sctp_tag> outer<eth_type ip_proto " 404cc9dbd9aSChengwen Feng "l4_src_port l4_dst_port tun_vni tun_flow_id>"); 405fcba820dSWei Hu (Xavier) } 406fcba820dSWei Hu (Xavier) 407a4732847SChengwen Feng hns3_set_tuple_config(hns, key_cfg); 408a4732847SChengwen Feng 409fcba820dSWei Hu (Xavier) /* roce_type is used to filter roce frames 410fcba820dSWei Hu (Xavier) * dst_vport is used to specify the rule 411fcba820dSWei Hu (Xavier) */ 41206b9ee34SHuisong Li key_cfg->meta_data_active = BIT(DST_VPORT) | BIT(TUNNEL_PACKET); 41306b9ee34SHuisong Li if (pf->fdir.vlan_match_mode) 41406b9ee34SHuisong Li key_cfg->meta_data_active |= BIT(VLAN_NUMBER); 41506b9ee34SHuisong Li 41606b9ee34SHuisong Li hns3_dbg(hw, "fdir meta data: dst_vport tunnel_packet %s", 41706b9ee34SHuisong Li (pf->fdir.vlan_match_mode == HNS3_FDIR_VLAN_STRICT_MATCH) ? 41806b9ee34SHuisong Li "vlan_number" : ""); 419fcba820dSWei Hu (Xavier) 420fcba820dSWei Hu (Xavier) ret = hns3_get_fd_allocation(hw, 421fcba820dSWei Hu (Xavier) &pf->fdir.fd_cfg.rule_num[HNS3_FD_STAGE_1], 422fcba820dSWei Hu (Xavier) &pf->fdir.fd_cfg.rule_num[HNS3_FD_STAGE_2], 423fcba820dSWei Hu (Xavier) &pf->fdir.fd_cfg.cnt_num[HNS3_FD_STAGE_1], 424fcba820dSWei Hu (Xavier) &pf->fdir.fd_cfg.cnt_num[HNS3_FD_STAGE_2]); 425fcba820dSWei Hu (Xavier) if (ret) 426fcba820dSWei Hu (Xavier) return ret; 427fcba820dSWei Hu (Xavier) 4285bddaf38SHuisong Li hns3_dbg(hw, "fdir: stage1<rules-%u counters-%u> stage2<rules-%u counters=%u>", 429cc9dbd9aSChengwen Feng pf->fdir.fd_cfg.rule_num[HNS3_FD_STAGE_1], 430cc9dbd9aSChengwen Feng pf->fdir.fd_cfg.cnt_num[HNS3_FD_STAGE_1], 431cc9dbd9aSChengwen Feng pf->fdir.fd_cfg.rule_num[HNS3_FD_STAGE_2], 432cc9dbd9aSChengwen Feng pf->fdir.fd_cfg.cnt_num[HNS3_FD_STAGE_2]); 433cc9dbd9aSChengwen Feng 434fcba820dSWei Hu (Xavier) return hns3_set_fd_key_config(hns); 435fcba820dSWei Hu (Xavier) } 436fcba820dSWei Hu (Xavier) 437fcba820dSWei Hu (Xavier) static int hns3_fd_tcam_config(struct hns3_hw *hw, bool sel_x, int loc, 438fcba820dSWei Hu (Xavier) uint8_t *key, bool is_add) 439fcba820dSWei Hu (Xavier) { 440fcba820dSWei Hu (Xavier) #define FD_TCAM_CMD_NUM 3 441fcba820dSWei Hu (Xavier) struct hns3_fd_tcam_config_1_cmd *req1; 442fcba820dSWei Hu (Xavier) struct hns3_fd_tcam_config_2_cmd *req2; 443fcba820dSWei Hu (Xavier) struct hns3_fd_tcam_config_3_cmd *req3; 444fcba820dSWei Hu (Xavier) struct hns3_cmd_desc desc[FD_TCAM_CMD_NUM]; 445fcba820dSWei Hu (Xavier) int len; 446fcba820dSWei Hu (Xavier) int ret; 447fcba820dSWei Hu (Xavier) 448fcba820dSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_FD_TCAM_OP, false); 449fcba820dSWei Hu (Xavier) desc[0].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); 450fcba820dSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc[1], HNS3_OPC_FD_TCAM_OP, false); 451fcba820dSWei Hu (Xavier) desc[1].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); 452fcba820dSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc[2], HNS3_OPC_FD_TCAM_OP, false); 453fcba820dSWei Hu (Xavier) 454fcba820dSWei Hu (Xavier) req1 = (struct hns3_fd_tcam_config_1_cmd *)desc[0].data; 455fcba820dSWei Hu (Xavier) req2 = (struct hns3_fd_tcam_config_2_cmd *)desc[1].data; 456fcba820dSWei Hu (Xavier) req3 = (struct hns3_fd_tcam_config_3_cmd *)desc[2].data; 457fcba820dSWei Hu (Xavier) 458fcba820dSWei Hu (Xavier) req1->stage = HNS3_FD_STAGE_1; 459fcba820dSWei Hu (Xavier) req1->xy_sel = sel_x ? 1 : 0; 460fcba820dSWei Hu (Xavier) hns3_set_bit(req1->port_info, HNS3_FD_EPORT_SW_EN_B, 0); 461fcba820dSWei Hu (Xavier) req1->index = rte_cpu_to_le_32(loc); 462fcba820dSWei Hu (Xavier) req1->entry_vld = sel_x ? is_add : 0; 463fcba820dSWei Hu (Xavier) 464fcba820dSWei Hu (Xavier) if (key) { 465fcba820dSWei Hu (Xavier) len = sizeof(req1->tcam_data); 466fcba820dSWei Hu (Xavier) memcpy(req1->tcam_data, key, len); 467fcba820dSWei Hu (Xavier) key += len; 468fcba820dSWei Hu (Xavier) 469fcba820dSWei Hu (Xavier) len = sizeof(req2->tcam_data); 470fcba820dSWei Hu (Xavier) memcpy(req2->tcam_data, key, len); 471fcba820dSWei Hu (Xavier) key += len; 472fcba820dSWei Hu (Xavier) 473fcba820dSWei Hu (Xavier) len = sizeof(req3->tcam_data); 474fcba820dSWei Hu (Xavier) memcpy(req3->tcam_data, key, len); 475fcba820dSWei Hu (Xavier) } 476fcba820dSWei Hu (Xavier) 477fcba820dSWei Hu (Xavier) ret = hns3_cmd_send(hw, desc, FD_TCAM_CMD_NUM); 478fcba820dSWei Hu (Xavier) if (ret) 479fcba820dSWei Hu (Xavier) hns3_err(hw, "Config tcam key fail, ret=%d loc=%d add=%d", 480fcba820dSWei Hu (Xavier) ret, loc, is_add); 481fcba820dSWei Hu (Xavier) return ret; 482fcba820dSWei Hu (Xavier) } 483fcba820dSWei Hu (Xavier) 484fcba820dSWei Hu (Xavier) static int hns3_fd_ad_config(struct hns3_hw *hw, int loc, 485fcba820dSWei Hu (Xavier) struct hns3_fd_ad_data *action) 486fcba820dSWei Hu (Xavier) { 487fcba820dSWei Hu (Xavier) struct hns3_fd_ad_config_cmd *req; 488fcba820dSWei Hu (Xavier) struct hns3_cmd_desc desc; 489fcba820dSWei Hu (Xavier) uint64_t ad_data = 0; 490fcba820dSWei Hu (Xavier) int ret; 491fcba820dSWei Hu (Xavier) 492fcba820dSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FD_AD_OP, false); 493fcba820dSWei Hu (Xavier) 494fcba820dSWei Hu (Xavier) req = (struct hns3_fd_ad_config_cmd *)desc.data; 495fcba820dSWei Hu (Xavier) req->index = rte_cpu_to_le_32(loc); 496fcba820dSWei Hu (Xavier) req->stage = HNS3_FD_STAGE_1; 497fcba820dSWei Hu (Xavier) 498fcba820dSWei Hu (Xavier) hns3_set_bit(ad_data, HNS3_FD_AD_WR_RULE_ID_B, 499fcba820dSWei Hu (Xavier) action->write_rule_id_to_bd); 500fcba820dSWei Hu (Xavier) hns3_set_field(ad_data, HNS3_FD_AD_RULE_ID_M, HNS3_FD_AD_RULE_ID_S, 501fcba820dSWei Hu (Xavier) action->rule_id); 502f8e7fcbfSChengwen Feng if (action->nb_queues > 1) { 503f8e7fcbfSChengwen Feng hns3_set_bit(ad_data, HNS3_FD_AD_QUEUE_REGION_EN_B, 1); 504f8e7fcbfSChengwen Feng hns3_set_field(ad_data, HNS3_FD_AD_QUEUE_REGION_SIZE_M, 505f8e7fcbfSChengwen Feng HNS3_FD_AD_QUEUE_REGION_SIZE_S, 506f8e7fcbfSChengwen Feng rte_log2_u32(action->nb_queues)); 507f8e7fcbfSChengwen Feng } 50859200fd7SWei Hu (Xavier) /* set extend bit if counter_id is in [128 ~ 255] */ 50959200fd7SWei Hu (Xavier) if (action->counter_id & BIT(HNS3_FD_AD_COUNTER_HIGH_BIT)) 51059200fd7SWei Hu (Xavier) hns3_set_bit(ad_data, HNS3_FD_AD_COUNTER_HIGH_BIT_B, 1); 51176d79456SWei Hu (Xavier) /* set extend bit if queue id > 1024 */ 51276d79456SWei Hu (Xavier) if (action->queue_id & BIT(HNS3_FD_AD_QUEUE_ID_HIGH_BIT)) 51376d79456SWei Hu (Xavier) hns3_set_bit(ad_data, HNS3_FD_AD_QUEUE_ID_HIGH_BIT_B, 1); 514fcba820dSWei Hu (Xavier) ad_data <<= HNS3_FD_AD_DATA_S; 515fcba820dSWei Hu (Xavier) hns3_set_bit(ad_data, HNS3_FD_AD_DROP_B, action->drop_packet); 516f8e7fcbfSChengwen Feng if (action->nb_queues == 1) 517f8e7fcbfSChengwen Feng hns3_set_bit(ad_data, HNS3_FD_AD_DIRECT_QID_B, 1); 518fcba820dSWei Hu (Xavier) hns3_set_field(ad_data, HNS3_FD_AD_QID_M, HNS3_FD_AD_QID_S, 519fcba820dSWei Hu (Xavier) action->queue_id); 520fcba820dSWei Hu (Xavier) hns3_set_bit(ad_data, HNS3_FD_AD_USE_COUNTER_B, action->use_counter); 521fcba820dSWei Hu (Xavier) hns3_set_field(ad_data, HNS3_FD_AD_COUNTER_NUM_M, 522fcba820dSWei Hu (Xavier) HNS3_FD_AD_COUNTER_NUM_S, action->counter_id); 523fcba820dSWei Hu (Xavier) hns3_set_bit(ad_data, HNS3_FD_AD_NXT_STEP_B, action->use_next_stage); 524fcba820dSWei Hu (Xavier) hns3_set_field(ad_data, HNS3_FD_AD_NXT_KEY_M, HNS3_FD_AD_NXT_KEY_S, 525f8e7fcbfSChengwen Feng action->next_input_key); 526fcba820dSWei Hu (Xavier) 527fcba820dSWei Hu (Xavier) req->ad_data = rte_cpu_to_le_64(ad_data); 528fcba820dSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc, 1); 529fcba820dSWei Hu (Xavier) if (ret) 530fcba820dSWei Hu (Xavier) hns3_err(hw, "Config fd ad fail, ret=%d loc=%d", ret, loc); 531fcba820dSWei Hu (Xavier) 532fcba820dSWei Hu (Xavier) return ret; 533fcba820dSWei Hu (Xavier) } 534fcba820dSWei Hu (Xavier) 535fcba820dSWei Hu (Xavier) static inline void hns3_fd_convert_mac(uint8_t *key, uint8_t *mask, 536fcba820dSWei Hu (Xavier) uint8_t *mac_x, uint8_t *mac_y) 537fcba820dSWei Hu (Xavier) { 538fcba820dSWei Hu (Xavier) uint8_t tmp; 539fcba820dSWei Hu (Xavier) int i; 540fcba820dSWei Hu (Xavier) 541fcba820dSWei Hu (Xavier) for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) { 542fcba820dSWei Hu (Xavier) tmp = RTE_ETHER_ADDR_LEN - 1 - i; 543fcba820dSWei Hu (Xavier) calc_x(mac_x[tmp], key[i], mask[i]); 544fcba820dSWei Hu (Xavier) calc_y(mac_y[tmp], key[i], mask[i]); 545fcba820dSWei Hu (Xavier) } 546fcba820dSWei Hu (Xavier) } 547fcba820dSWei Hu (Xavier) 548fcba820dSWei Hu (Xavier) static void hns3_fd_convert_int16(uint32_t tuple, struct hns3_fdir_rule *rule, 549fcba820dSWei Hu (Xavier) uint8_t *val_x, uint8_t *val_y) 550fcba820dSWei Hu (Xavier) { 551fcba820dSWei Hu (Xavier) uint16_t tmp_x_s; 552fcba820dSWei Hu (Xavier) uint16_t tmp_y_s; 553fcba820dSWei Hu (Xavier) uint16_t mask; 554fcba820dSWei Hu (Xavier) uint16_t key; 555fcba820dSWei Hu (Xavier) 556fcba820dSWei Hu (Xavier) switch (tuple) { 557a4732847SChengwen Feng case OUTER_VLAN_TAG_FST: 558a4732847SChengwen Feng key = rule->key_conf.spec.outer_vlan_tag1; 559a4732847SChengwen Feng mask = rule->key_conf.mask.outer_vlan_tag1; 560a4732847SChengwen Feng break; 561a4732847SChengwen Feng case OUTER_VLAN_TAG_SEC: 562a4732847SChengwen Feng key = rule->key_conf.spec.outer_vlan_tag2; 563a4732847SChengwen Feng mask = rule->key_conf.mask.outer_vlan_tag2; 564a4732847SChengwen Feng break; 565fcba820dSWei Hu (Xavier) case OUTER_SRC_PORT: 566fcba820dSWei Hu (Xavier) key = rule->key_conf.spec.outer_src_port; 567fcba820dSWei Hu (Xavier) mask = rule->key_conf.mask.outer_src_port; 568fcba820dSWei Hu (Xavier) break; 569fcba820dSWei Hu (Xavier) case OUTER_DST_PORT: 570fcba820dSWei Hu (Xavier) key = rule->key_conf.spec.tunnel_type; 571fcba820dSWei Hu (Xavier) mask = rule->key_conf.mask.tunnel_type; 572fcba820dSWei Hu (Xavier) break; 573fcba820dSWei Hu (Xavier) case OUTER_ETH_TYPE: 574fcba820dSWei Hu (Xavier) key = rule->key_conf.spec.outer_ether_type; 575fcba820dSWei Hu (Xavier) mask = rule->key_conf.mask.outer_ether_type; 576fcba820dSWei Hu (Xavier) break; 577fcba820dSWei Hu (Xavier) case INNER_SRC_PORT: 578fcba820dSWei Hu (Xavier) key = rule->key_conf.spec.src_port; 579fcba820dSWei Hu (Xavier) mask = rule->key_conf.mask.src_port; 580fcba820dSWei Hu (Xavier) break; 581fcba820dSWei Hu (Xavier) case INNER_DST_PORT: 582fcba820dSWei Hu (Xavier) key = rule->key_conf.spec.dst_port; 583fcba820dSWei Hu (Xavier) mask = rule->key_conf.mask.dst_port; 584fcba820dSWei Hu (Xavier) break; 585fcba820dSWei Hu (Xavier) case INNER_VLAN_TAG1: 586fcba820dSWei Hu (Xavier) key = rule->key_conf.spec.vlan_tag1; 587fcba820dSWei Hu (Xavier) mask = rule->key_conf.mask.vlan_tag1; 588fcba820dSWei Hu (Xavier) break; 589fcba820dSWei Hu (Xavier) case INNER_VLAN_TAG2: 590fcba820dSWei Hu (Xavier) key = rule->key_conf.spec.vlan_tag2; 591fcba820dSWei Hu (Xavier) mask = rule->key_conf.mask.vlan_tag2; 592fcba820dSWei Hu (Xavier) break; 593fcba820dSWei Hu (Xavier) default: 594fcba820dSWei Hu (Xavier) /* INNER_ETH_TYPE: */ 595fcba820dSWei Hu (Xavier) key = rule->key_conf.spec.ether_type; 596fcba820dSWei Hu (Xavier) mask = rule->key_conf.mask.ether_type; 597fcba820dSWei Hu (Xavier) break; 598fcba820dSWei Hu (Xavier) } 599fcba820dSWei Hu (Xavier) calc_x(tmp_x_s, key, mask); 600fcba820dSWei Hu (Xavier) calc_y(tmp_y_s, key, mask); 601fcba820dSWei Hu (Xavier) val_x[0] = rte_cpu_to_le_16(tmp_x_s) & 0xFF; 602fcba820dSWei Hu (Xavier) val_x[1] = rte_cpu_to_le_16(tmp_x_s) >> HNS3_BITS_PER_BYTE; 603fcba820dSWei Hu (Xavier) val_y[0] = rte_cpu_to_le_16(tmp_y_s) & 0xFF; 604fcba820dSWei Hu (Xavier) val_y[1] = rte_cpu_to_le_16(tmp_y_s) >> HNS3_BITS_PER_BYTE; 605fcba820dSWei Hu (Xavier) } 606fcba820dSWei Hu (Xavier) 607fcba820dSWei Hu (Xavier) static inline void hns3_fd_convert_int32(uint32_t key, uint32_t mask, 608fcba820dSWei Hu (Xavier) uint8_t *val_x, uint8_t *val_y) 609fcba820dSWei Hu (Xavier) { 610fcba820dSWei Hu (Xavier) uint32_t tmp_x_l; 611fcba820dSWei Hu (Xavier) uint32_t tmp_y_l; 612fcba820dSWei Hu (Xavier) 613fcba820dSWei Hu (Xavier) calc_x(tmp_x_l, key, mask); 614fcba820dSWei Hu (Xavier) calc_y(tmp_y_l, key, mask); 615fcba820dSWei Hu (Xavier) memcpy(val_x, &tmp_x_l, sizeof(tmp_x_l)); 616fcba820dSWei Hu (Xavier) memcpy(val_y, &tmp_y_l, sizeof(tmp_y_l)); 617fcba820dSWei Hu (Xavier) } 618fcba820dSWei Hu (Xavier) 61918a4b4c3SWei Hu (Xavier) static bool hns3_fd_convert_tuple(struct hns3_hw *hw, 62018a4b4c3SWei Hu (Xavier) uint32_t tuple, uint8_t *key_x, 621fcba820dSWei Hu (Xavier) uint8_t *key_y, struct hns3_fdir_rule *rule) 622fcba820dSWei Hu (Xavier) { 623fcba820dSWei Hu (Xavier) struct hns3_fdir_key_conf *key_conf; 624fcba820dSWei Hu (Xavier) int tmp; 625fcba820dSWei Hu (Xavier) int i; 626fcba820dSWei Hu (Xavier) 627fcba820dSWei Hu (Xavier) if ((rule->input_set & BIT(tuple)) == 0) 628fcba820dSWei Hu (Xavier) return true; 629fcba820dSWei Hu (Xavier) 630fcba820dSWei Hu (Xavier) key_conf = &rule->key_conf; 631fcba820dSWei Hu (Xavier) switch (tuple) { 632fcba820dSWei Hu (Xavier) case INNER_DST_MAC: 633fcba820dSWei Hu (Xavier) hns3_fd_convert_mac(key_conf->spec.dst_mac, 634fcba820dSWei Hu (Xavier) key_conf->mask.dst_mac, key_x, key_y); 635fcba820dSWei Hu (Xavier) break; 636fcba820dSWei Hu (Xavier) case INNER_SRC_MAC: 637fcba820dSWei Hu (Xavier) hns3_fd_convert_mac(key_conf->spec.src_mac, 638fcba820dSWei Hu (Xavier) key_conf->mask.src_mac, key_x, key_y); 639fcba820dSWei Hu (Xavier) break; 640a4732847SChengwen Feng case OUTER_VLAN_TAG_FST: 641a4732847SChengwen Feng case OUTER_VLAN_TAG_SEC: 642fcba820dSWei Hu (Xavier) case OUTER_SRC_PORT: 643fcba820dSWei Hu (Xavier) case OUTER_DST_PORT: 644fcba820dSWei Hu (Xavier) case OUTER_ETH_TYPE: 645fcba820dSWei Hu (Xavier) case INNER_SRC_PORT: 646fcba820dSWei Hu (Xavier) case INNER_DST_PORT: 647fcba820dSWei Hu (Xavier) case INNER_VLAN_TAG1: 648fcba820dSWei Hu (Xavier) case INNER_VLAN_TAG2: 649fcba820dSWei Hu (Xavier) case INNER_ETH_TYPE: 650fcba820dSWei Hu (Xavier) hns3_fd_convert_int16(tuple, rule, key_x, key_y); 651fcba820dSWei Hu (Xavier) break; 652fcba820dSWei Hu (Xavier) case INNER_SRC_IP: 653fcba820dSWei Hu (Xavier) hns3_fd_convert_int32(key_conf->spec.src_ip[IP_ADDR_KEY_ID], 654fcba820dSWei Hu (Xavier) key_conf->mask.src_ip[IP_ADDR_KEY_ID], 655fcba820dSWei Hu (Xavier) key_x, key_y); 656fcba820dSWei Hu (Xavier) break; 657fcba820dSWei Hu (Xavier) case INNER_DST_IP: 658fcba820dSWei Hu (Xavier) hns3_fd_convert_int32(key_conf->spec.dst_ip[IP_ADDR_KEY_ID], 659fcba820dSWei Hu (Xavier) key_conf->mask.dst_ip[IP_ADDR_KEY_ID], 660fcba820dSWei Hu (Xavier) key_x, key_y); 661fcba820dSWei Hu (Xavier) break; 662fcba820dSWei Hu (Xavier) case INNER_SCTP_TAG: 663fcba820dSWei Hu (Xavier) hns3_fd_convert_int32(key_conf->spec.sctp_tag, 664fcba820dSWei Hu (Xavier) key_conf->mask.sctp_tag, key_x, key_y); 665fcba820dSWei Hu (Xavier) break; 666fcba820dSWei Hu (Xavier) case OUTER_TUN_VNI: 667fcba820dSWei Hu (Xavier) for (i = 0; i < VNI_OR_TNI_LEN; i++) { 668fcba820dSWei Hu (Xavier) tmp = VNI_OR_TNI_LEN - 1 - i; 669fcba820dSWei Hu (Xavier) calc_x(key_x[tmp], 670fcba820dSWei Hu (Xavier) key_conf->spec.outer_tun_vni[i], 671fcba820dSWei Hu (Xavier) key_conf->mask.outer_tun_vni[i]); 672fcba820dSWei Hu (Xavier) calc_y(key_y[tmp], 673fcba820dSWei Hu (Xavier) key_conf->spec.outer_tun_vni[i], 674fcba820dSWei Hu (Xavier) key_conf->mask.outer_tun_vni[i]); 675fcba820dSWei Hu (Xavier) } 676fcba820dSWei Hu (Xavier) break; 677fcba820dSWei Hu (Xavier) case OUTER_TUN_FLOW_ID: 678fcba820dSWei Hu (Xavier) calc_x(*key_x, key_conf->spec.outer_tun_flow_id, 679fcba820dSWei Hu (Xavier) key_conf->mask.outer_tun_flow_id); 680fcba820dSWei Hu (Xavier) calc_y(*key_y, key_conf->spec.outer_tun_flow_id, 681fcba820dSWei Hu (Xavier) key_conf->mask.outer_tun_flow_id); 682fcba820dSWei Hu (Xavier) break; 683fcba820dSWei Hu (Xavier) case INNER_IP_TOS: 684fcba820dSWei Hu (Xavier) calc_x(*key_x, key_conf->spec.ip_tos, key_conf->mask.ip_tos); 685fcba820dSWei Hu (Xavier) calc_y(*key_y, key_conf->spec.ip_tos, key_conf->mask.ip_tos); 686fcba820dSWei Hu (Xavier) break; 687fcba820dSWei Hu (Xavier) case OUTER_IP_PROTO: 688fcba820dSWei Hu (Xavier) calc_x(*key_x, key_conf->spec.outer_proto, 689fcba820dSWei Hu (Xavier) key_conf->mask.outer_proto); 690fcba820dSWei Hu (Xavier) calc_y(*key_y, key_conf->spec.outer_proto, 691fcba820dSWei Hu (Xavier) key_conf->mask.outer_proto); 692fcba820dSWei Hu (Xavier) break; 693fcba820dSWei Hu (Xavier) case INNER_IP_PROTO: 694fcba820dSWei Hu (Xavier) calc_x(*key_x, key_conf->spec.ip_proto, 695fcba820dSWei Hu (Xavier) key_conf->mask.ip_proto); 696fcba820dSWei Hu (Xavier) calc_y(*key_y, key_conf->spec.ip_proto, 697fcba820dSWei Hu (Xavier) key_conf->mask.ip_proto); 698fcba820dSWei Hu (Xavier) break; 69918a4b4c3SWei Hu (Xavier) default: 7002427c27eSHongbo Zheng hns3_warn(hw, "not support tuple of (%u)", tuple); 70166689dc0SHuisong Li return false; 702fcba820dSWei Hu (Xavier) } 703fcba820dSWei Hu (Xavier) return true; 704fcba820dSWei Hu (Xavier) } 705fcba820dSWei Hu (Xavier) 706fcba820dSWei Hu (Xavier) static uint32_t hns3_get_port_number(uint8_t pf_id, uint8_t vf_id) 707fcba820dSWei Hu (Xavier) { 708fcba820dSWei Hu (Xavier) uint32_t port_number = 0; 709fcba820dSWei Hu (Xavier) 710fcba820dSWei Hu (Xavier) hns3_set_field(port_number, HNS3_PF_ID_M, HNS3_PF_ID_S, pf_id); 711fcba820dSWei Hu (Xavier) hns3_set_field(port_number, HNS3_VF_ID_M, HNS3_VF_ID_S, vf_id); 712fcba820dSWei Hu (Xavier) hns3_set_bit(port_number, HNS3_PORT_TYPE_B, HOST_PORT); 713fcba820dSWei Hu (Xavier) 714fcba820dSWei Hu (Xavier) return port_number; 715fcba820dSWei Hu (Xavier) } 716fcba820dSWei Hu (Xavier) 717fcba820dSWei Hu (Xavier) static void hns3_fd_convert_meta_data(struct hns3_fd_key_cfg *cfg, 718fcba820dSWei Hu (Xavier) uint8_t vf_id, 719fcba820dSWei Hu (Xavier) struct hns3_fdir_rule *rule, 720fcba820dSWei Hu (Xavier) uint8_t *key_x, uint8_t *key_y) 721fcba820dSWei Hu (Xavier) { 722fcba820dSWei Hu (Xavier) uint16_t meta_data = 0; 7235c471cb5SWei Hu (Xavier) uint32_t port_number; 724fcba820dSWei Hu (Xavier) uint8_t cur_pos = 0; 725fcba820dSWei Hu (Xavier) uint8_t tuple_size; 726fcba820dSWei Hu (Xavier) uint8_t shift_bits; 727fcba820dSWei Hu (Xavier) uint32_t tmp_x; 728fcba820dSWei Hu (Xavier) uint32_t tmp_y; 729fcba820dSWei Hu (Xavier) uint8_t i; 730fcba820dSWei Hu (Xavier) 731fcba820dSWei Hu (Xavier) for (i = 0; i < MAX_META_DATA; i++) { 732fcba820dSWei Hu (Xavier) if ((cfg->meta_data_active & BIT(i)) == 0) 733fcba820dSWei Hu (Xavier) continue; 734fcba820dSWei Hu (Xavier) 735fcba820dSWei Hu (Xavier) tuple_size = meta_data_key_info[i].key_length; 736fcba820dSWei Hu (Xavier) if (i == TUNNEL_PACKET) { 737fcba820dSWei Hu (Xavier) hns3_set_bit(meta_data, cur_pos, 738fcba820dSWei Hu (Xavier) rule->key_conf.spec.tunnel_type ? 1 : 0); 739fcba820dSWei Hu (Xavier) cur_pos += tuple_size; 740fcba820dSWei Hu (Xavier) } else if (i == VLAN_NUMBER) { 7415c471cb5SWei Hu (Xavier) uint32_t vlan_tag; 742fcba820dSWei Hu (Xavier) uint8_t vlan_num; 7435bddaf38SHuisong Li 744fcba820dSWei Hu (Xavier) if (rule->key_conf.spec.tunnel_type == 0) 745fcba820dSWei Hu (Xavier) vlan_num = rule->key_conf.vlan_num; 746fcba820dSWei Hu (Xavier) else 747fcba820dSWei Hu (Xavier) vlan_num = rule->key_conf.outer_vlan_num; 748fcba820dSWei Hu (Xavier) if (vlan_num == 1) 749fcba820dSWei Hu (Xavier) vlan_tag = HNS3_VLAN_TAG_TYPE_TAG1; 750fcba820dSWei Hu (Xavier) else if (vlan_num == VLAN_TAG_NUM_MAX) 751fcba820dSWei Hu (Xavier) vlan_tag = HNS3_VLAN_TAG_TYPE_TAG1_2; 752fcba820dSWei Hu (Xavier) else 753fcba820dSWei Hu (Xavier) vlan_tag = HNS3_VLAN_TAG_TYPE_NONE; 754fcba820dSWei Hu (Xavier) hns3_set_field(meta_data, 755fcba820dSWei Hu (Xavier) GENMASK(cur_pos + tuple_size, 756fcba820dSWei Hu (Xavier) cur_pos), cur_pos, vlan_tag); 757fcba820dSWei Hu (Xavier) cur_pos += tuple_size; 758fcba820dSWei Hu (Xavier) } else if (i == DST_VPORT) { 759fcba820dSWei Hu (Xavier) port_number = hns3_get_port_number(0, vf_id); 760fcba820dSWei Hu (Xavier) hns3_set_field(meta_data, 761fcba820dSWei Hu (Xavier) GENMASK(cur_pos + tuple_size, cur_pos), 762fcba820dSWei Hu (Xavier) cur_pos, port_number); 763fcba820dSWei Hu (Xavier) cur_pos += tuple_size; 764fcba820dSWei Hu (Xavier) } 765fcba820dSWei Hu (Xavier) } 766fcba820dSWei Hu (Xavier) 767fcba820dSWei Hu (Xavier) calc_x(tmp_x, meta_data, 0xFFFF); 768fcba820dSWei Hu (Xavier) calc_y(tmp_y, meta_data, 0xFFFF); 769fcba820dSWei Hu (Xavier) shift_bits = sizeof(meta_data) * HNS3_BITS_PER_BYTE - cur_pos; 770fcba820dSWei Hu (Xavier) 771fcba820dSWei Hu (Xavier) tmp_x = rte_cpu_to_le_32(tmp_x << shift_bits); 772fcba820dSWei Hu (Xavier) tmp_y = rte_cpu_to_le_32(tmp_y << shift_bits); 773fcba820dSWei Hu (Xavier) key_x[0] = tmp_x & 0xFF; 774fcba820dSWei Hu (Xavier) key_x[1] = (tmp_x >> HNS3_BITS_PER_BYTE) & 0xFF; 775fcba820dSWei Hu (Xavier) key_y[0] = tmp_y & 0xFF; 776fcba820dSWei Hu (Xavier) key_y[1] = (tmp_y >> HNS3_BITS_PER_BYTE) & 0xFF; 777fcba820dSWei Hu (Xavier) } 778fcba820dSWei Hu (Xavier) 779fcba820dSWei Hu (Xavier) /* A complete key is combined with meta data key and tuple key. 780fcba820dSWei Hu (Xavier) * Meta data key is stored at the MSB region, and tuple key is stored at 781fcba820dSWei Hu (Xavier) * the LSB region, unused bits will be filled 0. 782fcba820dSWei Hu (Xavier) */ 783fcba820dSWei Hu (Xavier) static int hns3_config_key(struct hns3_adapter *hns, 784fcba820dSWei Hu (Xavier) struct hns3_fdir_rule *rule) 785fcba820dSWei Hu (Xavier) { 786fcba820dSWei Hu (Xavier) struct hns3_pf *pf = &hns->pf; 787fcba820dSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 788fcba820dSWei Hu (Xavier) struct hns3_fd_key_cfg *key_cfg; 789fcba820dSWei Hu (Xavier) uint8_t *cur_key_x; 790fcba820dSWei Hu (Xavier) uint8_t *cur_key_y; 79127595cd8STyler Retzlaff alignas(4) uint8_t key_x[MAX_KEY_BYTES]; 79227595cd8STyler Retzlaff alignas(4) uint8_t key_y[MAX_KEY_BYTES]; 793fcba820dSWei Hu (Xavier) uint8_t vf_id = rule->vf_id; 794fcba820dSWei Hu (Xavier) uint8_t meta_data_region; 795fcba820dSWei Hu (Xavier) uint8_t tuple_size; 796fcba820dSWei Hu (Xavier) uint8_t i; 797fcba820dSWei Hu (Xavier) int ret; 798fcba820dSWei Hu (Xavier) 799fcba820dSWei Hu (Xavier) memset(key_x, 0, sizeof(key_x)); 800fcba820dSWei Hu (Xavier) memset(key_y, 0, sizeof(key_y)); 801fcba820dSWei Hu (Xavier) cur_key_x = key_x; 802fcba820dSWei Hu (Xavier) cur_key_y = key_y; 803fcba820dSWei Hu (Xavier) 804fcba820dSWei Hu (Xavier) key_cfg = &pf->fdir.fd_cfg.key_cfg[HNS3_FD_STAGE_1]; 805fcba820dSWei Hu (Xavier) for (i = 0; i < MAX_TUPLE; i++) { 806fcba820dSWei Hu (Xavier) bool tuple_valid; 807fcba820dSWei Hu (Xavier) 808fcba820dSWei Hu (Xavier) tuple_size = tuple_key_info[i].key_length / HNS3_BITS_PER_BYTE; 809fcba820dSWei Hu (Xavier) if (key_cfg->tuple_active & BIT(i)) { 81018a4b4c3SWei Hu (Xavier) tuple_valid = hns3_fd_convert_tuple(hw, i, cur_key_x, 811fcba820dSWei Hu (Xavier) cur_key_y, rule); 812fcba820dSWei Hu (Xavier) if (tuple_valid) { 813fcba820dSWei Hu (Xavier) cur_key_x += tuple_size; 814fcba820dSWei Hu (Xavier) cur_key_y += tuple_size; 815fcba820dSWei Hu (Xavier) } 816fcba820dSWei Hu (Xavier) } 817fcba820dSWei Hu (Xavier) } 818fcba820dSWei Hu (Xavier) 819fcba820dSWei Hu (Xavier) meta_data_region = pf->fdir.fd_cfg.max_key_length / HNS3_BITS_PER_BYTE - 820fcba820dSWei Hu (Xavier) MAX_META_DATA_LENGTH / HNS3_BITS_PER_BYTE; 821fcba820dSWei Hu (Xavier) 822fcba820dSWei Hu (Xavier) hns3_fd_convert_meta_data(key_cfg, vf_id, rule, 823fcba820dSWei Hu (Xavier) key_x + meta_data_region, 824fcba820dSWei Hu (Xavier) key_y + meta_data_region); 825fcba820dSWei Hu (Xavier) 826fcba820dSWei Hu (Xavier) ret = hns3_fd_tcam_config(hw, false, rule->location, key_y, true); 827fcba820dSWei Hu (Xavier) if (ret) { 8282427c27eSHongbo Zheng hns3_err(hw, "Config fd key_y fail, loc=%u, ret=%d", 829fcba820dSWei Hu (Xavier) rule->queue_id, ret); 830fcba820dSWei Hu (Xavier) return ret; 831fcba820dSWei Hu (Xavier) } 832fcba820dSWei Hu (Xavier) 833fcba820dSWei Hu (Xavier) ret = hns3_fd_tcam_config(hw, true, rule->location, key_x, true); 834fcba820dSWei Hu (Xavier) if (ret) 8352427c27eSHongbo Zheng hns3_err(hw, "Config fd key_x fail, loc=%u, ret=%d", 836fcba820dSWei Hu (Xavier) rule->queue_id, ret); 837fcba820dSWei Hu (Xavier) return ret; 838fcba820dSWei Hu (Xavier) } 839fcba820dSWei Hu (Xavier) 840fcba820dSWei Hu (Xavier) static int hns3_config_action(struct hns3_hw *hw, struct hns3_fdir_rule *rule) 841fcba820dSWei Hu (Xavier) { 842fcba820dSWei Hu (Xavier) struct hns3_fd_ad_data ad_data; 843fcba820dSWei Hu (Xavier) 844fcba820dSWei Hu (Xavier) ad_data.ad_id = rule->location; 845fcba820dSWei Hu (Xavier) 846fcba820dSWei Hu (Xavier) if (rule->action == HNS3_FD_ACTION_DROP_PACKET) { 847fcba820dSWei Hu (Xavier) ad_data.drop_packet = true; 848fcba820dSWei Hu (Xavier) ad_data.queue_id = 0; 849f8e7fcbfSChengwen Feng ad_data.nb_queues = 0; 850fcba820dSWei Hu (Xavier) } else { 851fcba820dSWei Hu (Xavier) ad_data.drop_packet = false; 852fcba820dSWei Hu (Xavier) ad_data.queue_id = rule->queue_id; 853f8e7fcbfSChengwen Feng ad_data.nb_queues = rule->nb_queues; 854fcba820dSWei Hu (Xavier) } 855fcba820dSWei Hu (Xavier) 856fcba820dSWei Hu (Xavier) if (unlikely(rule->flags & HNS3_RULE_FLAG_COUNTER)) { 857fcba820dSWei Hu (Xavier) ad_data.use_counter = true; 858fcba820dSWei Hu (Xavier) ad_data.counter_id = rule->act_cnt.id; 859fcba820dSWei Hu (Xavier) } else { 860fcba820dSWei Hu (Xavier) ad_data.use_counter = false; 861fcba820dSWei Hu (Xavier) ad_data.counter_id = 0; 862fcba820dSWei Hu (Xavier) } 863fcba820dSWei Hu (Xavier) 864fcba820dSWei Hu (Xavier) if (unlikely(rule->flags & HNS3_RULE_FLAG_FDID)) 865fcba820dSWei Hu (Xavier) ad_data.rule_id = rule->fd_id; 866fcba820dSWei Hu (Xavier) else 867fcba820dSWei Hu (Xavier) ad_data.rule_id = rule->location; 868fcba820dSWei Hu (Xavier) 869fcba820dSWei Hu (Xavier) ad_data.use_next_stage = false; 870fcba820dSWei Hu (Xavier) ad_data.next_input_key = 0; 871fcba820dSWei Hu (Xavier) 872fcba820dSWei Hu (Xavier) ad_data.write_rule_id_to_bd = true; 873fcba820dSWei Hu (Xavier) 874fcba820dSWei Hu (Xavier) return hns3_fd_ad_config(hw, ad_data.ad_id, &ad_data); 875fcba820dSWei Hu (Xavier) } 876fcba820dSWei Hu (Xavier) 87731cdde02SChengwen Feng static int hns3_fd_clear_all_rules(struct hns3_hw *hw, uint32_t rule_num) 87831cdde02SChengwen Feng { 87931cdde02SChengwen Feng uint32_t i; 88031cdde02SChengwen Feng int ret; 88131cdde02SChengwen Feng 88231cdde02SChengwen Feng for (i = 0; i < rule_num; i++) { 88331cdde02SChengwen Feng ret = hns3_fd_tcam_config(hw, true, i, NULL, false); 88431cdde02SChengwen Feng if (ret) 88531cdde02SChengwen Feng return ret; 88631cdde02SChengwen Feng } 88731cdde02SChengwen Feng 88831cdde02SChengwen Feng return 0; 88931cdde02SChengwen Feng } 89031cdde02SChengwen Feng 891fcba820dSWei Hu (Xavier) int hns3_fdir_filter_init(struct hns3_adapter *hns) 892fcba820dSWei Hu (Xavier) { 893fcba820dSWei Hu (Xavier) struct hns3_pf *pf = &hns->pf; 894fcba820dSWei Hu (Xavier) struct hns3_fdir_info *fdir_info = &pf->fdir; 895fcba820dSWei Hu (Xavier) uint32_t rule_num = fdir_info->fd_cfg.rule_num[HNS3_FD_STAGE_1]; 896fcba820dSWei Hu (Xavier) char fdir_hash_name[RTE_HASH_NAMESIZE]; 897fcba820dSWei Hu (Xavier) struct rte_hash_parameters fdir_hash_params = { 898fcba820dSWei Hu (Xavier) .name = fdir_hash_name, 899fcba820dSWei Hu (Xavier) .entries = rule_num, 900fcba820dSWei Hu (Xavier) .key_len = sizeof(struct hns3_fdir_key_conf), 901fcba820dSWei Hu (Xavier) .hash_func = rte_hash_crc, 902fcba820dSWei Hu (Xavier) .hash_func_init_val = 0, 903*b8e60c33SDengdui Huang .extra_flag = RTE_HASH_EXTRA_FLAGS_EXT_TABLE, 904fcba820dSWei Hu (Xavier) }; 90531cdde02SChengwen Feng int ret; 90631cdde02SChengwen Feng 90731cdde02SChengwen Feng ret = hns3_fd_clear_all_rules(&hns->hw, rule_num); 90831cdde02SChengwen Feng if (ret) { 90931cdde02SChengwen Feng PMD_INIT_LOG(ERR, "Clear all fd rules fail! ret = %d", ret); 91031cdde02SChengwen Feng return ret; 91131cdde02SChengwen Feng } 912fcba820dSWei Hu (Xavier) 913fcba820dSWei Hu (Xavier) fdir_hash_params.socket_id = rte_socket_id(); 914fcba820dSWei Hu (Xavier) TAILQ_INIT(&fdir_info->fdir_list); 915fcba820dSWei Hu (Xavier) snprintf(fdir_hash_name, RTE_HASH_NAMESIZE, "%s", hns->hw.data->name); 916fcba820dSWei Hu (Xavier) fdir_info->hash_handle = rte_hash_create(&fdir_hash_params); 917fcba820dSWei Hu (Xavier) if (fdir_info->hash_handle == NULL) { 918fcba820dSWei Hu (Xavier) PMD_INIT_LOG(ERR, "Create FDIR hash handle fail!"); 919fcba820dSWei Hu (Xavier) return -EINVAL; 920fcba820dSWei Hu (Xavier) } 921fcba820dSWei Hu (Xavier) fdir_info->hash_map = rte_zmalloc("hns3 FDIR hash", 922fcba820dSWei Hu (Xavier) rule_num * 923fcba820dSWei Hu (Xavier) sizeof(struct hns3_fdir_rule_ele *), 924fcba820dSWei Hu (Xavier) 0); 925fcba820dSWei Hu (Xavier) if (fdir_info->hash_map == NULL) { 926fcba820dSWei Hu (Xavier) PMD_INIT_LOG(ERR, "Allocate memory for FDIR hash map fail!"); 927fcba820dSWei Hu (Xavier) rte_hash_free(fdir_info->hash_handle); 928fcba820dSWei Hu (Xavier) return -ENOMEM; 929fcba820dSWei Hu (Xavier) } 930fcba820dSWei Hu (Xavier) 931fcba820dSWei Hu (Xavier) return 0; 932fcba820dSWei Hu (Xavier) } 933fcba820dSWei Hu (Xavier) 934fcba820dSWei Hu (Xavier) void hns3_fdir_filter_uninit(struct hns3_adapter *hns) 935fcba820dSWei Hu (Xavier) { 936fcba820dSWei Hu (Xavier) struct hns3_pf *pf = &hns->pf; 937fcba820dSWei Hu (Xavier) struct hns3_fdir_info *fdir_info = &pf->fdir; 938fcba820dSWei Hu (Xavier) struct hns3_fdir_rule_ele *fdir_filter; 939fcba820dSWei Hu (Xavier) 940fcba820dSWei Hu (Xavier) if (fdir_info->hash_map) { 941fcba820dSWei Hu (Xavier) rte_free(fdir_info->hash_map); 942fcba820dSWei Hu (Xavier) fdir_info->hash_map = NULL; 943fcba820dSWei Hu (Xavier) } 944fcba820dSWei Hu (Xavier) if (fdir_info->hash_handle) { 945fcba820dSWei Hu (Xavier) rte_hash_free(fdir_info->hash_handle); 946fcba820dSWei Hu (Xavier) fdir_info->hash_handle = NULL; 947fcba820dSWei Hu (Xavier) } 948fcba820dSWei Hu (Xavier) 949fcba820dSWei Hu (Xavier) fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list); 950fcba820dSWei Hu (Xavier) while (fdir_filter) { 951fcba820dSWei Hu (Xavier) TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries); 952fcba820dSWei Hu (Xavier) hns3_fd_tcam_config(&hns->hw, true, 953fcba820dSWei Hu (Xavier) fdir_filter->fdir_conf.location, NULL, 954fcba820dSWei Hu (Xavier) false); 955fcba820dSWei Hu (Xavier) rte_free(fdir_filter); 956fcba820dSWei Hu (Xavier) fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list); 957fcba820dSWei Hu (Xavier) } 958fcba820dSWei Hu (Xavier) } 959fcba820dSWei Hu (Xavier) 960fcba820dSWei Hu (Xavier) /* 961fcba820dSWei Hu (Xavier) * Find a key in the hash table. 962fcba820dSWei Hu (Xavier) * @return 963fcba820dSWei Hu (Xavier) * - Zero and positive values are key location. 964fcba820dSWei Hu (Xavier) * - -EINVAL if the parameters are invalid. 965fcba820dSWei Hu (Xavier) * - -ENOENT if the key is not found. 966fcba820dSWei Hu (Xavier) */ 967fcba820dSWei Hu (Xavier) static int hns3_fdir_filter_lookup(struct hns3_fdir_info *fdir_info, 968fcba820dSWei Hu (Xavier) struct hns3_fdir_key_conf *key) 969fcba820dSWei Hu (Xavier) { 970fcba820dSWei Hu (Xavier) hash_sig_t sig; 971fcba820dSWei Hu (Xavier) int ret; 972fcba820dSWei Hu (Xavier) 973fcba820dSWei Hu (Xavier) sig = rte_hash_crc(key, sizeof(*key), 0); 974fcba820dSWei Hu (Xavier) ret = rte_hash_lookup_with_hash(fdir_info->hash_handle, key, sig); 975fcba820dSWei Hu (Xavier) 976fcba820dSWei Hu (Xavier) return ret; 977fcba820dSWei Hu (Xavier) } 978fcba820dSWei Hu (Xavier) 979fcba820dSWei Hu (Xavier) static int hns3_insert_fdir_filter(struct hns3_hw *hw, 980fcba820dSWei Hu (Xavier) struct hns3_fdir_info *fdir_info, 981fcba820dSWei Hu (Xavier) struct hns3_fdir_rule_ele *fdir_filter) 982fcba820dSWei Hu (Xavier) { 983fcba820dSWei Hu (Xavier) struct hns3_fdir_key_conf *key; 984fcba820dSWei Hu (Xavier) hash_sig_t sig; 985ac72aae6SDengdui Huang int index; 986fcba820dSWei Hu (Xavier) 987fcba820dSWei Hu (Xavier) key = &fdir_filter->fdir_conf.key_conf; 988fcba820dSWei Hu (Xavier) sig = rte_hash_crc(key, sizeof(*key), 0); 989ac72aae6SDengdui Huang index = rte_hash_add_key_with_hash(fdir_info->hash_handle, key, sig); 990ac72aae6SDengdui Huang if (index < 0) { 991ac72aae6SDengdui Huang hns3_err(hw, "Hash table full? err:%d!", index); 992ac72aae6SDengdui Huang return index; 993fcba820dSWei Hu (Xavier) } 994fcba820dSWei Hu (Xavier) 995ac72aae6SDengdui Huang if (fdir_info->index_cfg == HNS3_FDIR_INDEX_CONFIG_PRIORITY) 996ac72aae6SDengdui Huang index = fdir_filter->fdir_conf.location; 997ac72aae6SDengdui Huang 998ac72aae6SDengdui Huang fdir_info->hash_map[index] = fdir_filter; 999fcba820dSWei Hu (Xavier) TAILQ_INSERT_TAIL(&fdir_info->fdir_list, fdir_filter, entries); 1000fcba820dSWei Hu (Xavier) 1001ac72aae6SDengdui Huang return index; 1002fcba820dSWei Hu (Xavier) } 1003fcba820dSWei Hu (Xavier) 1004fcba820dSWei Hu (Xavier) static int hns3_remove_fdir_filter(struct hns3_hw *hw, 1005fcba820dSWei Hu (Xavier) struct hns3_fdir_info *fdir_info, 1006ac72aae6SDengdui Huang struct hns3_fdir_rule *rule) 1007fcba820dSWei Hu (Xavier) { 1008fcba820dSWei Hu (Xavier) struct hns3_fdir_rule_ele *fdir_filter; 1009fcba820dSWei Hu (Xavier) hash_sig_t sig; 1010ac72aae6SDengdui Huang int index; 1011fcba820dSWei Hu (Xavier) 1012ac72aae6SDengdui Huang sig = rte_hash_crc(&rule->key_conf, sizeof(rule->key_conf), 0); 1013ac72aae6SDengdui Huang index = rte_hash_del_key_with_hash(fdir_info->hash_handle, &rule->key_conf, sig); 1014ac72aae6SDengdui Huang if (index < 0) { 1015ac72aae6SDengdui Huang hns3_err(hw, "Delete hash key fail ret=%d", index); 1016ac72aae6SDengdui Huang return index; 1017fcba820dSWei Hu (Xavier) } 1018fcba820dSWei Hu (Xavier) 1019ac72aae6SDengdui Huang if (fdir_info->index_cfg == HNS3_FDIR_INDEX_CONFIG_PRIORITY) 1020ac72aae6SDengdui Huang index = rule->location; 1021ac72aae6SDengdui Huang fdir_filter = fdir_info->hash_map[index]; 1022ac72aae6SDengdui Huang fdir_info->hash_map[index] = NULL; 1023fcba820dSWei Hu (Xavier) TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries); 1024fcba820dSWei Hu (Xavier) 1025fcba820dSWei Hu (Xavier) rte_free(fdir_filter); 1026fcba820dSWei Hu (Xavier) 1027fcba820dSWei Hu (Xavier) return 0; 1028fcba820dSWei Hu (Xavier) } 1029fcba820dSWei Hu (Xavier) 1030fcba820dSWei Hu (Xavier) int hns3_fdir_filter_program(struct hns3_adapter *hns, 1031fcba820dSWei Hu (Xavier) struct hns3_fdir_rule *rule, bool del) 1032fcba820dSWei Hu (Xavier) { 1033fcba820dSWei Hu (Xavier) struct hns3_pf *pf = &hns->pf; 1034fcba820dSWei Hu (Xavier) struct hns3_fdir_info *fdir_info = &pf->fdir; 1035fcba820dSWei Hu (Xavier) struct hns3_fdir_rule_ele *node; 1036fcba820dSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 1037fcba820dSWei Hu (Xavier) int ret; 1038fcba820dSWei Hu (Xavier) 1039fcba820dSWei Hu (Xavier) if (del) { 1040fcba820dSWei Hu (Xavier) ret = hns3_fd_tcam_config(hw, true, rule->location, NULL, 1041fcba820dSWei Hu (Xavier) false); 1042fcba820dSWei Hu (Xavier) if (ret) 10432427c27eSHongbo Zheng hns3_err(hw, "Failed to delete fdir: %u src_ip:%x " 10442427c27eSHongbo Zheng "dst_ip:%x src_port:%u dst_port:%u ret = %d", 1045fcba820dSWei Hu (Xavier) rule->location, 1046fcba820dSWei Hu (Xavier) rule->key_conf.spec.src_ip[IP_ADDR_KEY_ID], 1047fcba820dSWei Hu (Xavier) rule->key_conf.spec.dst_ip[IP_ADDR_KEY_ID], 1048fcba820dSWei Hu (Xavier) rule->key_conf.spec.src_port, 10498eed8accSLijun Ou rule->key_conf.spec.dst_port, ret); 1050fcba820dSWei Hu (Xavier) else 1051ac72aae6SDengdui Huang ret = hns3_remove_fdir_filter(hw, fdir_info, rule); 1052fcba820dSWei Hu (Xavier) 1053fcba820dSWei Hu (Xavier) return ret; 1054fcba820dSWei Hu (Xavier) } 1055fcba820dSWei Hu (Xavier) 1056fcba820dSWei Hu (Xavier) ret = hns3_fdir_filter_lookup(fdir_info, &rule->key_conf); 1057fcba820dSWei Hu (Xavier) if (ret >= 0) { 1058fcba820dSWei Hu (Xavier) hns3_err(hw, "Conflict with existing fdir loc: %d", ret); 1059fcba820dSWei Hu (Xavier) return -EINVAL; 1060fcba820dSWei Hu (Xavier) } 1061fcba820dSWei Hu (Xavier) 1062fcba820dSWei Hu (Xavier) node = rte_zmalloc("hns3 fdir rule", sizeof(struct hns3_fdir_rule_ele), 1063fcba820dSWei Hu (Xavier) 0); 1064fcba820dSWei Hu (Xavier) if (node == NULL) { 1065fcba820dSWei Hu (Xavier) hns3_err(hw, "Failed to allocate fdir_rule memory"); 1066fcba820dSWei Hu (Xavier) return -ENOMEM; 1067fcba820dSWei Hu (Xavier) } 1068fcba820dSWei Hu (Xavier) 1069fcba820dSWei Hu (Xavier) rte_memcpy(&node->fdir_conf, rule, sizeof(struct hns3_fdir_rule)); 1070fcba820dSWei Hu (Xavier) ret = hns3_insert_fdir_filter(hw, fdir_info, node); 1071fcba820dSWei Hu (Xavier) if (ret < 0) { 1072fcba820dSWei Hu (Xavier) rte_free(node); 1073fcba820dSWei Hu (Xavier) return ret; 1074fcba820dSWei Hu (Xavier) } 1075fcba820dSWei Hu (Xavier) rule->location = ret; 1076fcba820dSWei Hu (Xavier) node->fdir_conf.location = ret; 1077fcba820dSWei Hu (Xavier) 1078fcba820dSWei Hu (Xavier) ret = hns3_config_action(hw, rule); 1079fcba820dSWei Hu (Xavier) if (!ret) 1080fcba820dSWei Hu (Xavier) ret = hns3_config_key(hns, rule); 1081fcba820dSWei Hu (Xavier) if (ret) { 10822427c27eSHongbo Zheng hns3_err(hw, "Failed to config fdir: %u src_ip:%x dst_ip:%x " 10832427c27eSHongbo Zheng "src_port:%u dst_port:%u ret = %d", 1084fcba820dSWei Hu (Xavier) rule->location, 1085fcba820dSWei Hu (Xavier) rule->key_conf.spec.src_ip[IP_ADDR_KEY_ID], 1086fcba820dSWei Hu (Xavier) rule->key_conf.spec.dst_ip[IP_ADDR_KEY_ID], 1087fcba820dSWei Hu (Xavier) rule->key_conf.spec.src_port, 10888eed8accSLijun Ou rule->key_conf.spec.dst_port, ret); 1089ac72aae6SDengdui Huang (void)hns3_remove_fdir_filter(hw, fdir_info, rule); 1090fcba820dSWei Hu (Xavier) } 1091fcba820dSWei Hu (Xavier) 1092fcba820dSWei Hu (Xavier) return ret; 1093fcba820dSWei Hu (Xavier) } 1094fcba820dSWei Hu (Xavier) 1095fcba820dSWei Hu (Xavier) /* remove all the flow director filters */ 1096fcba820dSWei Hu (Xavier) int hns3_clear_all_fdir_filter(struct hns3_adapter *hns) 1097fcba820dSWei Hu (Xavier) { 1098fcba820dSWei Hu (Xavier) struct hns3_pf *pf = &hns->pf; 1099fcba820dSWei Hu (Xavier) struct hns3_fdir_info *fdir_info = &pf->fdir; 1100fcba820dSWei Hu (Xavier) struct hns3_fdir_rule_ele *fdir_filter; 1101fcba820dSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 1102f4e5c18fSChengwen Feng int succ_cnt = 0; 1103f4e5c18fSChengwen Feng int fail_cnt = 0; 1104fcba820dSWei Hu (Xavier) int ret = 0; 1105fcba820dSWei Hu (Xavier) 1106fcba820dSWei Hu (Xavier) /* flush flow director */ 1107fcba820dSWei Hu (Xavier) rte_hash_reset(fdir_info->hash_handle); 1108fcba820dSWei Hu (Xavier) 11097d01f89fSChengwen Feng memset(fdir_info->hash_map, 0, 11107d01f89fSChengwen Feng sizeof(struct hns3_fdir_rule_ele *) * 11117d01f89fSChengwen Feng fdir_info->fd_cfg.rule_num[HNS3_FD_STAGE_1]); 11127d01f89fSChengwen Feng 1113fcba820dSWei Hu (Xavier) fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list); 1114fcba820dSWei Hu (Xavier) while (fdir_filter) { 1115fcba820dSWei Hu (Xavier) TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries); 1116f4e5c18fSChengwen Feng ret = hns3_fd_tcam_config(hw, true, 1117fcba820dSWei Hu (Xavier) fdir_filter->fdir_conf.location, 1118fcba820dSWei Hu (Xavier) NULL, false); 1119f4e5c18fSChengwen Feng if (ret == 0) 1120f4e5c18fSChengwen Feng succ_cnt++; 1121f4e5c18fSChengwen Feng else 1122f4e5c18fSChengwen Feng fail_cnt++; 1123fcba820dSWei Hu (Xavier) rte_free(fdir_filter); 1124fcba820dSWei Hu (Xavier) fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list); 1125fcba820dSWei Hu (Xavier) } 1126fcba820dSWei Hu (Xavier) 1127f4e5c18fSChengwen Feng if (fail_cnt > 0) { 1128f4e5c18fSChengwen Feng hns3_err(hw, "fail to delete all FDIR filter, success num = %d " 1129f4e5c18fSChengwen Feng "fail num = %d", succ_cnt, fail_cnt); 1130fcba820dSWei Hu (Xavier) ret = -EIO; 1131fcba820dSWei Hu (Xavier) } 1132f4e5c18fSChengwen Feng 1133fcba820dSWei Hu (Xavier) return ret; 1134fcba820dSWei Hu (Xavier) } 1135fcba820dSWei Hu (Xavier) 1136fcba820dSWei Hu (Xavier) int hns3_restore_all_fdir_filter(struct hns3_adapter *hns) 1137fcba820dSWei Hu (Xavier) { 1138fcba820dSWei Hu (Xavier) struct hns3_pf *pf = &hns->pf; 1139fcba820dSWei Hu (Xavier) struct hns3_fdir_info *fdir_info = &pf->fdir; 1140fcba820dSWei Hu (Xavier) struct hns3_fdir_rule_ele *fdir_filter; 1141fcba820dSWei Hu (Xavier) struct hns3_hw *hw = &hns->hw; 1142fcba820dSWei Hu (Xavier) bool err = false; 1143fcba820dSWei Hu (Xavier) int ret; 1144fcba820dSWei Hu (Xavier) 1145860ed851SHuisong Li if (hns->is_vf) 1146860ed851SHuisong Li return 0; 1147860ed851SHuisong Li 11481bdcca80SChengwen Feng /* 11491bdcca80SChengwen Feng * This API is called in the reset recovery process, the parent function 11501bdcca80SChengwen Feng * must hold hw->lock. 11511bdcca80SChengwen Feng * There maybe deadlock if acquire hw->flows_lock directly because rte 11521bdcca80SChengwen Feng * flow driver ops first acquire hw->flows_lock and then may acquire 11531bdcca80SChengwen Feng * hw->lock. 11541bdcca80SChengwen Feng * So here first release the hw->lock and then acquire the 11551bdcca80SChengwen Feng * hw->flows_lock to avoid deadlock. 11561bdcca80SChengwen Feng */ 11571bdcca80SChengwen Feng rte_spinlock_unlock(&hw->lock); 11581bdcca80SChengwen Feng pthread_mutex_lock(&hw->flows_lock); 1159fcba820dSWei Hu (Xavier) TAILQ_FOREACH(fdir_filter, &fdir_info->fdir_list, entries) { 1160fcba820dSWei Hu (Xavier) ret = hns3_config_action(hw, &fdir_filter->fdir_conf); 1161fcba820dSWei Hu (Xavier) if (!ret) 1162fcba820dSWei Hu (Xavier) ret = hns3_config_key(hns, &fdir_filter->fdir_conf); 1163fcba820dSWei Hu (Xavier) if (ret) { 1164fcba820dSWei Hu (Xavier) err = true; 1165fcba820dSWei Hu (Xavier) if (ret == -EBUSY) 1166fcba820dSWei Hu (Xavier) break; 1167fcba820dSWei Hu (Xavier) } 1168fcba820dSWei Hu (Xavier) } 11691bdcca80SChengwen Feng pthread_mutex_unlock(&hw->flows_lock); 11701bdcca80SChengwen Feng rte_spinlock_lock(&hw->lock); 1171fcba820dSWei Hu (Xavier) 1172fcba820dSWei Hu (Xavier) if (err) { 11738eed8accSLijun Ou hns3_err(hw, "Fail to restore FDIR filter, ret = %d", ret); 1174fcba820dSWei Hu (Xavier) return -EIO; 1175fcba820dSWei Hu (Xavier) } 1176fcba820dSWei Hu (Xavier) return 0; 1177fcba820dSWei Hu (Xavier) } 1178fcba820dSWei Hu (Xavier) 117952600004SHuisong Li int hns3_fd_get_count(struct hns3_hw *hw, uint32_t id, uint64_t *value) 1180fcba820dSWei Hu (Xavier) { 1181fcba820dSWei Hu (Xavier) struct hns3_fd_get_cnt_cmd *req; 1182fcba820dSWei Hu (Xavier) struct hns3_cmd_desc desc; 1183fcba820dSWei Hu (Xavier) int ret; 1184fcba820dSWei Hu (Xavier) 1185fcba820dSWei Hu (Xavier) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FD_COUNTER_OP, true); 1186fcba820dSWei Hu (Xavier) 1187fcba820dSWei Hu (Xavier) req = (struct hns3_fd_get_cnt_cmd *)desc.data; 1188fcba820dSWei Hu (Xavier) req->stage = HNS3_FD_STAGE_1; 1189fcba820dSWei Hu (Xavier) req->index = rte_cpu_to_le_32(id); 1190fcba820dSWei Hu (Xavier) 1191fcba820dSWei Hu (Xavier) ret = hns3_cmd_send(hw, &desc, 1); 1192fcba820dSWei Hu (Xavier) if (ret) { 1193fcba820dSWei Hu (Xavier) hns3_err(hw, "Read counter fail, ret=%d", ret); 1194fcba820dSWei Hu (Xavier) return ret; 1195fcba820dSWei Hu (Xavier) } 1196fcba820dSWei Hu (Xavier) 1197fcba820dSWei Hu (Xavier) *value = req->value; 1198fcba820dSWei Hu (Xavier) 1199fcba820dSWei Hu (Xavier) return ret; 1200fcba820dSWei Hu (Xavier) } 1201a4732847SChengwen Feng 1202a4732847SChengwen Feng static struct { 1203a4732847SChengwen Feng enum hns3_fdir_tuple_config tuple_cfg; 1204a4732847SChengwen Feng const char *name; 1205a4732847SChengwen Feng } tuple_config_map[] = { 1206a4732847SChengwen Feng { HNS3_FDIR_TUPLE_CONFIG_DEFAULT, "default" }, 1207a4732847SChengwen Feng { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INSMAC, "+outvlan-insmac" }, 1208a4732847SChengwen Feng { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INDMAC, "+outvlan-indmac" }, 1209a4732847SChengwen Feng { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INSIP, "+outvlan-insip" }, 1210a4732847SChengwen Feng { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INDIP, "+outvlan-indip" }, 1211a4732847SChengwen Feng { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_SCTPTAG, "+outvlan-sctptag" }, 1212a4732847SChengwen Feng { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_TUNVNI, "+outvlan-tunvni" } 1213a4732847SChengwen Feng }; 1214a4732847SChengwen Feng 1215a4732847SChengwen Feng enum hns3_fdir_tuple_config 1216a4732847SChengwen Feng hns3_parse_tuple_config(const char *name) 1217a4732847SChengwen Feng { 1218a4732847SChengwen Feng uint32_t i; 1219a4732847SChengwen Feng 1220a4732847SChengwen Feng for (i = 0; i < RTE_DIM(tuple_config_map); i++) { 1221a4732847SChengwen Feng if (!strcmp(name, tuple_config_map[i].name)) 1222a4732847SChengwen Feng return tuple_config_map[i].tuple_cfg; 1223a4732847SChengwen Feng } 1224a4732847SChengwen Feng 1225a4732847SChengwen Feng return HNS3_FDIR_TUPLE_CONFIG_BUTT; 1226a4732847SChengwen Feng } 1227a4732847SChengwen Feng 1228a4732847SChengwen Feng const char * 1229a4732847SChengwen Feng hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg) 1230a4732847SChengwen Feng { 1231a4732847SChengwen Feng uint32_t i; 1232a4732847SChengwen Feng 1233a4732847SChengwen Feng for (i = 0; i < RTE_DIM(tuple_config_map); i++) { 1234a4732847SChengwen Feng if (tuple_cfg == tuple_config_map[i].tuple_cfg) 1235a4732847SChengwen Feng return tuple_config_map[i].name; 1236a4732847SChengwen Feng } 1237a4732847SChengwen Feng 1238a4732847SChengwen Feng return "unknown"; 1239a4732847SChengwen Feng } 1240ac72aae6SDengdui Huang 1241ac72aae6SDengdui Huang static struct { 1242ac72aae6SDengdui Huang enum hns3_fdir_index_config cfg; 1243ac72aae6SDengdui Huang const char *name; 1244ac72aae6SDengdui Huang } index_cfg_map[] = { 1245ac72aae6SDengdui Huang { HNS3_FDIR_INDEX_CONFIG_HASH, "hash"}, 1246ac72aae6SDengdui Huang { HNS3_FDIR_INDEX_CONFIG_PRIORITY, "priority"}, 1247ac72aae6SDengdui Huang }; 1248ac72aae6SDengdui Huang 1249ac72aae6SDengdui Huang const char * 1250ac72aae6SDengdui Huang hns3_fdir_index_config_name(enum hns3_fdir_index_config cfg) 1251ac72aae6SDengdui Huang { 1252ac72aae6SDengdui Huang uint32_t i; 1253ac72aae6SDengdui Huang 1254ac72aae6SDengdui Huang for (i = 0; i < RTE_DIM(index_cfg_map); i++) { 1255ac72aae6SDengdui Huang if (cfg == index_cfg_map[i].cfg) 1256ac72aae6SDengdui Huang return index_cfg_map[i].name; 1257ac72aae6SDengdui Huang } 1258ac72aae6SDengdui Huang 1259ac72aae6SDengdui Huang return "unknown"; 1260ac72aae6SDengdui Huang } 1261