11d918647SAlex Vesker // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 21d918647SAlex Vesker /* Copyright (c) 2019 Mellanox Technologies. */ 31d918647SAlex Vesker 41d918647SAlex Vesker #include "dr_types.h" 51d918647SAlex Vesker 61d918647SAlex Vesker int mlx5dr_cmd_query_esw_vport_context(struct mlx5_core_dev *mdev, 71d918647SAlex Vesker bool other_vport, 81d918647SAlex Vesker u16 vport_number, 91d918647SAlex Vesker u64 *icm_address_rx, 101d918647SAlex Vesker u64 *icm_address_tx) 111d918647SAlex Vesker { 121d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(query_esw_vport_context_out)] = {}; 131d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(query_esw_vport_context_in)] = {}; 141d918647SAlex Vesker int err; 151d918647SAlex Vesker 161d918647SAlex Vesker MLX5_SET(query_esw_vport_context_in, in, opcode, 171d918647SAlex Vesker MLX5_CMD_OP_QUERY_ESW_VPORT_CONTEXT); 181d918647SAlex Vesker MLX5_SET(query_esw_vport_context_in, in, other_vport, other_vport); 191d918647SAlex Vesker MLX5_SET(query_esw_vport_context_in, in, vport_number, vport_number); 201d918647SAlex Vesker 217ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(mdev, query_esw_vport_context, in, out); 221d918647SAlex Vesker if (err) 231d918647SAlex Vesker return err; 241d918647SAlex Vesker 251d918647SAlex Vesker *icm_address_rx = 261d918647SAlex Vesker MLX5_GET64(query_esw_vport_context_out, out, 271d918647SAlex Vesker esw_vport_context.sw_steering_vport_icm_address_rx); 281d918647SAlex Vesker *icm_address_tx = 291d918647SAlex Vesker MLX5_GET64(query_esw_vport_context_out, out, 301d918647SAlex Vesker esw_vport_context.sw_steering_vport_icm_address_tx); 311d918647SAlex Vesker return 0; 321d918647SAlex Vesker } 331d918647SAlex Vesker 341d918647SAlex Vesker int mlx5dr_cmd_query_gvmi(struct mlx5_core_dev *mdev, bool other_vport, 351d918647SAlex Vesker u16 vport_number, u16 *gvmi) 361d918647SAlex Vesker { 371d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {}; 381d918647SAlex Vesker int out_size; 391d918647SAlex Vesker void *out; 401d918647SAlex Vesker int err; 411d918647SAlex Vesker 421d918647SAlex Vesker out_size = MLX5_ST_SZ_BYTES(query_hca_cap_out); 431d918647SAlex Vesker out = kzalloc(out_size, GFP_KERNEL); 441d918647SAlex Vesker if (!out) 451d918647SAlex Vesker return -ENOMEM; 461d918647SAlex Vesker 471d918647SAlex Vesker MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); 481d918647SAlex Vesker MLX5_SET(query_hca_cap_in, in, other_function, other_vport); 491d918647SAlex Vesker MLX5_SET(query_hca_cap_in, in, function_id, vport_number); 501d918647SAlex Vesker MLX5_SET(query_hca_cap_in, in, op_mod, 511d918647SAlex Vesker MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE << 1 | 521d918647SAlex Vesker HCA_CAP_OPMOD_GET_CUR); 531d918647SAlex Vesker 547ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(mdev, query_hca_cap, in, out); 551d918647SAlex Vesker if (err) { 561d918647SAlex Vesker kfree(out); 571d918647SAlex Vesker return err; 581d918647SAlex Vesker } 591d918647SAlex Vesker 601d918647SAlex Vesker *gvmi = MLX5_GET(query_hca_cap_out, out, capability.cmd_hca_cap.vhca_id); 611d918647SAlex Vesker 621d918647SAlex Vesker kfree(out); 631d918647SAlex Vesker return 0; 641d918647SAlex Vesker } 651d918647SAlex Vesker 661d918647SAlex Vesker int mlx5dr_cmd_query_esw_caps(struct mlx5_core_dev *mdev, 671d918647SAlex Vesker struct mlx5dr_esw_caps *caps) 681d918647SAlex Vesker { 691d918647SAlex Vesker caps->drop_icm_address_rx = 701d918647SAlex Vesker MLX5_CAP64_ESW_FLOWTABLE(mdev, 711d918647SAlex Vesker sw_steering_fdb_action_drop_icm_address_rx); 721d918647SAlex Vesker caps->drop_icm_address_tx = 731d918647SAlex Vesker MLX5_CAP64_ESW_FLOWTABLE(mdev, 741d918647SAlex Vesker sw_steering_fdb_action_drop_icm_address_tx); 751d918647SAlex Vesker caps->uplink_icm_address_rx = 761d918647SAlex Vesker MLX5_CAP64_ESW_FLOWTABLE(mdev, 771d918647SAlex Vesker sw_steering_uplink_icm_address_rx); 781d918647SAlex Vesker caps->uplink_icm_address_tx = 791d918647SAlex Vesker MLX5_CAP64_ESW_FLOWTABLE(mdev, 801d918647SAlex Vesker sw_steering_uplink_icm_address_tx); 8164f45c0fSYevgeny Kliteynik caps->sw_owner_v2 = MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, sw_owner_v2); 8264f45c0fSYevgeny Kliteynik if (!caps->sw_owner_v2) 8364f45c0fSYevgeny Kliteynik caps->sw_owner = MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, sw_owner); 841d918647SAlex Vesker 851d918647SAlex Vesker return 0; 861d918647SAlex Vesker } 871d918647SAlex Vesker 887304d603SYevgeny Kliteynik static int dr_cmd_query_nic_vport_roce_en(struct mlx5_core_dev *mdev, 897304d603SYevgeny Kliteynik u16 vport, bool *roce_en) 907304d603SYevgeny Kliteynik { 917304d603SYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(query_nic_vport_context_out)] = {}; 927304d603SYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {}; 937304d603SYevgeny Kliteynik int err; 947304d603SYevgeny Kliteynik 957304d603SYevgeny Kliteynik MLX5_SET(query_nic_vport_context_in, in, opcode, 967304d603SYevgeny Kliteynik MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT); 977304d603SYevgeny Kliteynik MLX5_SET(query_nic_vport_context_in, in, vport_number, vport); 987304d603SYevgeny Kliteynik MLX5_SET(query_nic_vport_context_in, in, other_vport, !!vport); 997304d603SYevgeny Kliteynik 1007304d603SYevgeny Kliteynik err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 1017304d603SYevgeny Kliteynik if (err) 1027304d603SYevgeny Kliteynik return err; 1037304d603SYevgeny Kliteynik 1047304d603SYevgeny Kliteynik *roce_en = MLX5_GET(query_nic_vport_context_out, out, 1057304d603SYevgeny Kliteynik nic_vport_context.roce_en); 1067304d603SYevgeny Kliteynik return 0; 1077304d603SYevgeny Kliteynik } 1087304d603SYevgeny Kliteynik 1091d918647SAlex Vesker int mlx5dr_cmd_query_device(struct mlx5_core_dev *mdev, 1101d918647SAlex Vesker struct mlx5dr_cmd_caps *caps) 1111d918647SAlex Vesker { 1127304d603SYevgeny Kliteynik bool roce_en; 1137304d603SYevgeny Kliteynik int err; 1147304d603SYevgeny Kliteynik 1151d918647SAlex Vesker caps->prio_tag_required = MLX5_CAP_GEN(mdev, prio_tag_required); 1161d918647SAlex Vesker caps->eswitch_manager = MLX5_CAP_GEN(mdev, eswitch_manager); 1171d918647SAlex Vesker caps->gvmi = MLX5_CAP_GEN(mdev, vhca_id); 1181d918647SAlex Vesker caps->flex_protocols = MLX5_CAP_GEN(mdev, flex_parser_protocols); 119d421e466SYevgeny Kliteynik caps->sw_format_ver = MLX5_CAP_GEN(mdev, steering_format_version); 120*c7dd225bSYevgeny Kliteynik caps->roce_caps.fl_rc_qp_when_roce_disabled = 121*c7dd225bSYevgeny Kliteynik MLX5_CAP_GEN(mdev, fl_rc_qp_when_roce_disabled); 1221d918647SAlex Vesker 1237304d603SYevgeny Kliteynik if (MLX5_CAP_GEN(mdev, roce)) { 1247304d603SYevgeny Kliteynik err = dr_cmd_query_nic_vport_roce_en(mdev, 0, &roce_en); 1257304d603SYevgeny Kliteynik if (err) 1267304d603SYevgeny Kliteynik return err; 1277304d603SYevgeny Kliteynik 1287304d603SYevgeny Kliteynik caps->roce_caps.roce_en = roce_en; 129*c7dd225bSYevgeny Kliteynik caps->roce_caps.fl_rc_qp_when_roce_disabled |= 1307304d603SYevgeny Kliteynik MLX5_CAP_ROCE(mdev, fl_rc_qp_when_roce_disabled); 1317304d603SYevgeny Kliteynik caps->roce_caps.fl_rc_qp_when_roce_enabled = 1327304d603SYevgeny Kliteynik MLX5_CAP_ROCE(mdev, fl_rc_qp_when_roce_enabled); 1337304d603SYevgeny Kliteynik } 1347304d603SYevgeny Kliteynik 135aeacb52aSYevgeny Kliteynik caps->isolate_vl_tc = MLX5_CAP_GEN(mdev, isolate_vl_tc_new); 136aeacb52aSYevgeny Kliteynik 137b7ba743aSYevgeny Kliteynik caps->support_modify_argument = 138b7ba743aSYevgeny Kliteynik MLX5_CAP_GEN_64(mdev, general_obj_types) & 139b7ba743aSYevgeny Kliteynik MLX5_GENERAL_OBJ_TYPES_CAP_HEADER_MODIFY_ARGUMENT; 140b7ba743aSYevgeny Kliteynik 141b7ba743aSYevgeny Kliteynik if (caps->support_modify_argument) { 142b7ba743aSYevgeny Kliteynik caps->log_header_modify_argument_granularity = 143b7ba743aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, log_header_modify_argument_granularity); 144b7ba743aSYevgeny Kliteynik caps->log_header_modify_argument_max_alloc = 145b7ba743aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, log_header_modify_argument_max_alloc); 146b7ba743aSYevgeny Kliteynik } 147b7ba743aSYevgeny Kliteynik 148f59464e2SYevgeny Kliteynik /* geneve_tlv_option_0_exist is the indication of 149f59464e2SYevgeny Kliteynik * STE support for lookup type flex_parser_ok 150f59464e2SYevgeny Kliteynik */ 151f59464e2SYevgeny Kliteynik caps->flex_parser_ok_bits_supp = 152f59464e2SYevgeny Kliteynik MLX5_CAP_FLOWTABLE(mdev, 153f59464e2SYevgeny Kliteynik flow_table_properties_nic_receive.ft_field_support.geneve_tlv_option_0_exist); 154f59464e2SYevgeny Kliteynik 1558a8a1023SYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V4_ENABLED) { 1561d918647SAlex Vesker caps->flex_parser_id_icmp_dw0 = MLX5_CAP_GEN(mdev, flex_parser_id_icmp_dw0); 1571d918647SAlex Vesker caps->flex_parser_id_icmp_dw1 = MLX5_CAP_GEN(mdev, flex_parser_id_icmp_dw1); 1581d918647SAlex Vesker } 1591d918647SAlex Vesker 1608a8a1023SYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V6_ENABLED) { 1611d918647SAlex Vesker caps->flex_parser_id_icmpv6_dw0 = 1621d918647SAlex Vesker MLX5_CAP_GEN(mdev, flex_parser_id_icmpv6_dw0); 1631d918647SAlex Vesker caps->flex_parser_id_icmpv6_dw1 = 1641d918647SAlex Vesker MLX5_CAP_GEN(mdev, flex_parser_id_icmpv6_dw1); 1651d918647SAlex Vesker } 1661d918647SAlex Vesker 1673442e033SYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_GENEVE_TLV_OPTION_0_ENABLED) 1683442e033SYevgeny Kliteynik caps->flex_parser_id_geneve_tlv_option_0 = 1693442e033SYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_geneve_tlv_option_0); 1703442e033SYevgeny Kliteynik 17135ba005dSYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_MPLS_OVER_GRE_ENABLED) 17235ba005dSYevgeny Kliteynik caps->flex_parser_id_mpls_over_gre = 17335ba005dSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_outer_first_mpls_over_gre); 17435ba005dSYevgeny Kliteynik 175c3fb0e28SYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_MPLS_OVER_UDP_ENABLED) 17635ba005dSYevgeny Kliteynik caps->flex_parser_id_mpls_over_udp = 17735ba005dSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_outer_first_mpls_over_udp_label); 17835ba005dSYevgeny Kliteynik 179df9dd15aSYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_DW_0_ENABLED) 180df9dd15aSYevgeny Kliteynik caps->flex_parser_id_gtpu_dw_0 = 181df9dd15aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_gtpu_dw_0); 182df9dd15aSYevgeny Kliteynik 183df9dd15aSYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_TEID_ENABLED) 184df9dd15aSYevgeny Kliteynik caps->flex_parser_id_gtpu_teid = 185df9dd15aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_gtpu_teid); 186df9dd15aSYevgeny Kliteynik 187df9dd15aSYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_DW_2_ENABLED) 188df9dd15aSYevgeny Kliteynik caps->flex_parser_id_gtpu_dw_2 = 189df9dd15aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_gtpu_dw_2); 190df9dd15aSYevgeny Kliteynik 191df9dd15aSYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_FIRST_EXT_DW_0_ENABLED) 192df9dd15aSYevgeny Kliteynik caps->flex_parser_id_gtpu_first_ext_dw_0 = 193df9dd15aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_gtpu_first_ext_dw_0); 194df9dd15aSYevgeny Kliteynik 1951d918647SAlex Vesker caps->nic_rx_drop_address = 1961d918647SAlex Vesker MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_rx_action_drop_icm_address); 1971d918647SAlex Vesker caps->nic_tx_drop_address = 1981d918647SAlex Vesker MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_tx_action_drop_icm_address); 1991d918647SAlex Vesker caps->nic_tx_allow_address = 2001d918647SAlex Vesker MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_tx_action_allow_icm_address); 2011d918647SAlex Vesker 20264f45c0fSYevgeny Kliteynik caps->rx_sw_owner_v2 = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner_v2); 20364f45c0fSYevgeny Kliteynik caps->tx_sw_owner_v2 = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner_v2); 2041d918647SAlex Vesker 20564f45c0fSYevgeny Kliteynik if (!caps->rx_sw_owner_v2) 20664f45c0fSYevgeny Kliteynik caps->rx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner); 20764f45c0fSYevgeny Kliteynik if (!caps->tx_sw_owner_v2) 2081d918647SAlex Vesker caps->tx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner); 2091d918647SAlex Vesker 21064f45c0fSYevgeny Kliteynik caps->max_ft_level = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_ft_level); 21164f45c0fSYevgeny Kliteynik 2121d918647SAlex Vesker caps->log_icm_size = MLX5_CAP_DEV_MEM(mdev, log_steering_sw_icm_size); 2131d918647SAlex Vesker caps->hdr_modify_icm_addr = 2141d918647SAlex Vesker MLX5_CAP64_DEV_MEM(mdev, header_modify_sw_icm_start_address); 2151d918647SAlex Vesker 216108ff821SYevgeny Kliteynik caps->log_modify_pattern_icm_size = 217108ff821SYevgeny Kliteynik MLX5_CAP_DEV_MEM(mdev, log_header_modify_pattern_sw_icm_size); 218108ff821SYevgeny Kliteynik 219108ff821SYevgeny Kliteynik caps->hdr_modify_pattern_icm_addr = 220108ff821SYevgeny Kliteynik MLX5_CAP64_DEV_MEM(mdev, header_modify_pattern_sw_icm_start_address); 221108ff821SYevgeny Kliteynik 2221d918647SAlex Vesker caps->roce_min_src_udp = MLX5_CAP_ROCE(mdev, r_roce_min_src_udp_port); 2231d918647SAlex Vesker 224dd4acb2aSYevgeny Kliteynik caps->is_ecpf = mlx5_core_is_ecpf_esw_manager(mdev); 225dd4acb2aSYevgeny Kliteynik 2261d918647SAlex Vesker return 0; 2271d918647SAlex Vesker } 2281d918647SAlex Vesker 2291d918647SAlex Vesker int mlx5dr_cmd_query_flow_table(struct mlx5_core_dev *dev, 2301d918647SAlex Vesker enum fs_flow_table_type type, 2311d918647SAlex Vesker u32 table_id, 2321d918647SAlex Vesker struct mlx5dr_cmd_query_flow_table_details *output) 2331d918647SAlex Vesker { 2341d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(query_flow_table_out)] = {}; 2351d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(query_flow_table_in)] = {}; 2361d918647SAlex Vesker int err; 2371d918647SAlex Vesker 2381d918647SAlex Vesker MLX5_SET(query_flow_table_in, in, opcode, 2391d918647SAlex Vesker MLX5_CMD_OP_QUERY_FLOW_TABLE); 2401d918647SAlex Vesker 2411d918647SAlex Vesker MLX5_SET(query_flow_table_in, in, table_type, type); 2421d918647SAlex Vesker MLX5_SET(query_flow_table_in, in, table_id, table_id); 2431d918647SAlex Vesker 2447ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(dev, query_flow_table, in, out); 2451d918647SAlex Vesker if (err) 2461d918647SAlex Vesker return err; 2471d918647SAlex Vesker 2481d918647SAlex Vesker output->status = MLX5_GET(query_flow_table_out, out, status); 2491d918647SAlex Vesker output->level = MLX5_GET(query_flow_table_out, out, flow_table_context.level); 2501d918647SAlex Vesker 2511d918647SAlex Vesker output->sw_owner_icm_root_1 = MLX5_GET64(query_flow_table_out, out, 2521d918647SAlex Vesker flow_table_context.sw_owner_icm_root_1); 2531d918647SAlex Vesker output->sw_owner_icm_root_0 = MLX5_GET64(query_flow_table_out, out, 2541d918647SAlex Vesker flow_table_context.sw_owner_icm_root_0); 2551d918647SAlex Vesker 2561d918647SAlex Vesker return 0; 2571d918647SAlex Vesker } 2581d918647SAlex Vesker 2591ab6dc35SYevgeny Kliteynik int mlx5dr_cmd_query_flow_sampler(struct mlx5_core_dev *dev, 2601ab6dc35SYevgeny Kliteynik u32 sampler_id, 2611ab6dc35SYevgeny Kliteynik u64 *rx_icm_addr, 2621ab6dc35SYevgeny Kliteynik u64 *tx_icm_addr) 2631ab6dc35SYevgeny Kliteynik { 2641ab6dc35SYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(query_sampler_obj_out)] = {}; 2651ab6dc35SYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {}; 2661ab6dc35SYevgeny Kliteynik void *attr; 2671ab6dc35SYevgeny Kliteynik int ret; 2681ab6dc35SYevgeny Kliteynik 2691ab6dc35SYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, opcode, 2701ab6dc35SYevgeny Kliteynik MLX5_CMD_OP_QUERY_GENERAL_OBJECT); 2711ab6dc35SYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, 2721ab6dc35SYevgeny Kliteynik MLX5_GENERAL_OBJECT_TYPES_SAMPLER); 2731ab6dc35SYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, sampler_id); 2741ab6dc35SYevgeny Kliteynik 2751ab6dc35SYevgeny Kliteynik ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 2761ab6dc35SYevgeny Kliteynik if (ret) 2771ab6dc35SYevgeny Kliteynik return ret; 2781ab6dc35SYevgeny Kliteynik 2791ab6dc35SYevgeny Kliteynik attr = MLX5_ADDR_OF(query_sampler_obj_out, out, sampler_object); 2801ab6dc35SYevgeny Kliteynik 2811ab6dc35SYevgeny Kliteynik *rx_icm_addr = MLX5_GET64(sampler_obj, attr, 2821ab6dc35SYevgeny Kliteynik sw_steering_icm_address_rx); 2831ab6dc35SYevgeny Kliteynik *tx_icm_addr = MLX5_GET64(sampler_obj, attr, 2841ab6dc35SYevgeny Kliteynik sw_steering_icm_address_tx); 2851ab6dc35SYevgeny Kliteynik 2861ab6dc35SYevgeny Kliteynik return 0; 2871ab6dc35SYevgeny Kliteynik } 2881ab6dc35SYevgeny Kliteynik 2891d918647SAlex Vesker int mlx5dr_cmd_sync_steering(struct mlx5_core_dev *mdev) 2901d918647SAlex Vesker { 2911d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(sync_steering_in)] = {}; 2921d918647SAlex Vesker 293c4193a12SYevgeny Kliteynik /* Skip SYNC in case the device is internal error state. 294c4193a12SYevgeny Kliteynik * Besides a device error, this also happens when we're 295c4193a12SYevgeny Kliteynik * in fast teardown 296c4193a12SYevgeny Kliteynik */ 297c4193a12SYevgeny Kliteynik if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) 298c4193a12SYevgeny Kliteynik return 0; 299c4193a12SYevgeny Kliteynik 3001d918647SAlex Vesker MLX5_SET(sync_steering_in, in, opcode, MLX5_CMD_OP_SYNC_STEERING); 3011d918647SAlex Vesker 3027ba294e4SLeon Romanovsky return mlx5_cmd_exec_in(mdev, sync_steering, in); 3031d918647SAlex Vesker } 3041d918647SAlex Vesker 3051d918647SAlex Vesker int mlx5dr_cmd_set_fte_modify_and_vport(struct mlx5_core_dev *mdev, 3061d918647SAlex Vesker u32 table_type, 3071d918647SAlex Vesker u32 table_id, 3081d918647SAlex Vesker u32 group_id, 3091d918647SAlex Vesker u32 modify_header_id, 310f9f93bd5SYevgeny Kliteynik u16 vport) 3111d918647SAlex Vesker { 3121d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {}; 3131d918647SAlex Vesker void *in_flow_context; 3141d918647SAlex Vesker unsigned int inlen; 3151d918647SAlex Vesker void *in_dests; 3161d918647SAlex Vesker u32 *in; 3171d918647SAlex Vesker int err; 3181d918647SAlex Vesker 3191d918647SAlex Vesker inlen = MLX5_ST_SZ_BYTES(set_fte_in) + 3201d918647SAlex Vesker 1 * MLX5_ST_SZ_BYTES(dest_format_struct); /* One destination only */ 3211d918647SAlex Vesker 3221d918647SAlex Vesker in = kvzalloc(inlen, GFP_KERNEL); 3231d918647SAlex Vesker if (!in) 3241d918647SAlex Vesker return -ENOMEM; 3251d918647SAlex Vesker 3261d918647SAlex Vesker MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY); 3271d918647SAlex Vesker MLX5_SET(set_fte_in, in, table_type, table_type); 3281d918647SAlex Vesker MLX5_SET(set_fte_in, in, table_id, table_id); 3291d918647SAlex Vesker 3301d918647SAlex Vesker in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context); 3311d918647SAlex Vesker MLX5_SET(flow_context, in_flow_context, group_id, group_id); 3321d918647SAlex Vesker MLX5_SET(flow_context, in_flow_context, modify_header_id, modify_header_id); 3331d918647SAlex Vesker MLX5_SET(flow_context, in_flow_context, destination_list_size, 1); 3341d918647SAlex Vesker MLX5_SET(flow_context, in_flow_context, action, 3351d918647SAlex Vesker MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | 3361d918647SAlex Vesker MLX5_FLOW_CONTEXT_ACTION_MOD_HDR); 3371d918647SAlex Vesker 3381d918647SAlex Vesker in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination); 3391d918647SAlex Vesker MLX5_SET(dest_format_struct, in_dests, destination_type, 340d639af62SMark Bloch MLX5_IFC_FLOW_DESTINATION_TYPE_VPORT); 341f9f93bd5SYevgeny Kliteynik MLX5_SET(dest_format_struct, in_dests, destination_id, vport); 3421d918647SAlex Vesker 3431d918647SAlex Vesker err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); 3441d918647SAlex Vesker kvfree(in); 3451d918647SAlex Vesker 3461d918647SAlex Vesker return err; 3471d918647SAlex Vesker } 3481d918647SAlex Vesker 3491d918647SAlex Vesker int mlx5dr_cmd_del_flow_table_entry(struct mlx5_core_dev *mdev, 3501d918647SAlex Vesker u32 table_type, 3511d918647SAlex Vesker u32 table_id) 3521d918647SAlex Vesker { 3531d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(delete_fte_in)] = {}; 3541d918647SAlex Vesker 3551d918647SAlex Vesker MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY); 3561d918647SAlex Vesker MLX5_SET(delete_fte_in, in, table_type, table_type); 3571d918647SAlex Vesker MLX5_SET(delete_fte_in, in, table_id, table_id); 3581d918647SAlex Vesker 3597ba294e4SLeon Romanovsky return mlx5_cmd_exec_in(mdev, delete_fte, in); 3601d918647SAlex Vesker } 3611d918647SAlex Vesker 3621d918647SAlex Vesker int mlx5dr_cmd_alloc_modify_header(struct mlx5_core_dev *mdev, 3631d918647SAlex Vesker u32 table_type, 3641d918647SAlex Vesker u8 num_of_actions, 3651d918647SAlex Vesker u64 *actions, 3661d918647SAlex Vesker u32 *modify_header_id) 3671d918647SAlex Vesker { 3681d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(alloc_modify_header_context_out)] = {}; 3691d918647SAlex Vesker void *p_actions; 3701d918647SAlex Vesker u32 inlen; 3711d918647SAlex Vesker u32 *in; 3721d918647SAlex Vesker int err; 3731d918647SAlex Vesker 3741d918647SAlex Vesker inlen = MLX5_ST_SZ_BYTES(alloc_modify_header_context_in) + 3751d918647SAlex Vesker num_of_actions * sizeof(u64); 3761d918647SAlex Vesker in = kvzalloc(inlen, GFP_KERNEL); 3771d918647SAlex Vesker if (!in) 3781d918647SAlex Vesker return -ENOMEM; 3791d918647SAlex Vesker 3801d918647SAlex Vesker MLX5_SET(alloc_modify_header_context_in, in, opcode, 3811d918647SAlex Vesker MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT); 3821d918647SAlex Vesker MLX5_SET(alloc_modify_header_context_in, in, table_type, table_type); 3831d918647SAlex Vesker MLX5_SET(alloc_modify_header_context_in, in, num_of_actions, num_of_actions); 3841d918647SAlex Vesker p_actions = MLX5_ADDR_OF(alloc_modify_header_context_in, in, actions); 3851d918647SAlex Vesker memcpy(p_actions, actions, num_of_actions * sizeof(u64)); 3861d918647SAlex Vesker 3871d918647SAlex Vesker err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); 3881d918647SAlex Vesker if (err) 3891d918647SAlex Vesker goto out; 3901d918647SAlex Vesker 3911d918647SAlex Vesker *modify_header_id = MLX5_GET(alloc_modify_header_context_out, out, 3921d918647SAlex Vesker modify_header_id); 3931d918647SAlex Vesker out: 3941d918647SAlex Vesker kvfree(in); 3951d918647SAlex Vesker return err; 3961d918647SAlex Vesker } 3971d918647SAlex Vesker 3981d918647SAlex Vesker int mlx5dr_cmd_dealloc_modify_header(struct mlx5_core_dev *mdev, 3991d918647SAlex Vesker u32 modify_header_id) 4001d918647SAlex Vesker { 4011d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(dealloc_modify_header_context_in)] = {}; 4021d918647SAlex Vesker 4031d918647SAlex Vesker MLX5_SET(dealloc_modify_header_context_in, in, opcode, 4041d918647SAlex Vesker MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT); 4051d918647SAlex Vesker MLX5_SET(dealloc_modify_header_context_in, in, modify_header_id, 4061d918647SAlex Vesker modify_header_id); 4071d918647SAlex Vesker 4087ba294e4SLeon Romanovsky return mlx5_cmd_exec_in(mdev, dealloc_modify_header_context, in); 4091d918647SAlex Vesker } 4101d918647SAlex Vesker 4111d918647SAlex Vesker int mlx5dr_cmd_create_empty_flow_group(struct mlx5_core_dev *mdev, 4121d918647SAlex Vesker u32 table_type, 4131d918647SAlex Vesker u32 table_id, 4141d918647SAlex Vesker u32 *group_id) 4151d918647SAlex Vesker { 4161d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(create_flow_group_out)] = {}; 4171d918647SAlex Vesker int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 4181d918647SAlex Vesker u32 *in; 4191d918647SAlex Vesker int err; 4201d918647SAlex Vesker 421b7f86258SRoi Dayan in = kvzalloc(inlen, GFP_KERNEL); 4221d918647SAlex Vesker if (!in) 4231d918647SAlex Vesker return -ENOMEM; 4241d918647SAlex Vesker 4251d918647SAlex Vesker MLX5_SET(create_flow_group_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_GROUP); 4261d918647SAlex Vesker MLX5_SET(create_flow_group_in, in, table_type, table_type); 4271d918647SAlex Vesker MLX5_SET(create_flow_group_in, in, table_id, table_id); 4281d918647SAlex Vesker 4297ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(mdev, create_flow_group, in, out); 4301d918647SAlex Vesker if (err) 4311d918647SAlex Vesker goto out; 4321d918647SAlex Vesker 4331d918647SAlex Vesker *group_id = MLX5_GET(create_flow_group_out, out, group_id); 4341d918647SAlex Vesker 4351d918647SAlex Vesker out: 436b7f86258SRoi Dayan kvfree(in); 4371d918647SAlex Vesker return err; 4381d918647SAlex Vesker } 4391d918647SAlex Vesker 4401d918647SAlex Vesker int mlx5dr_cmd_destroy_flow_group(struct mlx5_core_dev *mdev, 4411d918647SAlex Vesker u32 table_type, 4421d918647SAlex Vesker u32 table_id, 4431d918647SAlex Vesker u32 group_id) 4441d918647SAlex Vesker { 4451d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)] = {}; 4461d918647SAlex Vesker 4477ba294e4SLeon Romanovsky MLX5_SET(destroy_flow_group_in, in, opcode, 4487ba294e4SLeon Romanovsky MLX5_CMD_OP_DESTROY_FLOW_GROUP); 4491d918647SAlex Vesker MLX5_SET(destroy_flow_group_in, in, table_type, table_type); 4501d918647SAlex Vesker MLX5_SET(destroy_flow_group_in, in, table_id, table_id); 4511d918647SAlex Vesker MLX5_SET(destroy_flow_group_in, in, group_id, group_id); 4521d918647SAlex Vesker 4537ba294e4SLeon Romanovsky return mlx5_cmd_exec_in(mdev, destroy_flow_group, in); 4541d918647SAlex Vesker } 4551d918647SAlex Vesker 4561d918647SAlex Vesker int mlx5dr_cmd_create_flow_table(struct mlx5_core_dev *mdev, 457cc78dbd7SAlex Vesker struct mlx5dr_cmd_create_flow_table_attr *attr, 4581d918647SAlex Vesker u64 *fdb_rx_icm_addr, 4591d918647SAlex Vesker u32 *table_id) 4601d918647SAlex Vesker { 4611d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {}; 4621d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(create_flow_table_in)] = {}; 4631d918647SAlex Vesker void *ft_mdev; 4641d918647SAlex Vesker int err; 4651d918647SAlex Vesker 4661d918647SAlex Vesker MLX5_SET(create_flow_table_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_TABLE); 467cc78dbd7SAlex Vesker MLX5_SET(create_flow_table_in, in, table_type, attr->table_type); 468b0bb369eSMark Bloch MLX5_SET(create_flow_table_in, in, uid, attr->uid); 4691d918647SAlex Vesker 4701d918647SAlex Vesker ft_mdev = MLX5_ADDR_OF(create_flow_table_in, in, flow_table_context); 471cc78dbd7SAlex Vesker MLX5_SET(flow_table_context, ft_mdev, termination_table, attr->term_tbl); 472cc78dbd7SAlex Vesker MLX5_SET(flow_table_context, ft_mdev, sw_owner, attr->sw_owner); 473cc78dbd7SAlex Vesker MLX5_SET(flow_table_context, ft_mdev, level, attr->level); 4741d918647SAlex Vesker 475cc78dbd7SAlex Vesker if (attr->sw_owner) { 4761d918647SAlex Vesker /* icm_addr_0 used for FDB RX / NIC TX / NIC_RX 4771d918647SAlex Vesker * icm_addr_1 used for FDB TX 4781d918647SAlex Vesker */ 479cc78dbd7SAlex Vesker if (attr->table_type == MLX5_FLOW_TABLE_TYPE_NIC_RX) { 4801d918647SAlex Vesker MLX5_SET64(flow_table_context, ft_mdev, 481cc78dbd7SAlex Vesker sw_owner_icm_root_0, attr->icm_addr_rx); 482cc78dbd7SAlex Vesker } else if (attr->table_type == MLX5_FLOW_TABLE_TYPE_NIC_TX) { 4831d918647SAlex Vesker MLX5_SET64(flow_table_context, ft_mdev, 484cc78dbd7SAlex Vesker sw_owner_icm_root_0, attr->icm_addr_tx); 485cc78dbd7SAlex Vesker } else if (attr->table_type == MLX5_FLOW_TABLE_TYPE_FDB) { 4861d918647SAlex Vesker MLX5_SET64(flow_table_context, ft_mdev, 487cc78dbd7SAlex Vesker sw_owner_icm_root_0, attr->icm_addr_rx); 4881d918647SAlex Vesker MLX5_SET64(flow_table_context, ft_mdev, 489cc78dbd7SAlex Vesker sw_owner_icm_root_1, attr->icm_addr_tx); 4901d918647SAlex Vesker } 4911d918647SAlex Vesker } 4921d918647SAlex Vesker 493cc78dbd7SAlex Vesker MLX5_SET(create_flow_table_in, in, flow_table_context.decap_en, 494cc78dbd7SAlex Vesker attr->decap_en); 495cc78dbd7SAlex Vesker MLX5_SET(create_flow_table_in, in, flow_table_context.reformat_en, 496cc78dbd7SAlex Vesker attr->reformat_en); 497cc78dbd7SAlex Vesker 4987ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(mdev, create_flow_table, in, out); 4991d918647SAlex Vesker if (err) 5001d918647SAlex Vesker return err; 5011d918647SAlex Vesker 5021d918647SAlex Vesker *table_id = MLX5_GET(create_flow_table_out, out, table_id); 503cc78dbd7SAlex Vesker if (!attr->sw_owner && attr->table_type == MLX5_FLOW_TABLE_TYPE_FDB && 504cc78dbd7SAlex Vesker fdb_rx_icm_addr) 5051d918647SAlex Vesker *fdb_rx_icm_addr = 5061d918647SAlex Vesker (u64)MLX5_GET(create_flow_table_out, out, icm_address_31_0) | 5071d918647SAlex Vesker (u64)MLX5_GET(create_flow_table_out, out, icm_address_39_32) << 32 | 5081d918647SAlex Vesker (u64)MLX5_GET(create_flow_table_out, out, icm_address_63_40) << 40; 5091d918647SAlex Vesker 5101d918647SAlex Vesker return 0; 5111d918647SAlex Vesker } 5121d918647SAlex Vesker 5131d918647SAlex Vesker int mlx5dr_cmd_destroy_flow_table(struct mlx5_core_dev *mdev, 5141d918647SAlex Vesker u32 table_id, 5151d918647SAlex Vesker u32 table_type) 5161d918647SAlex Vesker { 5171d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)] = {}; 5181d918647SAlex Vesker 5191d918647SAlex Vesker MLX5_SET(destroy_flow_table_in, in, opcode, 5201d918647SAlex Vesker MLX5_CMD_OP_DESTROY_FLOW_TABLE); 5211d918647SAlex Vesker MLX5_SET(destroy_flow_table_in, in, table_type, table_type); 5221d918647SAlex Vesker MLX5_SET(destroy_flow_table_in, in, table_id, table_id); 5231d918647SAlex Vesker 5247ba294e4SLeon Romanovsky return mlx5_cmd_exec_in(mdev, destroy_flow_table, in); 5251d918647SAlex Vesker } 5261d918647SAlex Vesker 5271d918647SAlex Vesker int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev, 5281d918647SAlex Vesker enum mlx5_reformat_ctx_type rt, 5297ea9b398SYevgeny Kliteynik u8 reformat_param_0, 5307ea9b398SYevgeny Kliteynik u8 reformat_param_1, 5311d918647SAlex Vesker size_t reformat_size, 5321d918647SAlex Vesker void *reformat_data, 5331d918647SAlex Vesker u32 *reformat_id) 5341d918647SAlex Vesker { 5351d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(alloc_packet_reformat_context_out)] = {}; 5361d918647SAlex Vesker size_t inlen, cmd_data_sz, cmd_total_sz; 5371d918647SAlex Vesker void *prctx; 5381d918647SAlex Vesker void *pdata; 5391d918647SAlex Vesker void *in; 5401d918647SAlex Vesker int err; 5411d918647SAlex Vesker 5421d918647SAlex Vesker cmd_total_sz = MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in); 5431d918647SAlex Vesker cmd_data_sz = MLX5_FLD_SZ_BYTES(alloc_packet_reformat_context_in, 5441d918647SAlex Vesker packet_reformat_context.reformat_data); 5451d918647SAlex Vesker inlen = ALIGN(cmd_total_sz + reformat_size - cmd_data_sz, 4); 5461d918647SAlex Vesker in = kvzalloc(inlen, GFP_KERNEL); 5471d918647SAlex Vesker if (!in) 5481d918647SAlex Vesker return -ENOMEM; 5491d918647SAlex Vesker 5501d918647SAlex Vesker MLX5_SET(alloc_packet_reformat_context_in, in, opcode, 5511d918647SAlex Vesker MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT); 5521d918647SAlex Vesker 5531d918647SAlex Vesker prctx = MLX5_ADDR_OF(alloc_packet_reformat_context_in, in, packet_reformat_context); 5541d918647SAlex Vesker pdata = MLX5_ADDR_OF(packet_reformat_context_in, prctx, reformat_data); 5551d918647SAlex Vesker 5561d918647SAlex Vesker MLX5_SET(packet_reformat_context_in, prctx, reformat_type, rt); 5577ea9b398SYevgeny Kliteynik MLX5_SET(packet_reformat_context_in, prctx, reformat_param_0, reformat_param_0); 5587ea9b398SYevgeny Kliteynik MLX5_SET(packet_reformat_context_in, prctx, reformat_param_1, reformat_param_1); 5591d918647SAlex Vesker MLX5_SET(packet_reformat_context_in, prctx, reformat_data_size, reformat_size); 5607ea9b398SYevgeny Kliteynik if (reformat_data && reformat_size) 5611d918647SAlex Vesker memcpy(pdata, reformat_data, reformat_size); 5621d918647SAlex Vesker 5631d918647SAlex Vesker err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); 5641d918647SAlex Vesker if (err) 5651d918647SAlex Vesker return err; 5661d918647SAlex Vesker 5671d918647SAlex Vesker *reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id); 5681d918647SAlex Vesker kvfree(in); 5691d918647SAlex Vesker 5701d918647SAlex Vesker return err; 5711d918647SAlex Vesker } 5721d918647SAlex Vesker 5731d918647SAlex Vesker void mlx5dr_cmd_destroy_reformat_ctx(struct mlx5_core_dev *mdev, 5741d918647SAlex Vesker u32 reformat_id) 5751d918647SAlex Vesker { 5761d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_in)] = {}; 5771d918647SAlex Vesker 5781d918647SAlex Vesker MLX5_SET(dealloc_packet_reformat_context_in, in, opcode, 5791d918647SAlex Vesker MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT); 5801d918647SAlex Vesker MLX5_SET(dealloc_packet_reformat_context_in, in, packet_reformat_id, 5811d918647SAlex Vesker reformat_id); 5821d918647SAlex Vesker 5837ba294e4SLeon Romanovsky mlx5_cmd_exec_in(mdev, dealloc_packet_reformat_context, in); 5841d918647SAlex Vesker } 5851d918647SAlex Vesker 586e046b86eSYevgeny Kliteynik static void dr_cmd_set_definer_format(void *ptr, u16 format_id, 587e046b86eSYevgeny Kliteynik u8 *dw_selectors, 588e046b86eSYevgeny Kliteynik u8 *byte_selectors) 589e046b86eSYevgeny Kliteynik { 590e046b86eSYevgeny Kliteynik if (format_id != MLX5_IFC_DEFINER_FORMAT_ID_SELECT) 591e046b86eSYevgeny Kliteynik return; 592e046b86eSYevgeny Kliteynik 593e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw0, dw_selectors[0]); 594e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw1, dw_selectors[1]); 595e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw2, dw_selectors[2]); 596e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw3, dw_selectors[3]); 597e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw4, dw_selectors[4]); 598e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw5, dw_selectors[5]); 599e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw6, dw_selectors[6]); 600e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw7, dw_selectors[7]); 601e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw8, dw_selectors[8]); 602e046b86eSYevgeny Kliteynik 603e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte0, byte_selectors[0]); 604e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte1, byte_selectors[1]); 605e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte2, byte_selectors[2]); 606e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte3, byte_selectors[3]); 607e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte4, byte_selectors[4]); 608e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte5, byte_selectors[5]); 609e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte6, byte_selectors[6]); 610e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte7, byte_selectors[7]); 611e046b86eSYevgeny Kliteynik } 612e046b86eSYevgeny Kliteynik 613e046b86eSYevgeny Kliteynik int mlx5dr_cmd_create_definer(struct mlx5_core_dev *mdev, 614e046b86eSYevgeny Kliteynik u16 format_id, 615e046b86eSYevgeny Kliteynik u8 *dw_selectors, 616e046b86eSYevgeny Kliteynik u8 *byte_selectors, 617e046b86eSYevgeny Kliteynik u8 *match_mask, 618e046b86eSYevgeny Kliteynik u32 *definer_id) 619e046b86eSYevgeny Kliteynik { 620e046b86eSYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {}; 621e046b86eSYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(create_match_definer_in)] = {}; 622e046b86eSYevgeny Kliteynik void *ptr; 623e046b86eSYevgeny Kliteynik int err; 624e046b86eSYevgeny Kliteynik 625e046b86eSYevgeny Kliteynik ptr = MLX5_ADDR_OF(create_match_definer_in, in, 626e046b86eSYevgeny Kliteynik general_obj_in_cmd_hdr); 627e046b86eSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode, 628e046b86eSYevgeny Kliteynik MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 629e046b86eSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type, 630e046b86eSYevgeny Kliteynik MLX5_OBJ_TYPE_MATCH_DEFINER); 631e046b86eSYevgeny Kliteynik 632e046b86eSYevgeny Kliteynik ptr = MLX5_ADDR_OF(create_match_definer_in, in, obj_context); 633e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_id, format_id); 634e046b86eSYevgeny Kliteynik 635e046b86eSYevgeny Kliteynik dr_cmd_set_definer_format(ptr, format_id, 636e046b86eSYevgeny Kliteynik dw_selectors, byte_selectors); 637e046b86eSYevgeny Kliteynik 638e046b86eSYevgeny Kliteynik ptr = MLX5_ADDR_OF(match_definer, ptr, match_mask); 639e046b86eSYevgeny Kliteynik memcpy(ptr, match_mask, MLX5_FLD_SZ_BYTES(match_definer, match_mask)); 640e046b86eSYevgeny Kliteynik 641e046b86eSYevgeny Kliteynik err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 642e046b86eSYevgeny Kliteynik if (err) 643e046b86eSYevgeny Kliteynik return err; 644e046b86eSYevgeny Kliteynik 645e046b86eSYevgeny Kliteynik *definer_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 646e046b86eSYevgeny Kliteynik 647e046b86eSYevgeny Kliteynik return 0; 648e046b86eSYevgeny Kliteynik } 649e046b86eSYevgeny Kliteynik 650e046b86eSYevgeny Kliteynik void 651e046b86eSYevgeny Kliteynik mlx5dr_cmd_destroy_definer(struct mlx5_core_dev *mdev, u32 definer_id) 652e046b86eSYevgeny Kliteynik { 653e046b86eSYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {}; 654e046b86eSYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 655e046b86eSYevgeny Kliteynik 656e046b86eSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT); 657e046b86eSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, MLX5_OBJ_TYPE_MATCH_DEFINER); 658e046b86eSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, definer_id); 659e046b86eSYevgeny Kliteynik 660e046b86eSYevgeny Kliteynik mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 661e046b86eSYevgeny Kliteynik } 662e046b86eSYevgeny Kliteynik 6631d918647SAlex Vesker int mlx5dr_cmd_query_gid(struct mlx5_core_dev *mdev, u8 vhca_port_num, 6641d918647SAlex Vesker u16 index, struct mlx5dr_cmd_gid_attr *attr) 6651d918647SAlex Vesker { 6661d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(query_roce_address_out)] = {}; 6671d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(query_roce_address_in)] = {}; 6681d918647SAlex Vesker int err; 6691d918647SAlex Vesker 6701d918647SAlex Vesker MLX5_SET(query_roce_address_in, in, opcode, 6711d918647SAlex Vesker MLX5_CMD_OP_QUERY_ROCE_ADDRESS); 6721d918647SAlex Vesker 6731d918647SAlex Vesker MLX5_SET(query_roce_address_in, in, roce_address_index, index); 6741d918647SAlex Vesker MLX5_SET(query_roce_address_in, in, vhca_port_num, vhca_port_num); 6751d918647SAlex Vesker 6767ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(mdev, query_roce_address, in, out); 6771d918647SAlex Vesker if (err) 6781d918647SAlex Vesker return err; 6791d918647SAlex Vesker 6801d918647SAlex Vesker memcpy(&attr->gid, 6811d918647SAlex Vesker MLX5_ADDR_OF(query_roce_address_out, 6821d918647SAlex Vesker out, roce_address.source_l3_address), 6831d918647SAlex Vesker sizeof(attr->gid)); 6841d918647SAlex Vesker memcpy(attr->mac, 6851d918647SAlex Vesker MLX5_ADDR_OF(query_roce_address_out, out, 6861d918647SAlex Vesker roce_address.source_mac_47_32), 6871d918647SAlex Vesker sizeof(attr->mac)); 6881d918647SAlex Vesker 6891d918647SAlex Vesker if (MLX5_GET(query_roce_address_out, out, 6901d918647SAlex Vesker roce_address.roce_version) == MLX5_ROCE_VERSION_2) 6911d918647SAlex Vesker attr->roce_ver = MLX5_ROCE_VERSION_2; 6921d918647SAlex Vesker else 6931d918647SAlex Vesker attr->roce_ver = MLX5_ROCE_VERSION_1; 6941d918647SAlex Vesker 6951d918647SAlex Vesker return 0; 6961d918647SAlex Vesker } 6976de03d2dSErez Shitrit 698de69696bSYevgeny Kliteynik int mlx5dr_cmd_create_modify_header_arg(struct mlx5_core_dev *dev, 699de69696bSYevgeny Kliteynik u16 log_obj_range, u32 pd, 700de69696bSYevgeny Kliteynik u32 *obj_id) 701de69696bSYevgeny Kliteynik { 702de69696bSYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(create_modify_header_arg_in)] = {}; 703de69696bSYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {}; 704de69696bSYevgeny Kliteynik void *attr; 705de69696bSYevgeny Kliteynik int ret; 706de69696bSYevgeny Kliteynik 707de69696bSYevgeny Kliteynik attr = MLX5_ADDR_OF(create_modify_header_arg_in, in, hdr); 708de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, attr, opcode, 709de69696bSYevgeny Kliteynik MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 710de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, attr, obj_type, 711de69696bSYevgeny Kliteynik MLX5_OBJ_TYPE_HEADER_MODIFY_ARGUMENT); 712de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, attr, 713de69696bSYevgeny Kliteynik op_param.create.log_obj_range, log_obj_range); 714de69696bSYevgeny Kliteynik 715de69696bSYevgeny Kliteynik attr = MLX5_ADDR_OF(create_modify_header_arg_in, in, arg); 716de69696bSYevgeny Kliteynik MLX5_SET(modify_header_arg, attr, access_pd, pd); 717de69696bSYevgeny Kliteynik 718de69696bSYevgeny Kliteynik ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 719de69696bSYevgeny Kliteynik if (ret) 720de69696bSYevgeny Kliteynik return ret; 721de69696bSYevgeny Kliteynik 722de69696bSYevgeny Kliteynik *obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 723de69696bSYevgeny Kliteynik return 0; 724de69696bSYevgeny Kliteynik } 725de69696bSYevgeny Kliteynik 726de69696bSYevgeny Kliteynik void mlx5dr_cmd_destroy_modify_header_arg(struct mlx5_core_dev *dev, 727de69696bSYevgeny Kliteynik u32 obj_id) 728de69696bSYevgeny Kliteynik { 729de69696bSYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {}; 730de69696bSYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {}; 731de69696bSYevgeny Kliteynik 732de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, opcode, 733de69696bSYevgeny Kliteynik MLX5_CMD_OP_DESTROY_GENERAL_OBJECT); 734de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, 735de69696bSYevgeny Kliteynik MLX5_OBJ_TYPE_HEADER_MODIFY_ARGUMENT); 736de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, obj_id); 737de69696bSYevgeny Kliteynik 738de69696bSYevgeny Kliteynik mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 739de69696bSYevgeny Kliteynik } 740de69696bSYevgeny Kliteynik 7416de03d2dSErez Shitrit static int mlx5dr_cmd_set_extended_dest(struct mlx5_core_dev *dev, 7426de03d2dSErez Shitrit struct mlx5dr_cmd_fte_info *fte, 7436de03d2dSErez Shitrit bool *extended_dest) 7446de03d2dSErez Shitrit { 7456de03d2dSErez Shitrit int fw_log_max_fdb_encap_uplink = MLX5_CAP_ESW(dev, log_max_fdb_encap_uplink); 7466de03d2dSErez Shitrit int num_fwd_destinations = 0; 7476de03d2dSErez Shitrit int num_encap = 0; 7486de03d2dSErez Shitrit int i; 7496de03d2dSErez Shitrit 7506de03d2dSErez Shitrit *extended_dest = false; 7516de03d2dSErez Shitrit if (!(fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST)) 7526de03d2dSErez Shitrit return 0; 7536de03d2dSErez Shitrit for (i = 0; i < fte->dests_size; i++) { 7546510bc0dSMark Bloch if (fte->dest_arr[i].type == MLX5_FLOW_DESTINATION_TYPE_COUNTER || 7556510bc0dSMark Bloch fte->dest_arr[i].type == MLX5_FLOW_DESTINATION_TYPE_NONE) 7566de03d2dSErez Shitrit continue; 757e3a0f40bSYevgeny Kliteynik if ((fte->dest_arr[i].type == MLX5_FLOW_DESTINATION_TYPE_VPORT || 758e3a0f40bSYevgeny Kliteynik fte->dest_arr[i].type == MLX5_FLOW_DESTINATION_TYPE_UPLINK) && 7596de03d2dSErez Shitrit fte->dest_arr[i].vport.flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID) 7606de03d2dSErez Shitrit num_encap++; 7616de03d2dSErez Shitrit num_fwd_destinations++; 7626de03d2dSErez Shitrit } 7636de03d2dSErez Shitrit 7646de03d2dSErez Shitrit if (num_fwd_destinations > 1 && num_encap > 0) 7656de03d2dSErez Shitrit *extended_dest = true; 7666de03d2dSErez Shitrit 7676de03d2dSErez Shitrit if (*extended_dest && !fw_log_max_fdb_encap_uplink) { 7686de03d2dSErez Shitrit mlx5_core_warn(dev, "FW does not support extended destination"); 7696de03d2dSErez Shitrit return -EOPNOTSUPP; 7706de03d2dSErez Shitrit } 7716de03d2dSErez Shitrit if (num_encap > (1 << fw_log_max_fdb_encap_uplink)) { 7726de03d2dSErez Shitrit mlx5_core_warn(dev, "FW does not support more than %d encaps", 7736de03d2dSErez Shitrit 1 << fw_log_max_fdb_encap_uplink); 7746de03d2dSErez Shitrit return -EOPNOTSUPP; 7756de03d2dSErez Shitrit } 7766de03d2dSErez Shitrit 7776de03d2dSErez Shitrit return 0; 7786de03d2dSErez Shitrit } 7796de03d2dSErez Shitrit 7806de03d2dSErez Shitrit int mlx5dr_cmd_set_fte(struct mlx5_core_dev *dev, 7816de03d2dSErez Shitrit int opmod, int modify_mask, 7826de03d2dSErez Shitrit struct mlx5dr_cmd_ft_info *ft, 7836de03d2dSErez Shitrit u32 group_id, 7846de03d2dSErez Shitrit struct mlx5dr_cmd_fte_info *fte) 7856de03d2dSErez Shitrit { 7866de03d2dSErez Shitrit u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {}; 7876de03d2dSErez Shitrit void *in_flow_context, *vlan; 7886de03d2dSErez Shitrit bool extended_dest = false; 7896de03d2dSErez Shitrit void *in_match_value; 7906de03d2dSErez Shitrit unsigned int inlen; 7916de03d2dSErez Shitrit int dst_cnt_size; 7926de03d2dSErez Shitrit void *in_dests; 7936de03d2dSErez Shitrit u32 *in; 7946de03d2dSErez Shitrit int err; 7956de03d2dSErez Shitrit int i; 7966de03d2dSErez Shitrit 7976de03d2dSErez Shitrit if (mlx5dr_cmd_set_extended_dest(dev, fte, &extended_dest)) 7986de03d2dSErez Shitrit return -EOPNOTSUPP; 7996de03d2dSErez Shitrit 8006de03d2dSErez Shitrit if (!extended_dest) 8016de03d2dSErez Shitrit dst_cnt_size = MLX5_ST_SZ_BYTES(dest_format_struct); 8026de03d2dSErez Shitrit else 8036de03d2dSErez Shitrit dst_cnt_size = MLX5_ST_SZ_BYTES(extended_dest_format); 8046de03d2dSErez Shitrit 8056de03d2dSErez Shitrit inlen = MLX5_ST_SZ_BYTES(set_fte_in) + fte->dests_size * dst_cnt_size; 8066de03d2dSErez Shitrit in = kvzalloc(inlen, GFP_KERNEL); 8076de03d2dSErez Shitrit if (!in) 8086de03d2dSErez Shitrit return -ENOMEM; 8096de03d2dSErez Shitrit 8106de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY); 8116de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, op_mod, opmod); 8126de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, modify_enable_mask, modify_mask); 8136de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, table_type, ft->type); 8146de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, table_id, ft->id); 8156de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, flow_index, fte->index); 81663b85f49SYevgeny Kliteynik MLX5_SET(set_fte_in, in, ignore_flow_level, fte->ignore_flow_level); 8176de03d2dSErez Shitrit if (ft->vport) { 8186de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, vport_number, ft->vport); 8196de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, other_vport, 1); 8206de03d2dSErez Shitrit } 8216de03d2dSErez Shitrit 8226de03d2dSErez Shitrit in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context); 8236de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, group_id, group_id); 8246de03d2dSErez Shitrit 8256de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, flow_tag, 8266de03d2dSErez Shitrit fte->flow_context.flow_tag); 8276de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, flow_source, 8286de03d2dSErez Shitrit fte->flow_context.flow_source); 8296de03d2dSErez Shitrit 8306de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, extended_destination, 8316de03d2dSErez Shitrit extended_dest); 8326de03d2dSErez Shitrit if (extended_dest) { 8336de03d2dSErez Shitrit u32 action; 8346de03d2dSErez Shitrit 8356de03d2dSErez Shitrit action = fte->action.action & 8366de03d2dSErez Shitrit ~MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; 8376de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, action, action); 8386de03d2dSErez Shitrit } else { 8396de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, action, 8406de03d2dSErez Shitrit fte->action.action); 8416de03d2dSErez Shitrit if (fte->action.pkt_reformat) 8426de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, packet_reformat_id, 8436de03d2dSErez Shitrit fte->action.pkt_reformat->id); 8446de03d2dSErez Shitrit } 8456de03d2dSErez Shitrit if (fte->action.modify_hdr) 8466de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, modify_header_id, 8476de03d2dSErez Shitrit fte->action.modify_hdr->id); 8486de03d2dSErez Shitrit 8496de03d2dSErez Shitrit vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan); 8506de03d2dSErez Shitrit 8516de03d2dSErez Shitrit MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[0].ethtype); 8526de03d2dSErez Shitrit MLX5_SET(vlan, vlan, vid, fte->action.vlan[0].vid); 8536de03d2dSErez Shitrit MLX5_SET(vlan, vlan, prio, fte->action.vlan[0].prio); 8546de03d2dSErez Shitrit 8556de03d2dSErez Shitrit vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan_2); 8566de03d2dSErez Shitrit 8576de03d2dSErez Shitrit MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[1].ethtype); 8586de03d2dSErez Shitrit MLX5_SET(vlan, vlan, vid, fte->action.vlan[1].vid); 8596de03d2dSErez Shitrit MLX5_SET(vlan, vlan, prio, fte->action.vlan[1].prio); 8606de03d2dSErez Shitrit 8616de03d2dSErez Shitrit in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context, 8626de03d2dSErez Shitrit match_value); 8636de03d2dSErez Shitrit memcpy(in_match_value, fte->val, sizeof(u32) * MLX5_ST_SZ_DW_MATCH_PARAM); 8646de03d2dSErez Shitrit 8656de03d2dSErez Shitrit in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination); 8666de03d2dSErez Shitrit if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { 8676de03d2dSErez Shitrit int list_size = 0; 8686de03d2dSErez Shitrit 8696de03d2dSErez Shitrit for (i = 0; i < fte->dests_size; i++) { 870d639af62SMark Bloch enum mlx5_flow_destination_type type = fte->dest_arr[i].type; 871d639af62SMark Bloch enum mlx5_ifc_flow_destination_type ifc_type; 872d639af62SMark Bloch unsigned int id; 8736de03d2dSErez Shitrit 8746de03d2dSErez Shitrit if (type == MLX5_FLOW_DESTINATION_TYPE_COUNTER) 8756de03d2dSErez Shitrit continue; 8766de03d2dSErez Shitrit 8776de03d2dSErez Shitrit switch (type) { 8786510bc0dSMark Bloch case MLX5_FLOW_DESTINATION_TYPE_NONE: 8796510bc0dSMark Bloch continue; 8806de03d2dSErez Shitrit case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM: 8816de03d2dSErez Shitrit id = fte->dest_arr[i].ft_num; 882d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_TABLE; 8836de03d2dSErez Shitrit break; 8846de03d2dSErez Shitrit case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE: 8856de03d2dSErez Shitrit id = fte->dest_arr[i].ft_id; 886d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_TABLE; 887d639af62SMark Bloch 8886de03d2dSErez Shitrit break; 889e3a0f40bSYevgeny Kliteynik case MLX5_FLOW_DESTINATION_TYPE_UPLINK: 8906de03d2dSErez Shitrit case MLX5_FLOW_DESTINATION_TYPE_VPORT: 891e3a0f40bSYevgeny Kliteynik if (type == MLX5_FLOW_DESTINATION_TYPE_VPORT) { 8926de03d2dSErez Shitrit id = fte->dest_arr[i].vport.num; 8936de03d2dSErez Shitrit MLX5_SET(dest_format_struct, in_dests, 8946de03d2dSErez Shitrit destination_eswitch_owner_vhca_id_valid, 8956de03d2dSErez Shitrit !!(fte->dest_arr[i].vport.flags & 8966de03d2dSErez Shitrit MLX5_FLOW_DEST_VPORT_VHCA_ID)); 897d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_VPORT; 898e3a0f40bSYevgeny Kliteynik } else { 899e3a0f40bSYevgeny Kliteynik id = 0; 900d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_UPLINK; 901e3a0f40bSYevgeny Kliteynik MLX5_SET(dest_format_struct, in_dests, 902e3a0f40bSYevgeny Kliteynik destination_eswitch_owner_vhca_id_valid, 1); 903e3a0f40bSYevgeny Kliteynik } 9046de03d2dSErez Shitrit MLX5_SET(dest_format_struct, in_dests, 9056de03d2dSErez Shitrit destination_eswitch_owner_vhca_id, 9066de03d2dSErez Shitrit fte->dest_arr[i].vport.vhca_id); 9076de03d2dSErez Shitrit if (extended_dest && (fte->dest_arr[i].vport.flags & 9086de03d2dSErez Shitrit MLX5_FLOW_DEST_VPORT_REFORMAT_ID)) { 9096de03d2dSErez Shitrit MLX5_SET(dest_format_struct, in_dests, 9106de03d2dSErez Shitrit packet_reformat, 9116de03d2dSErez Shitrit !!(fte->dest_arr[i].vport.flags & 9126de03d2dSErez Shitrit MLX5_FLOW_DEST_VPORT_REFORMAT_ID)); 9136de03d2dSErez Shitrit MLX5_SET(extended_dest_format, in_dests, 9146de03d2dSErez Shitrit packet_reformat_id, 9156de03d2dSErez Shitrit fte->dest_arr[i].vport.reformat_id); 9166de03d2dSErez Shitrit } 9176de03d2dSErez Shitrit break; 9181ab6dc35SYevgeny Kliteynik case MLX5_FLOW_DESTINATION_TYPE_FLOW_SAMPLER: 9191ab6dc35SYevgeny Kliteynik id = fte->dest_arr[i].sampler_id; 920d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_SAMPLER; 9211ab6dc35SYevgeny Kliteynik break; 9226de03d2dSErez Shitrit default: 9236de03d2dSErez Shitrit id = fte->dest_arr[i].tir_num; 924d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_TIR; 9256de03d2dSErez Shitrit } 9266de03d2dSErez Shitrit 9276de03d2dSErez Shitrit MLX5_SET(dest_format_struct, in_dests, destination_type, 928d639af62SMark Bloch ifc_type); 9296de03d2dSErez Shitrit MLX5_SET(dest_format_struct, in_dests, destination_id, id); 9306de03d2dSErez Shitrit in_dests += dst_cnt_size; 9316de03d2dSErez Shitrit list_size++; 9326de03d2dSErez Shitrit } 9336de03d2dSErez Shitrit 9346de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, destination_list_size, 9356de03d2dSErez Shitrit list_size); 9366de03d2dSErez Shitrit } 9376de03d2dSErez Shitrit 9386de03d2dSErez Shitrit if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { 9396de03d2dSErez Shitrit int max_list_size = BIT(MLX5_CAP_FLOWTABLE_TYPE(dev, 9406de03d2dSErez Shitrit log_max_flow_counter, 9416de03d2dSErez Shitrit ft->type)); 9426de03d2dSErez Shitrit int list_size = 0; 9436de03d2dSErez Shitrit 9446de03d2dSErez Shitrit for (i = 0; i < fte->dests_size; i++) { 9456de03d2dSErez Shitrit if (fte->dest_arr[i].type != 9466de03d2dSErez Shitrit MLX5_FLOW_DESTINATION_TYPE_COUNTER) 9476de03d2dSErez Shitrit continue; 9486de03d2dSErez Shitrit 9496de03d2dSErez Shitrit MLX5_SET(flow_counter_list, in_dests, flow_counter_id, 9506de03d2dSErez Shitrit fte->dest_arr[i].counter_id); 9516de03d2dSErez Shitrit in_dests += dst_cnt_size; 9526de03d2dSErez Shitrit list_size++; 9536de03d2dSErez Shitrit } 9546de03d2dSErez Shitrit if (list_size > max_list_size) { 9556de03d2dSErez Shitrit err = -EINVAL; 9566de03d2dSErez Shitrit goto err_out; 9576de03d2dSErez Shitrit } 9586de03d2dSErez Shitrit 9596de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, flow_counter_list_size, 9606de03d2dSErez Shitrit list_size); 9616de03d2dSErez Shitrit } 9626de03d2dSErez Shitrit 9636de03d2dSErez Shitrit err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); 9646de03d2dSErez Shitrit err_out: 9656de03d2dSErez Shitrit kvfree(in); 9666de03d2dSErez Shitrit return err; 9676de03d2dSErez Shitrit } 968