19db810edSAlex Vesker // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 29db810edSAlex Vesker /* Copyright (c) 2019 Mellanox Technologies. */ 39db810edSAlex Vesker 49db810edSAlex Vesker #include "dr_types.h" 5d7418b4eSYevgeny Kliteynik #include "dr_ste.h" 69db810edSAlex Vesker 79db810edSAlex Vesker enum dr_action_domain { 89db810edSAlex Vesker DR_ACTION_DOMAIN_NIC_INGRESS, 99db810edSAlex Vesker DR_ACTION_DOMAIN_NIC_EGRESS, 109db810edSAlex Vesker DR_ACTION_DOMAIN_FDB_INGRESS, 119db810edSAlex Vesker DR_ACTION_DOMAIN_FDB_EGRESS, 129db810edSAlex Vesker DR_ACTION_DOMAIN_MAX, 139db810edSAlex Vesker }; 149db810edSAlex Vesker 159db810edSAlex Vesker enum dr_action_valid_state { 169db810edSAlex Vesker DR_ACTION_STATE_ERR, 179db810edSAlex Vesker DR_ACTION_STATE_NO_ACTION, 1828de41a4SYevgeny Kliteynik DR_ACTION_STATE_ENCAP, 1928de41a4SYevgeny Kliteynik DR_ACTION_STATE_DECAP, 209db810edSAlex Vesker DR_ACTION_STATE_MODIFY_HDR, 21f5e22be5SYevgeny Kliteynik DR_ACTION_STATE_POP_VLAN, 22f5e22be5SYevgeny Kliteynik DR_ACTION_STATE_PUSH_VLAN, 239db810edSAlex Vesker DR_ACTION_STATE_NON_TERM, 249db810edSAlex Vesker DR_ACTION_STATE_TERM, 258920d92bSYevgeny Kliteynik DR_ACTION_STATE_ASO, 269db810edSAlex Vesker DR_ACTION_STATE_MAX, 279db810edSAlex Vesker }; 289db810edSAlex Vesker 29f35715a6SYevgeny Kliteynik static const char * const action_type_to_str[] = { 30f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_TNL_L2_TO_L2] = "DR_ACTION_TYP_TNL_L2_TO_L2", 31f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = "DR_ACTION_TYP_L2_TO_TNL_L2", 32f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_TNL_L3_TO_L2] = "DR_ACTION_TYP_TNL_L3_TO_L2", 33f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = "DR_ACTION_TYP_L2_TO_TNL_L3", 34f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_DROP] = "DR_ACTION_TYP_DROP", 35f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_QP] = "DR_ACTION_TYP_QP", 36f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_FT] = "DR_ACTION_TYP_FT", 37f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = "DR_ACTION_TYP_CTR", 38f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_TAG] = "DR_ACTION_TYP_TAG", 39f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_MODIFY_HDR] = "DR_ACTION_TYP_MODIFY_HDR", 40f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_VPORT] = "DR_ACTION_TYP_VPORT", 41f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = "DR_ACTION_TYP_POP_VLAN", 42f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = "DR_ACTION_TYP_PUSH_VLAN", 4398576013SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = "DR_ACTION_TYP_SAMPLER", 44f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = "DR_ACTION_TYP_INSERT_HDR", 45f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_REMOVE_HDR] = "DR_ACTION_TYP_REMOVE_HDR", 468920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = "DR_ACTION_TYP_ASO_FLOW_METER", 47*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = "DR_ACTION_TYP_RANGE", 48f35715a6SYevgeny Kliteynik [DR_ACTION_TYP_MAX] = "DR_ACTION_UNKNOWN", 49f35715a6SYevgeny Kliteynik }; 50f35715a6SYevgeny Kliteynik 51f35715a6SYevgeny Kliteynik static const char *dr_action_id_to_str(enum mlx5dr_action_type action_id) 52f35715a6SYevgeny Kliteynik { 53f35715a6SYevgeny Kliteynik if (action_id > DR_ACTION_TYP_MAX) 54f35715a6SYevgeny Kliteynik action_id = DR_ACTION_TYP_MAX; 55f35715a6SYevgeny Kliteynik return action_type_to_str[action_id]; 56f35715a6SYevgeny Kliteynik } 57f35715a6SYevgeny Kliteynik 589db810edSAlex Vesker static const enum dr_action_valid_state 599db810edSAlex Vesker next_action_state[DR_ACTION_DOMAIN_MAX][DR_ACTION_STATE_MAX][DR_ACTION_TYP_MAX] = { 609db810edSAlex Vesker [DR_ACTION_DOMAIN_NIC_INGRESS] = { 619db810edSAlex Vesker [DR_ACTION_STATE_NO_ACTION] = { 629db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 639db810edSAlex Vesker [DR_ACTION_TYP_QP] = DR_ACTION_STATE_TERM, 649db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 65*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 661ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 679db810edSAlex Vesker [DR_ACTION_TYP_TAG] = DR_ACTION_STATE_NON_TERM, 689db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_NON_TERM, 6928de41a4SYevgeny Kliteynik [DR_ACTION_TYP_TNL_L2_TO_L2] = DR_ACTION_STATE_DECAP, 7028de41a4SYevgeny Kliteynik [DR_ACTION_TYP_TNL_L3_TO_L2] = DR_ACTION_STATE_DECAP, 71d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 72d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 737ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 740139145fSYevgeny Kliteynik [DR_ACTION_TYP_REMOVE_HDR] = DR_ACTION_STATE_DECAP, 759db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 76f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 772de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 788920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 799db810edSAlex Vesker }, 8028de41a4SYevgeny Kliteynik [DR_ACTION_STATE_DECAP] = { 819db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 829db810edSAlex Vesker [DR_ACTION_TYP_QP] = DR_ACTION_STATE_TERM, 839db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 84*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 851ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 8628de41a4SYevgeny Kliteynik [DR_ACTION_TYP_TAG] = DR_ACTION_STATE_DECAP, 8728de41a4SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_DECAP, 88d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 89d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 907ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 919db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 92f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 932de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 948920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 959db810edSAlex Vesker }, 96d7418b4eSYevgeny Kliteynik [DR_ACTION_STATE_ENCAP] = { 97d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 98d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_QP] = DR_ACTION_STATE_TERM, 99d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 100*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 1011ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 102d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_TAG] = DR_ACTION_STATE_ENCAP, 103d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_ENCAP, 1048920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 105d7418b4eSYevgeny Kliteynik }, 1069db810edSAlex Vesker [DR_ACTION_STATE_MODIFY_HDR] = { 1079db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 1089db810edSAlex Vesker [DR_ACTION_TYP_QP] = DR_ACTION_STATE_TERM, 1099db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 110*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 1111ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 1129db810edSAlex Vesker [DR_ACTION_TYP_TAG] = DR_ACTION_STATE_MODIFY_HDR, 1139db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_MODIFY_HDR, 114d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 115d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 1167ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 1172de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 1188920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 1199db810edSAlex Vesker }, 120f5e22be5SYevgeny Kliteynik [DR_ACTION_STATE_POP_VLAN] = { 1219db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 1229db810edSAlex Vesker [DR_ACTION_TYP_QP] = DR_ACTION_STATE_TERM, 1239db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 124*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 1251ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 126f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_TAG] = DR_ACTION_STATE_POP_VLAN, 127f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_POP_VLAN, 128f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 1299db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 130d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 131d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 1327ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 1338920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 1349db810edSAlex Vesker }, 1352de40f68SYevgeny Kliteynik [DR_ACTION_STATE_PUSH_VLAN] = { 1362de40f68SYevgeny Kliteynik [DR_ACTION_TYP_QP] = DR_ACTION_STATE_TERM, 1372de40f68SYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 138*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 1392de40f68SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 1402de40f68SYevgeny Kliteynik [DR_ACTION_TYP_TAG] = DR_ACTION_STATE_PUSH_VLAN, 1412de40f68SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_PUSH_VLAN, 1422de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 1432de40f68SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 1442de40f68SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 1458920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 1462de40f68SYevgeny Kliteynik }, 1479db810edSAlex Vesker [DR_ACTION_STATE_NON_TERM] = { 1489db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 1499db810edSAlex Vesker [DR_ACTION_TYP_QP] = DR_ACTION_STATE_TERM, 1509db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 151*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 1521ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 1539db810edSAlex Vesker [DR_ACTION_TYP_TAG] = DR_ACTION_STATE_NON_TERM, 1549db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_NON_TERM, 15528de41a4SYevgeny Kliteynik [DR_ACTION_TYP_TNL_L2_TO_L2] = DR_ACTION_STATE_DECAP, 15628de41a4SYevgeny Kliteynik [DR_ACTION_TYP_TNL_L3_TO_L2] = DR_ACTION_STATE_DECAP, 157d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 158d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 1597ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 1600139145fSYevgeny Kliteynik [DR_ACTION_TYP_REMOVE_HDR] = DR_ACTION_STATE_DECAP, 1619db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 162f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 1632de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 1648920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 1658920d92bSYevgeny Kliteynik }, 1668920d92bSYevgeny Kliteynik [DR_ACTION_STATE_ASO] = { 1678920d92bSYevgeny Kliteynik [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 1688920d92bSYevgeny Kliteynik [DR_ACTION_TYP_QP] = DR_ACTION_STATE_TERM, 1698920d92bSYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 170*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 1718920d92bSYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_ASO, 1729db810edSAlex Vesker }, 1739db810edSAlex Vesker [DR_ACTION_STATE_TERM] = { 1749db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_TERM, 1759db810edSAlex Vesker }, 1769db810edSAlex Vesker }, 1779db810edSAlex Vesker [DR_ACTION_DOMAIN_NIC_EGRESS] = { 1789db810edSAlex Vesker [DR_ACTION_STATE_NO_ACTION] = { 1799db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 1809db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 181*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 1821ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 1839db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_NON_TERM, 18428de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 18528de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 1867ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 1870139145fSYevgeny Kliteynik [DR_ACTION_TYP_REMOVE_HDR] = DR_ACTION_STATE_DECAP, 1889db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 189f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 1902de40f68SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 1918920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 1929db810edSAlex Vesker }, 1930139145fSYevgeny Kliteynik [DR_ACTION_STATE_DECAP] = { 1940139145fSYevgeny Kliteynik [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 1950139145fSYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 196*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 1970139145fSYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 1980139145fSYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_DECAP, 1998920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 2000139145fSYevgeny Kliteynik }, 20128de41a4SYevgeny Kliteynik [DR_ACTION_STATE_ENCAP] = { 2029db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 2039db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 204*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 2051ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 20628de41a4SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_ENCAP, 2078920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 2089db810edSAlex Vesker }, 2099db810edSAlex Vesker [DR_ACTION_STATE_MODIFY_HDR] = { 2109db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 2119db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 212*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 2131ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 2149db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_MODIFY_HDR, 21528de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 21628de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 2177ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 218f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 2198920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 2209db810edSAlex Vesker }, 2212de40f68SYevgeny Kliteynik [DR_ACTION_STATE_POP_VLAN] = { 2222de40f68SYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 223*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 2242de40f68SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 2252de40f68SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_POP_VLAN, 2262de40f68SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 2272de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 2282de40f68SYevgeny Kliteynik [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 2292de40f68SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 2302de40f68SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 2312de40f68SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 2328920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 2332de40f68SYevgeny Kliteynik }, 234f5e22be5SYevgeny Kliteynik [DR_ACTION_STATE_PUSH_VLAN] = { 2359db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 2369db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 237*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 2381ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 239f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_PUSH_VLAN, 240f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 24128de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 24228de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 2437ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 2448920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 2459db810edSAlex Vesker }, 2469db810edSAlex Vesker [DR_ACTION_STATE_NON_TERM] = { 2479db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 2489db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 249*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 2501ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 2519db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_NON_TERM, 25228de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 25328de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 2547ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 2550139145fSYevgeny Kliteynik [DR_ACTION_TYP_REMOVE_HDR] = DR_ACTION_STATE_DECAP, 2569db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 257f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 2582de40f68SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 2598920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 2608920d92bSYevgeny Kliteynik }, 2618920d92bSYevgeny Kliteynik [DR_ACTION_STATE_ASO] = { 2628920d92bSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 2638920d92bSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 2648920d92bSYevgeny Kliteynik [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 2658920d92bSYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 2668920d92bSYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_ASO, 2678920d92bSYevgeny Kliteynik [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 2688920d92bSYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 269*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 2709db810edSAlex Vesker }, 2719db810edSAlex Vesker [DR_ACTION_STATE_TERM] = { 2729db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_TERM, 2739db810edSAlex Vesker }, 2749db810edSAlex Vesker }, 2759db810edSAlex Vesker [DR_ACTION_DOMAIN_FDB_INGRESS] = { 2769db810edSAlex Vesker [DR_ACTION_STATE_NO_ACTION] = { 2779db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 2789db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 279*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 2801ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 2819db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_NON_TERM, 28228de41a4SYevgeny Kliteynik [DR_ACTION_TYP_TNL_L2_TO_L2] = DR_ACTION_STATE_DECAP, 28328de41a4SYevgeny Kliteynik [DR_ACTION_TYP_TNL_L3_TO_L2] = DR_ACTION_STATE_DECAP, 284d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 285d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 2867ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 2870139145fSYevgeny Kliteynik [DR_ACTION_TYP_REMOVE_HDR] = DR_ACTION_STATE_DECAP, 2889db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 2892de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 290f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 2919db810edSAlex Vesker [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 2928920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 2939db810edSAlex Vesker }, 29428de41a4SYevgeny Kliteynik [DR_ACTION_STATE_DECAP] = { 2959db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 2969db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 297*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 29828de41a4SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_DECAP, 2991ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 3009db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 3019db810edSAlex Vesker [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 302d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 303d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 3047ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 3052de40f68SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 3062de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 3078920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 308d7418b4eSYevgeny Kliteynik }, 309d7418b4eSYevgeny Kliteynik [DR_ACTION_STATE_ENCAP] = { 310d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 311d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_QP] = DR_ACTION_STATE_TERM, 312d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 313*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 314d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 3151ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 316d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_ENCAP, 3178920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 3189db810edSAlex Vesker }, 3199db810edSAlex Vesker [DR_ACTION_STATE_MODIFY_HDR] = { 3209db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 3219db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 322*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 3231ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 3249db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_MODIFY_HDR, 3259db810edSAlex Vesker [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 326d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 327d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 3287ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 3292de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 3308920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 3319db810edSAlex Vesker }, 332f5e22be5SYevgeny Kliteynik [DR_ACTION_STATE_POP_VLAN] = { 3339db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 3349db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 335*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 3361ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 337f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 338f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_POP_VLAN, 3399db810edSAlex Vesker [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 3409db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 341d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 342d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 3437ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 3448920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 3459db810edSAlex Vesker }, 3462de40f68SYevgeny Kliteynik [DR_ACTION_STATE_PUSH_VLAN] = { 3472de40f68SYevgeny Kliteynik [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 3482de40f68SYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 349*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 3502de40f68SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 3512de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 3522de40f68SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_PUSH_VLAN, 3532de40f68SYevgeny Kliteynik [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 3542de40f68SYevgeny Kliteynik [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 3552de40f68SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 3562de40f68SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 3572de40f68SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 3588920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 3592de40f68SYevgeny Kliteynik }, 3609db810edSAlex Vesker [DR_ACTION_STATE_NON_TERM] = { 3619db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 3629db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 363*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 3641ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 3659db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_NON_TERM, 36628de41a4SYevgeny Kliteynik [DR_ACTION_TYP_TNL_L2_TO_L2] = DR_ACTION_STATE_DECAP, 36728de41a4SYevgeny Kliteynik [DR_ACTION_TYP_TNL_L3_TO_L2] = DR_ACTION_STATE_DECAP, 368d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 369d7418b4eSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 3707ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 3710139145fSYevgeny Kliteynik [DR_ACTION_TYP_REMOVE_HDR] = DR_ACTION_STATE_DECAP, 3729db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 373f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 3742de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 3759db810edSAlex Vesker [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 3768920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 3778920d92bSYevgeny Kliteynik }, 3788920d92bSYevgeny Kliteynik [DR_ACTION_STATE_ASO] = { 3798920d92bSYevgeny Kliteynik [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 3808920d92bSYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 381*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 3828920d92bSYevgeny Kliteynik [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 3838920d92bSYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_ASO, 3849db810edSAlex Vesker }, 3859db810edSAlex Vesker [DR_ACTION_STATE_TERM] = { 3869db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_TERM, 3879db810edSAlex Vesker }, 3889db810edSAlex Vesker }, 3899db810edSAlex Vesker [DR_ACTION_DOMAIN_FDB_EGRESS] = { 3909db810edSAlex Vesker [DR_ACTION_STATE_NO_ACTION] = { 3919db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 3929db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 393*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 3941ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 3959db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_NON_TERM, 3969db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 39728de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 39828de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 3997ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 4000139145fSYevgeny Kliteynik [DR_ACTION_TYP_REMOVE_HDR] = DR_ACTION_STATE_DECAP, 401f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 4022de40f68SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 4039db810edSAlex Vesker [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 4048920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 4059db810edSAlex Vesker }, 4060139145fSYevgeny Kliteynik [DR_ACTION_STATE_DECAP] = { 4070139145fSYevgeny Kliteynik [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 4080139145fSYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 409*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 4100139145fSYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_DECAP, 4110139145fSYevgeny Kliteynik [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 4120139145fSYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 4138920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 4140139145fSYevgeny Kliteynik }, 41528de41a4SYevgeny Kliteynik [DR_ACTION_STATE_ENCAP] = { 4169db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 4179db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 418*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 41928de41a4SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_ENCAP, 4201ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 4219db810edSAlex Vesker [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 4228920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 4239db810edSAlex Vesker }, 4249db810edSAlex Vesker [DR_ACTION_STATE_MODIFY_HDR] = { 4259db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 4269db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 427*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 4281ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 4299db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_MODIFY_HDR, 43028de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 43128de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 4327ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 433f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 4349db810edSAlex Vesker [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 4358920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 4369db810edSAlex Vesker }, 4372de40f68SYevgeny Kliteynik [DR_ACTION_STATE_POP_VLAN] = { 4382de40f68SYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 439*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 4402de40f68SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 4412de40f68SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_POP_VLAN, 4422de40f68SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 4432de40f68SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 4442de40f68SYevgeny Kliteynik [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 4452de40f68SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 4462de40f68SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 4472de40f68SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 4482de40f68SYevgeny Kliteynik [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 4498920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 4502de40f68SYevgeny Kliteynik }, 451f5e22be5SYevgeny Kliteynik [DR_ACTION_STATE_PUSH_VLAN] = { 4529db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 4539db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 454*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 4551ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 456f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 457f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_PUSH_VLAN, 45828de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 45928de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 4607ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 4619db810edSAlex Vesker [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 4628920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 4639db810edSAlex Vesker }, 4649db810edSAlex Vesker [DR_ACTION_STATE_NON_TERM] = { 4659db810edSAlex Vesker [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 4669db810edSAlex Vesker [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 467*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 4681ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = DR_ACTION_STATE_TERM, 4699db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_NON_TERM, 4709db810edSAlex Vesker [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 47128de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 47228de41a4SYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 4737ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = DR_ACTION_STATE_ENCAP, 4740139145fSYevgeny Kliteynik [DR_ACTION_TYP_REMOVE_HDR] = DR_ACTION_STATE_DECAP, 475f5e22be5SYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 4762de40f68SYevgeny Kliteynik [DR_ACTION_TYP_POP_VLAN] = DR_ACTION_STATE_POP_VLAN, 4779db810edSAlex Vesker [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 4788920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = DR_ACTION_STATE_ASO, 4798920d92bSYevgeny Kliteynik }, 4808920d92bSYevgeny Kliteynik [DR_ACTION_STATE_ASO] = { 4818920d92bSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L2] = DR_ACTION_STATE_ENCAP, 4828920d92bSYevgeny Kliteynik [DR_ACTION_TYP_L2_TO_TNL_L3] = DR_ACTION_STATE_ENCAP, 4838920d92bSYevgeny Kliteynik [DR_ACTION_TYP_MODIFY_HDR] = DR_ACTION_STATE_MODIFY_HDR, 4848920d92bSYevgeny Kliteynik [DR_ACTION_TYP_PUSH_VLAN] = DR_ACTION_STATE_PUSH_VLAN, 4858920d92bSYevgeny Kliteynik [DR_ACTION_TYP_DROP] = DR_ACTION_STATE_TERM, 4868920d92bSYevgeny Kliteynik [DR_ACTION_TYP_FT] = DR_ACTION_STATE_TERM, 487*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = DR_ACTION_STATE_TERM, 4888920d92bSYevgeny Kliteynik [DR_ACTION_TYP_VPORT] = DR_ACTION_STATE_TERM, 4898920d92bSYevgeny Kliteynik [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_ASO, 4909db810edSAlex Vesker }, 4919db810edSAlex Vesker [DR_ACTION_STATE_TERM] = { 4929db810edSAlex Vesker [DR_ACTION_TYP_CTR] = DR_ACTION_STATE_TERM, 4939db810edSAlex Vesker }, 4949db810edSAlex Vesker }, 4959db810edSAlex Vesker }; 4969db810edSAlex Vesker 4979db810edSAlex Vesker static int 4989db810edSAlex Vesker dr_action_reformat_to_action_type(enum mlx5dr_action_reformat_type reformat_type, 4999db810edSAlex Vesker enum mlx5dr_action_type *action_type) 5009db810edSAlex Vesker { 5019db810edSAlex Vesker switch (reformat_type) { 5029db810edSAlex Vesker case DR_ACTION_REFORMAT_TYP_TNL_L2_TO_L2: 5039db810edSAlex Vesker *action_type = DR_ACTION_TYP_TNL_L2_TO_L2; 5049db810edSAlex Vesker break; 5059db810edSAlex Vesker case DR_ACTION_REFORMAT_TYP_L2_TO_TNL_L2: 5069db810edSAlex Vesker *action_type = DR_ACTION_TYP_L2_TO_TNL_L2; 5079db810edSAlex Vesker break; 5089db810edSAlex Vesker case DR_ACTION_REFORMAT_TYP_TNL_L3_TO_L2: 5099db810edSAlex Vesker *action_type = DR_ACTION_TYP_TNL_L3_TO_L2; 5109db810edSAlex Vesker break; 5119db810edSAlex Vesker case DR_ACTION_REFORMAT_TYP_L2_TO_TNL_L3: 5129db810edSAlex Vesker *action_type = DR_ACTION_TYP_L2_TO_TNL_L3; 5139db810edSAlex Vesker break; 5147ea9b398SYevgeny Kliteynik case DR_ACTION_REFORMAT_TYP_INSERT_HDR: 5157ea9b398SYevgeny Kliteynik *action_type = DR_ACTION_TYP_INSERT_HDR; 5167ea9b398SYevgeny Kliteynik break; 5170139145fSYevgeny Kliteynik case DR_ACTION_REFORMAT_TYP_REMOVE_HDR: 5180139145fSYevgeny Kliteynik *action_type = DR_ACTION_TYP_REMOVE_HDR; 5190139145fSYevgeny Kliteynik break; 5209db810edSAlex Vesker default: 5219db810edSAlex Vesker return -EINVAL; 5229db810edSAlex Vesker } 5239db810edSAlex Vesker 5249db810edSAlex Vesker return 0; 5259db810edSAlex Vesker } 5269db810edSAlex Vesker 5279db810edSAlex Vesker /* Apply the actions on the rule STE array starting from the last_ste. 5289db810edSAlex Vesker * Actions might require more than one STE, new_num_stes will return 5299db810edSAlex Vesker * the new size of the STEs array, rule with actions. 5309db810edSAlex Vesker */ 5319db810edSAlex Vesker static void dr_actions_apply(struct mlx5dr_domain *dmn, 53246f2a8aeSYevgeny Kliteynik enum mlx5dr_domain_nic_type nic_type, 5339db810edSAlex Vesker u8 *action_type_set, 5349db810edSAlex Vesker u8 *last_ste, 53564c78942SYevgeny Kliteynik struct mlx5dr_ste_actions_attr *attr, 5369db810edSAlex Vesker u32 *new_num_stes) 5379db810edSAlex Vesker { 5386b93b400SYevgeny Kliteynik struct mlx5dr_ste_ctx *ste_ctx = dmn->ste_ctx; 5399db810edSAlex Vesker u32 added_stes = 0; 5409db810edSAlex Vesker 54146f2a8aeSYevgeny Kliteynik if (nic_type == DR_DOMAIN_NIC_TYPE_RX) 5426b93b400SYevgeny Kliteynik mlx5dr_ste_set_actions_rx(ste_ctx, dmn, action_type_set, 54364c78942SYevgeny Kliteynik last_ste, attr, &added_stes); 5449db810edSAlex Vesker else 5456b93b400SYevgeny Kliteynik mlx5dr_ste_set_actions_tx(ste_ctx, dmn, action_type_set, 54664c78942SYevgeny Kliteynik last_ste, attr, &added_stes); 5479db810edSAlex Vesker 5489db810edSAlex Vesker *new_num_stes += added_stes; 5499db810edSAlex Vesker } 5509db810edSAlex Vesker 5519db810edSAlex Vesker static enum dr_action_domain 5529db810edSAlex Vesker dr_action_get_action_domain(enum mlx5dr_domain_type domain, 55346f2a8aeSYevgeny Kliteynik enum mlx5dr_domain_nic_type nic_type) 5549db810edSAlex Vesker { 5559db810edSAlex Vesker switch (domain) { 5569db810edSAlex Vesker case MLX5DR_DOMAIN_TYPE_NIC_RX: 5579db810edSAlex Vesker return DR_ACTION_DOMAIN_NIC_INGRESS; 5589db810edSAlex Vesker case MLX5DR_DOMAIN_TYPE_NIC_TX: 5599db810edSAlex Vesker return DR_ACTION_DOMAIN_NIC_EGRESS; 5609db810edSAlex Vesker case MLX5DR_DOMAIN_TYPE_FDB: 56146f2a8aeSYevgeny Kliteynik if (nic_type == DR_DOMAIN_NIC_TYPE_RX) 5629db810edSAlex Vesker return DR_ACTION_DOMAIN_FDB_INGRESS; 5639db810edSAlex Vesker return DR_ACTION_DOMAIN_FDB_EGRESS; 5649db810edSAlex Vesker default: 5659db810edSAlex Vesker WARN_ON(true); 5669db810edSAlex Vesker return DR_ACTION_DOMAIN_MAX; 5679db810edSAlex Vesker } 5689db810edSAlex Vesker } 5699db810edSAlex Vesker 5709db810edSAlex Vesker static 5719db810edSAlex Vesker int dr_action_validate_and_get_next_state(enum dr_action_domain action_domain, 5729db810edSAlex Vesker u32 action_type, 5739db810edSAlex Vesker u32 *state) 5749db810edSAlex Vesker { 5759db810edSAlex Vesker u32 cur_state = *state; 5769db810edSAlex Vesker 5779db810edSAlex Vesker /* Check action state machine is valid */ 5789db810edSAlex Vesker *state = next_action_state[action_domain][cur_state][action_type]; 5799db810edSAlex Vesker 5809db810edSAlex Vesker if (*state == DR_ACTION_STATE_ERR) 5819db810edSAlex Vesker return -EOPNOTSUPP; 5829db810edSAlex Vesker 5839db810edSAlex Vesker return 0; 5849db810edSAlex Vesker } 5859db810edSAlex Vesker 5869db810edSAlex Vesker static int dr_action_handle_cs_recalc(struct mlx5dr_domain *dmn, 5879db810edSAlex Vesker struct mlx5dr_action *dest_action, 5889db810edSAlex Vesker u64 *final_icm_addr) 5899db810edSAlex Vesker { 5909db810edSAlex Vesker int ret; 5919db810edSAlex Vesker 5929db810edSAlex Vesker switch (dest_action->action_type) { 5939db810edSAlex Vesker case DR_ACTION_TYP_FT: 5949db810edSAlex Vesker /* Allow destination flow table only if table is a terminating 5959db810edSAlex Vesker * table, since there is an *assumption* that in such case FW 5969db810edSAlex Vesker * will recalculate the CS. 5979db810edSAlex Vesker */ 5989dac2966SJianbo Liu if (dest_action->dest_tbl->is_fw_tbl) { 5999dac2966SJianbo Liu *final_icm_addr = dest_action->dest_tbl->fw_tbl.rx_icm_addr; 6009db810edSAlex Vesker } else { 6019db810edSAlex Vesker mlx5dr_dbg(dmn, 6029db810edSAlex Vesker "Destination FT should be terminating when modify TTL is used\n"); 6039db810edSAlex Vesker return -EINVAL; 6049db810edSAlex Vesker } 6059db810edSAlex Vesker break; 6069db810edSAlex Vesker 6079db810edSAlex Vesker case DR_ACTION_TYP_VPORT: 6089db810edSAlex Vesker /* If destination is vport we will get the FW flow table 6099db810edSAlex Vesker * that recalculates the CS and forwards to the vport. 6109db810edSAlex Vesker */ 611c0e90fc2SYevgeny Kliteynik ret = mlx5dr_domain_get_recalc_cs_ft_addr(dest_action->vport->dmn, 6129dac2966SJianbo Liu dest_action->vport->caps->num, 6139db810edSAlex Vesker final_icm_addr); 6149db810edSAlex Vesker if (ret) { 6159db810edSAlex Vesker mlx5dr_err(dmn, "Failed to get FW cs recalc flow table\n"); 6169db810edSAlex Vesker return ret; 6179db810edSAlex Vesker } 6189db810edSAlex Vesker break; 6199db810edSAlex Vesker 6209db810edSAlex Vesker default: 6219db810edSAlex Vesker break; 6229db810edSAlex Vesker } 6239db810edSAlex Vesker 6249db810edSAlex Vesker return 0; 6259db810edSAlex Vesker } 6269db810edSAlex Vesker 627785d7ed2SYevgeny Kliteynik static void dr_action_modify_ttl_adjust(struct mlx5dr_domain *dmn, 628785d7ed2SYevgeny Kliteynik struct mlx5dr_ste_actions_attr *attr, 629785d7ed2SYevgeny Kliteynik bool rx_rule, 630785d7ed2SYevgeny Kliteynik bool *recalc_cs_required) 631785d7ed2SYevgeny Kliteynik { 632785d7ed2SYevgeny Kliteynik *recalc_cs_required = false; 633785d7ed2SYevgeny Kliteynik 634785d7ed2SYevgeny Kliteynik /* if device supports csum recalculation - no adjustment needed */ 635785d7ed2SYevgeny Kliteynik if (mlx5dr_ste_supp_ttl_cs_recalc(&dmn->info.caps)) 636785d7ed2SYevgeny Kliteynik return; 637785d7ed2SYevgeny Kliteynik 638785d7ed2SYevgeny Kliteynik /* no adjustment needed on TX rules */ 639785d7ed2SYevgeny Kliteynik if (!rx_rule) 640785d7ed2SYevgeny Kliteynik return; 641785d7ed2SYevgeny Kliteynik 642785d7ed2SYevgeny Kliteynik if (!MLX5_CAP_ESW_FLOWTABLE(dmn->mdev, fdb_ipv4_ttl_modify)) { 643785d7ed2SYevgeny Kliteynik /* Ignore the modify TTL action. 644785d7ed2SYevgeny Kliteynik * It is always kept as last HW action. 645785d7ed2SYevgeny Kliteynik */ 646785d7ed2SYevgeny Kliteynik attr->modify_actions--; 647785d7ed2SYevgeny Kliteynik return; 648785d7ed2SYevgeny Kliteynik } 649785d7ed2SYevgeny Kliteynik 650785d7ed2SYevgeny Kliteynik if (dmn->type == MLX5DR_DOMAIN_TYPE_FDB) 651785d7ed2SYevgeny Kliteynik /* Due to a HW bug on some devices, modifying TTL on RX flows 652785d7ed2SYevgeny Kliteynik * will cause an incorrect checksum calculation. In such cases 653785d7ed2SYevgeny Kliteynik * we will use a FW table to recalculate the checksum. 654785d7ed2SYevgeny Kliteynik */ 655785d7ed2SYevgeny Kliteynik *recalc_cs_required = true; 656785d7ed2SYevgeny Kliteynik } 657785d7ed2SYevgeny Kliteynik 658f35715a6SYevgeny Kliteynik static void dr_action_print_sequence(struct mlx5dr_domain *dmn, 659f35715a6SYevgeny Kliteynik struct mlx5dr_action *actions[], 660f35715a6SYevgeny Kliteynik int last_idx) 661f35715a6SYevgeny Kliteynik { 662f35715a6SYevgeny Kliteynik int i; 663f35715a6SYevgeny Kliteynik 664f35715a6SYevgeny Kliteynik for (i = 0; i <= last_idx; i++) 665f35715a6SYevgeny Kliteynik mlx5dr_err(dmn, "< %s (%d) > ", 666f35715a6SYevgeny Kliteynik dr_action_id_to_str(actions[i]->action_type), 667f35715a6SYevgeny Kliteynik actions[i]->action_type); 668f35715a6SYevgeny Kliteynik } 669f35715a6SYevgeny Kliteynik 670c72a57adSYevgeny Kliteynik static int dr_action_get_dest_fw_tbl_addr(struct mlx5dr_matcher *matcher, 671c72a57adSYevgeny Kliteynik struct mlx5dr_action_dest_tbl *dest_tbl, 672c72a57adSYevgeny Kliteynik bool is_rx_rule, 673c72a57adSYevgeny Kliteynik u64 *final_icm_addr) 674c72a57adSYevgeny Kliteynik { 675c72a57adSYevgeny Kliteynik struct mlx5dr_cmd_query_flow_table_details output; 676c72a57adSYevgeny Kliteynik struct mlx5dr_domain *dmn = matcher->tbl->dmn; 677c72a57adSYevgeny Kliteynik int ret; 678c72a57adSYevgeny Kliteynik 679c72a57adSYevgeny Kliteynik if (!dest_tbl->fw_tbl.rx_icm_addr) { 680c72a57adSYevgeny Kliteynik ret = mlx5dr_cmd_query_flow_table(dmn->mdev, 681c72a57adSYevgeny Kliteynik dest_tbl->fw_tbl.type, 682c72a57adSYevgeny Kliteynik dest_tbl->fw_tbl.id, 683c72a57adSYevgeny Kliteynik &output); 684c72a57adSYevgeny Kliteynik if (ret) { 685c72a57adSYevgeny Kliteynik mlx5dr_err(dmn, 686c72a57adSYevgeny Kliteynik "Failed mlx5_cmd_query_flow_table ret: %d\n", 687c72a57adSYevgeny Kliteynik ret); 688c72a57adSYevgeny Kliteynik return ret; 689c72a57adSYevgeny Kliteynik } 690c72a57adSYevgeny Kliteynik 691c72a57adSYevgeny Kliteynik dest_tbl->fw_tbl.tx_icm_addr = output.sw_owner_icm_root_1; 692c72a57adSYevgeny Kliteynik dest_tbl->fw_tbl.rx_icm_addr = output.sw_owner_icm_root_0; 693c72a57adSYevgeny Kliteynik } 694c72a57adSYevgeny Kliteynik 695c72a57adSYevgeny Kliteynik *final_icm_addr = is_rx_rule ? dest_tbl->fw_tbl.rx_icm_addr : 696c72a57adSYevgeny Kliteynik dest_tbl->fw_tbl.tx_icm_addr; 697c72a57adSYevgeny Kliteynik return 0; 698c72a57adSYevgeny Kliteynik } 699c72a57adSYevgeny Kliteynik 700c72a57adSYevgeny Kliteynik static int dr_action_get_dest_sw_tbl_addr(struct mlx5dr_matcher *matcher, 701c72a57adSYevgeny Kliteynik struct mlx5dr_action_dest_tbl *dest_tbl, 702c72a57adSYevgeny Kliteynik bool is_rx_rule, 703c72a57adSYevgeny Kliteynik u64 *final_icm_addr) 704c72a57adSYevgeny Kliteynik { 705c72a57adSYevgeny Kliteynik struct mlx5dr_domain *dmn = matcher->tbl->dmn; 706c72a57adSYevgeny Kliteynik struct mlx5dr_icm_chunk *chunk; 707c72a57adSYevgeny Kliteynik 708c72a57adSYevgeny Kliteynik if (dest_tbl->tbl->dmn != dmn) { 709c72a57adSYevgeny Kliteynik mlx5dr_err(dmn, 710c72a57adSYevgeny Kliteynik "Destination table belongs to a different domain\n"); 711c72a57adSYevgeny Kliteynik return -EINVAL; 712c72a57adSYevgeny Kliteynik } 713c72a57adSYevgeny Kliteynik 714c72a57adSYevgeny Kliteynik if (dest_tbl->tbl->level <= matcher->tbl->level) { 715c72a57adSYevgeny Kliteynik mlx5_core_dbg_once(dmn->mdev, 716c72a57adSYevgeny Kliteynik "Connecting table to a lower/same level destination table\n"); 717c72a57adSYevgeny Kliteynik mlx5dr_dbg(dmn, 718c72a57adSYevgeny Kliteynik "Connecting table at level %d to a destination table at level %d\n", 719c72a57adSYevgeny Kliteynik matcher->tbl->level, 720c72a57adSYevgeny Kliteynik dest_tbl->tbl->level); 721c72a57adSYevgeny Kliteynik } 722c72a57adSYevgeny Kliteynik 723c72a57adSYevgeny Kliteynik chunk = is_rx_rule ? dest_tbl->tbl->rx.s_anchor->chunk : 724c72a57adSYevgeny Kliteynik dest_tbl->tbl->tx.s_anchor->chunk; 725c72a57adSYevgeny Kliteynik 726c72a57adSYevgeny Kliteynik *final_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(chunk); 727c72a57adSYevgeny Kliteynik return 0; 728c72a57adSYevgeny Kliteynik } 729c72a57adSYevgeny Kliteynik 730c72a57adSYevgeny Kliteynik static int dr_action_get_dest_tbl_addr(struct mlx5dr_matcher *matcher, 731c72a57adSYevgeny Kliteynik struct mlx5dr_action_dest_tbl *dest_tbl, 732c72a57adSYevgeny Kliteynik bool is_rx_rule, 733c72a57adSYevgeny Kliteynik u64 *final_icm_addr) 734c72a57adSYevgeny Kliteynik { 735c72a57adSYevgeny Kliteynik if (dest_tbl->is_fw_tbl) 736c72a57adSYevgeny Kliteynik return dr_action_get_dest_fw_tbl_addr(matcher, 737c72a57adSYevgeny Kliteynik dest_tbl, 738c72a57adSYevgeny Kliteynik is_rx_rule, 739c72a57adSYevgeny Kliteynik final_icm_addr); 740c72a57adSYevgeny Kliteynik 741c72a57adSYevgeny Kliteynik return dr_action_get_dest_sw_tbl_addr(matcher, 742c72a57adSYevgeny Kliteynik dest_tbl, 743c72a57adSYevgeny Kliteynik is_rx_rule, 744c72a57adSYevgeny Kliteynik final_icm_addr); 745c72a57adSYevgeny Kliteynik } 746c72a57adSYevgeny Kliteynik 7479db810edSAlex Vesker #define WITH_VLAN_NUM_HW_ACTIONS 6 7489db810edSAlex Vesker 7499db810edSAlex Vesker int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher, 7509db810edSAlex Vesker struct mlx5dr_matcher_rx_tx *nic_matcher, 7519db810edSAlex Vesker struct mlx5dr_action *actions[], 7529db810edSAlex Vesker u32 num_actions, 7539db810edSAlex Vesker u8 *ste_arr, 7549db810edSAlex Vesker u32 *new_hw_ste_arr_sz) 7559db810edSAlex Vesker { 7569db810edSAlex Vesker struct mlx5dr_domain_rx_tx *nic_dmn = nic_matcher->nic_tbl->nic_dmn; 75746f2a8aeSYevgeny Kliteynik bool rx_rule = nic_dmn->type == DR_DOMAIN_NIC_TYPE_RX; 7589db810edSAlex Vesker struct mlx5dr_domain *dmn = matcher->tbl->dmn; 7599db810edSAlex Vesker u8 action_type_set[DR_ACTION_TYP_MAX] = {}; 76064c78942SYevgeny Kliteynik struct mlx5dr_ste_actions_attr attr = {}; 7619db810edSAlex Vesker struct mlx5dr_action *dest_action = NULL; 7629db810edSAlex Vesker u32 state = DR_ACTION_STATE_NO_ACTION; 7639db810edSAlex Vesker enum dr_action_domain action_domain; 7649db810edSAlex Vesker bool recalc_cs_required = false; 7659db810edSAlex Vesker u8 *last_ste; 7669db810edSAlex Vesker int i, ret; 7679db810edSAlex Vesker 7689db810edSAlex Vesker attr.gvmi = dmn->info.caps.gvmi; 7699db810edSAlex Vesker attr.hit_gvmi = dmn->info.caps.gvmi; 7709db810edSAlex Vesker attr.final_icm_addr = nic_dmn->default_icm_addr; 77146f2a8aeSYevgeny Kliteynik action_domain = dr_action_get_action_domain(dmn->type, nic_dmn->type); 7729db810edSAlex Vesker 7739db810edSAlex Vesker for (i = 0; i < num_actions; i++) { 7749db810edSAlex Vesker struct mlx5dr_action *action; 7759db810edSAlex Vesker int max_actions_type = 1; 7769db810edSAlex Vesker u32 action_type; 7779db810edSAlex Vesker 7789db810edSAlex Vesker action = actions[i]; 7799db810edSAlex Vesker action_type = action->action_type; 7809db810edSAlex Vesker 7819db810edSAlex Vesker switch (action_type) { 7829db810edSAlex Vesker case DR_ACTION_TYP_DROP: 7839db810edSAlex Vesker attr.final_icm_addr = nic_dmn->drop_icm_addr; 7849db810edSAlex Vesker break; 7859db810edSAlex Vesker case DR_ACTION_TYP_FT: 7869db810edSAlex Vesker dest_action = action; 787c72a57adSYevgeny Kliteynik ret = dr_action_get_dest_tbl_addr(matcher, action->dest_tbl, 788c72a57adSYevgeny Kliteynik rx_rule, &attr.final_icm_addr); 789c72a57adSYevgeny Kliteynik if (ret) 7909db810edSAlex Vesker return ret; 7919db810edSAlex Vesker break; 792*be6d5daeSYevgeny Kliteynik case DR_ACTION_TYP_RANGE: 793*be6d5daeSYevgeny Kliteynik ret = dr_action_get_dest_tbl_addr(matcher, 794*be6d5daeSYevgeny Kliteynik action->range->hit_tbl_action->dest_tbl, 795*be6d5daeSYevgeny Kliteynik rx_rule, &attr.final_icm_addr); 796*be6d5daeSYevgeny Kliteynik if (ret) 797*be6d5daeSYevgeny Kliteynik return ret; 798*be6d5daeSYevgeny Kliteynik 799*be6d5daeSYevgeny Kliteynik ret = dr_action_get_dest_tbl_addr(matcher, 800*be6d5daeSYevgeny Kliteynik action->range->miss_tbl_action->dest_tbl, 801*be6d5daeSYevgeny Kliteynik rx_rule, &attr.range.miss_icm_addr); 802*be6d5daeSYevgeny Kliteynik if (ret) 803*be6d5daeSYevgeny Kliteynik return ret; 804*be6d5daeSYevgeny Kliteynik 805*be6d5daeSYevgeny Kliteynik attr.range.definer_id = action->range->definer_id; 806*be6d5daeSYevgeny Kliteynik attr.range.min = action->range->min; 807*be6d5daeSYevgeny Kliteynik attr.range.max = action->range->max; 808*be6d5daeSYevgeny Kliteynik break; 8099db810edSAlex Vesker case DR_ACTION_TYP_QP: 8109db810edSAlex Vesker mlx5dr_info(dmn, "Domain doesn't support QP\n"); 811f35715a6SYevgeny Kliteynik return -EOPNOTSUPP; 8129db810edSAlex Vesker case DR_ACTION_TYP_CTR: 8139dac2966SJianbo Liu attr.ctr_id = action->ctr->ctr_id + 8145dde00a7SYevgeny Kliteynik action->ctr->offset; 8159db810edSAlex Vesker break; 8169db810edSAlex Vesker case DR_ACTION_TYP_TAG: 8179dac2966SJianbo Liu attr.flow_tag = action->flow_tag->flow_tag; 8189db810edSAlex Vesker break; 8199db810edSAlex Vesker case DR_ACTION_TYP_TNL_L2_TO_L2: 8209db810edSAlex Vesker break; 8219db810edSAlex Vesker case DR_ACTION_TYP_TNL_L3_TO_L2: 8229dac2966SJianbo Liu attr.decap_index = action->rewrite->index; 8239dac2966SJianbo Liu attr.decap_actions = action->rewrite->num_of_actions; 8249db810edSAlex Vesker attr.decap_with_vlan = 8259db810edSAlex Vesker attr.decap_actions == WITH_VLAN_NUM_HW_ACTIONS; 8269db810edSAlex Vesker break; 8279db810edSAlex Vesker case DR_ACTION_TYP_MODIFY_HDR: 8289dac2966SJianbo Liu attr.modify_index = action->rewrite->index; 8299dac2966SJianbo Liu attr.modify_actions = action->rewrite->num_of_actions; 830785d7ed2SYevgeny Kliteynik if (action->rewrite->modify_ttl) 831785d7ed2SYevgeny Kliteynik dr_action_modify_ttl_adjust(dmn, &attr, rx_rule, 832785d7ed2SYevgeny Kliteynik &recalc_cs_required); 8339db810edSAlex Vesker break; 8349db810edSAlex Vesker case DR_ACTION_TYP_L2_TO_TNL_L2: 8359db810edSAlex Vesker case DR_ACTION_TYP_L2_TO_TNL_L3: 836d7418b4eSYevgeny Kliteynik if (rx_rule && 837d7418b4eSYevgeny Kliteynik !(dmn->ste_ctx->actions_caps & DR_STE_CTX_ACTION_CAP_RX_ENCAP)) { 838d7418b4eSYevgeny Kliteynik mlx5dr_info(dmn, "Device doesn't support Encap on RX\n"); 839f35715a6SYevgeny Kliteynik return -EOPNOTSUPP; 840d7418b4eSYevgeny Kliteynik } 8417ea9b398SYevgeny Kliteynik attr.reformat.size = action->reformat->size; 8427ea9b398SYevgeny Kliteynik attr.reformat.id = action->reformat->id; 8439db810edSAlex Vesker break; 8441ab6dc35SYevgeny Kliteynik case DR_ACTION_TYP_SAMPLER: 8451ab6dc35SYevgeny Kliteynik attr.final_icm_addr = rx_rule ? action->sampler->rx_icm_addr : 8461ab6dc35SYevgeny Kliteynik action->sampler->tx_icm_addr; 8471ab6dc35SYevgeny Kliteynik break; 8489db810edSAlex Vesker case DR_ACTION_TYP_VPORT: 8499dac2966SJianbo Liu attr.hit_gvmi = action->vport->caps->vhca_gvmi; 8509db810edSAlex Vesker dest_action = action; 851aa818fbfSShun Hao attr.final_icm_addr = rx_rule ? 852aa818fbfSShun Hao action->vport->caps->icm_address_rx : 853aa818fbfSShun Hao action->vport->caps->icm_address_tx; 8549db810edSAlex Vesker break; 8559db810edSAlex Vesker case DR_ACTION_TYP_POP_VLAN: 8562de40f68SYevgeny Kliteynik if (!rx_rule && !(dmn->ste_ctx->actions_caps & 8572de40f68SYevgeny Kliteynik DR_STE_CTX_ACTION_CAP_TX_POP)) { 8582de40f68SYevgeny Kliteynik mlx5dr_dbg(dmn, "Device doesn't support POP VLAN action on TX\n"); 859f35715a6SYevgeny Kliteynik return -EOPNOTSUPP; 8602de40f68SYevgeny Kliteynik } 8612de40f68SYevgeny Kliteynik 86264c78942SYevgeny Kliteynik max_actions_type = MLX5DR_MAX_VLANS; 8639db810edSAlex Vesker attr.vlans.count++; 8649db810edSAlex Vesker break; 8659db810edSAlex Vesker case DR_ACTION_TYP_PUSH_VLAN: 8662de40f68SYevgeny Kliteynik if (rx_rule && !(dmn->ste_ctx->actions_caps & 8672de40f68SYevgeny Kliteynik DR_STE_CTX_ACTION_CAP_RX_PUSH)) { 8682de40f68SYevgeny Kliteynik mlx5dr_dbg(dmn, "Device doesn't support PUSH VLAN action on RX\n"); 869f35715a6SYevgeny Kliteynik return -EOPNOTSUPP; 8702de40f68SYevgeny Kliteynik } 8712de40f68SYevgeny Kliteynik 87264c78942SYevgeny Kliteynik max_actions_type = MLX5DR_MAX_VLANS; 873f35715a6SYevgeny Kliteynik if (attr.vlans.count == MLX5DR_MAX_VLANS) { 874f35715a6SYevgeny Kliteynik mlx5dr_dbg(dmn, "Max VLAN push/pop count exceeded\n"); 8759db810edSAlex Vesker return -EINVAL; 876f35715a6SYevgeny Kliteynik } 8779db810edSAlex Vesker 8789dac2966SJianbo Liu attr.vlans.headers[attr.vlans.count++] = action->push_vlan->vlan_hdr; 8799db810edSAlex Vesker break; 8807ea9b398SYevgeny Kliteynik case DR_ACTION_TYP_INSERT_HDR: 8810139145fSYevgeny Kliteynik case DR_ACTION_TYP_REMOVE_HDR: 8827ea9b398SYevgeny Kliteynik attr.reformat.size = action->reformat->size; 8837ea9b398SYevgeny Kliteynik attr.reformat.id = action->reformat->id; 8847ea9b398SYevgeny Kliteynik attr.reformat.param_0 = action->reformat->param_0; 8857ea9b398SYevgeny Kliteynik attr.reformat.param_1 = action->reformat->param_1; 8867ea9b398SYevgeny Kliteynik break; 8878920d92bSYevgeny Kliteynik case DR_ACTION_TYP_ASO_FLOW_METER: 8888920d92bSYevgeny Kliteynik attr.aso_flow_meter.obj_id = action->aso->obj_id; 8898920d92bSYevgeny Kliteynik attr.aso_flow_meter.offset = action->aso->offset; 8908920d92bSYevgeny Kliteynik attr.aso_flow_meter.dest_reg_id = action->aso->dest_reg_id; 8918920d92bSYevgeny Kliteynik attr.aso_flow_meter.init_color = action->aso->init_color; 8928920d92bSYevgeny Kliteynik break; 8939db810edSAlex Vesker default: 894f35715a6SYevgeny Kliteynik mlx5dr_err(dmn, "Unsupported action type %d\n", action_type); 895f35715a6SYevgeny Kliteynik return -EINVAL; 8969db810edSAlex Vesker } 8979db810edSAlex Vesker 8989db810edSAlex Vesker /* Check action duplication */ 8999db810edSAlex Vesker if (++action_type_set[action_type] > max_actions_type) { 900b7d0db55SErez Shitrit mlx5dr_err(dmn, "Action type %d supports only max %d time(s)\n", 9019db810edSAlex Vesker action_type, max_actions_type); 902f35715a6SYevgeny Kliteynik return -EINVAL; 9039db810edSAlex Vesker } 9049db810edSAlex Vesker 9059db810edSAlex Vesker /* Check action state machine is valid */ 9069db810edSAlex Vesker if (dr_action_validate_and_get_next_state(action_domain, 9079db810edSAlex Vesker action_type, 9089db810edSAlex Vesker &state)) { 909f35715a6SYevgeny Kliteynik mlx5dr_err(dmn, "Invalid action (gvmi: %d, is_rx: %d) sequence provided:", 910f35715a6SYevgeny Kliteynik attr.gvmi, rx_rule); 911f35715a6SYevgeny Kliteynik dr_action_print_sequence(dmn, actions, i); 9129db810edSAlex Vesker return -EOPNOTSUPP; 9139db810edSAlex Vesker } 9149db810edSAlex Vesker } 9159db810edSAlex Vesker 9169db810edSAlex Vesker *new_hw_ste_arr_sz = nic_matcher->num_of_builders; 9179db810edSAlex Vesker last_ste = ste_arr + DR_STE_SIZE * (nic_matcher->num_of_builders - 1); 9189db810edSAlex Vesker 919785d7ed2SYevgeny Kliteynik if (recalc_cs_required && dest_action) { 9209db810edSAlex Vesker ret = dr_action_handle_cs_recalc(dmn, dest_action, &attr.final_icm_addr); 9219db810edSAlex Vesker if (ret) { 922b7d0db55SErez Shitrit mlx5dr_err(dmn, 9239db810edSAlex Vesker "Failed to handle checksum recalculation err %d\n", 9249db810edSAlex Vesker ret); 9259db810edSAlex Vesker return ret; 9269db810edSAlex Vesker } 9279db810edSAlex Vesker } 9289db810edSAlex Vesker 9299db810edSAlex Vesker dr_actions_apply(dmn, 93046f2a8aeSYevgeny Kliteynik nic_dmn->type, 9319db810edSAlex Vesker action_type_set, 9329db810edSAlex Vesker last_ste, 9339db810edSAlex Vesker &attr, 9349db810edSAlex Vesker new_hw_ste_arr_sz); 9359db810edSAlex Vesker 9369db810edSAlex Vesker return 0; 9379db810edSAlex Vesker } 9389db810edSAlex Vesker 9399dac2966SJianbo Liu static unsigned int action_size[DR_ACTION_TYP_MAX] = { 9409dac2966SJianbo Liu [DR_ACTION_TYP_TNL_L2_TO_L2] = sizeof(struct mlx5dr_action_reformat), 9419dac2966SJianbo Liu [DR_ACTION_TYP_L2_TO_TNL_L2] = sizeof(struct mlx5dr_action_reformat), 9429dac2966SJianbo Liu [DR_ACTION_TYP_TNL_L3_TO_L2] = sizeof(struct mlx5dr_action_rewrite), 9439dac2966SJianbo Liu [DR_ACTION_TYP_L2_TO_TNL_L3] = sizeof(struct mlx5dr_action_reformat), 9449dac2966SJianbo Liu [DR_ACTION_TYP_FT] = sizeof(struct mlx5dr_action_dest_tbl), 9459dac2966SJianbo Liu [DR_ACTION_TYP_CTR] = sizeof(struct mlx5dr_action_ctr), 9469dac2966SJianbo Liu [DR_ACTION_TYP_TAG] = sizeof(struct mlx5dr_action_flow_tag), 9479dac2966SJianbo Liu [DR_ACTION_TYP_MODIFY_HDR] = sizeof(struct mlx5dr_action_rewrite), 9489dac2966SJianbo Liu [DR_ACTION_TYP_VPORT] = sizeof(struct mlx5dr_action_vport), 9499dac2966SJianbo Liu [DR_ACTION_TYP_PUSH_VLAN] = sizeof(struct mlx5dr_action_push_vlan), 9507ea9b398SYevgeny Kliteynik [DR_ACTION_TYP_INSERT_HDR] = sizeof(struct mlx5dr_action_reformat), 9510139145fSYevgeny Kliteynik [DR_ACTION_TYP_REMOVE_HDR] = sizeof(struct mlx5dr_action_reformat), 9521ab6dc35SYevgeny Kliteynik [DR_ACTION_TYP_SAMPLER] = sizeof(struct mlx5dr_action_sampler), 9538920d92bSYevgeny Kliteynik [DR_ACTION_TYP_ASO_FLOW_METER] = sizeof(struct mlx5dr_action_aso_flow_meter), 954*be6d5daeSYevgeny Kliteynik [DR_ACTION_TYP_RANGE] = sizeof(struct mlx5dr_action_range), 9559dac2966SJianbo Liu }; 9569dac2966SJianbo Liu 9579db810edSAlex Vesker static struct mlx5dr_action * 9589db810edSAlex Vesker dr_action_create_generic(enum mlx5dr_action_type action_type) 9599db810edSAlex Vesker { 9609db810edSAlex Vesker struct mlx5dr_action *action; 9619dac2966SJianbo Liu int extra_size; 9629db810edSAlex Vesker 9639dac2966SJianbo Liu if (action_type < DR_ACTION_TYP_MAX) 9649dac2966SJianbo Liu extra_size = action_size[action_type]; 9659dac2966SJianbo Liu else 9669dac2966SJianbo Liu return NULL; 9679dac2966SJianbo Liu 9689dac2966SJianbo Liu action = kzalloc(sizeof(*action) + extra_size, GFP_KERNEL); 9699db810edSAlex Vesker if (!action) 9709db810edSAlex Vesker return NULL; 9719db810edSAlex Vesker 9729db810edSAlex Vesker action->action_type = action_type; 9739db810edSAlex Vesker refcount_set(&action->refcount, 1); 9749dac2966SJianbo Liu action->data = action + 1; 9759db810edSAlex Vesker 9769db810edSAlex Vesker return action; 9779db810edSAlex Vesker } 9789db810edSAlex Vesker 9799db810edSAlex Vesker struct mlx5dr_action *mlx5dr_action_create_drop(void) 9809db810edSAlex Vesker { 9819db810edSAlex Vesker return dr_action_create_generic(DR_ACTION_TYP_DROP); 9829db810edSAlex Vesker } 9839db810edSAlex Vesker 9849db810edSAlex Vesker struct mlx5dr_action * 985de346f40SAlex Vesker mlx5dr_action_create_dest_table_num(struct mlx5dr_domain *dmn, u32 table_num) 986de346f40SAlex Vesker { 987de346f40SAlex Vesker struct mlx5dr_action *action; 988de346f40SAlex Vesker 989de346f40SAlex Vesker action = dr_action_create_generic(DR_ACTION_TYP_FT); 990de346f40SAlex Vesker if (!action) 991de346f40SAlex Vesker return NULL; 992de346f40SAlex Vesker 9939dac2966SJianbo Liu action->dest_tbl->is_fw_tbl = true; 9949dac2966SJianbo Liu action->dest_tbl->fw_tbl.dmn = dmn; 9959dac2966SJianbo Liu action->dest_tbl->fw_tbl.id = table_num; 9969dac2966SJianbo Liu action->dest_tbl->fw_tbl.type = FS_FT_FDB; 997de346f40SAlex Vesker refcount_inc(&dmn->refcount); 998de346f40SAlex Vesker 999de346f40SAlex Vesker return action; 1000de346f40SAlex Vesker } 1001de346f40SAlex Vesker 1002de346f40SAlex Vesker struct mlx5dr_action * 10039db810edSAlex Vesker mlx5dr_action_create_dest_table(struct mlx5dr_table *tbl) 10049db810edSAlex Vesker { 10059db810edSAlex Vesker struct mlx5dr_action *action; 10069db810edSAlex Vesker 10079db810edSAlex Vesker refcount_inc(&tbl->refcount); 10089db810edSAlex Vesker 10099db810edSAlex Vesker action = dr_action_create_generic(DR_ACTION_TYP_FT); 10109db810edSAlex Vesker if (!action) 10119db810edSAlex Vesker goto dec_ref; 10129db810edSAlex Vesker 10139dac2966SJianbo Liu action->dest_tbl->tbl = tbl; 10149db810edSAlex Vesker 10159db810edSAlex Vesker return action; 10169db810edSAlex Vesker 10179db810edSAlex Vesker dec_ref: 10189db810edSAlex Vesker refcount_dec(&tbl->refcount); 10199db810edSAlex Vesker return NULL; 10209db810edSAlex Vesker } 10219db810edSAlex Vesker 1022*be6d5daeSYevgeny Kliteynik static void dr_action_range_definer_fill(u16 *format_id, 1023*be6d5daeSYevgeny Kliteynik u8 *dw_selectors, 1024*be6d5daeSYevgeny Kliteynik u8 *byte_selectors, 1025*be6d5daeSYevgeny Kliteynik u8 *match_mask) 1026*be6d5daeSYevgeny Kliteynik { 1027*be6d5daeSYevgeny Kliteynik int i; 1028*be6d5daeSYevgeny Kliteynik 1029*be6d5daeSYevgeny Kliteynik *format_id = MLX5_IFC_DEFINER_FORMAT_ID_SELECT; 1030*be6d5daeSYevgeny Kliteynik 1031*be6d5daeSYevgeny Kliteynik dw_selectors[0] = MLX5_IFC_DEFINER_FORMAT_OFFSET_OUTER_ETH_PKT_LEN / 4; 1032*be6d5daeSYevgeny Kliteynik 1033*be6d5daeSYevgeny Kliteynik for (i = 1; i < MLX5_IFC_DEFINER_DW_SELECTORS_NUM; i++) 1034*be6d5daeSYevgeny Kliteynik dw_selectors[i] = MLX5_IFC_DEFINER_FORMAT_OFFSET_UNUSED; 1035*be6d5daeSYevgeny Kliteynik 1036*be6d5daeSYevgeny Kliteynik for (i = 0; i < MLX5_IFC_DEFINER_BYTE_SELECTORS_NUM; i++) 1037*be6d5daeSYevgeny Kliteynik byte_selectors[i] = MLX5_IFC_DEFINER_FORMAT_OFFSET_UNUSED; 1038*be6d5daeSYevgeny Kliteynik 1039*be6d5daeSYevgeny Kliteynik MLX5_SET(match_definer_match_mask, match_mask, 1040*be6d5daeSYevgeny Kliteynik match_dw_0, 0xffffUL << 16); 1041*be6d5daeSYevgeny Kliteynik } 1042*be6d5daeSYevgeny Kliteynik 1043*be6d5daeSYevgeny Kliteynik static int dr_action_create_range_definer(struct mlx5dr_action *action) 1044*be6d5daeSYevgeny Kliteynik { 1045*be6d5daeSYevgeny Kliteynik u8 match_mask[MLX5_FLD_SZ_BYTES(match_definer, match_mask)] = {}; 1046*be6d5daeSYevgeny Kliteynik u8 byte_selectors[MLX5_IFC_DEFINER_BYTE_SELECTORS_NUM] = {}; 1047*be6d5daeSYevgeny Kliteynik u8 dw_selectors[MLX5_IFC_DEFINER_DW_SELECTORS_NUM] = {}; 1048*be6d5daeSYevgeny Kliteynik struct mlx5dr_domain *dmn = action->range->dmn; 1049*be6d5daeSYevgeny Kliteynik u32 definer_id; 1050*be6d5daeSYevgeny Kliteynik u16 format_id; 1051*be6d5daeSYevgeny Kliteynik int ret; 1052*be6d5daeSYevgeny Kliteynik 1053*be6d5daeSYevgeny Kliteynik dr_action_range_definer_fill(&format_id, 1054*be6d5daeSYevgeny Kliteynik dw_selectors, 1055*be6d5daeSYevgeny Kliteynik byte_selectors, 1056*be6d5daeSYevgeny Kliteynik match_mask); 1057*be6d5daeSYevgeny Kliteynik 1058*be6d5daeSYevgeny Kliteynik ret = mlx5dr_definer_get(dmn, format_id, 1059*be6d5daeSYevgeny Kliteynik dw_selectors, byte_selectors, 1060*be6d5daeSYevgeny Kliteynik match_mask, &definer_id); 1061*be6d5daeSYevgeny Kliteynik if (ret) 1062*be6d5daeSYevgeny Kliteynik return ret; 1063*be6d5daeSYevgeny Kliteynik 1064*be6d5daeSYevgeny Kliteynik action->range->definer_id = definer_id; 1065*be6d5daeSYevgeny Kliteynik return 0; 1066*be6d5daeSYevgeny Kliteynik } 1067*be6d5daeSYevgeny Kliteynik 1068*be6d5daeSYevgeny Kliteynik static void dr_action_destroy_range_definer(struct mlx5dr_action *action) 1069*be6d5daeSYevgeny Kliteynik { 1070*be6d5daeSYevgeny Kliteynik mlx5dr_definer_put(action->range->dmn, action->range->definer_id); 1071*be6d5daeSYevgeny Kliteynik } 1072*be6d5daeSYevgeny Kliteynik 1073*be6d5daeSYevgeny Kliteynik struct mlx5dr_action * 1074*be6d5daeSYevgeny Kliteynik mlx5dr_action_create_dest_match_range(struct mlx5dr_domain *dmn, 1075*be6d5daeSYevgeny Kliteynik u32 field, 1076*be6d5daeSYevgeny Kliteynik struct mlx5_flow_table *hit_ft, 1077*be6d5daeSYevgeny Kliteynik struct mlx5_flow_table *miss_ft, 1078*be6d5daeSYevgeny Kliteynik u32 min, 1079*be6d5daeSYevgeny Kliteynik u32 max) 1080*be6d5daeSYevgeny Kliteynik { 1081*be6d5daeSYevgeny Kliteynik struct mlx5dr_action *action; 1082*be6d5daeSYevgeny Kliteynik int ret; 1083*be6d5daeSYevgeny Kliteynik 1084*be6d5daeSYevgeny Kliteynik if (!mlx5dr_supp_match_ranges(dmn->mdev)) { 1085*be6d5daeSYevgeny Kliteynik mlx5dr_dbg(dmn, "SELECT definer support is needed for match range\n"); 1086*be6d5daeSYevgeny Kliteynik return NULL; 1087*be6d5daeSYevgeny Kliteynik } 1088*be6d5daeSYevgeny Kliteynik 1089*be6d5daeSYevgeny Kliteynik if (field != MLX5_FLOW_DEST_RANGE_FIELD_PKT_LEN || 1090*be6d5daeSYevgeny Kliteynik min > 0xffff || max > 0xffff) { 1091*be6d5daeSYevgeny Kliteynik mlx5dr_err(dmn, "Invalid match range parameters\n"); 1092*be6d5daeSYevgeny Kliteynik return NULL; 1093*be6d5daeSYevgeny Kliteynik } 1094*be6d5daeSYevgeny Kliteynik 1095*be6d5daeSYevgeny Kliteynik action = dr_action_create_generic(DR_ACTION_TYP_RANGE); 1096*be6d5daeSYevgeny Kliteynik if (!action) 1097*be6d5daeSYevgeny Kliteynik return NULL; 1098*be6d5daeSYevgeny Kliteynik 1099*be6d5daeSYevgeny Kliteynik action->range->hit_tbl_action = 1100*be6d5daeSYevgeny Kliteynik mlx5dr_is_fw_table(hit_ft) ? 1101*be6d5daeSYevgeny Kliteynik mlx5dr_action_create_dest_flow_fw_table(dmn, hit_ft) : 1102*be6d5daeSYevgeny Kliteynik mlx5dr_action_create_dest_table(hit_ft->fs_dr_table.dr_table); 1103*be6d5daeSYevgeny Kliteynik 1104*be6d5daeSYevgeny Kliteynik if (!action->range->hit_tbl_action) 1105*be6d5daeSYevgeny Kliteynik goto free_action; 1106*be6d5daeSYevgeny Kliteynik 1107*be6d5daeSYevgeny Kliteynik action->range->miss_tbl_action = 1108*be6d5daeSYevgeny Kliteynik mlx5dr_is_fw_table(miss_ft) ? 1109*be6d5daeSYevgeny Kliteynik mlx5dr_action_create_dest_flow_fw_table(dmn, miss_ft) : 1110*be6d5daeSYevgeny Kliteynik mlx5dr_action_create_dest_table(miss_ft->fs_dr_table.dr_table); 1111*be6d5daeSYevgeny Kliteynik 1112*be6d5daeSYevgeny Kliteynik if (!action->range->miss_tbl_action) 1113*be6d5daeSYevgeny Kliteynik goto free_hit_tbl_action; 1114*be6d5daeSYevgeny Kliteynik 1115*be6d5daeSYevgeny Kliteynik action->range->min = min; 1116*be6d5daeSYevgeny Kliteynik action->range->max = max; 1117*be6d5daeSYevgeny Kliteynik action->range->dmn = dmn; 1118*be6d5daeSYevgeny Kliteynik 1119*be6d5daeSYevgeny Kliteynik ret = dr_action_create_range_definer(action); 1120*be6d5daeSYevgeny Kliteynik if (ret) 1121*be6d5daeSYevgeny Kliteynik goto free_miss_tbl_action; 1122*be6d5daeSYevgeny Kliteynik 1123*be6d5daeSYevgeny Kliteynik /* No need to increase refcount on domain for this action, 1124*be6d5daeSYevgeny Kliteynik * the hit/miss table actions will do it internally. 1125*be6d5daeSYevgeny Kliteynik */ 1126*be6d5daeSYevgeny Kliteynik 1127*be6d5daeSYevgeny Kliteynik return action; 1128*be6d5daeSYevgeny Kliteynik 1129*be6d5daeSYevgeny Kliteynik free_miss_tbl_action: 1130*be6d5daeSYevgeny Kliteynik mlx5dr_action_destroy(action->range->miss_tbl_action); 1131*be6d5daeSYevgeny Kliteynik free_hit_tbl_action: 1132*be6d5daeSYevgeny Kliteynik mlx5dr_action_destroy(action->range->hit_tbl_action); 1133*be6d5daeSYevgeny Kliteynik free_action: 1134*be6d5daeSYevgeny Kliteynik kfree(action); 1135*be6d5daeSYevgeny Kliteynik 1136*be6d5daeSYevgeny Kliteynik return NULL; 1137*be6d5daeSYevgeny Kliteynik } 1138*be6d5daeSYevgeny Kliteynik 11399db810edSAlex Vesker struct mlx5dr_action * 1140b8853c96SAlex Vesker mlx5dr_action_create_mult_dest_tbl(struct mlx5dr_domain *dmn, 1141b8853c96SAlex Vesker struct mlx5dr_action_dest *dests, 114263b85f49SYevgeny Kliteynik u32 num_of_dests, 11432c5fc6cdSMaor Dickman bool ignore_flow_level, 11442c5fc6cdSMaor Dickman u32 flow_source) 1145b8853c96SAlex Vesker { 1146b8853c96SAlex Vesker struct mlx5dr_cmd_flow_destination_hw_info *hw_dests; 1147b8853c96SAlex Vesker struct mlx5dr_action **ref_actions; 1148b8853c96SAlex Vesker struct mlx5dr_action *action; 1149b8853c96SAlex Vesker bool reformat_req = false; 1150b8853c96SAlex Vesker u32 num_of_ref = 0; 11510e6f3ef4SLen Baker u32 ref_act_cnt; 1152b8853c96SAlex Vesker int ret; 1153b8853c96SAlex Vesker int i; 1154b8853c96SAlex Vesker 1155b8853c96SAlex Vesker if (dmn->type != MLX5DR_DOMAIN_TYPE_FDB) { 1156b8853c96SAlex Vesker mlx5dr_err(dmn, "Multiple destination support is for FDB only\n"); 1157b8853c96SAlex Vesker return NULL; 1158b8853c96SAlex Vesker } 1159b8853c96SAlex Vesker 11600e6f3ef4SLen Baker hw_dests = kcalloc(num_of_dests, sizeof(*hw_dests), GFP_KERNEL); 1161b8853c96SAlex Vesker if (!hw_dests) 1162b8853c96SAlex Vesker return NULL; 1163b8853c96SAlex Vesker 11640e6f3ef4SLen Baker if (unlikely(check_mul_overflow(num_of_dests, 2u, &ref_act_cnt))) 11650e6f3ef4SLen Baker goto free_hw_dests; 11660e6f3ef4SLen Baker 11670e6f3ef4SLen Baker ref_actions = kcalloc(ref_act_cnt, sizeof(*ref_actions), GFP_KERNEL); 1168b8853c96SAlex Vesker if (!ref_actions) 1169b8853c96SAlex Vesker goto free_hw_dests; 1170b8853c96SAlex Vesker 1171b8853c96SAlex Vesker for (i = 0; i < num_of_dests; i++) { 1172b8853c96SAlex Vesker struct mlx5dr_action *reformat_action = dests[i].reformat; 1173b8853c96SAlex Vesker struct mlx5dr_action *dest_action = dests[i].dest; 1174b8853c96SAlex Vesker 1175b8853c96SAlex Vesker ref_actions[num_of_ref++] = dest_action; 1176b8853c96SAlex Vesker 1177b8853c96SAlex Vesker switch (dest_action->action_type) { 1178b8853c96SAlex Vesker case DR_ACTION_TYP_VPORT: 1179b8853c96SAlex Vesker hw_dests[i].vport.flags = MLX5_FLOW_DEST_VPORT_VHCA_ID; 1180b8853c96SAlex Vesker hw_dests[i].type = MLX5_FLOW_DESTINATION_TYPE_VPORT; 11819dac2966SJianbo Liu hw_dests[i].vport.num = dest_action->vport->caps->num; 11829dac2966SJianbo Liu hw_dests[i].vport.vhca_id = dest_action->vport->caps->vhca_gvmi; 1183b8853c96SAlex Vesker if (reformat_action) { 1184b8853c96SAlex Vesker reformat_req = true; 1185b8853c96SAlex Vesker hw_dests[i].vport.reformat_id = 11867ea9b398SYevgeny Kliteynik reformat_action->reformat->id; 1187b8853c96SAlex Vesker ref_actions[num_of_ref++] = reformat_action; 1188b8853c96SAlex Vesker hw_dests[i].vport.flags |= MLX5_FLOW_DEST_VPORT_REFORMAT_ID; 1189b8853c96SAlex Vesker } 1190b8853c96SAlex Vesker break; 1191b8853c96SAlex Vesker 1192b8853c96SAlex Vesker case DR_ACTION_TYP_FT: 1193b8853c96SAlex Vesker hw_dests[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 11949dac2966SJianbo Liu if (dest_action->dest_tbl->is_fw_tbl) 11959dac2966SJianbo Liu hw_dests[i].ft_id = dest_action->dest_tbl->fw_tbl.id; 1196b8853c96SAlex Vesker else 11979dac2966SJianbo Liu hw_dests[i].ft_id = dest_action->dest_tbl->tbl->table_id; 1198b8853c96SAlex Vesker break; 1199b8853c96SAlex Vesker 1200b8853c96SAlex Vesker default: 1201b8853c96SAlex Vesker mlx5dr_dbg(dmn, "Invalid multiple destinations action\n"); 1202b8853c96SAlex Vesker goto free_ref_actions; 1203b8853c96SAlex Vesker } 1204b8853c96SAlex Vesker } 1205b8853c96SAlex Vesker 1206b8853c96SAlex Vesker action = dr_action_create_generic(DR_ACTION_TYP_FT); 1207b8853c96SAlex Vesker if (!action) 1208b8853c96SAlex Vesker goto free_ref_actions; 1209b8853c96SAlex Vesker 1210b8853c96SAlex Vesker ret = mlx5dr_fw_create_md_tbl(dmn, 1211b8853c96SAlex Vesker hw_dests, 1212b8853c96SAlex Vesker num_of_dests, 1213b8853c96SAlex Vesker reformat_req, 12149dac2966SJianbo Liu &action->dest_tbl->fw_tbl.id, 121563b85f49SYevgeny Kliteynik &action->dest_tbl->fw_tbl.group_id, 12162c5fc6cdSMaor Dickman ignore_flow_level, 12172c5fc6cdSMaor Dickman flow_source); 1218b8853c96SAlex Vesker if (ret) 1219b8853c96SAlex Vesker goto free_action; 1220b8853c96SAlex Vesker 1221b8853c96SAlex Vesker refcount_inc(&dmn->refcount); 1222b8853c96SAlex Vesker 1223b8853c96SAlex Vesker for (i = 0; i < num_of_ref; i++) 1224b8853c96SAlex Vesker refcount_inc(&ref_actions[i]->refcount); 1225b8853c96SAlex Vesker 12269dac2966SJianbo Liu action->dest_tbl->is_fw_tbl = true; 12279dac2966SJianbo Liu action->dest_tbl->fw_tbl.dmn = dmn; 12289dac2966SJianbo Liu action->dest_tbl->fw_tbl.type = FS_FT_FDB; 12299dac2966SJianbo Liu action->dest_tbl->fw_tbl.ref_actions = ref_actions; 12309dac2966SJianbo Liu action->dest_tbl->fw_tbl.num_of_ref_actions = num_of_ref; 1231b8853c96SAlex Vesker 1232b8853c96SAlex Vesker kfree(hw_dests); 1233b8853c96SAlex Vesker 1234b8853c96SAlex Vesker return action; 1235b8853c96SAlex Vesker 1236b8853c96SAlex Vesker free_action: 1237b8853c96SAlex Vesker kfree(action); 1238b8853c96SAlex Vesker free_ref_actions: 1239b8853c96SAlex Vesker kfree(ref_actions); 1240b8853c96SAlex Vesker free_hw_dests: 1241b8853c96SAlex Vesker kfree(hw_dests); 1242b8853c96SAlex Vesker return NULL; 1243b8853c96SAlex Vesker } 1244b8853c96SAlex Vesker 1245b8853c96SAlex Vesker struct mlx5dr_action * 1246aec292eeSAlex Vesker mlx5dr_action_create_dest_flow_fw_table(struct mlx5dr_domain *dmn, 1247aec292eeSAlex Vesker struct mlx5_flow_table *ft) 12489db810edSAlex Vesker { 12499db810edSAlex Vesker struct mlx5dr_action *action; 12509db810edSAlex Vesker 12519db810edSAlex Vesker action = dr_action_create_generic(DR_ACTION_TYP_FT); 12529db810edSAlex Vesker if (!action) 12539db810edSAlex Vesker return NULL; 12549db810edSAlex Vesker 12559dac2966SJianbo Liu action->dest_tbl->is_fw_tbl = 1; 12569dac2966SJianbo Liu action->dest_tbl->fw_tbl.type = ft->type; 12579dac2966SJianbo Liu action->dest_tbl->fw_tbl.id = ft->id; 12589dac2966SJianbo Liu action->dest_tbl->fw_tbl.dmn = dmn; 1259aec292eeSAlex Vesker 1260aec292eeSAlex Vesker refcount_inc(&dmn->refcount); 12619db810edSAlex Vesker 12629db810edSAlex Vesker return action; 12639db810edSAlex Vesker } 12649db810edSAlex Vesker 12659db810edSAlex Vesker struct mlx5dr_action * 12669db810edSAlex Vesker mlx5dr_action_create_flow_counter(u32 counter_id) 12679db810edSAlex Vesker { 12689db810edSAlex Vesker struct mlx5dr_action *action; 12699db810edSAlex Vesker 12709db810edSAlex Vesker action = dr_action_create_generic(DR_ACTION_TYP_CTR); 12719db810edSAlex Vesker if (!action) 12729db810edSAlex Vesker return NULL; 12739db810edSAlex Vesker 12749dac2966SJianbo Liu action->ctr->ctr_id = counter_id; 12759db810edSAlex Vesker 12769db810edSAlex Vesker return action; 12779db810edSAlex Vesker } 12789db810edSAlex Vesker 12799db810edSAlex Vesker struct mlx5dr_action *mlx5dr_action_create_tag(u32 tag_value) 12809db810edSAlex Vesker { 12819db810edSAlex Vesker struct mlx5dr_action *action; 12829db810edSAlex Vesker 12839db810edSAlex Vesker action = dr_action_create_generic(DR_ACTION_TYP_TAG); 12849db810edSAlex Vesker if (!action) 12859db810edSAlex Vesker return NULL; 12869db810edSAlex Vesker 12879dac2966SJianbo Liu action->flow_tag->flow_tag = tag_value & 0xffffff; 12889db810edSAlex Vesker 12899db810edSAlex Vesker return action; 12909db810edSAlex Vesker } 12919db810edSAlex Vesker 12921ab6dc35SYevgeny Kliteynik struct mlx5dr_action * 12931ab6dc35SYevgeny Kliteynik mlx5dr_action_create_flow_sampler(struct mlx5dr_domain *dmn, u32 sampler_id) 12941ab6dc35SYevgeny Kliteynik { 12951ab6dc35SYevgeny Kliteynik struct mlx5dr_action *action; 12961ab6dc35SYevgeny Kliteynik u64 icm_rx, icm_tx; 12971ab6dc35SYevgeny Kliteynik int ret; 12981ab6dc35SYevgeny Kliteynik 12991ab6dc35SYevgeny Kliteynik ret = mlx5dr_cmd_query_flow_sampler(dmn->mdev, sampler_id, 13001ab6dc35SYevgeny Kliteynik &icm_rx, &icm_tx); 13011ab6dc35SYevgeny Kliteynik if (ret) 13021ab6dc35SYevgeny Kliteynik return NULL; 13031ab6dc35SYevgeny Kliteynik 13041ab6dc35SYevgeny Kliteynik action = dr_action_create_generic(DR_ACTION_TYP_SAMPLER); 13051ab6dc35SYevgeny Kliteynik if (!action) 13061ab6dc35SYevgeny Kliteynik return NULL; 13071ab6dc35SYevgeny Kliteynik 13081ab6dc35SYevgeny Kliteynik action->sampler->dmn = dmn; 13091ab6dc35SYevgeny Kliteynik action->sampler->sampler_id = sampler_id; 13101ab6dc35SYevgeny Kliteynik action->sampler->rx_icm_addr = icm_rx; 13111ab6dc35SYevgeny Kliteynik action->sampler->tx_icm_addr = icm_tx; 13121ab6dc35SYevgeny Kliteynik 13131ab6dc35SYevgeny Kliteynik refcount_inc(&dmn->refcount); 13141ab6dc35SYevgeny Kliteynik return action; 13151ab6dc35SYevgeny Kliteynik } 13161ab6dc35SYevgeny Kliteynik 13179db810edSAlex Vesker static int 13189db810edSAlex Vesker dr_action_verify_reformat_params(enum mlx5dr_action_type reformat_type, 13199db810edSAlex Vesker struct mlx5dr_domain *dmn, 13207ea9b398SYevgeny Kliteynik u8 reformat_param_0, 13217ea9b398SYevgeny Kliteynik u8 reformat_param_1, 13229db810edSAlex Vesker size_t data_sz, 13239db810edSAlex Vesker void *data) 13249db810edSAlex Vesker { 13250139145fSYevgeny Kliteynik if (reformat_type == DR_ACTION_TYP_INSERT_HDR) { 13267ea9b398SYevgeny Kliteynik if ((!data && data_sz) || (data && !data_sz) || 13270139145fSYevgeny Kliteynik MLX5_CAP_GEN_2(dmn->mdev, max_reformat_insert_size) < data_sz || 13280139145fSYevgeny Kliteynik MLX5_CAP_GEN_2(dmn->mdev, max_reformat_insert_offset) < reformat_param_1) { 13290139145fSYevgeny Kliteynik mlx5dr_dbg(dmn, "Invalid reformat parameters for INSERT_HDR\n"); 13300139145fSYevgeny Kliteynik goto out_err; 13310139145fSYevgeny Kliteynik } 13320139145fSYevgeny Kliteynik } else if (reformat_type == DR_ACTION_TYP_REMOVE_HDR) { 13330139145fSYevgeny Kliteynik if (data || 13340139145fSYevgeny Kliteynik MLX5_CAP_GEN_2(dmn->mdev, max_reformat_remove_size) < data_sz || 13350139145fSYevgeny Kliteynik MLX5_CAP_GEN_2(dmn->mdev, max_reformat_remove_offset) < reformat_param_1) { 13360139145fSYevgeny Kliteynik mlx5dr_dbg(dmn, "Invalid reformat parameters for REMOVE_HDR\n"); 13370139145fSYevgeny Kliteynik goto out_err; 13380139145fSYevgeny Kliteynik } 13390139145fSYevgeny Kliteynik } else if (reformat_param_0 || reformat_param_1 || 13400139145fSYevgeny Kliteynik reformat_type > DR_ACTION_TYP_REMOVE_HDR) { 13410139145fSYevgeny Kliteynik mlx5dr_dbg(dmn, "Invalid reformat parameters\n"); 13429db810edSAlex Vesker goto out_err; 13439db810edSAlex Vesker } 13449db810edSAlex Vesker 13459db810edSAlex Vesker if (dmn->type == MLX5DR_DOMAIN_TYPE_FDB) 13469db810edSAlex Vesker return 0; 13479db810edSAlex Vesker 13489db810edSAlex Vesker if (dmn->type == MLX5DR_DOMAIN_TYPE_NIC_RX) { 13499db810edSAlex Vesker if (reformat_type != DR_ACTION_TYP_TNL_L2_TO_L2 && 13509db810edSAlex Vesker reformat_type != DR_ACTION_TYP_TNL_L3_TO_L2) { 13519db810edSAlex Vesker mlx5dr_dbg(dmn, "Action reformat type not support on RX domain\n"); 13529db810edSAlex Vesker goto out_err; 13539db810edSAlex Vesker } 13549db810edSAlex Vesker } else if (dmn->type == MLX5DR_DOMAIN_TYPE_NIC_TX) { 13559db810edSAlex Vesker if (reformat_type != DR_ACTION_TYP_L2_TO_TNL_L2 && 13569db810edSAlex Vesker reformat_type != DR_ACTION_TYP_L2_TO_TNL_L3) { 13579db810edSAlex Vesker mlx5dr_dbg(dmn, "Action reformat type not support on TX domain\n"); 13589db810edSAlex Vesker goto out_err; 13599db810edSAlex Vesker } 13609db810edSAlex Vesker } 13619db810edSAlex Vesker 13629db810edSAlex Vesker return 0; 13639db810edSAlex Vesker 13649db810edSAlex Vesker out_err: 13659db810edSAlex Vesker return -EINVAL; 13669db810edSAlex Vesker } 13679db810edSAlex Vesker 13689db810edSAlex Vesker #define ACTION_CACHE_LINE_SIZE 64 13699db810edSAlex Vesker 13709db810edSAlex Vesker static int 13719db810edSAlex Vesker dr_action_create_reformat_action(struct mlx5dr_domain *dmn, 13727ea9b398SYevgeny Kliteynik u8 reformat_param_0, u8 reformat_param_1, 13739db810edSAlex Vesker size_t data_sz, void *data, 13749db810edSAlex Vesker struct mlx5dr_action *action) 13759db810edSAlex Vesker { 13769db810edSAlex Vesker u32 reformat_id; 13779db810edSAlex Vesker int ret; 13789db810edSAlex Vesker 13799db810edSAlex Vesker switch (action->action_type) { 13809db810edSAlex Vesker case DR_ACTION_TYP_L2_TO_TNL_L2: 13819db810edSAlex Vesker case DR_ACTION_TYP_L2_TO_TNL_L3: 13829db810edSAlex Vesker { 13837550d541SNathan Chancellor enum mlx5_reformat_ctx_type rt; 13849db810edSAlex Vesker 13859db810edSAlex Vesker if (action->action_type == DR_ACTION_TYP_L2_TO_TNL_L2) 13869db810edSAlex Vesker rt = MLX5_REFORMAT_TYPE_L2_TO_L2_TUNNEL; 13879db810edSAlex Vesker else 13889db810edSAlex Vesker rt = MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL; 13899db810edSAlex Vesker 13907ea9b398SYevgeny Kliteynik ret = mlx5dr_cmd_create_reformat_ctx(dmn->mdev, rt, 0, 0, 13917ea9b398SYevgeny Kliteynik data_sz, data, 13929db810edSAlex Vesker &reformat_id); 13939db810edSAlex Vesker if (ret) 13949db810edSAlex Vesker return ret; 13959db810edSAlex Vesker 13967ea9b398SYevgeny Kliteynik action->reformat->id = reformat_id; 13977ea9b398SYevgeny Kliteynik action->reformat->size = data_sz; 13989db810edSAlex Vesker return 0; 13999db810edSAlex Vesker } 14009db810edSAlex Vesker case DR_ACTION_TYP_TNL_L2_TO_L2: 14019db810edSAlex Vesker { 14029db810edSAlex Vesker return 0; 14039db810edSAlex Vesker } 14049db810edSAlex Vesker case DR_ACTION_TYP_TNL_L3_TO_L2: 14059db810edSAlex Vesker { 14064781df92SYevgeny Kliteynik u8 hw_actions[ACTION_CACHE_LINE_SIZE] = {}; 14074781df92SYevgeny Kliteynik int ret; 14084781df92SYevgeny Kliteynik 14094781df92SYevgeny Kliteynik ret = mlx5dr_ste_set_action_decap_l3_list(dmn->ste_ctx, 14104781df92SYevgeny Kliteynik data, data_sz, 14114781df92SYevgeny Kliteynik hw_actions, 14124781df92SYevgeny Kliteynik ACTION_CACHE_LINE_SIZE, 14139dac2966SJianbo Liu &action->rewrite->num_of_actions); 14144781df92SYevgeny Kliteynik if (ret) { 14154781df92SYevgeny Kliteynik mlx5dr_dbg(dmn, "Failed creating decap l3 action list\n"); 14164781df92SYevgeny Kliteynik return ret; 14174781df92SYevgeny Kliteynik } 14189db810edSAlex Vesker 14199dac2966SJianbo Liu action->rewrite->chunk = mlx5dr_icm_alloc_chunk(dmn->action_icm_pool, 14209db810edSAlex Vesker DR_CHUNK_SIZE_8); 14219dac2966SJianbo Liu if (!action->rewrite->chunk) { 14224781df92SYevgeny Kliteynik mlx5dr_dbg(dmn, "Failed allocating modify header chunk\n"); 14239db810edSAlex Vesker return -ENOMEM; 14244781df92SYevgeny Kliteynik } 14259db810edSAlex Vesker 14269dac2966SJianbo Liu action->rewrite->data = (void *)hw_actions; 14275c4f9b6eSRongwei Liu action->rewrite->index = (mlx5dr_icm_pool_get_chunk_icm_addr 14285c4f9b6eSRongwei Liu (action->rewrite->chunk) - 14299db810edSAlex Vesker dmn->info.caps.hdr_modify_icm_addr) / 14309db810edSAlex Vesker ACTION_CACHE_LINE_SIZE; 14319db810edSAlex Vesker 14324781df92SYevgeny Kliteynik ret = mlx5dr_send_postsend_action(dmn, action); 14339db810edSAlex Vesker if (ret) { 14344781df92SYevgeny Kliteynik mlx5dr_dbg(dmn, "Writing decap l3 actions to ICM failed\n"); 14359dac2966SJianbo Liu mlx5dr_icm_free_chunk(action->rewrite->chunk); 14369db810edSAlex Vesker return ret; 14379db810edSAlex Vesker } 14389db810edSAlex Vesker return 0; 14399db810edSAlex Vesker } 14407ea9b398SYevgeny Kliteynik case DR_ACTION_TYP_INSERT_HDR: 14417ea9b398SYevgeny Kliteynik ret = mlx5dr_cmd_create_reformat_ctx(dmn->mdev, 14427ea9b398SYevgeny Kliteynik MLX5_REFORMAT_TYPE_INSERT_HDR, 14437ea9b398SYevgeny Kliteynik reformat_param_0, 14447ea9b398SYevgeny Kliteynik reformat_param_1, 14457ea9b398SYevgeny Kliteynik data_sz, data, 14467ea9b398SYevgeny Kliteynik &reformat_id); 14477ea9b398SYevgeny Kliteynik if (ret) 14487ea9b398SYevgeny Kliteynik return ret; 14497ea9b398SYevgeny Kliteynik 14507ea9b398SYevgeny Kliteynik action->reformat->id = reformat_id; 14517ea9b398SYevgeny Kliteynik action->reformat->size = data_sz; 14527ea9b398SYevgeny Kliteynik action->reformat->param_0 = reformat_param_0; 14537ea9b398SYevgeny Kliteynik action->reformat->param_1 = reformat_param_1; 14547ea9b398SYevgeny Kliteynik return 0; 14550139145fSYevgeny Kliteynik case DR_ACTION_TYP_REMOVE_HDR: 14560139145fSYevgeny Kliteynik action->reformat->id = 0; 14570139145fSYevgeny Kliteynik action->reformat->size = data_sz; 14580139145fSYevgeny Kliteynik action->reformat->param_0 = reformat_param_0; 14590139145fSYevgeny Kliteynik action->reformat->param_1 = reformat_param_1; 14600139145fSYevgeny Kliteynik return 0; 14619db810edSAlex Vesker default: 14629db810edSAlex Vesker mlx5dr_info(dmn, "Reformat type is not supported %d\n", action->action_type); 14639db810edSAlex Vesker return -EINVAL; 14649db810edSAlex Vesker } 14659db810edSAlex Vesker } 14669db810edSAlex Vesker 14674781df92SYevgeny Kliteynik #define CVLAN_ETHERTYPE 0x8100 14684781df92SYevgeny Kliteynik #define SVLAN_ETHERTYPE 0x88a8 14694781df92SYevgeny Kliteynik 14709db810edSAlex Vesker struct mlx5dr_action *mlx5dr_action_create_pop_vlan(void) 14719db810edSAlex Vesker { 14729db810edSAlex Vesker return dr_action_create_generic(DR_ACTION_TYP_POP_VLAN); 14739db810edSAlex Vesker } 14749db810edSAlex Vesker 14759db810edSAlex Vesker struct mlx5dr_action *mlx5dr_action_create_push_vlan(struct mlx5dr_domain *dmn, 14769db810edSAlex Vesker __be32 vlan_hdr) 14779db810edSAlex Vesker { 14789db810edSAlex Vesker u32 vlan_hdr_h = ntohl(vlan_hdr); 14799db810edSAlex Vesker u16 ethertype = vlan_hdr_h >> 16; 14809db810edSAlex Vesker struct mlx5dr_action *action; 14819db810edSAlex Vesker 14829db810edSAlex Vesker if (ethertype != SVLAN_ETHERTYPE && ethertype != CVLAN_ETHERTYPE) { 14839db810edSAlex Vesker mlx5dr_dbg(dmn, "Invalid vlan ethertype\n"); 14849db810edSAlex Vesker return NULL; 14859db810edSAlex Vesker } 14869db810edSAlex Vesker 14879db810edSAlex Vesker action = dr_action_create_generic(DR_ACTION_TYP_PUSH_VLAN); 14889db810edSAlex Vesker if (!action) 14899db810edSAlex Vesker return NULL; 14909db810edSAlex Vesker 14919dac2966SJianbo Liu action->push_vlan->vlan_hdr = vlan_hdr_h; 14929db810edSAlex Vesker return action; 14939db810edSAlex Vesker } 14949db810edSAlex Vesker 14959db810edSAlex Vesker struct mlx5dr_action * 14969db810edSAlex Vesker mlx5dr_action_create_packet_reformat(struct mlx5dr_domain *dmn, 14979db810edSAlex Vesker enum mlx5dr_action_reformat_type reformat_type, 14983f3f05abSYevgeny Kliteynik u8 reformat_param_0, 14993f3f05abSYevgeny Kliteynik u8 reformat_param_1, 15009db810edSAlex Vesker size_t data_sz, 15019db810edSAlex Vesker void *data) 15029db810edSAlex Vesker { 15039db810edSAlex Vesker enum mlx5dr_action_type action_type; 15049db810edSAlex Vesker struct mlx5dr_action *action; 15059db810edSAlex Vesker int ret; 15069db810edSAlex Vesker 15079db810edSAlex Vesker refcount_inc(&dmn->refcount); 15089db810edSAlex Vesker 15099db810edSAlex Vesker /* General checks */ 15109db810edSAlex Vesker ret = dr_action_reformat_to_action_type(reformat_type, &action_type); 15119db810edSAlex Vesker if (ret) { 15129db810edSAlex Vesker mlx5dr_dbg(dmn, "Invalid reformat_type provided\n"); 15139db810edSAlex Vesker goto dec_ref; 15149db810edSAlex Vesker } 15159db810edSAlex Vesker 15167ea9b398SYevgeny Kliteynik ret = dr_action_verify_reformat_params(action_type, dmn, 15177ea9b398SYevgeny Kliteynik reformat_param_0, reformat_param_1, 15187ea9b398SYevgeny Kliteynik data_sz, data); 15199db810edSAlex Vesker if (ret) 15209db810edSAlex Vesker goto dec_ref; 15219db810edSAlex Vesker 15229db810edSAlex Vesker action = dr_action_create_generic(action_type); 15239db810edSAlex Vesker if (!action) 15249db810edSAlex Vesker goto dec_ref; 15259db810edSAlex Vesker 15269dac2966SJianbo Liu action->reformat->dmn = dmn; 15279db810edSAlex Vesker 15289db810edSAlex Vesker ret = dr_action_create_reformat_action(dmn, 15297ea9b398SYevgeny Kliteynik reformat_param_0, 15307ea9b398SYevgeny Kliteynik reformat_param_1, 15319db810edSAlex Vesker data_sz, 15329db810edSAlex Vesker data, 15339db810edSAlex Vesker action); 15349db810edSAlex Vesker if (ret) { 15359db810edSAlex Vesker mlx5dr_dbg(dmn, "Failed creating reformat action %d\n", ret); 15369db810edSAlex Vesker goto free_action; 15379db810edSAlex Vesker } 15389db810edSAlex Vesker 15399db810edSAlex Vesker return action; 15409db810edSAlex Vesker 15419db810edSAlex Vesker free_action: 15429db810edSAlex Vesker kfree(action); 15439db810edSAlex Vesker dec_ref: 15449db810edSAlex Vesker refcount_dec(&dmn->refcount); 15459db810edSAlex Vesker return NULL; 15469db810edSAlex Vesker } 15479db810edSAlex Vesker 15489db810edSAlex Vesker static int 1549a51dcc10SHamdan Igbaria dr_action_modify_sw_to_hw_add(struct mlx5dr_domain *dmn, 15509db810edSAlex Vesker __be64 *sw_action, 15519db810edSAlex Vesker __be64 *hw_action, 15524781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field **ret_hw_info) 15539db810edSAlex Vesker { 15544781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field *hw_action_info; 1555a51dcc10SHamdan Igbaria u8 max_length; 15569db810edSAlex Vesker u16 sw_field; 15579db810edSAlex Vesker u32 data; 15589db810edSAlex Vesker 15599db810edSAlex Vesker /* Get SW modify action data */ 1560a51dcc10SHamdan Igbaria sw_field = MLX5_GET(set_action_in, sw_action, field); 1561a51dcc10SHamdan Igbaria data = MLX5_GET(set_action_in, sw_action, data); 1562a51dcc10SHamdan Igbaria 1563a51dcc10SHamdan Igbaria /* Convert SW data to HW modify action format */ 15644781df92SYevgeny Kliteynik hw_action_info = mlx5dr_ste_conv_modify_hdr_sw_field(dmn->ste_ctx, sw_field); 1565a51dcc10SHamdan Igbaria if (!hw_action_info) { 1566a51dcc10SHamdan Igbaria mlx5dr_dbg(dmn, "Modify add action invalid field given\n"); 1567a51dcc10SHamdan Igbaria return -EINVAL; 1568a51dcc10SHamdan Igbaria } 1569a51dcc10SHamdan Igbaria 1570a51dcc10SHamdan Igbaria max_length = hw_action_info->end - hw_action_info->start + 1; 1571a51dcc10SHamdan Igbaria 15724781df92SYevgeny Kliteynik mlx5dr_ste_set_action_add(dmn->ste_ctx, 15734781df92SYevgeny Kliteynik hw_action, 15744781df92SYevgeny Kliteynik hw_action_info->hw_field, 15754781df92SYevgeny Kliteynik hw_action_info->start, 15764781df92SYevgeny Kliteynik max_length, 15774781df92SYevgeny Kliteynik data); 1578a51dcc10SHamdan Igbaria 1579a51dcc10SHamdan Igbaria *ret_hw_info = hw_action_info; 1580a51dcc10SHamdan Igbaria 1581a51dcc10SHamdan Igbaria return 0; 1582a51dcc10SHamdan Igbaria } 1583a51dcc10SHamdan Igbaria 1584a51dcc10SHamdan Igbaria static int 1585a51dcc10SHamdan Igbaria dr_action_modify_sw_to_hw_set(struct mlx5dr_domain *dmn, 1586a51dcc10SHamdan Igbaria __be64 *sw_action, 1587a51dcc10SHamdan Igbaria __be64 *hw_action, 15884781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field **ret_hw_info) 1589a51dcc10SHamdan Igbaria { 15904781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field *hw_action_info; 1591a51dcc10SHamdan Igbaria u8 offset, length, max_length; 1592a51dcc10SHamdan Igbaria u16 sw_field; 1593a51dcc10SHamdan Igbaria u32 data; 1594a51dcc10SHamdan Igbaria 1595a51dcc10SHamdan Igbaria /* Get SW modify action data */ 15969db810edSAlex Vesker length = MLX5_GET(set_action_in, sw_action, length); 15979db810edSAlex Vesker offset = MLX5_GET(set_action_in, sw_action, offset); 15989db810edSAlex Vesker sw_field = MLX5_GET(set_action_in, sw_action, field); 15999db810edSAlex Vesker data = MLX5_GET(set_action_in, sw_action, data); 16009db810edSAlex Vesker 16019db810edSAlex Vesker /* Convert SW data to HW modify action format */ 16024781df92SYevgeny Kliteynik hw_action_info = mlx5dr_ste_conv_modify_hdr_sw_field(dmn->ste_ctx, sw_field); 16039db810edSAlex Vesker if (!hw_action_info) { 1604a51dcc10SHamdan Igbaria mlx5dr_dbg(dmn, "Modify set action invalid field given\n"); 16059db810edSAlex Vesker return -EINVAL; 16069db810edSAlex Vesker } 16079db810edSAlex Vesker 16089db810edSAlex Vesker /* PRM defines that length zero specific length of 32bits */ 1609a51dcc10SHamdan Igbaria length = length ? length : 32; 1610a51dcc10SHamdan Igbaria 1611a51dcc10SHamdan Igbaria max_length = hw_action_info->end - hw_action_info->start + 1; 16129db810edSAlex Vesker 16139db810edSAlex Vesker if (length + offset > max_length) { 16149db810edSAlex Vesker mlx5dr_dbg(dmn, "Modify action length + offset exceeds limit\n"); 16159db810edSAlex Vesker return -EINVAL; 16169db810edSAlex Vesker } 16179db810edSAlex Vesker 16184781df92SYevgeny Kliteynik mlx5dr_ste_set_action_set(dmn->ste_ctx, 16194781df92SYevgeny Kliteynik hw_action, 16204781df92SYevgeny Kliteynik hw_action_info->hw_field, 16214781df92SYevgeny Kliteynik hw_action_info->start + offset, 16224781df92SYevgeny Kliteynik length, 16234781df92SYevgeny Kliteynik data); 16249db810edSAlex Vesker 16259db810edSAlex Vesker *ret_hw_info = hw_action_info; 16269db810edSAlex Vesker 16279db810edSAlex Vesker return 0; 16289db810edSAlex Vesker } 16299db810edSAlex Vesker 16309db810edSAlex Vesker static int 1631c21a49b3SHamdan Igbaria dr_action_modify_sw_to_hw_copy(struct mlx5dr_domain *dmn, 1632c21a49b3SHamdan Igbaria __be64 *sw_action, 1633c21a49b3SHamdan Igbaria __be64 *hw_action, 16344781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field **ret_dst_hw_info, 16354781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field **ret_src_hw_info) 1636c21a49b3SHamdan Igbaria { 1637c21a49b3SHamdan Igbaria u8 src_offset, dst_offset, src_max_length, dst_max_length, length; 16384781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field *hw_dst_action_info; 16394781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field *hw_src_action_info; 1640c21a49b3SHamdan Igbaria u16 src_field, dst_field; 1641c21a49b3SHamdan Igbaria 1642c21a49b3SHamdan Igbaria /* Get SW modify action data */ 1643c21a49b3SHamdan Igbaria src_field = MLX5_GET(copy_action_in, sw_action, src_field); 1644c21a49b3SHamdan Igbaria dst_field = MLX5_GET(copy_action_in, sw_action, dst_field); 1645c21a49b3SHamdan Igbaria src_offset = MLX5_GET(copy_action_in, sw_action, src_offset); 1646c21a49b3SHamdan Igbaria dst_offset = MLX5_GET(copy_action_in, sw_action, dst_offset); 1647c21a49b3SHamdan Igbaria length = MLX5_GET(copy_action_in, sw_action, length); 1648c21a49b3SHamdan Igbaria 1649c21a49b3SHamdan Igbaria /* Convert SW data to HW modify action format */ 16504781df92SYevgeny Kliteynik hw_src_action_info = mlx5dr_ste_conv_modify_hdr_sw_field(dmn->ste_ctx, src_field); 16514781df92SYevgeny Kliteynik hw_dst_action_info = mlx5dr_ste_conv_modify_hdr_sw_field(dmn->ste_ctx, dst_field); 1652c21a49b3SHamdan Igbaria if (!hw_src_action_info || !hw_dst_action_info) { 1653c21a49b3SHamdan Igbaria mlx5dr_dbg(dmn, "Modify copy action invalid field given\n"); 1654c21a49b3SHamdan Igbaria return -EINVAL; 1655c21a49b3SHamdan Igbaria } 1656c21a49b3SHamdan Igbaria 1657c21a49b3SHamdan Igbaria /* PRM defines that length zero specific length of 32bits */ 1658c21a49b3SHamdan Igbaria length = length ? length : 32; 1659c21a49b3SHamdan Igbaria 1660c21a49b3SHamdan Igbaria src_max_length = hw_src_action_info->end - 1661c21a49b3SHamdan Igbaria hw_src_action_info->start + 1; 1662c21a49b3SHamdan Igbaria dst_max_length = hw_dst_action_info->end - 1663c21a49b3SHamdan Igbaria hw_dst_action_info->start + 1; 1664c21a49b3SHamdan Igbaria 1665c21a49b3SHamdan Igbaria if (length + src_offset > src_max_length || 1666c21a49b3SHamdan Igbaria length + dst_offset > dst_max_length) { 1667c21a49b3SHamdan Igbaria mlx5dr_dbg(dmn, "Modify action length + offset exceeds limit\n"); 1668c21a49b3SHamdan Igbaria return -EINVAL; 1669c21a49b3SHamdan Igbaria } 1670c21a49b3SHamdan Igbaria 16714781df92SYevgeny Kliteynik mlx5dr_ste_set_action_copy(dmn->ste_ctx, 16724781df92SYevgeny Kliteynik hw_action, 16734781df92SYevgeny Kliteynik hw_dst_action_info->hw_field, 16744781df92SYevgeny Kliteynik hw_dst_action_info->start + dst_offset, 16754781df92SYevgeny Kliteynik length, 16764781df92SYevgeny Kliteynik hw_src_action_info->hw_field, 16774781df92SYevgeny Kliteynik hw_src_action_info->start + src_offset); 1678c21a49b3SHamdan Igbaria 1679c21a49b3SHamdan Igbaria *ret_dst_hw_info = hw_dst_action_info; 1680c21a49b3SHamdan Igbaria *ret_src_hw_info = hw_src_action_info; 1681c21a49b3SHamdan Igbaria 1682c21a49b3SHamdan Igbaria return 0; 1683c21a49b3SHamdan Igbaria } 1684c21a49b3SHamdan Igbaria 1685c21a49b3SHamdan Igbaria static int 1686a51dcc10SHamdan Igbaria dr_action_modify_sw_to_hw(struct mlx5dr_domain *dmn, 1687a51dcc10SHamdan Igbaria __be64 *sw_action, 1688a51dcc10SHamdan Igbaria __be64 *hw_action, 16894781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field **ret_dst_hw_info, 16904781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field **ret_src_hw_info) 16919db810edSAlex Vesker { 16929db810edSAlex Vesker u8 action; 1693a51dcc10SHamdan Igbaria int ret; 16949db810edSAlex Vesker 1695a51dcc10SHamdan Igbaria *hw_action = 0; 1696c21a49b3SHamdan Igbaria *ret_src_hw_info = NULL; 1697a51dcc10SHamdan Igbaria 1698a51dcc10SHamdan Igbaria /* Get SW modify action type */ 16999db810edSAlex Vesker action = MLX5_GET(set_action_in, sw_action, action_type); 17009db810edSAlex Vesker 1701a51dcc10SHamdan Igbaria switch (action) { 1702a51dcc10SHamdan Igbaria case MLX5_ACTION_TYPE_SET: 1703a51dcc10SHamdan Igbaria ret = dr_action_modify_sw_to_hw_set(dmn, sw_action, 1704a51dcc10SHamdan Igbaria hw_action, 1705c21a49b3SHamdan Igbaria ret_dst_hw_info); 1706a51dcc10SHamdan Igbaria break; 1707a51dcc10SHamdan Igbaria 1708a51dcc10SHamdan Igbaria case MLX5_ACTION_TYPE_ADD: 1709a51dcc10SHamdan Igbaria ret = dr_action_modify_sw_to_hw_add(dmn, sw_action, 1710a51dcc10SHamdan Igbaria hw_action, 1711c21a49b3SHamdan Igbaria ret_dst_hw_info); 1712c21a49b3SHamdan Igbaria break; 1713c21a49b3SHamdan Igbaria 1714c21a49b3SHamdan Igbaria case MLX5_ACTION_TYPE_COPY: 1715c21a49b3SHamdan Igbaria ret = dr_action_modify_sw_to_hw_copy(dmn, sw_action, 1716c21a49b3SHamdan Igbaria hw_action, 1717c21a49b3SHamdan Igbaria ret_dst_hw_info, 1718c21a49b3SHamdan Igbaria ret_src_hw_info); 1719a51dcc10SHamdan Igbaria break; 1720a51dcc10SHamdan Igbaria 1721a51dcc10SHamdan Igbaria default: 1722a51dcc10SHamdan Igbaria mlx5dr_info(dmn, "Unsupported action_type for modify action\n"); 1723a51dcc10SHamdan Igbaria ret = -EOPNOTSUPP; 1724a51dcc10SHamdan Igbaria } 1725a51dcc10SHamdan Igbaria 1726a51dcc10SHamdan Igbaria return ret; 1727a51dcc10SHamdan Igbaria } 1728a51dcc10SHamdan Igbaria 1729a51dcc10SHamdan Igbaria static int 1730a51dcc10SHamdan Igbaria dr_action_modify_check_set_field_limitation(struct mlx5dr_action *action, 1731a51dcc10SHamdan Igbaria const __be64 *sw_action) 1732a51dcc10SHamdan Igbaria { 1733a51dcc10SHamdan Igbaria u16 sw_field = MLX5_GET(set_action_in, sw_action, field); 17349dac2966SJianbo Liu struct mlx5dr_domain *dmn = action->rewrite->dmn; 1735a51dcc10SHamdan Igbaria 17369db810edSAlex Vesker if (sw_field == MLX5_ACTION_IN_FIELD_METADATA_REG_A) { 17379dac2966SJianbo Liu action->rewrite->allow_rx = 0; 17389db810edSAlex Vesker if (dmn->type != MLX5DR_DOMAIN_TYPE_NIC_TX) { 17399db810edSAlex Vesker mlx5dr_dbg(dmn, "Unsupported field %d for RX/FDB set action\n", 17409db810edSAlex Vesker sw_field); 17419db810edSAlex Vesker return -EINVAL; 17429db810edSAlex Vesker } 1743a51dcc10SHamdan Igbaria } else if (sw_field == MLX5_ACTION_IN_FIELD_METADATA_REG_B) { 17449dac2966SJianbo Liu action->rewrite->allow_tx = 0; 17459db810edSAlex Vesker if (dmn->type != MLX5DR_DOMAIN_TYPE_NIC_RX) { 17469db810edSAlex Vesker mlx5dr_dbg(dmn, "Unsupported field %d for TX/FDB set action\n", 17479db810edSAlex Vesker sw_field); 17489db810edSAlex Vesker return -EINVAL; 17499db810edSAlex Vesker } 17509db810edSAlex Vesker } 1751a51dcc10SHamdan Igbaria 17529dac2966SJianbo Liu if (!action->rewrite->allow_rx && !action->rewrite->allow_tx) { 1753a51dcc10SHamdan Igbaria mlx5dr_dbg(dmn, "Modify SET actions not supported on both RX and TX\n"); 1754a51dcc10SHamdan Igbaria return -EINVAL; 1755a51dcc10SHamdan Igbaria } 1756a51dcc10SHamdan Igbaria 1757a51dcc10SHamdan Igbaria return 0; 1758a51dcc10SHamdan Igbaria } 1759a51dcc10SHamdan Igbaria 1760a51dcc10SHamdan Igbaria static int 1761a51dcc10SHamdan Igbaria dr_action_modify_check_add_field_limitation(struct mlx5dr_action *action, 1762a51dcc10SHamdan Igbaria const __be64 *sw_action) 1763a51dcc10SHamdan Igbaria { 1764a51dcc10SHamdan Igbaria u16 sw_field = MLX5_GET(set_action_in, sw_action, field); 17659dac2966SJianbo Liu struct mlx5dr_domain *dmn = action->rewrite->dmn; 1766a51dcc10SHamdan Igbaria 17679db810edSAlex Vesker if (sw_field != MLX5_ACTION_IN_FIELD_OUT_IP_TTL && 17689db810edSAlex Vesker sw_field != MLX5_ACTION_IN_FIELD_OUT_IPV6_HOPLIMIT && 17699db810edSAlex Vesker sw_field != MLX5_ACTION_IN_FIELD_OUT_TCP_SEQ_NUM && 17709db810edSAlex Vesker sw_field != MLX5_ACTION_IN_FIELD_OUT_TCP_ACK_NUM) { 1771a51dcc10SHamdan Igbaria mlx5dr_dbg(dmn, "Unsupported field %d for add action\n", 1772a51dcc10SHamdan Igbaria sw_field); 17739db810edSAlex Vesker return -EINVAL; 17749db810edSAlex Vesker } 17759db810edSAlex Vesker 17769db810edSAlex Vesker return 0; 17779db810edSAlex Vesker } 17789db810edSAlex Vesker 1779a51dcc10SHamdan Igbaria static int 1780c21a49b3SHamdan Igbaria dr_action_modify_check_copy_field_limitation(struct mlx5dr_action *action, 1781c21a49b3SHamdan Igbaria const __be64 *sw_action) 1782c21a49b3SHamdan Igbaria { 17839dac2966SJianbo Liu struct mlx5dr_domain *dmn = action->rewrite->dmn; 1784c21a49b3SHamdan Igbaria u16 sw_fields[2]; 1785c21a49b3SHamdan Igbaria int i; 1786c21a49b3SHamdan Igbaria 1787c21a49b3SHamdan Igbaria sw_fields[0] = MLX5_GET(copy_action_in, sw_action, src_field); 1788c21a49b3SHamdan Igbaria sw_fields[1] = MLX5_GET(copy_action_in, sw_action, dst_field); 1789c21a49b3SHamdan Igbaria 1790c21a49b3SHamdan Igbaria for (i = 0; i < 2; i++) { 1791c21a49b3SHamdan Igbaria if (sw_fields[i] == MLX5_ACTION_IN_FIELD_METADATA_REG_A) { 17929dac2966SJianbo Liu action->rewrite->allow_rx = 0; 1793c21a49b3SHamdan Igbaria if (dmn->type != MLX5DR_DOMAIN_TYPE_NIC_TX) { 1794c21a49b3SHamdan Igbaria mlx5dr_dbg(dmn, "Unsupported field %d for RX/FDB set action\n", 1795c21a49b3SHamdan Igbaria sw_fields[i]); 1796c21a49b3SHamdan Igbaria return -EINVAL; 1797c21a49b3SHamdan Igbaria } 1798c21a49b3SHamdan Igbaria } else if (sw_fields[i] == MLX5_ACTION_IN_FIELD_METADATA_REG_B) { 17999dac2966SJianbo Liu action->rewrite->allow_tx = 0; 1800c21a49b3SHamdan Igbaria if (dmn->type != MLX5DR_DOMAIN_TYPE_NIC_RX) { 1801c21a49b3SHamdan Igbaria mlx5dr_dbg(dmn, "Unsupported field %d for TX/FDB set action\n", 1802c21a49b3SHamdan Igbaria sw_fields[i]); 1803c21a49b3SHamdan Igbaria return -EINVAL; 1804c21a49b3SHamdan Igbaria } 1805c21a49b3SHamdan Igbaria } 1806c21a49b3SHamdan Igbaria } 1807c21a49b3SHamdan Igbaria 18089dac2966SJianbo Liu if (!action->rewrite->allow_rx && !action->rewrite->allow_tx) { 1809c21a49b3SHamdan Igbaria mlx5dr_dbg(dmn, "Modify copy actions not supported on both RX and TX\n"); 1810c21a49b3SHamdan Igbaria return -EINVAL; 1811c21a49b3SHamdan Igbaria } 1812c21a49b3SHamdan Igbaria 1813c21a49b3SHamdan Igbaria return 0; 1814c21a49b3SHamdan Igbaria } 1815c21a49b3SHamdan Igbaria 1816c21a49b3SHamdan Igbaria static int 1817a51dcc10SHamdan Igbaria dr_action_modify_check_field_limitation(struct mlx5dr_action *action, 1818a51dcc10SHamdan Igbaria const __be64 *sw_action) 1819a51dcc10SHamdan Igbaria { 18209dac2966SJianbo Liu struct mlx5dr_domain *dmn = action->rewrite->dmn; 1821a51dcc10SHamdan Igbaria u8 action_type; 1822a51dcc10SHamdan Igbaria int ret; 1823a51dcc10SHamdan Igbaria 1824a51dcc10SHamdan Igbaria action_type = MLX5_GET(set_action_in, sw_action, action_type); 1825a51dcc10SHamdan Igbaria 1826a51dcc10SHamdan Igbaria switch (action_type) { 1827a51dcc10SHamdan Igbaria case MLX5_ACTION_TYPE_SET: 1828a51dcc10SHamdan Igbaria ret = dr_action_modify_check_set_field_limitation(action, 1829a51dcc10SHamdan Igbaria sw_action); 1830a51dcc10SHamdan Igbaria break; 1831a51dcc10SHamdan Igbaria 1832a51dcc10SHamdan Igbaria case MLX5_ACTION_TYPE_ADD: 1833a51dcc10SHamdan Igbaria ret = dr_action_modify_check_add_field_limitation(action, 1834a51dcc10SHamdan Igbaria sw_action); 1835a51dcc10SHamdan Igbaria break; 1836a51dcc10SHamdan Igbaria 1837c21a49b3SHamdan Igbaria case MLX5_ACTION_TYPE_COPY: 1838c21a49b3SHamdan Igbaria ret = dr_action_modify_check_copy_field_limitation(action, 1839c21a49b3SHamdan Igbaria sw_action); 1840c21a49b3SHamdan Igbaria break; 1841c21a49b3SHamdan Igbaria 1842a51dcc10SHamdan Igbaria default: 1843a51dcc10SHamdan Igbaria mlx5dr_info(dmn, "Unsupported action %d modify action\n", 1844a51dcc10SHamdan Igbaria action_type); 1845a51dcc10SHamdan Igbaria ret = -EOPNOTSUPP; 1846a51dcc10SHamdan Igbaria } 1847a51dcc10SHamdan Igbaria 1848a51dcc10SHamdan Igbaria return ret; 1849a51dcc10SHamdan Igbaria } 1850a51dcc10SHamdan Igbaria 18519db810edSAlex Vesker static bool 1852618f88c4SSaeed Mahameed dr_action_modify_check_is_ttl_modify(const void *sw_action) 18539db810edSAlex Vesker { 18549db810edSAlex Vesker u16 sw_field = MLX5_GET(set_action_in, sw_action, field); 18559db810edSAlex Vesker 18569db810edSAlex Vesker return sw_field == MLX5_ACTION_IN_FIELD_OUT_IP_TTL; 18579db810edSAlex Vesker } 18589db810edSAlex Vesker 1859a51dcc10SHamdan Igbaria static int dr_actions_convert_modify_header(struct mlx5dr_action *action, 18609db810edSAlex Vesker u32 max_hw_actions, 18619db810edSAlex Vesker u32 num_sw_actions, 18629db810edSAlex Vesker __be64 sw_actions[], 18639db810edSAlex Vesker __be64 hw_actions[], 18649db810edSAlex Vesker u32 *num_hw_actions, 18659db810edSAlex Vesker bool *modify_ttl) 18669db810edSAlex Vesker { 18674781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field *hw_dst_action_info; 18684781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field *hw_src_action_info; 18699dac2966SJianbo Liu struct mlx5dr_domain *dmn = action->rewrite->dmn; 1870785d7ed2SYevgeny Kliteynik __be64 *modify_ttl_sw_action = NULL; 18719db810edSAlex Vesker int ret, i, hw_idx = 0; 18729db810edSAlex Vesker __be64 *sw_action; 18739db810edSAlex Vesker __be64 hw_action; 18744781df92SYevgeny Kliteynik u16 hw_field = 0; 18754781df92SYevgeny Kliteynik u32 l3_type = 0; 18764781df92SYevgeny Kliteynik u32 l4_type = 0; 18779db810edSAlex Vesker 18789db810edSAlex Vesker *modify_ttl = false; 18799db810edSAlex Vesker 18809dac2966SJianbo Liu action->rewrite->allow_rx = 1; 18819dac2966SJianbo Liu action->rewrite->allow_tx = 1; 1882a51dcc10SHamdan Igbaria 1883785d7ed2SYevgeny Kliteynik for (i = 0; i < num_sw_actions || modify_ttl_sw_action; i++) { 1884785d7ed2SYevgeny Kliteynik /* modify TTL is handled separately, as a last action */ 1885785d7ed2SYevgeny Kliteynik if (i == num_sw_actions) { 1886785d7ed2SYevgeny Kliteynik sw_action = modify_ttl_sw_action; 1887785d7ed2SYevgeny Kliteynik modify_ttl_sw_action = NULL; 1888785d7ed2SYevgeny Kliteynik } else { 18899db810edSAlex Vesker sw_action = &sw_actions[i]; 1890785d7ed2SYevgeny Kliteynik } 18919db810edSAlex Vesker 1892a51dcc10SHamdan Igbaria ret = dr_action_modify_check_field_limitation(action, 1893a51dcc10SHamdan Igbaria sw_action); 18949db810edSAlex Vesker if (ret) 18959db810edSAlex Vesker return ret; 18969db810edSAlex Vesker 18974ff725e1SYevgeny Kliteynik if (!(*modify_ttl) && 18984ff725e1SYevgeny Kliteynik dr_action_modify_check_is_ttl_modify(sw_action)) { 1899785d7ed2SYevgeny Kliteynik modify_ttl_sw_action = sw_action; 19004ff725e1SYevgeny Kliteynik *modify_ttl = true; 1901785d7ed2SYevgeny Kliteynik continue; 19024ff725e1SYevgeny Kliteynik } 19039db810edSAlex Vesker 19049db810edSAlex Vesker /* Convert SW action to HW action */ 19059db810edSAlex Vesker ret = dr_action_modify_sw_to_hw(dmn, 19069db810edSAlex Vesker sw_action, 19079db810edSAlex Vesker &hw_action, 1908c21a49b3SHamdan Igbaria &hw_dst_action_info, 1909c21a49b3SHamdan Igbaria &hw_src_action_info); 19109db810edSAlex Vesker if (ret) 19119db810edSAlex Vesker return ret; 19129db810edSAlex Vesker 19139db810edSAlex Vesker /* Due to a HW limitation we cannot modify 2 different L3 types */ 1914c21a49b3SHamdan Igbaria if (l3_type && hw_dst_action_info->l3_type && 1915c21a49b3SHamdan Igbaria hw_dst_action_info->l3_type != l3_type) { 19169db810edSAlex Vesker mlx5dr_dbg(dmn, "Action list can't support two different L3 types\n"); 19179db810edSAlex Vesker return -EINVAL; 19189db810edSAlex Vesker } 1919c21a49b3SHamdan Igbaria if (hw_dst_action_info->l3_type) 1920c21a49b3SHamdan Igbaria l3_type = hw_dst_action_info->l3_type; 19219db810edSAlex Vesker 19229db810edSAlex Vesker /* Due to a HW limitation we cannot modify two different L4 types */ 1923c21a49b3SHamdan Igbaria if (l4_type && hw_dst_action_info->l4_type && 1924c21a49b3SHamdan Igbaria hw_dst_action_info->l4_type != l4_type) { 19259db810edSAlex Vesker mlx5dr_dbg(dmn, "Action list can't support two different L4 types\n"); 19269db810edSAlex Vesker return -EINVAL; 19279db810edSAlex Vesker } 1928c21a49b3SHamdan Igbaria if (hw_dst_action_info->l4_type) 1929c21a49b3SHamdan Igbaria l4_type = hw_dst_action_info->l4_type; 19309db810edSAlex Vesker 19319db810edSAlex Vesker /* HW reads and executes two actions at once this means we 19329db810edSAlex Vesker * need to create a gap if two actions access the same field 19339db810edSAlex Vesker */ 1934c21a49b3SHamdan Igbaria if ((hw_idx % 2) && (hw_field == hw_dst_action_info->hw_field || 1935c21a49b3SHamdan Igbaria (hw_src_action_info && 1936c21a49b3SHamdan Igbaria hw_field == hw_src_action_info->hw_field))) { 19379db810edSAlex Vesker /* Check if after gap insertion the total number of HW 19389db810edSAlex Vesker * modify actions doesn't exceeds the limit 19399db810edSAlex Vesker */ 19409db810edSAlex Vesker hw_idx++; 19414ff725e1SYevgeny Kliteynik if (hw_idx >= max_hw_actions) { 19429db810edSAlex Vesker mlx5dr_dbg(dmn, "Modify header action number exceeds HW limit\n"); 19439db810edSAlex Vesker return -EINVAL; 19449db810edSAlex Vesker } 19459db810edSAlex Vesker } 1946c21a49b3SHamdan Igbaria hw_field = hw_dst_action_info->hw_field; 19479db810edSAlex Vesker 19489db810edSAlex Vesker hw_actions[hw_idx] = hw_action; 19499db810edSAlex Vesker hw_idx++; 19509db810edSAlex Vesker } 19519db810edSAlex Vesker 19524ff725e1SYevgeny Kliteynik /* if the resulting HW actions list is empty, add NOP action */ 19534ff725e1SYevgeny Kliteynik if (!hw_idx) 19544ff725e1SYevgeny Kliteynik hw_idx++; 19554ff725e1SYevgeny Kliteynik 19569db810edSAlex Vesker *num_hw_actions = hw_idx; 19579db810edSAlex Vesker 19589db810edSAlex Vesker return 0; 19599db810edSAlex Vesker } 19609db810edSAlex Vesker 19619db810edSAlex Vesker static int dr_action_create_modify_action(struct mlx5dr_domain *dmn, 19629db810edSAlex Vesker size_t actions_sz, 19639db810edSAlex Vesker __be64 actions[], 19649db810edSAlex Vesker struct mlx5dr_action *action) 19659db810edSAlex Vesker { 19669db810edSAlex Vesker struct mlx5dr_icm_chunk *chunk; 19679db810edSAlex Vesker u32 max_hw_actions; 19689db810edSAlex Vesker u32 num_hw_actions; 19699db810edSAlex Vesker u32 num_sw_actions; 19709db810edSAlex Vesker __be64 *hw_actions; 19719db810edSAlex Vesker bool modify_ttl; 19729db810edSAlex Vesker int ret; 19739db810edSAlex Vesker 19749db810edSAlex Vesker num_sw_actions = actions_sz / DR_MODIFY_ACTION_SIZE; 19759db810edSAlex Vesker max_hw_actions = mlx5dr_icm_pool_chunk_size_to_entries(DR_CHUNK_SIZE_16); 19769db810edSAlex Vesker 19779db810edSAlex Vesker if (num_sw_actions > max_hw_actions) { 19789db810edSAlex Vesker mlx5dr_dbg(dmn, "Max number of actions %d exceeds limit %d\n", 19799db810edSAlex Vesker num_sw_actions, max_hw_actions); 19809db810edSAlex Vesker return -EINVAL; 19819db810edSAlex Vesker } 19829db810edSAlex Vesker 19839db810edSAlex Vesker chunk = mlx5dr_icm_alloc_chunk(dmn->action_icm_pool, DR_CHUNK_SIZE_16); 19849db810edSAlex Vesker if (!chunk) 19859db810edSAlex Vesker return -ENOMEM; 19869db810edSAlex Vesker 19879db810edSAlex Vesker hw_actions = kcalloc(1, max_hw_actions * DR_MODIFY_ACTION_SIZE, GFP_KERNEL); 19889db810edSAlex Vesker if (!hw_actions) { 19899db810edSAlex Vesker ret = -ENOMEM; 19909db810edSAlex Vesker goto free_chunk; 19919db810edSAlex Vesker } 19929db810edSAlex Vesker 1993a51dcc10SHamdan Igbaria ret = dr_actions_convert_modify_header(action, 19949db810edSAlex Vesker max_hw_actions, 19959db810edSAlex Vesker num_sw_actions, 19969db810edSAlex Vesker actions, 19979db810edSAlex Vesker hw_actions, 19989db810edSAlex Vesker &num_hw_actions, 19999db810edSAlex Vesker &modify_ttl); 20009db810edSAlex Vesker if (ret) 20019db810edSAlex Vesker goto free_hw_actions; 20029db810edSAlex Vesker 20039dac2966SJianbo Liu action->rewrite->chunk = chunk; 20049dac2966SJianbo Liu action->rewrite->modify_ttl = modify_ttl; 20059dac2966SJianbo Liu action->rewrite->data = (u8 *)hw_actions; 20069dac2966SJianbo Liu action->rewrite->num_of_actions = num_hw_actions; 20075c4f9b6eSRongwei Liu action->rewrite->index = (mlx5dr_icm_pool_get_chunk_icm_addr(chunk) - 20089db810edSAlex Vesker dmn->info.caps.hdr_modify_icm_addr) / 20099db810edSAlex Vesker ACTION_CACHE_LINE_SIZE; 20109db810edSAlex Vesker 20119db810edSAlex Vesker ret = mlx5dr_send_postsend_action(dmn, action); 20129db810edSAlex Vesker if (ret) 20139db810edSAlex Vesker goto free_hw_actions; 20149db810edSAlex Vesker 20159db810edSAlex Vesker return 0; 20169db810edSAlex Vesker 20179db810edSAlex Vesker free_hw_actions: 20189db810edSAlex Vesker kfree(hw_actions); 20199db810edSAlex Vesker free_chunk: 20209db810edSAlex Vesker mlx5dr_icm_free_chunk(chunk); 20219db810edSAlex Vesker return ret; 20229db810edSAlex Vesker } 20239db810edSAlex Vesker 20249db810edSAlex Vesker struct mlx5dr_action * 20259db810edSAlex Vesker mlx5dr_action_create_modify_header(struct mlx5dr_domain *dmn, 20269db810edSAlex Vesker u32 flags, 20279db810edSAlex Vesker size_t actions_sz, 20289db810edSAlex Vesker __be64 actions[]) 20299db810edSAlex Vesker { 20309db810edSAlex Vesker struct mlx5dr_action *action; 20319db810edSAlex Vesker int ret = 0; 20329db810edSAlex Vesker 20339db810edSAlex Vesker refcount_inc(&dmn->refcount); 20349db810edSAlex Vesker 20359db810edSAlex Vesker if (actions_sz % DR_MODIFY_ACTION_SIZE) { 20369db810edSAlex Vesker mlx5dr_dbg(dmn, "Invalid modify actions size provided\n"); 20379db810edSAlex Vesker goto dec_ref; 20389db810edSAlex Vesker } 20399db810edSAlex Vesker 20409db810edSAlex Vesker action = dr_action_create_generic(DR_ACTION_TYP_MODIFY_HDR); 20419db810edSAlex Vesker if (!action) 20429db810edSAlex Vesker goto dec_ref; 20439db810edSAlex Vesker 20449dac2966SJianbo Liu action->rewrite->dmn = dmn; 20459db810edSAlex Vesker 20469db810edSAlex Vesker ret = dr_action_create_modify_action(dmn, 20479db810edSAlex Vesker actions_sz, 20489db810edSAlex Vesker actions, 20499db810edSAlex Vesker action); 20509db810edSAlex Vesker if (ret) { 20519db810edSAlex Vesker mlx5dr_dbg(dmn, "Failed creating modify header action %d\n", ret); 20529db810edSAlex Vesker goto free_action; 20539db810edSAlex Vesker } 20549db810edSAlex Vesker 20559db810edSAlex Vesker return action; 20569db810edSAlex Vesker 20579db810edSAlex Vesker free_action: 20589db810edSAlex Vesker kfree(action); 20599db810edSAlex Vesker dec_ref: 20609db810edSAlex Vesker refcount_dec(&dmn->refcount); 20619db810edSAlex Vesker return NULL; 20629db810edSAlex Vesker } 20639db810edSAlex Vesker 20649db810edSAlex Vesker struct mlx5dr_action * 20659db810edSAlex Vesker mlx5dr_action_create_dest_vport(struct mlx5dr_domain *dmn, 2066f9f93bd5SYevgeny Kliteynik u16 vport, u8 vhca_id_valid, 20679db810edSAlex Vesker u16 vhca_id) 20689db810edSAlex Vesker { 20699db810edSAlex Vesker struct mlx5dr_cmd_vport_cap *vport_cap; 20709db810edSAlex Vesker struct mlx5dr_domain *vport_dmn; 20719db810edSAlex Vesker struct mlx5dr_action *action; 20729db810edSAlex Vesker u8 peer_vport; 20739db810edSAlex Vesker 20749db810edSAlex Vesker peer_vport = vhca_id_valid && (vhca_id != dmn->info.caps.gvmi); 20759db810edSAlex Vesker vport_dmn = peer_vport ? dmn->peer_dmn : dmn; 20769db810edSAlex Vesker if (!vport_dmn) { 20779db810edSAlex Vesker mlx5dr_dbg(dmn, "No peer vport domain for given vhca_id\n"); 20789db810edSAlex Vesker return NULL; 20799db810edSAlex Vesker } 20809db810edSAlex Vesker 20819db810edSAlex Vesker if (vport_dmn->type != MLX5DR_DOMAIN_TYPE_FDB) { 20829db810edSAlex Vesker mlx5dr_dbg(dmn, "Domain doesn't support vport actions\n"); 20839db810edSAlex Vesker return NULL; 20849db810edSAlex Vesker } 20859db810edSAlex Vesker 208611a45defSYevgeny Kliteynik vport_cap = mlx5dr_domain_get_vport_cap(vport_dmn, vport); 20879db810edSAlex Vesker if (!vport_cap) { 2088ee1887fbSYevgeny Kliteynik mlx5dr_err(dmn, 2089ee1887fbSYevgeny Kliteynik "Failed to get vport 0x%x caps - vport is disabled or invalid\n", 2090ee1887fbSYevgeny Kliteynik vport); 20919db810edSAlex Vesker return NULL; 20929db810edSAlex Vesker } 20939db810edSAlex Vesker 20949db810edSAlex Vesker action = dr_action_create_generic(DR_ACTION_TYP_VPORT); 20959db810edSAlex Vesker if (!action) 20969db810edSAlex Vesker return NULL; 20979db810edSAlex Vesker 20989dac2966SJianbo Liu action->vport->dmn = vport_dmn; 20999dac2966SJianbo Liu action->vport->caps = vport_cap; 21009db810edSAlex Vesker 21019db810edSAlex Vesker return action; 21029db810edSAlex Vesker } 21039db810edSAlex Vesker 21048920d92bSYevgeny Kliteynik struct mlx5dr_action * 21058920d92bSYevgeny Kliteynik mlx5dr_action_create_aso(struct mlx5dr_domain *dmn, u32 obj_id, 21068920d92bSYevgeny Kliteynik u8 dest_reg_id, u8 aso_type, 21078920d92bSYevgeny Kliteynik u8 init_color, u8 meter_id) 21088920d92bSYevgeny Kliteynik { 21098920d92bSYevgeny Kliteynik struct mlx5dr_action *action; 21108920d92bSYevgeny Kliteynik 21118920d92bSYevgeny Kliteynik if (aso_type != MLX5_EXE_ASO_FLOW_METER) 21128920d92bSYevgeny Kliteynik return NULL; 21138920d92bSYevgeny Kliteynik 21148920d92bSYevgeny Kliteynik if (init_color > MLX5_FLOW_METER_COLOR_UNDEFINED) 21158920d92bSYevgeny Kliteynik return NULL; 21168920d92bSYevgeny Kliteynik 21178920d92bSYevgeny Kliteynik action = dr_action_create_generic(DR_ACTION_TYP_ASO_FLOW_METER); 21188920d92bSYevgeny Kliteynik if (!action) 21198920d92bSYevgeny Kliteynik return NULL; 21208920d92bSYevgeny Kliteynik 21218920d92bSYevgeny Kliteynik action->aso->obj_id = obj_id; 21228920d92bSYevgeny Kliteynik action->aso->offset = meter_id; 21238920d92bSYevgeny Kliteynik action->aso->dest_reg_id = dest_reg_id; 21248920d92bSYevgeny Kliteynik action->aso->init_color = init_color; 21258920d92bSYevgeny Kliteynik action->aso->dmn = dmn; 21268920d92bSYevgeny Kliteynik 21278920d92bSYevgeny Kliteynik refcount_inc(&dmn->refcount); 21288920d92bSYevgeny Kliteynik 21298920d92bSYevgeny Kliteynik return action; 21308920d92bSYevgeny Kliteynik } 21318920d92bSYevgeny Kliteynik 21329db810edSAlex Vesker int mlx5dr_action_destroy(struct mlx5dr_action *action) 21339db810edSAlex Vesker { 2134b5412827SYevgeny Kliteynik if (WARN_ON_ONCE(refcount_read(&action->refcount) > 1)) 21359db810edSAlex Vesker return -EBUSY; 21369db810edSAlex Vesker 21379db810edSAlex Vesker switch (action->action_type) { 21389db810edSAlex Vesker case DR_ACTION_TYP_FT: 21399dac2966SJianbo Liu if (action->dest_tbl->is_fw_tbl) 21409dac2966SJianbo Liu refcount_dec(&action->dest_tbl->fw_tbl.dmn->refcount); 2141aec292eeSAlex Vesker else 21429dac2966SJianbo Liu refcount_dec(&action->dest_tbl->tbl->refcount); 2143b8853c96SAlex Vesker 21449dac2966SJianbo Liu if (action->dest_tbl->is_fw_tbl && 21459dac2966SJianbo Liu action->dest_tbl->fw_tbl.num_of_ref_actions) { 2146b8853c96SAlex Vesker struct mlx5dr_action **ref_actions; 2147b8853c96SAlex Vesker int i; 2148b8853c96SAlex Vesker 21499dac2966SJianbo Liu ref_actions = action->dest_tbl->fw_tbl.ref_actions; 21509dac2966SJianbo Liu for (i = 0; i < action->dest_tbl->fw_tbl.num_of_ref_actions; i++) 2151b8853c96SAlex Vesker refcount_dec(&ref_actions[i]->refcount); 2152b8853c96SAlex Vesker 2153b8853c96SAlex Vesker kfree(ref_actions); 2154b8853c96SAlex Vesker 21559dac2966SJianbo Liu mlx5dr_fw_destroy_md_tbl(action->dest_tbl->fw_tbl.dmn, 21569dac2966SJianbo Liu action->dest_tbl->fw_tbl.id, 21579dac2966SJianbo Liu action->dest_tbl->fw_tbl.group_id); 2158b8853c96SAlex Vesker } 21599db810edSAlex Vesker break; 21609db810edSAlex Vesker case DR_ACTION_TYP_TNL_L2_TO_L2: 21610139145fSYevgeny Kliteynik case DR_ACTION_TYP_REMOVE_HDR: 21629dac2966SJianbo Liu refcount_dec(&action->reformat->dmn->refcount); 21639db810edSAlex Vesker break; 21649db810edSAlex Vesker case DR_ACTION_TYP_TNL_L3_TO_L2: 21659dac2966SJianbo Liu mlx5dr_icm_free_chunk(action->rewrite->chunk); 21669dac2966SJianbo Liu refcount_dec(&action->rewrite->dmn->refcount); 21679db810edSAlex Vesker break; 21689db810edSAlex Vesker case DR_ACTION_TYP_L2_TO_TNL_L2: 21699db810edSAlex Vesker case DR_ACTION_TYP_L2_TO_TNL_L3: 21707ea9b398SYevgeny Kliteynik case DR_ACTION_TYP_INSERT_HDR: 21719dac2966SJianbo Liu mlx5dr_cmd_destroy_reformat_ctx((action->reformat->dmn)->mdev, 21727ea9b398SYevgeny Kliteynik action->reformat->id); 21739dac2966SJianbo Liu refcount_dec(&action->reformat->dmn->refcount); 21749db810edSAlex Vesker break; 21759db810edSAlex Vesker case DR_ACTION_TYP_MODIFY_HDR: 21769dac2966SJianbo Liu mlx5dr_icm_free_chunk(action->rewrite->chunk); 21779dac2966SJianbo Liu kfree(action->rewrite->data); 21789dac2966SJianbo Liu refcount_dec(&action->rewrite->dmn->refcount); 21799db810edSAlex Vesker break; 21801ab6dc35SYevgeny Kliteynik case DR_ACTION_TYP_SAMPLER: 21811ab6dc35SYevgeny Kliteynik refcount_dec(&action->sampler->dmn->refcount); 21821ab6dc35SYevgeny Kliteynik break; 21838920d92bSYevgeny Kliteynik case DR_ACTION_TYP_ASO_FLOW_METER: 21848920d92bSYevgeny Kliteynik refcount_dec(&action->aso->dmn->refcount); 21858920d92bSYevgeny Kliteynik break; 2186*be6d5daeSYevgeny Kliteynik case DR_ACTION_TYP_RANGE: 2187*be6d5daeSYevgeny Kliteynik dr_action_destroy_range_definer(action); 2188*be6d5daeSYevgeny Kliteynik mlx5dr_action_destroy(action->range->miss_tbl_action); 2189*be6d5daeSYevgeny Kliteynik mlx5dr_action_destroy(action->range->hit_tbl_action); 2190*be6d5daeSYevgeny Kliteynik break; 21919db810edSAlex Vesker default: 21929db810edSAlex Vesker break; 21939db810edSAlex Vesker } 21949db810edSAlex Vesker 21959db810edSAlex Vesker kfree(action); 21969db810edSAlex Vesker return 0; 21979db810edSAlex Vesker } 2198