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
mlx5dr_cmd_query_esw_vport_context(struct mlx5_core_dev * mdev,bool other_vport,u16 vport_number,u64 * icm_address_rx,u64 * icm_address_tx)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
mlx5dr_cmd_query_gvmi(struct mlx5_core_dev * mdev,bool other_vport,u16 vport_number,u16 * gvmi)341d918647SAlex Vesker int mlx5dr_cmd_query_gvmi(struct mlx5_core_dev *mdev, bool other_vport,
351d918647SAlex Vesker u16 vport_number, u16 *gvmi)
361d918647SAlex Vesker {
378bbe544eSDaniel Jurgens bool ec_vf_func = other_vport ? mlx5_core_is_ec_vf_vport(mdev, vport_number) : false;
381d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {};
391d918647SAlex Vesker int out_size;
401d918647SAlex Vesker void *out;
411d918647SAlex Vesker int err;
421d918647SAlex Vesker
431d918647SAlex Vesker out_size = MLX5_ST_SZ_BYTES(query_hca_cap_out);
441d918647SAlex Vesker out = kzalloc(out_size, GFP_KERNEL);
451d918647SAlex Vesker if (!out)
461d918647SAlex Vesker return -ENOMEM;
471d918647SAlex Vesker
481d918647SAlex Vesker MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
491d918647SAlex Vesker MLX5_SET(query_hca_cap_in, in, other_function, other_vport);
508bbe544eSDaniel Jurgens MLX5_SET(query_hca_cap_in, in, function_id, mlx5_vport_to_func_id(mdev, vport_number, ec_vf_func));
518bbe544eSDaniel Jurgens MLX5_SET(query_hca_cap_in, in, ec_vf_function, ec_vf_func);
521d918647SAlex Vesker MLX5_SET(query_hca_cap_in, in, op_mod,
531d918647SAlex Vesker MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE << 1 |
541d918647SAlex Vesker HCA_CAP_OPMOD_GET_CUR);
551d918647SAlex Vesker
567ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(mdev, query_hca_cap, in, out);
571d918647SAlex Vesker if (err) {
581d918647SAlex Vesker kfree(out);
591d918647SAlex Vesker return err;
601d918647SAlex Vesker }
611d918647SAlex Vesker
621d918647SAlex Vesker *gvmi = MLX5_GET(query_hca_cap_out, out, capability.cmd_hca_cap.vhca_id);
631d918647SAlex Vesker
641d918647SAlex Vesker kfree(out);
651d918647SAlex Vesker return 0;
661d918647SAlex Vesker }
671d918647SAlex Vesker
mlx5dr_cmd_query_esw_caps(struct mlx5_core_dev * mdev,struct mlx5dr_esw_caps * caps)681d918647SAlex Vesker int mlx5dr_cmd_query_esw_caps(struct mlx5_core_dev *mdev,
691d918647SAlex Vesker struct mlx5dr_esw_caps *caps)
701d918647SAlex Vesker {
711d918647SAlex Vesker caps->drop_icm_address_rx =
721d918647SAlex Vesker MLX5_CAP64_ESW_FLOWTABLE(mdev,
731d918647SAlex Vesker sw_steering_fdb_action_drop_icm_address_rx);
741d918647SAlex Vesker caps->drop_icm_address_tx =
751d918647SAlex Vesker MLX5_CAP64_ESW_FLOWTABLE(mdev,
761d918647SAlex Vesker sw_steering_fdb_action_drop_icm_address_tx);
771d918647SAlex Vesker caps->uplink_icm_address_rx =
781d918647SAlex Vesker MLX5_CAP64_ESW_FLOWTABLE(mdev,
791d918647SAlex Vesker sw_steering_uplink_icm_address_rx);
801d918647SAlex Vesker caps->uplink_icm_address_tx =
811d918647SAlex Vesker MLX5_CAP64_ESW_FLOWTABLE(mdev,
821d918647SAlex Vesker sw_steering_uplink_icm_address_tx);
8364f45c0fSYevgeny Kliteynik caps->sw_owner_v2 = MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, sw_owner_v2);
8464f45c0fSYevgeny Kliteynik if (!caps->sw_owner_v2)
8564f45c0fSYevgeny Kliteynik caps->sw_owner = MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, sw_owner);
861d918647SAlex Vesker
871d918647SAlex Vesker return 0;
881d918647SAlex Vesker }
891d918647SAlex Vesker
dr_cmd_query_nic_vport_roce_en(struct mlx5_core_dev * mdev,u16 vport,bool * roce_en)907304d603SYevgeny Kliteynik static int dr_cmd_query_nic_vport_roce_en(struct mlx5_core_dev *mdev,
917304d603SYevgeny Kliteynik u16 vport, bool *roce_en)
927304d603SYevgeny Kliteynik {
937304d603SYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(query_nic_vport_context_out)] = {};
947304d603SYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {};
957304d603SYevgeny Kliteynik int err;
967304d603SYevgeny Kliteynik
977304d603SYevgeny Kliteynik MLX5_SET(query_nic_vport_context_in, in, opcode,
987304d603SYevgeny Kliteynik MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
997304d603SYevgeny Kliteynik MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
1007304d603SYevgeny Kliteynik MLX5_SET(query_nic_vport_context_in, in, other_vport, !!vport);
1017304d603SYevgeny Kliteynik
1027304d603SYevgeny Kliteynik err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
1037304d603SYevgeny Kliteynik if (err)
1047304d603SYevgeny Kliteynik return err;
1057304d603SYevgeny Kliteynik
1067304d603SYevgeny Kliteynik *roce_en = MLX5_GET(query_nic_vport_context_out, out,
1077304d603SYevgeny Kliteynik nic_vport_context.roce_en);
1087304d603SYevgeny Kliteynik return 0;
1097304d603SYevgeny Kliteynik }
1107304d603SYevgeny Kliteynik
mlx5dr_cmd_query_device(struct mlx5_core_dev * mdev,struct mlx5dr_cmd_caps * caps)1111d918647SAlex Vesker int mlx5dr_cmd_query_device(struct mlx5_core_dev *mdev,
1121d918647SAlex Vesker struct mlx5dr_cmd_caps *caps)
1131d918647SAlex Vesker {
1147304d603SYevgeny Kliteynik bool roce_en;
1157304d603SYevgeny Kliteynik int err;
1167304d603SYevgeny Kliteynik
1171d918647SAlex Vesker caps->prio_tag_required = MLX5_CAP_GEN(mdev, prio_tag_required);
1181d918647SAlex Vesker caps->eswitch_manager = MLX5_CAP_GEN(mdev, eswitch_manager);
1191d918647SAlex Vesker caps->gvmi = MLX5_CAP_GEN(mdev, vhca_id);
1201d918647SAlex Vesker caps->flex_protocols = MLX5_CAP_GEN(mdev, flex_parser_protocols);
121d421e466SYevgeny Kliteynik caps->sw_format_ver = MLX5_CAP_GEN(mdev, steering_format_version);
122c7dd225bSYevgeny Kliteynik caps->roce_caps.fl_rc_qp_when_roce_disabled =
123c7dd225bSYevgeny Kliteynik MLX5_CAP_GEN(mdev, fl_rc_qp_when_roce_disabled);
1241d918647SAlex Vesker
1257304d603SYevgeny Kliteynik if (MLX5_CAP_GEN(mdev, roce)) {
1267304d603SYevgeny Kliteynik err = dr_cmd_query_nic_vport_roce_en(mdev, 0, &roce_en);
1277304d603SYevgeny Kliteynik if (err)
1287304d603SYevgeny Kliteynik return err;
1297304d603SYevgeny Kliteynik
1307304d603SYevgeny Kliteynik caps->roce_caps.roce_en = roce_en;
131c7dd225bSYevgeny Kliteynik caps->roce_caps.fl_rc_qp_when_roce_disabled |=
1327304d603SYevgeny Kliteynik MLX5_CAP_ROCE(mdev, fl_rc_qp_when_roce_disabled);
1337304d603SYevgeny Kliteynik caps->roce_caps.fl_rc_qp_when_roce_enabled =
1347304d603SYevgeny Kliteynik MLX5_CAP_ROCE(mdev, fl_rc_qp_when_roce_enabled);
1357304d603SYevgeny Kliteynik }
1367304d603SYevgeny Kliteynik
137aeacb52aSYevgeny Kliteynik caps->isolate_vl_tc = MLX5_CAP_GEN(mdev, isolate_vl_tc_new);
138aeacb52aSYevgeny Kliteynik
139b7ba743aSYevgeny Kliteynik caps->support_modify_argument =
140b7ba743aSYevgeny Kliteynik MLX5_CAP_GEN_64(mdev, general_obj_types) &
141b7ba743aSYevgeny Kliteynik MLX5_GENERAL_OBJ_TYPES_CAP_HEADER_MODIFY_ARGUMENT;
142b7ba743aSYevgeny Kliteynik
143b7ba743aSYevgeny Kliteynik if (caps->support_modify_argument) {
144b7ba743aSYevgeny Kliteynik caps->log_header_modify_argument_granularity =
145b7ba743aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, log_header_modify_argument_granularity);
146b7ba743aSYevgeny Kliteynik caps->log_header_modify_argument_max_alloc =
147b7ba743aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, log_header_modify_argument_max_alloc);
148b7ba743aSYevgeny Kliteynik }
149b7ba743aSYevgeny Kliteynik
150f59464e2SYevgeny Kliteynik /* geneve_tlv_option_0_exist is the indication of
151f59464e2SYevgeny Kliteynik * STE support for lookup type flex_parser_ok
152f59464e2SYevgeny Kliteynik */
153f59464e2SYevgeny Kliteynik caps->flex_parser_ok_bits_supp =
154f59464e2SYevgeny Kliteynik MLX5_CAP_FLOWTABLE(mdev,
155f59464e2SYevgeny Kliteynik flow_table_properties_nic_receive.ft_field_support.geneve_tlv_option_0_exist);
156f59464e2SYevgeny Kliteynik
1578a8a1023SYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V4_ENABLED) {
1581d918647SAlex Vesker caps->flex_parser_id_icmp_dw0 = MLX5_CAP_GEN(mdev, flex_parser_id_icmp_dw0);
1591d918647SAlex Vesker caps->flex_parser_id_icmp_dw1 = MLX5_CAP_GEN(mdev, flex_parser_id_icmp_dw1);
1601d918647SAlex Vesker }
1611d918647SAlex Vesker
1628a8a1023SYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V6_ENABLED) {
1631d918647SAlex Vesker caps->flex_parser_id_icmpv6_dw0 =
1641d918647SAlex Vesker MLX5_CAP_GEN(mdev, flex_parser_id_icmpv6_dw0);
1651d918647SAlex Vesker caps->flex_parser_id_icmpv6_dw1 =
1661d918647SAlex Vesker MLX5_CAP_GEN(mdev, flex_parser_id_icmpv6_dw1);
1671d918647SAlex Vesker }
1681d918647SAlex Vesker
1693442e033SYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_GENEVE_TLV_OPTION_0_ENABLED)
1703442e033SYevgeny Kliteynik caps->flex_parser_id_geneve_tlv_option_0 =
1713442e033SYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_geneve_tlv_option_0);
1723442e033SYevgeny Kliteynik
17335ba005dSYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_MPLS_OVER_GRE_ENABLED)
17435ba005dSYevgeny Kliteynik caps->flex_parser_id_mpls_over_gre =
17535ba005dSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_outer_first_mpls_over_gre);
17635ba005dSYevgeny Kliteynik
177c3fb0e28SYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_MPLS_OVER_UDP_ENABLED)
17835ba005dSYevgeny Kliteynik caps->flex_parser_id_mpls_over_udp =
17935ba005dSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_outer_first_mpls_over_udp_label);
18035ba005dSYevgeny Kliteynik
181df9dd15aSYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_DW_0_ENABLED)
182df9dd15aSYevgeny Kliteynik caps->flex_parser_id_gtpu_dw_0 =
183df9dd15aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_gtpu_dw_0);
184df9dd15aSYevgeny Kliteynik
185df9dd15aSYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_TEID_ENABLED)
186df9dd15aSYevgeny Kliteynik caps->flex_parser_id_gtpu_teid =
187df9dd15aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_gtpu_teid);
188df9dd15aSYevgeny Kliteynik
189df9dd15aSYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_DW_2_ENABLED)
190df9dd15aSYevgeny Kliteynik caps->flex_parser_id_gtpu_dw_2 =
191df9dd15aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_gtpu_dw_2);
192df9dd15aSYevgeny Kliteynik
193df9dd15aSYevgeny Kliteynik if (caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_FIRST_EXT_DW_0_ENABLED)
194df9dd15aSYevgeny Kliteynik caps->flex_parser_id_gtpu_first_ext_dw_0 =
195df9dd15aSYevgeny Kliteynik MLX5_CAP_GEN(mdev, flex_parser_id_gtpu_first_ext_dw_0);
196df9dd15aSYevgeny Kliteynik
1971d918647SAlex Vesker caps->nic_rx_drop_address =
1981d918647SAlex Vesker MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_rx_action_drop_icm_address);
1991d918647SAlex Vesker caps->nic_tx_drop_address =
2001d918647SAlex Vesker MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_tx_action_drop_icm_address);
2011d918647SAlex Vesker caps->nic_tx_allow_address =
2021d918647SAlex Vesker MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_tx_action_allow_icm_address);
2031d918647SAlex Vesker
20464f45c0fSYevgeny Kliteynik caps->rx_sw_owner_v2 = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner_v2);
20564f45c0fSYevgeny Kliteynik caps->tx_sw_owner_v2 = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner_v2);
2061d918647SAlex Vesker
20764f45c0fSYevgeny Kliteynik if (!caps->rx_sw_owner_v2)
20864f45c0fSYevgeny Kliteynik caps->rx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner);
20964f45c0fSYevgeny Kliteynik if (!caps->tx_sw_owner_v2)
2101d918647SAlex Vesker caps->tx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner);
2111d918647SAlex Vesker
21264f45c0fSYevgeny Kliteynik caps->max_ft_level = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_ft_level);
21364f45c0fSYevgeny Kliteynik
2141d918647SAlex Vesker caps->log_icm_size = MLX5_CAP_DEV_MEM(mdev, log_steering_sw_icm_size);
2151d918647SAlex Vesker caps->hdr_modify_icm_addr =
2161d918647SAlex Vesker MLX5_CAP64_DEV_MEM(mdev, header_modify_sw_icm_start_address);
2171d918647SAlex Vesker
218108ff821SYevgeny Kliteynik caps->log_modify_pattern_icm_size =
219108ff821SYevgeny Kliteynik MLX5_CAP_DEV_MEM(mdev, log_header_modify_pattern_sw_icm_size);
220108ff821SYevgeny Kliteynik
221108ff821SYevgeny Kliteynik caps->hdr_modify_pattern_icm_addr =
222108ff821SYevgeny Kliteynik MLX5_CAP64_DEV_MEM(mdev, header_modify_pattern_sw_icm_start_address);
223108ff821SYevgeny Kliteynik
2241d918647SAlex Vesker caps->roce_min_src_udp = MLX5_CAP_ROCE(mdev, r_roce_min_src_udp_port);
2251d918647SAlex Vesker
226dd4acb2aSYevgeny Kliteynik caps->is_ecpf = mlx5_core_is_ecpf_esw_manager(mdev);
227dd4acb2aSYevgeny Kliteynik
2281d918647SAlex Vesker return 0;
2291d918647SAlex Vesker }
2301d918647SAlex Vesker
mlx5dr_cmd_query_flow_table(struct mlx5_core_dev * dev,enum fs_flow_table_type type,u32 table_id,struct mlx5dr_cmd_query_flow_table_details * output)2311d918647SAlex Vesker int mlx5dr_cmd_query_flow_table(struct mlx5_core_dev *dev,
2321d918647SAlex Vesker enum fs_flow_table_type type,
2331d918647SAlex Vesker u32 table_id,
2341d918647SAlex Vesker struct mlx5dr_cmd_query_flow_table_details *output)
2351d918647SAlex Vesker {
2361d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(query_flow_table_out)] = {};
2371d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(query_flow_table_in)] = {};
2381d918647SAlex Vesker int err;
2391d918647SAlex Vesker
2401d918647SAlex Vesker MLX5_SET(query_flow_table_in, in, opcode,
2411d918647SAlex Vesker MLX5_CMD_OP_QUERY_FLOW_TABLE);
2421d918647SAlex Vesker
2431d918647SAlex Vesker MLX5_SET(query_flow_table_in, in, table_type, type);
2441d918647SAlex Vesker MLX5_SET(query_flow_table_in, in, table_id, table_id);
2451d918647SAlex Vesker
2467ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(dev, query_flow_table, in, out);
2471d918647SAlex Vesker if (err)
2481d918647SAlex Vesker return err;
2491d918647SAlex Vesker
2501d918647SAlex Vesker output->status = MLX5_GET(query_flow_table_out, out, status);
2511d918647SAlex Vesker output->level = MLX5_GET(query_flow_table_out, out, flow_table_context.level);
2521d918647SAlex Vesker
2531d918647SAlex Vesker output->sw_owner_icm_root_1 = MLX5_GET64(query_flow_table_out, out,
2541d918647SAlex Vesker flow_table_context.sw_owner_icm_root_1);
2551d918647SAlex Vesker output->sw_owner_icm_root_0 = MLX5_GET64(query_flow_table_out, out,
2561d918647SAlex Vesker flow_table_context.sw_owner_icm_root_0);
2571d918647SAlex Vesker
2581d918647SAlex Vesker return 0;
2591d918647SAlex Vesker }
2601d918647SAlex Vesker
mlx5dr_cmd_query_flow_sampler(struct mlx5_core_dev * dev,u32 sampler_id,u64 * rx_icm_addr,u64 * tx_icm_addr)2611ab6dc35SYevgeny Kliteynik int mlx5dr_cmd_query_flow_sampler(struct mlx5_core_dev *dev,
2621ab6dc35SYevgeny Kliteynik u32 sampler_id,
2631ab6dc35SYevgeny Kliteynik u64 *rx_icm_addr,
2641ab6dc35SYevgeny Kliteynik u64 *tx_icm_addr)
2651ab6dc35SYevgeny Kliteynik {
2661ab6dc35SYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(query_sampler_obj_out)] = {};
2671ab6dc35SYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};
2681ab6dc35SYevgeny Kliteynik void *attr;
2691ab6dc35SYevgeny Kliteynik int ret;
2701ab6dc35SYevgeny Kliteynik
2711ab6dc35SYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, opcode,
2721ab6dc35SYevgeny Kliteynik MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
2731ab6dc35SYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_type,
2741ab6dc35SYevgeny Kliteynik MLX5_GENERAL_OBJECT_TYPES_SAMPLER);
2751ab6dc35SYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, sampler_id);
2761ab6dc35SYevgeny Kliteynik
2771ab6dc35SYevgeny Kliteynik ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
2781ab6dc35SYevgeny Kliteynik if (ret)
2791ab6dc35SYevgeny Kliteynik return ret;
2801ab6dc35SYevgeny Kliteynik
2811ab6dc35SYevgeny Kliteynik attr = MLX5_ADDR_OF(query_sampler_obj_out, out, sampler_object);
2821ab6dc35SYevgeny Kliteynik
2831ab6dc35SYevgeny Kliteynik *rx_icm_addr = MLX5_GET64(sampler_obj, attr,
2841ab6dc35SYevgeny Kliteynik sw_steering_icm_address_rx);
2851ab6dc35SYevgeny Kliteynik *tx_icm_addr = MLX5_GET64(sampler_obj, attr,
2861ab6dc35SYevgeny Kliteynik sw_steering_icm_address_tx);
2871ab6dc35SYevgeny Kliteynik
2881ab6dc35SYevgeny Kliteynik return 0;
2891ab6dc35SYevgeny Kliteynik }
2901ab6dc35SYevgeny Kliteynik
mlx5dr_cmd_sync_steering(struct mlx5_core_dev * mdev)2911d918647SAlex Vesker int mlx5dr_cmd_sync_steering(struct mlx5_core_dev *mdev)
2921d918647SAlex Vesker {
2931d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(sync_steering_in)] = {};
2941d918647SAlex Vesker
295c4193a12SYevgeny Kliteynik /* Skip SYNC in case the device is internal error state.
296c4193a12SYevgeny Kliteynik * Besides a device error, this also happens when we're
297c4193a12SYevgeny Kliteynik * in fast teardown
298c4193a12SYevgeny Kliteynik */
299c4193a12SYevgeny Kliteynik if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
300c4193a12SYevgeny Kliteynik return 0;
301c4193a12SYevgeny Kliteynik
3021d918647SAlex Vesker MLX5_SET(sync_steering_in, in, opcode, MLX5_CMD_OP_SYNC_STEERING);
3031d918647SAlex Vesker
3047ba294e4SLeon Romanovsky return mlx5_cmd_exec_in(mdev, sync_steering, in);
3051d918647SAlex Vesker }
3061d918647SAlex Vesker
mlx5dr_cmd_set_fte_modify_and_vport(struct mlx5_core_dev * mdev,u32 table_type,u32 table_id,u32 group_id,u32 modify_header_id,u16 vport)3071d918647SAlex Vesker int mlx5dr_cmd_set_fte_modify_and_vport(struct mlx5_core_dev *mdev,
3081d918647SAlex Vesker u32 table_type,
3091d918647SAlex Vesker u32 table_id,
3101d918647SAlex Vesker u32 group_id,
3111d918647SAlex Vesker u32 modify_header_id,
312f9f93bd5SYevgeny Kliteynik u16 vport)
3131d918647SAlex Vesker {
3141d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {};
3151d918647SAlex Vesker void *in_flow_context;
3161d918647SAlex Vesker unsigned int inlen;
3171d918647SAlex Vesker void *in_dests;
3181d918647SAlex Vesker u32 *in;
3191d918647SAlex Vesker int err;
3201d918647SAlex Vesker
3211d918647SAlex Vesker inlen = MLX5_ST_SZ_BYTES(set_fte_in) +
3221d918647SAlex Vesker 1 * MLX5_ST_SZ_BYTES(dest_format_struct); /* One destination only */
3231d918647SAlex Vesker
3241d918647SAlex Vesker in = kvzalloc(inlen, GFP_KERNEL);
3251d918647SAlex Vesker if (!in)
3261d918647SAlex Vesker return -ENOMEM;
3271d918647SAlex Vesker
3281d918647SAlex Vesker MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY);
3291d918647SAlex Vesker MLX5_SET(set_fte_in, in, table_type, table_type);
3301d918647SAlex Vesker MLX5_SET(set_fte_in, in, table_id, table_id);
3311d918647SAlex Vesker
3321d918647SAlex Vesker in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
3331d918647SAlex Vesker MLX5_SET(flow_context, in_flow_context, group_id, group_id);
3341d918647SAlex Vesker MLX5_SET(flow_context, in_flow_context, modify_header_id, modify_header_id);
3351d918647SAlex Vesker MLX5_SET(flow_context, in_flow_context, destination_list_size, 1);
3361d918647SAlex Vesker MLX5_SET(flow_context, in_flow_context, action,
3371d918647SAlex Vesker MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
3381d918647SAlex Vesker MLX5_FLOW_CONTEXT_ACTION_MOD_HDR);
3391d918647SAlex Vesker
3401d918647SAlex Vesker in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
3411d918647SAlex Vesker MLX5_SET(dest_format_struct, in_dests, destination_type,
342d639af62SMark Bloch MLX5_IFC_FLOW_DESTINATION_TYPE_VPORT);
343f9f93bd5SYevgeny Kliteynik MLX5_SET(dest_format_struct, in_dests, destination_id, vport);
3441d918647SAlex Vesker
3451d918647SAlex Vesker err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
3461d918647SAlex Vesker kvfree(in);
3471d918647SAlex Vesker
3481d918647SAlex Vesker return err;
3491d918647SAlex Vesker }
3501d918647SAlex Vesker
mlx5dr_cmd_del_flow_table_entry(struct mlx5_core_dev * mdev,u32 table_type,u32 table_id)3511d918647SAlex Vesker int mlx5dr_cmd_del_flow_table_entry(struct mlx5_core_dev *mdev,
3521d918647SAlex Vesker u32 table_type,
3531d918647SAlex Vesker u32 table_id)
3541d918647SAlex Vesker {
3551d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(delete_fte_in)] = {};
3561d918647SAlex Vesker
3571d918647SAlex Vesker MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY);
3581d918647SAlex Vesker MLX5_SET(delete_fte_in, in, table_type, table_type);
3591d918647SAlex Vesker MLX5_SET(delete_fte_in, in, table_id, table_id);
3601d918647SAlex Vesker
3617ba294e4SLeon Romanovsky return mlx5_cmd_exec_in(mdev, delete_fte, in);
3621d918647SAlex Vesker }
3631d918647SAlex Vesker
mlx5dr_cmd_alloc_modify_header(struct mlx5_core_dev * mdev,u32 table_type,u8 num_of_actions,u64 * actions,u32 * modify_header_id)3641d918647SAlex Vesker int mlx5dr_cmd_alloc_modify_header(struct mlx5_core_dev *mdev,
3651d918647SAlex Vesker u32 table_type,
3661d918647SAlex Vesker u8 num_of_actions,
3671d918647SAlex Vesker u64 *actions,
3681d918647SAlex Vesker u32 *modify_header_id)
3691d918647SAlex Vesker {
3701d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(alloc_modify_header_context_out)] = {};
3711d918647SAlex Vesker void *p_actions;
3721d918647SAlex Vesker u32 inlen;
3731d918647SAlex Vesker u32 *in;
3741d918647SAlex Vesker int err;
3751d918647SAlex Vesker
3761d918647SAlex Vesker inlen = MLX5_ST_SZ_BYTES(alloc_modify_header_context_in) +
3771d918647SAlex Vesker num_of_actions * sizeof(u64);
3781d918647SAlex Vesker in = kvzalloc(inlen, GFP_KERNEL);
3791d918647SAlex Vesker if (!in)
3801d918647SAlex Vesker return -ENOMEM;
3811d918647SAlex Vesker
3821d918647SAlex Vesker MLX5_SET(alloc_modify_header_context_in, in, opcode,
3831d918647SAlex Vesker MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT);
3841d918647SAlex Vesker MLX5_SET(alloc_modify_header_context_in, in, table_type, table_type);
3851d918647SAlex Vesker MLX5_SET(alloc_modify_header_context_in, in, num_of_actions, num_of_actions);
3861d918647SAlex Vesker p_actions = MLX5_ADDR_OF(alloc_modify_header_context_in, in, actions);
3871d918647SAlex Vesker memcpy(p_actions, actions, num_of_actions * sizeof(u64));
3881d918647SAlex Vesker
3891d918647SAlex Vesker err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
3901d918647SAlex Vesker if (err)
3911d918647SAlex Vesker goto out;
3921d918647SAlex Vesker
3931d918647SAlex Vesker *modify_header_id = MLX5_GET(alloc_modify_header_context_out, out,
3941d918647SAlex Vesker modify_header_id);
3951d918647SAlex Vesker out:
3961d918647SAlex Vesker kvfree(in);
3971d918647SAlex Vesker return err;
3981d918647SAlex Vesker }
3991d918647SAlex Vesker
mlx5dr_cmd_dealloc_modify_header(struct mlx5_core_dev * mdev,u32 modify_header_id)4001d918647SAlex Vesker int mlx5dr_cmd_dealloc_modify_header(struct mlx5_core_dev *mdev,
4011d918647SAlex Vesker u32 modify_header_id)
4021d918647SAlex Vesker {
4031d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(dealloc_modify_header_context_in)] = {};
4041d918647SAlex Vesker
4051d918647SAlex Vesker MLX5_SET(dealloc_modify_header_context_in, in, opcode,
4061d918647SAlex Vesker MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT);
4071d918647SAlex Vesker MLX5_SET(dealloc_modify_header_context_in, in, modify_header_id,
4081d918647SAlex Vesker modify_header_id);
4091d918647SAlex Vesker
4107ba294e4SLeon Romanovsky return mlx5_cmd_exec_in(mdev, dealloc_modify_header_context, in);
4111d918647SAlex Vesker }
4121d918647SAlex Vesker
mlx5dr_cmd_create_empty_flow_group(struct mlx5_core_dev * mdev,u32 table_type,u32 table_id,u32 * group_id)4131d918647SAlex Vesker int mlx5dr_cmd_create_empty_flow_group(struct mlx5_core_dev *mdev,
4141d918647SAlex Vesker u32 table_type,
4151d918647SAlex Vesker u32 table_id,
4161d918647SAlex Vesker u32 *group_id)
4171d918647SAlex Vesker {
4181d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(create_flow_group_out)] = {};
4191d918647SAlex Vesker int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
4201d918647SAlex Vesker u32 *in;
4211d918647SAlex Vesker int err;
4221d918647SAlex Vesker
423b7f86258SRoi Dayan in = kvzalloc(inlen, GFP_KERNEL);
4241d918647SAlex Vesker if (!in)
4251d918647SAlex Vesker return -ENOMEM;
4261d918647SAlex Vesker
4271d918647SAlex Vesker MLX5_SET(create_flow_group_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_GROUP);
4281d918647SAlex Vesker MLX5_SET(create_flow_group_in, in, table_type, table_type);
4291d918647SAlex Vesker MLX5_SET(create_flow_group_in, in, table_id, table_id);
4301d918647SAlex Vesker
4317ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(mdev, create_flow_group, in, out);
4321d918647SAlex Vesker if (err)
4331d918647SAlex Vesker goto out;
4341d918647SAlex Vesker
4351d918647SAlex Vesker *group_id = MLX5_GET(create_flow_group_out, out, group_id);
4361d918647SAlex Vesker
4371d918647SAlex Vesker out:
438b7f86258SRoi Dayan kvfree(in);
4391d918647SAlex Vesker return err;
4401d918647SAlex Vesker }
4411d918647SAlex Vesker
mlx5dr_cmd_destroy_flow_group(struct mlx5_core_dev * mdev,u32 table_type,u32 table_id,u32 group_id)4421d918647SAlex Vesker int mlx5dr_cmd_destroy_flow_group(struct mlx5_core_dev *mdev,
4431d918647SAlex Vesker u32 table_type,
4441d918647SAlex Vesker u32 table_id,
4451d918647SAlex Vesker u32 group_id)
4461d918647SAlex Vesker {
4471d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)] = {};
4481d918647SAlex Vesker
4497ba294e4SLeon Romanovsky MLX5_SET(destroy_flow_group_in, in, opcode,
4507ba294e4SLeon Romanovsky MLX5_CMD_OP_DESTROY_FLOW_GROUP);
4511d918647SAlex Vesker MLX5_SET(destroy_flow_group_in, in, table_type, table_type);
4521d918647SAlex Vesker MLX5_SET(destroy_flow_group_in, in, table_id, table_id);
4531d918647SAlex Vesker MLX5_SET(destroy_flow_group_in, in, group_id, group_id);
4541d918647SAlex Vesker
4557ba294e4SLeon Romanovsky return mlx5_cmd_exec_in(mdev, destroy_flow_group, in);
4561d918647SAlex Vesker }
4571d918647SAlex Vesker
mlx5dr_cmd_create_flow_table(struct mlx5_core_dev * mdev,struct mlx5dr_cmd_create_flow_table_attr * attr,u64 * fdb_rx_icm_addr,u32 * table_id)4581d918647SAlex Vesker int mlx5dr_cmd_create_flow_table(struct mlx5_core_dev *mdev,
459cc78dbd7SAlex Vesker struct mlx5dr_cmd_create_flow_table_attr *attr,
4601d918647SAlex Vesker u64 *fdb_rx_icm_addr,
4611d918647SAlex Vesker u32 *table_id)
4621d918647SAlex Vesker {
4631d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {};
4641d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(create_flow_table_in)] = {};
4651d918647SAlex Vesker void *ft_mdev;
4661d918647SAlex Vesker int err;
4671d918647SAlex Vesker
4681d918647SAlex Vesker MLX5_SET(create_flow_table_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_TABLE);
469cc78dbd7SAlex Vesker MLX5_SET(create_flow_table_in, in, table_type, attr->table_type);
470b0bb369eSMark Bloch MLX5_SET(create_flow_table_in, in, uid, attr->uid);
4711d918647SAlex Vesker
4721d918647SAlex Vesker ft_mdev = MLX5_ADDR_OF(create_flow_table_in, in, flow_table_context);
473cc78dbd7SAlex Vesker MLX5_SET(flow_table_context, ft_mdev, termination_table, attr->term_tbl);
474cc78dbd7SAlex Vesker MLX5_SET(flow_table_context, ft_mdev, sw_owner, attr->sw_owner);
475cc78dbd7SAlex Vesker MLX5_SET(flow_table_context, ft_mdev, level, attr->level);
4761d918647SAlex Vesker
477cc78dbd7SAlex Vesker if (attr->sw_owner) {
4781d918647SAlex Vesker /* icm_addr_0 used for FDB RX / NIC TX / NIC_RX
4791d918647SAlex Vesker * icm_addr_1 used for FDB TX
4801d918647SAlex Vesker */
481cc78dbd7SAlex Vesker if (attr->table_type == MLX5_FLOW_TABLE_TYPE_NIC_RX) {
4821d918647SAlex Vesker MLX5_SET64(flow_table_context, ft_mdev,
483cc78dbd7SAlex Vesker sw_owner_icm_root_0, attr->icm_addr_rx);
484cc78dbd7SAlex Vesker } else if (attr->table_type == MLX5_FLOW_TABLE_TYPE_NIC_TX) {
4851d918647SAlex Vesker MLX5_SET64(flow_table_context, ft_mdev,
486cc78dbd7SAlex Vesker sw_owner_icm_root_0, attr->icm_addr_tx);
487cc78dbd7SAlex Vesker } else if (attr->table_type == MLX5_FLOW_TABLE_TYPE_FDB) {
4881d918647SAlex Vesker MLX5_SET64(flow_table_context, ft_mdev,
489cc78dbd7SAlex Vesker sw_owner_icm_root_0, attr->icm_addr_rx);
4901d918647SAlex Vesker MLX5_SET64(flow_table_context, ft_mdev,
491cc78dbd7SAlex Vesker sw_owner_icm_root_1, attr->icm_addr_tx);
4921d918647SAlex Vesker }
4931d918647SAlex Vesker }
4941d918647SAlex Vesker
495cc78dbd7SAlex Vesker MLX5_SET(create_flow_table_in, in, flow_table_context.decap_en,
496cc78dbd7SAlex Vesker attr->decap_en);
497cc78dbd7SAlex Vesker MLX5_SET(create_flow_table_in, in, flow_table_context.reformat_en,
498cc78dbd7SAlex Vesker attr->reformat_en);
499cc78dbd7SAlex Vesker
5007ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(mdev, create_flow_table, in, out);
5011d918647SAlex Vesker if (err)
5021d918647SAlex Vesker return err;
5031d918647SAlex Vesker
5041d918647SAlex Vesker *table_id = MLX5_GET(create_flow_table_out, out, table_id);
505cc78dbd7SAlex Vesker if (!attr->sw_owner && attr->table_type == MLX5_FLOW_TABLE_TYPE_FDB &&
506cc78dbd7SAlex Vesker fdb_rx_icm_addr)
5071d918647SAlex Vesker *fdb_rx_icm_addr =
5081d918647SAlex Vesker (u64)MLX5_GET(create_flow_table_out, out, icm_address_31_0) |
5091d918647SAlex Vesker (u64)MLX5_GET(create_flow_table_out, out, icm_address_39_32) << 32 |
5101d918647SAlex Vesker (u64)MLX5_GET(create_flow_table_out, out, icm_address_63_40) << 40;
5111d918647SAlex Vesker
5121d918647SAlex Vesker return 0;
5131d918647SAlex Vesker }
5141d918647SAlex Vesker
mlx5dr_cmd_destroy_flow_table(struct mlx5_core_dev * mdev,u32 table_id,u32 table_type)5151d918647SAlex Vesker int mlx5dr_cmd_destroy_flow_table(struct mlx5_core_dev *mdev,
5161d918647SAlex Vesker u32 table_id,
5171d918647SAlex Vesker u32 table_type)
5181d918647SAlex Vesker {
5191d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)] = {};
5201d918647SAlex Vesker
5211d918647SAlex Vesker MLX5_SET(destroy_flow_table_in, in, opcode,
5221d918647SAlex Vesker MLX5_CMD_OP_DESTROY_FLOW_TABLE);
5231d918647SAlex Vesker MLX5_SET(destroy_flow_table_in, in, table_type, table_type);
5241d918647SAlex Vesker MLX5_SET(destroy_flow_table_in, in, table_id, table_id);
5251d918647SAlex Vesker
5267ba294e4SLeon Romanovsky return mlx5_cmd_exec_in(mdev, destroy_flow_table, in);
5271d918647SAlex Vesker }
5281d918647SAlex Vesker
mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev * mdev,enum mlx5_reformat_ctx_type rt,u8 reformat_param_0,u8 reformat_param_1,size_t reformat_size,void * reformat_data,u32 * reformat_id)5291d918647SAlex Vesker int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev,
5301d918647SAlex Vesker enum mlx5_reformat_ctx_type rt,
5317ea9b398SYevgeny Kliteynik u8 reformat_param_0,
5327ea9b398SYevgeny Kliteynik u8 reformat_param_1,
5331d918647SAlex Vesker size_t reformat_size,
5341d918647SAlex Vesker void *reformat_data,
5351d918647SAlex Vesker u32 *reformat_id)
5361d918647SAlex Vesker {
5371d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(alloc_packet_reformat_context_out)] = {};
5381d918647SAlex Vesker size_t inlen, cmd_data_sz, cmd_total_sz;
5391d918647SAlex Vesker void *prctx;
5401d918647SAlex Vesker void *pdata;
5411d918647SAlex Vesker void *in;
5421d918647SAlex Vesker int err;
5431d918647SAlex Vesker
5441d918647SAlex Vesker cmd_total_sz = MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in);
5451d918647SAlex Vesker cmd_data_sz = MLX5_FLD_SZ_BYTES(alloc_packet_reformat_context_in,
5461d918647SAlex Vesker packet_reformat_context.reformat_data);
5471d918647SAlex Vesker inlen = ALIGN(cmd_total_sz + reformat_size - cmd_data_sz, 4);
5481d918647SAlex Vesker in = kvzalloc(inlen, GFP_KERNEL);
5491d918647SAlex Vesker if (!in)
5501d918647SAlex Vesker return -ENOMEM;
5511d918647SAlex Vesker
5521d918647SAlex Vesker MLX5_SET(alloc_packet_reformat_context_in, in, opcode,
5531d918647SAlex Vesker MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT);
5541d918647SAlex Vesker
5551d918647SAlex Vesker prctx = MLX5_ADDR_OF(alloc_packet_reformat_context_in, in, packet_reformat_context);
5561d918647SAlex Vesker pdata = MLX5_ADDR_OF(packet_reformat_context_in, prctx, reformat_data);
5571d918647SAlex Vesker
5581d918647SAlex Vesker MLX5_SET(packet_reformat_context_in, prctx, reformat_type, rt);
5597ea9b398SYevgeny Kliteynik MLX5_SET(packet_reformat_context_in, prctx, reformat_param_0, reformat_param_0);
5607ea9b398SYevgeny Kliteynik MLX5_SET(packet_reformat_context_in, prctx, reformat_param_1, reformat_param_1);
5611d918647SAlex Vesker MLX5_SET(packet_reformat_context_in, prctx, reformat_data_size, reformat_size);
5627ea9b398SYevgeny Kliteynik if (reformat_data && reformat_size)
5631d918647SAlex Vesker memcpy(pdata, reformat_data, reformat_size);
5641d918647SAlex Vesker
5651d918647SAlex Vesker err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
5661d918647SAlex Vesker if (err)
567*5dd77585SZhengchao Shao goto err_free_in;
5681d918647SAlex Vesker
5691d918647SAlex Vesker *reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id);
5701d918647SAlex Vesker
571*5dd77585SZhengchao Shao err_free_in:
572*5dd77585SZhengchao Shao kvfree(in);
5731d918647SAlex Vesker return err;
5741d918647SAlex Vesker }
5751d918647SAlex Vesker
mlx5dr_cmd_destroy_reformat_ctx(struct mlx5_core_dev * mdev,u32 reformat_id)5761d918647SAlex Vesker void mlx5dr_cmd_destroy_reformat_ctx(struct mlx5_core_dev *mdev,
5771d918647SAlex Vesker u32 reformat_id)
5781d918647SAlex Vesker {
5791d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_in)] = {};
5801d918647SAlex Vesker
5811d918647SAlex Vesker MLX5_SET(dealloc_packet_reformat_context_in, in, opcode,
5821d918647SAlex Vesker MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT);
5831d918647SAlex Vesker MLX5_SET(dealloc_packet_reformat_context_in, in, packet_reformat_id,
5841d918647SAlex Vesker reformat_id);
5851d918647SAlex Vesker
5867ba294e4SLeon Romanovsky mlx5_cmd_exec_in(mdev, dealloc_packet_reformat_context, in);
5871d918647SAlex Vesker }
5881d918647SAlex Vesker
dr_cmd_set_definer_format(void * ptr,u16 format_id,u8 * dw_selectors,u8 * byte_selectors)589e046b86eSYevgeny Kliteynik static void dr_cmd_set_definer_format(void *ptr, u16 format_id,
590e046b86eSYevgeny Kliteynik u8 *dw_selectors,
591e046b86eSYevgeny Kliteynik u8 *byte_selectors)
592e046b86eSYevgeny Kliteynik {
593e046b86eSYevgeny Kliteynik if (format_id != MLX5_IFC_DEFINER_FORMAT_ID_SELECT)
594e046b86eSYevgeny Kliteynik return;
595e046b86eSYevgeny Kliteynik
596e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw0, dw_selectors[0]);
597e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw1, dw_selectors[1]);
598e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw2, dw_selectors[2]);
599e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw3, dw_selectors[3]);
600e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw4, dw_selectors[4]);
601e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw5, dw_selectors[5]);
602e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw6, dw_selectors[6]);
603e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw7, dw_selectors[7]);
604e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_dw8, dw_selectors[8]);
605e046b86eSYevgeny Kliteynik
606e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte0, byte_selectors[0]);
607e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte1, byte_selectors[1]);
608e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte2, byte_selectors[2]);
609e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte3, byte_selectors[3]);
610e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte4, byte_selectors[4]);
611e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte5, byte_selectors[5]);
612e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte6, byte_selectors[6]);
613e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_select_byte7, byte_selectors[7]);
614e046b86eSYevgeny Kliteynik }
615e046b86eSYevgeny Kliteynik
mlx5dr_cmd_create_definer(struct mlx5_core_dev * mdev,u16 format_id,u8 * dw_selectors,u8 * byte_selectors,u8 * match_mask,u32 * definer_id)616e046b86eSYevgeny Kliteynik int mlx5dr_cmd_create_definer(struct mlx5_core_dev *mdev,
617e046b86eSYevgeny Kliteynik u16 format_id,
618e046b86eSYevgeny Kliteynik u8 *dw_selectors,
619e046b86eSYevgeny Kliteynik u8 *byte_selectors,
620e046b86eSYevgeny Kliteynik u8 *match_mask,
621e046b86eSYevgeny Kliteynik u32 *definer_id)
622e046b86eSYevgeny Kliteynik {
623e046b86eSYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
624e046b86eSYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(create_match_definer_in)] = {};
625e046b86eSYevgeny Kliteynik void *ptr;
626e046b86eSYevgeny Kliteynik int err;
627e046b86eSYevgeny Kliteynik
628e046b86eSYevgeny Kliteynik ptr = MLX5_ADDR_OF(create_match_definer_in, in,
629e046b86eSYevgeny Kliteynik general_obj_in_cmd_hdr);
630e046b86eSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode,
631e046b86eSYevgeny Kliteynik MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
632e046b86eSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type,
633e046b86eSYevgeny Kliteynik MLX5_OBJ_TYPE_MATCH_DEFINER);
634e046b86eSYevgeny Kliteynik
635e046b86eSYevgeny Kliteynik ptr = MLX5_ADDR_OF(create_match_definer_in, in, obj_context);
636e046b86eSYevgeny Kliteynik MLX5_SET(match_definer, ptr, format_id, format_id);
637e046b86eSYevgeny Kliteynik
638e046b86eSYevgeny Kliteynik dr_cmd_set_definer_format(ptr, format_id,
639e046b86eSYevgeny Kliteynik dw_selectors, byte_selectors);
640e046b86eSYevgeny Kliteynik
641e046b86eSYevgeny Kliteynik ptr = MLX5_ADDR_OF(match_definer, ptr, match_mask);
642e046b86eSYevgeny Kliteynik memcpy(ptr, match_mask, MLX5_FLD_SZ_BYTES(match_definer, match_mask));
643e046b86eSYevgeny Kliteynik
644e046b86eSYevgeny Kliteynik err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
645e046b86eSYevgeny Kliteynik if (err)
646e046b86eSYevgeny Kliteynik return err;
647e046b86eSYevgeny Kliteynik
648e046b86eSYevgeny Kliteynik *definer_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
649e046b86eSYevgeny Kliteynik
650e046b86eSYevgeny Kliteynik return 0;
651e046b86eSYevgeny Kliteynik }
652e046b86eSYevgeny Kliteynik
653e046b86eSYevgeny Kliteynik void
mlx5dr_cmd_destroy_definer(struct mlx5_core_dev * mdev,u32 definer_id)654e046b86eSYevgeny Kliteynik mlx5dr_cmd_destroy_definer(struct mlx5_core_dev *mdev, u32 definer_id)
655e046b86eSYevgeny Kliteynik {
656e046b86eSYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};
657e046b86eSYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
658e046b86eSYevgeny Kliteynik
659e046b86eSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
660e046b86eSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, MLX5_OBJ_TYPE_MATCH_DEFINER);
661e046b86eSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, definer_id);
662e046b86eSYevgeny Kliteynik
663e046b86eSYevgeny Kliteynik mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
664e046b86eSYevgeny Kliteynik }
665e046b86eSYevgeny Kliteynik
mlx5dr_cmd_query_gid(struct mlx5_core_dev * mdev,u8 vhca_port_num,u16 index,struct mlx5dr_cmd_gid_attr * attr)6661d918647SAlex Vesker int mlx5dr_cmd_query_gid(struct mlx5_core_dev *mdev, u8 vhca_port_num,
6671d918647SAlex Vesker u16 index, struct mlx5dr_cmd_gid_attr *attr)
6681d918647SAlex Vesker {
6691d918647SAlex Vesker u32 out[MLX5_ST_SZ_DW(query_roce_address_out)] = {};
6701d918647SAlex Vesker u32 in[MLX5_ST_SZ_DW(query_roce_address_in)] = {};
6711d918647SAlex Vesker int err;
6721d918647SAlex Vesker
6731d918647SAlex Vesker MLX5_SET(query_roce_address_in, in, opcode,
6741d918647SAlex Vesker MLX5_CMD_OP_QUERY_ROCE_ADDRESS);
6751d918647SAlex Vesker
6761d918647SAlex Vesker MLX5_SET(query_roce_address_in, in, roce_address_index, index);
6771d918647SAlex Vesker MLX5_SET(query_roce_address_in, in, vhca_port_num, vhca_port_num);
6781d918647SAlex Vesker
6797ba294e4SLeon Romanovsky err = mlx5_cmd_exec_inout(mdev, query_roce_address, in, out);
6801d918647SAlex Vesker if (err)
6811d918647SAlex Vesker return err;
6821d918647SAlex Vesker
6831d918647SAlex Vesker memcpy(&attr->gid,
6841d918647SAlex Vesker MLX5_ADDR_OF(query_roce_address_out,
6851d918647SAlex Vesker out, roce_address.source_l3_address),
6861d918647SAlex Vesker sizeof(attr->gid));
6871d918647SAlex Vesker memcpy(attr->mac,
6881d918647SAlex Vesker MLX5_ADDR_OF(query_roce_address_out, out,
6891d918647SAlex Vesker roce_address.source_mac_47_32),
6901d918647SAlex Vesker sizeof(attr->mac));
6911d918647SAlex Vesker
6921d918647SAlex Vesker if (MLX5_GET(query_roce_address_out, out,
6931d918647SAlex Vesker roce_address.roce_version) == MLX5_ROCE_VERSION_2)
6941d918647SAlex Vesker attr->roce_ver = MLX5_ROCE_VERSION_2;
6951d918647SAlex Vesker else
6961d918647SAlex Vesker attr->roce_ver = MLX5_ROCE_VERSION_1;
6971d918647SAlex Vesker
6981d918647SAlex Vesker return 0;
6991d918647SAlex Vesker }
7006de03d2dSErez Shitrit
mlx5dr_cmd_create_modify_header_arg(struct mlx5_core_dev * dev,u16 log_obj_range,u32 pd,u32 * obj_id)701de69696bSYevgeny Kliteynik int mlx5dr_cmd_create_modify_header_arg(struct mlx5_core_dev *dev,
702de69696bSYevgeny Kliteynik u16 log_obj_range, u32 pd,
703de69696bSYevgeny Kliteynik u32 *obj_id)
704de69696bSYevgeny Kliteynik {
705de69696bSYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(create_modify_header_arg_in)] = {};
706de69696bSYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
707de69696bSYevgeny Kliteynik void *attr;
708de69696bSYevgeny Kliteynik int ret;
709de69696bSYevgeny Kliteynik
710de69696bSYevgeny Kliteynik attr = MLX5_ADDR_OF(create_modify_header_arg_in, in, hdr);
711de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, attr, opcode,
712de69696bSYevgeny Kliteynik MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
713de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, attr, obj_type,
714de69696bSYevgeny Kliteynik MLX5_OBJ_TYPE_HEADER_MODIFY_ARGUMENT);
715de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, attr,
716de69696bSYevgeny Kliteynik op_param.create.log_obj_range, log_obj_range);
717de69696bSYevgeny Kliteynik
718de69696bSYevgeny Kliteynik attr = MLX5_ADDR_OF(create_modify_header_arg_in, in, arg);
719de69696bSYevgeny Kliteynik MLX5_SET(modify_header_arg, attr, access_pd, pd);
720de69696bSYevgeny Kliteynik
721de69696bSYevgeny Kliteynik ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
722de69696bSYevgeny Kliteynik if (ret)
723de69696bSYevgeny Kliteynik return ret;
724de69696bSYevgeny Kliteynik
725de69696bSYevgeny Kliteynik *obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
726de69696bSYevgeny Kliteynik return 0;
727de69696bSYevgeny Kliteynik }
728de69696bSYevgeny Kliteynik
mlx5dr_cmd_destroy_modify_header_arg(struct mlx5_core_dev * dev,u32 obj_id)729de69696bSYevgeny Kliteynik void mlx5dr_cmd_destroy_modify_header_arg(struct mlx5_core_dev *dev,
730de69696bSYevgeny Kliteynik u32 obj_id)
731de69696bSYevgeny Kliteynik {
732de69696bSYevgeny Kliteynik u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
733de69696bSYevgeny Kliteynik u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};
734de69696bSYevgeny Kliteynik
735de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, opcode,
736de69696bSYevgeny Kliteynik MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
737de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_type,
738de69696bSYevgeny Kliteynik MLX5_OBJ_TYPE_HEADER_MODIFY_ARGUMENT);
739de69696bSYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, obj_id);
740de69696bSYevgeny Kliteynik
741de69696bSYevgeny Kliteynik mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
742de69696bSYevgeny Kliteynik }
743de69696bSYevgeny Kliteynik
mlx5dr_cmd_set_extended_dest(struct mlx5_core_dev * dev,struct mlx5dr_cmd_fte_info * fte,bool * extended_dest)7446de03d2dSErez Shitrit static int mlx5dr_cmd_set_extended_dest(struct mlx5_core_dev *dev,
7456de03d2dSErez Shitrit struct mlx5dr_cmd_fte_info *fte,
7466de03d2dSErez Shitrit bool *extended_dest)
7476de03d2dSErez Shitrit {
7486de03d2dSErez Shitrit int fw_log_max_fdb_encap_uplink = MLX5_CAP_ESW(dev, log_max_fdb_encap_uplink);
7496de03d2dSErez Shitrit int num_fwd_destinations = 0;
7506de03d2dSErez Shitrit int num_encap = 0;
7516de03d2dSErez Shitrit int i;
7526de03d2dSErez Shitrit
7536de03d2dSErez Shitrit *extended_dest = false;
7546de03d2dSErez Shitrit if (!(fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST))
7556de03d2dSErez Shitrit return 0;
7566de03d2dSErez Shitrit for (i = 0; i < fte->dests_size; i++) {
7576510bc0dSMark Bloch if (fte->dest_arr[i].type == MLX5_FLOW_DESTINATION_TYPE_COUNTER ||
7586510bc0dSMark Bloch fte->dest_arr[i].type == MLX5_FLOW_DESTINATION_TYPE_NONE)
7596de03d2dSErez Shitrit continue;
760e3a0f40bSYevgeny Kliteynik if ((fte->dest_arr[i].type == MLX5_FLOW_DESTINATION_TYPE_VPORT ||
761e3a0f40bSYevgeny Kliteynik fte->dest_arr[i].type == MLX5_FLOW_DESTINATION_TYPE_UPLINK) &&
7626de03d2dSErez Shitrit fte->dest_arr[i].vport.flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID)
7636de03d2dSErez Shitrit num_encap++;
7646de03d2dSErez Shitrit num_fwd_destinations++;
7656de03d2dSErez Shitrit }
7666de03d2dSErez Shitrit
7676de03d2dSErez Shitrit if (num_fwd_destinations > 1 && num_encap > 0)
7686de03d2dSErez Shitrit *extended_dest = true;
7696de03d2dSErez Shitrit
7706de03d2dSErez Shitrit if (*extended_dest && !fw_log_max_fdb_encap_uplink) {
7716de03d2dSErez Shitrit mlx5_core_warn(dev, "FW does not support extended destination");
7726de03d2dSErez Shitrit return -EOPNOTSUPP;
7736de03d2dSErez Shitrit }
7746de03d2dSErez Shitrit if (num_encap > (1 << fw_log_max_fdb_encap_uplink)) {
7756de03d2dSErez Shitrit mlx5_core_warn(dev, "FW does not support more than %d encaps",
7766de03d2dSErez Shitrit 1 << fw_log_max_fdb_encap_uplink);
7776de03d2dSErez Shitrit return -EOPNOTSUPP;
7786de03d2dSErez Shitrit }
7796de03d2dSErez Shitrit
7806de03d2dSErez Shitrit return 0;
7816de03d2dSErez Shitrit }
7826de03d2dSErez Shitrit
mlx5dr_cmd_set_fte(struct mlx5_core_dev * dev,int opmod,int modify_mask,struct mlx5dr_cmd_ft_info * ft,u32 group_id,struct mlx5dr_cmd_fte_info * fte)7836de03d2dSErez Shitrit int mlx5dr_cmd_set_fte(struct mlx5_core_dev *dev,
7846de03d2dSErez Shitrit int opmod, int modify_mask,
7856de03d2dSErez Shitrit struct mlx5dr_cmd_ft_info *ft,
7866de03d2dSErez Shitrit u32 group_id,
7876de03d2dSErez Shitrit struct mlx5dr_cmd_fte_info *fte)
7886de03d2dSErez Shitrit {
7896de03d2dSErez Shitrit u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {};
7906de03d2dSErez Shitrit void *in_flow_context, *vlan;
7916de03d2dSErez Shitrit bool extended_dest = false;
7926de03d2dSErez Shitrit void *in_match_value;
7936de03d2dSErez Shitrit unsigned int inlen;
7946de03d2dSErez Shitrit int dst_cnt_size;
7956de03d2dSErez Shitrit void *in_dests;
7966de03d2dSErez Shitrit u32 *in;
7976de03d2dSErez Shitrit int err;
7986de03d2dSErez Shitrit int i;
7996de03d2dSErez Shitrit
8006de03d2dSErez Shitrit if (mlx5dr_cmd_set_extended_dest(dev, fte, &extended_dest))
8016de03d2dSErez Shitrit return -EOPNOTSUPP;
8026de03d2dSErez Shitrit
8036de03d2dSErez Shitrit if (!extended_dest)
8046de03d2dSErez Shitrit dst_cnt_size = MLX5_ST_SZ_BYTES(dest_format_struct);
8056de03d2dSErez Shitrit else
8066de03d2dSErez Shitrit dst_cnt_size = MLX5_ST_SZ_BYTES(extended_dest_format);
8076de03d2dSErez Shitrit
8086de03d2dSErez Shitrit inlen = MLX5_ST_SZ_BYTES(set_fte_in) + fte->dests_size * dst_cnt_size;
8096de03d2dSErez Shitrit in = kvzalloc(inlen, GFP_KERNEL);
8106de03d2dSErez Shitrit if (!in)
8116de03d2dSErez Shitrit return -ENOMEM;
8126de03d2dSErez Shitrit
8136de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY);
8146de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, op_mod, opmod);
8156de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, modify_enable_mask, modify_mask);
8166de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, table_type, ft->type);
8176de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, table_id, ft->id);
8186de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, flow_index, fte->index);
81963b85f49SYevgeny Kliteynik MLX5_SET(set_fte_in, in, ignore_flow_level, fte->ignore_flow_level);
8206de03d2dSErez Shitrit if (ft->vport) {
8216de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, vport_number, ft->vport);
8226de03d2dSErez Shitrit MLX5_SET(set_fte_in, in, other_vport, 1);
8236de03d2dSErez Shitrit }
8246de03d2dSErez Shitrit
8256de03d2dSErez Shitrit in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
8266de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, group_id, group_id);
8276de03d2dSErez Shitrit
8286de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, flow_tag,
8296de03d2dSErez Shitrit fte->flow_context.flow_tag);
8306de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, flow_source,
8316de03d2dSErez Shitrit fte->flow_context.flow_source);
8326de03d2dSErez Shitrit
8336de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, extended_destination,
8346de03d2dSErez Shitrit extended_dest);
8356de03d2dSErez Shitrit if (extended_dest) {
8366de03d2dSErez Shitrit u32 action;
8376de03d2dSErez Shitrit
8386de03d2dSErez Shitrit action = fte->action.action &
8396de03d2dSErez Shitrit ~MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
8406de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, action, action);
8416de03d2dSErez Shitrit } else {
8426de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, action,
8436de03d2dSErez Shitrit fte->action.action);
8446de03d2dSErez Shitrit if (fte->action.pkt_reformat)
8456de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, packet_reformat_id,
8466de03d2dSErez Shitrit fte->action.pkt_reformat->id);
8476de03d2dSErez Shitrit }
8486de03d2dSErez Shitrit if (fte->action.modify_hdr)
8496de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, modify_header_id,
8506de03d2dSErez Shitrit fte->action.modify_hdr->id);
8516de03d2dSErez Shitrit
8526de03d2dSErez Shitrit vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan);
8536de03d2dSErez Shitrit
8546de03d2dSErez Shitrit MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[0].ethtype);
8556de03d2dSErez Shitrit MLX5_SET(vlan, vlan, vid, fte->action.vlan[0].vid);
8566de03d2dSErez Shitrit MLX5_SET(vlan, vlan, prio, fte->action.vlan[0].prio);
8576de03d2dSErez Shitrit
8586de03d2dSErez Shitrit vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan_2);
8596de03d2dSErez Shitrit
8606de03d2dSErez Shitrit MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[1].ethtype);
8616de03d2dSErez Shitrit MLX5_SET(vlan, vlan, vid, fte->action.vlan[1].vid);
8626de03d2dSErez Shitrit MLX5_SET(vlan, vlan, prio, fte->action.vlan[1].prio);
8636de03d2dSErez Shitrit
8646de03d2dSErez Shitrit in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context,
8656de03d2dSErez Shitrit match_value);
8666de03d2dSErez Shitrit memcpy(in_match_value, fte->val, sizeof(u32) * MLX5_ST_SZ_DW_MATCH_PARAM);
8676de03d2dSErez Shitrit
8686de03d2dSErez Shitrit in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
8696de03d2dSErez Shitrit if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
8706de03d2dSErez Shitrit int list_size = 0;
8716de03d2dSErez Shitrit
8726de03d2dSErez Shitrit for (i = 0; i < fte->dests_size; i++) {
873d639af62SMark Bloch enum mlx5_flow_destination_type type = fte->dest_arr[i].type;
874d639af62SMark Bloch enum mlx5_ifc_flow_destination_type ifc_type;
875d639af62SMark Bloch unsigned int id;
8766de03d2dSErez Shitrit
8776de03d2dSErez Shitrit if (type == MLX5_FLOW_DESTINATION_TYPE_COUNTER)
8786de03d2dSErez Shitrit continue;
8796de03d2dSErez Shitrit
8806de03d2dSErez Shitrit switch (type) {
8816510bc0dSMark Bloch case MLX5_FLOW_DESTINATION_TYPE_NONE:
8826510bc0dSMark Bloch continue;
8836de03d2dSErez Shitrit case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM:
8846de03d2dSErez Shitrit id = fte->dest_arr[i].ft_num;
885d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_TABLE;
8866de03d2dSErez Shitrit break;
8876de03d2dSErez Shitrit case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE:
8886de03d2dSErez Shitrit id = fte->dest_arr[i].ft_id;
889d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_TABLE;
890d639af62SMark Bloch
8916de03d2dSErez Shitrit break;
892e3a0f40bSYevgeny Kliteynik case MLX5_FLOW_DESTINATION_TYPE_UPLINK:
8936de03d2dSErez Shitrit case MLX5_FLOW_DESTINATION_TYPE_VPORT:
894e3a0f40bSYevgeny Kliteynik if (type == MLX5_FLOW_DESTINATION_TYPE_VPORT) {
8956de03d2dSErez Shitrit id = fte->dest_arr[i].vport.num;
8966de03d2dSErez Shitrit MLX5_SET(dest_format_struct, in_dests,
8976de03d2dSErez Shitrit destination_eswitch_owner_vhca_id_valid,
8986de03d2dSErez Shitrit !!(fte->dest_arr[i].vport.flags &
8996de03d2dSErez Shitrit MLX5_FLOW_DEST_VPORT_VHCA_ID));
900d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_VPORT;
901e3a0f40bSYevgeny Kliteynik } else {
902e3a0f40bSYevgeny Kliteynik id = 0;
903d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_UPLINK;
904e3a0f40bSYevgeny Kliteynik MLX5_SET(dest_format_struct, in_dests,
905e3a0f40bSYevgeny Kliteynik destination_eswitch_owner_vhca_id_valid, 1);
906e3a0f40bSYevgeny Kliteynik }
9076de03d2dSErez Shitrit MLX5_SET(dest_format_struct, in_dests,
9086de03d2dSErez Shitrit destination_eswitch_owner_vhca_id,
9096de03d2dSErez Shitrit fte->dest_arr[i].vport.vhca_id);
9106de03d2dSErez Shitrit if (extended_dest && (fte->dest_arr[i].vport.flags &
9116de03d2dSErez Shitrit MLX5_FLOW_DEST_VPORT_REFORMAT_ID)) {
9126de03d2dSErez Shitrit MLX5_SET(dest_format_struct, in_dests,
9136de03d2dSErez Shitrit packet_reformat,
9146de03d2dSErez Shitrit !!(fte->dest_arr[i].vport.flags &
9156de03d2dSErez Shitrit MLX5_FLOW_DEST_VPORT_REFORMAT_ID));
9166de03d2dSErez Shitrit MLX5_SET(extended_dest_format, in_dests,
9176de03d2dSErez Shitrit packet_reformat_id,
9186de03d2dSErez Shitrit fte->dest_arr[i].vport.reformat_id);
9196de03d2dSErez Shitrit }
9206de03d2dSErez Shitrit break;
9211ab6dc35SYevgeny Kliteynik case MLX5_FLOW_DESTINATION_TYPE_FLOW_SAMPLER:
9221ab6dc35SYevgeny Kliteynik id = fte->dest_arr[i].sampler_id;
923d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_SAMPLER;
9241ab6dc35SYevgeny Kliteynik break;
9256de03d2dSErez Shitrit default:
9266de03d2dSErez Shitrit id = fte->dest_arr[i].tir_num;
927d639af62SMark Bloch ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_TIR;
9286de03d2dSErez Shitrit }
9296de03d2dSErez Shitrit
9306de03d2dSErez Shitrit MLX5_SET(dest_format_struct, in_dests, destination_type,
931d639af62SMark Bloch ifc_type);
9326de03d2dSErez Shitrit MLX5_SET(dest_format_struct, in_dests, destination_id, id);
9336de03d2dSErez Shitrit in_dests += dst_cnt_size;
9346de03d2dSErez Shitrit list_size++;
9356de03d2dSErez Shitrit }
9366de03d2dSErez Shitrit
9376de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, destination_list_size,
9386de03d2dSErez Shitrit list_size);
9396de03d2dSErez Shitrit }
9406de03d2dSErez Shitrit
9416de03d2dSErez Shitrit if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
9426de03d2dSErez Shitrit int max_list_size = BIT(MLX5_CAP_FLOWTABLE_TYPE(dev,
9436de03d2dSErez Shitrit log_max_flow_counter,
9446de03d2dSErez Shitrit ft->type));
9456de03d2dSErez Shitrit int list_size = 0;
9466de03d2dSErez Shitrit
9476de03d2dSErez Shitrit for (i = 0; i < fte->dests_size; i++) {
9486de03d2dSErez Shitrit if (fte->dest_arr[i].type !=
9496de03d2dSErez Shitrit MLX5_FLOW_DESTINATION_TYPE_COUNTER)
9506de03d2dSErez Shitrit continue;
9516de03d2dSErez Shitrit
9526de03d2dSErez Shitrit MLX5_SET(flow_counter_list, in_dests, flow_counter_id,
9536de03d2dSErez Shitrit fte->dest_arr[i].counter_id);
9546de03d2dSErez Shitrit in_dests += dst_cnt_size;
9556de03d2dSErez Shitrit list_size++;
9566de03d2dSErez Shitrit }
9576de03d2dSErez Shitrit if (list_size > max_list_size) {
9586de03d2dSErez Shitrit err = -EINVAL;
9596de03d2dSErez Shitrit goto err_out;
9606de03d2dSErez Shitrit }
9616de03d2dSErez Shitrit
9626de03d2dSErez Shitrit MLX5_SET(flow_context, in_flow_context, flow_counter_list_size,
9636de03d2dSErez Shitrit list_size);
9646de03d2dSErez Shitrit }
9656de03d2dSErez Shitrit
9666de03d2dSErez Shitrit err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
9676de03d2dSErez Shitrit err_out:
9686de03d2dSErez Shitrit kvfree(in);
9696de03d2dSErez Shitrit return err;
9706de03d2dSErez Shitrit }
971