0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/mlx5/driver.h>
0034 #include <linux/mlx5/device.h>
0035 #include <linux/mlx5/mlx5_ifc.h>
0036
0037 #include "fs_core.h"
0038 #include "fs_cmd.h"
0039 #include "fs_ft_pool.h"
0040 #include "mlx5_core.h"
0041 #include "eswitch.h"
0042
0043 static int mlx5_cmd_stub_update_root_ft(struct mlx5_flow_root_namespace *ns,
0044 struct mlx5_flow_table *ft,
0045 u32 underlay_qpn,
0046 bool disconnect)
0047 {
0048 return 0;
0049 }
0050
0051 static int mlx5_cmd_stub_create_flow_table(struct mlx5_flow_root_namespace *ns,
0052 struct mlx5_flow_table *ft,
0053 struct mlx5_flow_table_attr *ft_attr,
0054 struct mlx5_flow_table *next_ft)
0055 {
0056 int max_fte = ft_attr->max_fte;
0057
0058 ft->max_fte = max_fte ? roundup_pow_of_two(max_fte) : 1;
0059
0060 return 0;
0061 }
0062
0063 static int mlx5_cmd_stub_destroy_flow_table(struct mlx5_flow_root_namespace *ns,
0064 struct mlx5_flow_table *ft)
0065 {
0066 return 0;
0067 }
0068
0069 static int mlx5_cmd_stub_modify_flow_table(struct mlx5_flow_root_namespace *ns,
0070 struct mlx5_flow_table *ft,
0071 struct mlx5_flow_table *next_ft)
0072 {
0073 return 0;
0074 }
0075
0076 static int mlx5_cmd_stub_create_flow_group(struct mlx5_flow_root_namespace *ns,
0077 struct mlx5_flow_table *ft,
0078 u32 *in,
0079 struct mlx5_flow_group *fg)
0080 {
0081 return 0;
0082 }
0083
0084 static int mlx5_cmd_stub_destroy_flow_group(struct mlx5_flow_root_namespace *ns,
0085 struct mlx5_flow_table *ft,
0086 struct mlx5_flow_group *fg)
0087 {
0088 return 0;
0089 }
0090
0091 static int mlx5_cmd_stub_create_fte(struct mlx5_flow_root_namespace *ns,
0092 struct mlx5_flow_table *ft,
0093 struct mlx5_flow_group *group,
0094 struct fs_fte *fte)
0095 {
0096 return 0;
0097 }
0098
0099 static int mlx5_cmd_stub_update_fte(struct mlx5_flow_root_namespace *ns,
0100 struct mlx5_flow_table *ft,
0101 struct mlx5_flow_group *group,
0102 int modify_mask,
0103 struct fs_fte *fte)
0104 {
0105 return -EOPNOTSUPP;
0106 }
0107
0108 static int mlx5_cmd_stub_delete_fte(struct mlx5_flow_root_namespace *ns,
0109 struct mlx5_flow_table *ft,
0110 struct fs_fte *fte)
0111 {
0112 return 0;
0113 }
0114
0115 static int mlx5_cmd_stub_packet_reformat_alloc(struct mlx5_flow_root_namespace *ns,
0116 struct mlx5_pkt_reformat_params *params,
0117 enum mlx5_flow_namespace_type namespace,
0118 struct mlx5_pkt_reformat *pkt_reformat)
0119 {
0120 return 0;
0121 }
0122
0123 static void mlx5_cmd_stub_packet_reformat_dealloc(struct mlx5_flow_root_namespace *ns,
0124 struct mlx5_pkt_reformat *pkt_reformat)
0125 {
0126 }
0127
0128 static int mlx5_cmd_stub_modify_header_alloc(struct mlx5_flow_root_namespace *ns,
0129 u8 namespace, u8 num_actions,
0130 void *modify_actions,
0131 struct mlx5_modify_hdr *modify_hdr)
0132 {
0133 return 0;
0134 }
0135
0136 static void mlx5_cmd_stub_modify_header_dealloc(struct mlx5_flow_root_namespace *ns,
0137 struct mlx5_modify_hdr *modify_hdr)
0138 {
0139 }
0140
0141 static int mlx5_cmd_stub_set_peer(struct mlx5_flow_root_namespace *ns,
0142 struct mlx5_flow_root_namespace *peer_ns)
0143 {
0144 return 0;
0145 }
0146
0147 static int mlx5_cmd_stub_create_ns(struct mlx5_flow_root_namespace *ns)
0148 {
0149 return 0;
0150 }
0151
0152 static int mlx5_cmd_stub_destroy_ns(struct mlx5_flow_root_namespace *ns)
0153 {
0154 return 0;
0155 }
0156
0157 static u32 mlx5_cmd_stub_get_capabilities(struct mlx5_flow_root_namespace *ns,
0158 enum fs_flow_table_type ft_type)
0159 {
0160 return 0;
0161 }
0162
0163 static int mlx5_cmd_set_slave_root_fdb(struct mlx5_core_dev *master,
0164 struct mlx5_core_dev *slave,
0165 bool ft_id_valid,
0166 u32 ft_id)
0167 {
0168 u32 out[MLX5_ST_SZ_DW(set_flow_table_root_out)] = {};
0169 u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)] = {};
0170 struct mlx5_flow_root_namespace *root;
0171 struct mlx5_flow_namespace *ns;
0172
0173 MLX5_SET(set_flow_table_root_in, in, opcode,
0174 MLX5_CMD_OP_SET_FLOW_TABLE_ROOT);
0175 MLX5_SET(set_flow_table_root_in, in, table_type,
0176 FS_FT_FDB);
0177 if (ft_id_valid) {
0178 MLX5_SET(set_flow_table_root_in, in,
0179 table_eswitch_owner_vhca_id_valid, 1);
0180 MLX5_SET(set_flow_table_root_in, in,
0181 table_eswitch_owner_vhca_id,
0182 MLX5_CAP_GEN(master, vhca_id));
0183 MLX5_SET(set_flow_table_root_in, in, table_id,
0184 ft_id);
0185 } else {
0186 ns = mlx5_get_flow_namespace(slave,
0187 MLX5_FLOW_NAMESPACE_FDB);
0188 root = find_root(&ns->node);
0189 MLX5_SET(set_flow_table_root_in, in, table_id,
0190 root->root_ft->id);
0191 }
0192
0193 return mlx5_cmd_exec(slave, in, sizeof(in), out, sizeof(out));
0194 }
0195
0196 static int
0197 mlx5_cmd_stub_destroy_match_definer(struct mlx5_flow_root_namespace *ns,
0198 int definer_id)
0199 {
0200 return 0;
0201 }
0202
0203 static int
0204 mlx5_cmd_stub_create_match_definer(struct mlx5_flow_root_namespace *ns,
0205 u16 format_id, u32 *match_mask)
0206 {
0207 return 0;
0208 }
0209
0210 static int mlx5_cmd_update_root_ft(struct mlx5_flow_root_namespace *ns,
0211 struct mlx5_flow_table *ft, u32 underlay_qpn,
0212 bool disconnect)
0213 {
0214 u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)] = {};
0215 struct mlx5_core_dev *dev = ns->dev;
0216 int err;
0217
0218 if ((MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_IB) &&
0219 underlay_qpn == 0)
0220 return 0;
0221
0222 if (ft->type == FS_FT_FDB &&
0223 mlx5_lag_is_shared_fdb(dev) &&
0224 !mlx5_lag_is_master(dev))
0225 return 0;
0226
0227 MLX5_SET(set_flow_table_root_in, in, opcode,
0228 MLX5_CMD_OP_SET_FLOW_TABLE_ROOT);
0229 MLX5_SET(set_flow_table_root_in, in, table_type, ft->type);
0230
0231 if (disconnect)
0232 MLX5_SET(set_flow_table_root_in, in, op_mod, 1);
0233 else
0234 MLX5_SET(set_flow_table_root_in, in, table_id, ft->id);
0235
0236 MLX5_SET(set_flow_table_root_in, in, underlay_qpn, underlay_qpn);
0237 MLX5_SET(set_flow_table_root_in, in, vport_number, ft->vport);
0238 MLX5_SET(set_flow_table_root_in, in, other_vport,
0239 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
0240
0241 err = mlx5_cmd_exec_in(dev, set_flow_table_root, in);
0242 if (!err &&
0243 ft->type == FS_FT_FDB &&
0244 mlx5_lag_is_shared_fdb(dev) &&
0245 mlx5_lag_is_master(dev)) {
0246 err = mlx5_cmd_set_slave_root_fdb(dev,
0247 mlx5_lag_get_peer_mdev(dev),
0248 !disconnect, (!disconnect) ?
0249 ft->id : 0);
0250 if (err && !disconnect) {
0251 MLX5_SET(set_flow_table_root_in, in, op_mod, 0);
0252 MLX5_SET(set_flow_table_root_in, in, table_id,
0253 ns->root_ft->id);
0254 mlx5_cmd_exec_in(dev, set_flow_table_root, in);
0255 }
0256 }
0257
0258 return err;
0259 }
0260
0261 static int mlx5_cmd_create_flow_table(struct mlx5_flow_root_namespace *ns,
0262 struct mlx5_flow_table *ft,
0263 struct mlx5_flow_table_attr *ft_attr,
0264 struct mlx5_flow_table *next_ft)
0265 {
0266 int en_encap = !!(ft->flags & MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT);
0267 int en_decap = !!(ft->flags & MLX5_FLOW_TABLE_TUNNEL_EN_DECAP);
0268 int term = !!(ft->flags & MLX5_FLOW_TABLE_TERMINATION);
0269 u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {};
0270 u32 in[MLX5_ST_SZ_DW(create_flow_table_in)] = {};
0271 struct mlx5_core_dev *dev = ns->dev;
0272 unsigned int size;
0273 int err;
0274
0275 if (ft_attr->max_fte != POOL_NEXT_SIZE)
0276 size = roundup_pow_of_two(ft_attr->max_fte);
0277 size = mlx5_ft_pool_get_avail_sz(dev, ft->type, ft_attr->max_fte);
0278 if (!size)
0279 return -ENOSPC;
0280
0281 MLX5_SET(create_flow_table_in, in, opcode,
0282 MLX5_CMD_OP_CREATE_FLOW_TABLE);
0283
0284 MLX5_SET(create_flow_table_in, in, uid, ft_attr->uid);
0285 MLX5_SET(create_flow_table_in, in, table_type, ft->type);
0286 MLX5_SET(create_flow_table_in, in, flow_table_context.level, ft->level);
0287 MLX5_SET(create_flow_table_in, in, flow_table_context.log_size, size ? ilog2(size) : 0);
0288 MLX5_SET(create_flow_table_in, in, vport_number, ft->vport);
0289 MLX5_SET(create_flow_table_in, in, other_vport,
0290 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
0291
0292 MLX5_SET(create_flow_table_in, in, flow_table_context.decap_en,
0293 en_decap);
0294 MLX5_SET(create_flow_table_in, in, flow_table_context.reformat_en,
0295 en_encap);
0296 MLX5_SET(create_flow_table_in, in, flow_table_context.termination_table,
0297 term);
0298
0299 switch (ft->op_mod) {
0300 case FS_FT_OP_MOD_NORMAL:
0301 if (next_ft) {
0302 MLX5_SET(create_flow_table_in, in,
0303 flow_table_context.table_miss_action,
0304 MLX5_FLOW_TABLE_MISS_ACTION_FWD);
0305 MLX5_SET(create_flow_table_in, in,
0306 flow_table_context.table_miss_id, next_ft->id);
0307 } else {
0308 MLX5_SET(create_flow_table_in, in,
0309 flow_table_context.table_miss_action,
0310 ft->def_miss_action);
0311 }
0312 break;
0313
0314 case FS_FT_OP_MOD_LAG_DEMUX:
0315 MLX5_SET(create_flow_table_in, in, op_mod, 0x1);
0316 if (next_ft)
0317 MLX5_SET(create_flow_table_in, in,
0318 flow_table_context.lag_master_next_table_id,
0319 next_ft->id);
0320 break;
0321 }
0322
0323 err = mlx5_cmd_exec_inout(dev, create_flow_table, in, out);
0324 if (!err) {
0325 ft->id = MLX5_GET(create_flow_table_out, out,
0326 table_id);
0327 ft->max_fte = size;
0328 } else {
0329 mlx5_ft_pool_put_sz(ns->dev, size);
0330 }
0331
0332 return err;
0333 }
0334
0335 static int mlx5_cmd_destroy_flow_table(struct mlx5_flow_root_namespace *ns,
0336 struct mlx5_flow_table *ft)
0337 {
0338 u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)] = {};
0339 struct mlx5_core_dev *dev = ns->dev;
0340 int err;
0341
0342 MLX5_SET(destroy_flow_table_in, in, opcode,
0343 MLX5_CMD_OP_DESTROY_FLOW_TABLE);
0344 MLX5_SET(destroy_flow_table_in, in, table_type, ft->type);
0345 MLX5_SET(destroy_flow_table_in, in, table_id, ft->id);
0346 MLX5_SET(destroy_flow_table_in, in, vport_number, ft->vport);
0347 MLX5_SET(destroy_flow_table_in, in, other_vport,
0348 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
0349
0350 err = mlx5_cmd_exec_in(dev, destroy_flow_table, in);
0351 if (!err)
0352 mlx5_ft_pool_put_sz(ns->dev, ft->max_fte);
0353
0354 return err;
0355 }
0356
0357 static int mlx5_cmd_modify_flow_table(struct mlx5_flow_root_namespace *ns,
0358 struct mlx5_flow_table *ft,
0359 struct mlx5_flow_table *next_ft)
0360 {
0361 u32 in[MLX5_ST_SZ_DW(modify_flow_table_in)] = {};
0362 struct mlx5_core_dev *dev = ns->dev;
0363
0364 MLX5_SET(modify_flow_table_in, in, opcode,
0365 MLX5_CMD_OP_MODIFY_FLOW_TABLE);
0366 MLX5_SET(modify_flow_table_in, in, table_type, ft->type);
0367 MLX5_SET(modify_flow_table_in, in, table_id, ft->id);
0368
0369 if (ft->op_mod == FS_FT_OP_MOD_LAG_DEMUX) {
0370 MLX5_SET(modify_flow_table_in, in, modify_field_select,
0371 MLX5_MODIFY_FLOW_TABLE_LAG_NEXT_TABLE_ID);
0372 if (next_ft) {
0373 MLX5_SET(modify_flow_table_in, in,
0374 flow_table_context.lag_master_next_table_id, next_ft->id);
0375 } else {
0376 MLX5_SET(modify_flow_table_in, in,
0377 flow_table_context.lag_master_next_table_id, 0);
0378 }
0379 } else {
0380 MLX5_SET(modify_flow_table_in, in, vport_number, ft->vport);
0381 MLX5_SET(modify_flow_table_in, in, other_vport,
0382 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
0383 MLX5_SET(modify_flow_table_in, in, modify_field_select,
0384 MLX5_MODIFY_FLOW_TABLE_MISS_TABLE_ID);
0385 if (next_ft) {
0386 MLX5_SET(modify_flow_table_in, in,
0387 flow_table_context.table_miss_action,
0388 MLX5_FLOW_TABLE_MISS_ACTION_FWD);
0389 MLX5_SET(modify_flow_table_in, in,
0390 flow_table_context.table_miss_id,
0391 next_ft->id);
0392 } else {
0393 MLX5_SET(modify_flow_table_in, in,
0394 flow_table_context.table_miss_action,
0395 ft->def_miss_action);
0396 }
0397 }
0398
0399 return mlx5_cmd_exec_in(dev, modify_flow_table, in);
0400 }
0401
0402 static int mlx5_cmd_create_flow_group(struct mlx5_flow_root_namespace *ns,
0403 struct mlx5_flow_table *ft,
0404 u32 *in,
0405 struct mlx5_flow_group *fg)
0406 {
0407 u32 out[MLX5_ST_SZ_DW(create_flow_group_out)] = {};
0408 struct mlx5_core_dev *dev = ns->dev;
0409 int err;
0410
0411 MLX5_SET(create_flow_group_in, in, opcode,
0412 MLX5_CMD_OP_CREATE_FLOW_GROUP);
0413 MLX5_SET(create_flow_group_in, in, table_type, ft->type);
0414 MLX5_SET(create_flow_group_in, in, table_id, ft->id);
0415 if (ft->vport) {
0416 MLX5_SET(create_flow_group_in, in, vport_number, ft->vport);
0417 MLX5_SET(create_flow_group_in, in, other_vport, 1);
0418 }
0419
0420 MLX5_SET(create_flow_group_in, in, vport_number, ft->vport);
0421 MLX5_SET(create_flow_group_in, in, other_vport,
0422 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
0423 err = mlx5_cmd_exec_inout(dev, create_flow_group, in, out);
0424 if (!err)
0425 fg->id = MLX5_GET(create_flow_group_out, out,
0426 group_id);
0427 return err;
0428 }
0429
0430 static int mlx5_cmd_destroy_flow_group(struct mlx5_flow_root_namespace *ns,
0431 struct mlx5_flow_table *ft,
0432 struct mlx5_flow_group *fg)
0433 {
0434 u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)] = {};
0435 struct mlx5_core_dev *dev = ns->dev;
0436
0437 MLX5_SET(destroy_flow_group_in, in, opcode,
0438 MLX5_CMD_OP_DESTROY_FLOW_GROUP);
0439 MLX5_SET(destroy_flow_group_in, in, table_type, ft->type);
0440 MLX5_SET(destroy_flow_group_in, in, table_id, ft->id);
0441 MLX5_SET(destroy_flow_group_in, in, group_id, fg->id);
0442 MLX5_SET(destroy_flow_group_in, in, vport_number, ft->vport);
0443 MLX5_SET(destroy_flow_group_in, in, other_vport,
0444 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
0445 return mlx5_cmd_exec_in(dev, destroy_flow_group, in);
0446 }
0447
0448 static int mlx5_set_extended_dest(struct mlx5_core_dev *dev,
0449 struct fs_fte *fte, bool *extended_dest)
0450 {
0451 int fw_log_max_fdb_encap_uplink =
0452 MLX5_CAP_ESW(dev, log_max_fdb_encap_uplink);
0453 int num_fwd_destinations = 0;
0454 struct mlx5_flow_rule *dst;
0455 int num_encap = 0;
0456
0457 *extended_dest = false;
0458 if (!(fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST))
0459 return 0;
0460
0461 list_for_each_entry(dst, &fte->node.children, node.list) {
0462 if (dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER ||
0463 dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_NONE)
0464 continue;
0465 if ((dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_VPORT ||
0466 dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_UPLINK) &&
0467 dst->dest_attr.vport.flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID)
0468 num_encap++;
0469 num_fwd_destinations++;
0470 }
0471 if (num_fwd_destinations > 1 && num_encap > 0)
0472 *extended_dest = true;
0473
0474 if (*extended_dest && !fw_log_max_fdb_encap_uplink) {
0475 mlx5_core_warn(dev, "FW does not support extended destination");
0476 return -EOPNOTSUPP;
0477 }
0478 if (num_encap > (1 << fw_log_max_fdb_encap_uplink)) {
0479 mlx5_core_warn(dev, "FW does not support more than %d encaps",
0480 1 << fw_log_max_fdb_encap_uplink);
0481 return -EOPNOTSUPP;
0482 }
0483
0484 return 0;
0485 }
0486
0487 static void
0488 mlx5_cmd_set_fte_flow_meter(struct fs_fte *fte, void *in_flow_context)
0489 {
0490 void *exe_aso_ctrl;
0491 void *execute_aso;
0492
0493 execute_aso = MLX5_ADDR_OF(flow_context, in_flow_context,
0494 execute_aso[0]);
0495 MLX5_SET(execute_aso, execute_aso, valid, 1);
0496 MLX5_SET(execute_aso, execute_aso, aso_object_id,
0497 fte->action.exe_aso.object_id);
0498
0499 exe_aso_ctrl = MLX5_ADDR_OF(execute_aso, execute_aso, exe_aso_ctrl);
0500 MLX5_SET(exe_aso_ctrl_flow_meter, exe_aso_ctrl, return_reg_id,
0501 fte->action.exe_aso.return_reg_id);
0502 MLX5_SET(exe_aso_ctrl_flow_meter, exe_aso_ctrl, aso_type,
0503 fte->action.exe_aso.type);
0504 MLX5_SET(exe_aso_ctrl_flow_meter, exe_aso_ctrl, init_color,
0505 fte->action.exe_aso.flow_meter.init_color);
0506 MLX5_SET(exe_aso_ctrl_flow_meter, exe_aso_ctrl, meter_id,
0507 fte->action.exe_aso.flow_meter.meter_idx);
0508 }
0509
0510 static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
0511 int opmod, int modify_mask,
0512 struct mlx5_flow_table *ft,
0513 unsigned group_id,
0514 struct fs_fte *fte)
0515 {
0516 u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {0};
0517 bool extended_dest = false;
0518 struct mlx5_flow_rule *dst;
0519 void *in_flow_context, *vlan;
0520 void *in_match_value;
0521 unsigned int inlen;
0522 int dst_cnt_size;
0523 void *in_dests;
0524 u32 *in;
0525 int err;
0526
0527 if (mlx5_set_extended_dest(dev, fte, &extended_dest))
0528 return -EOPNOTSUPP;
0529
0530 if (!extended_dest)
0531 dst_cnt_size = MLX5_ST_SZ_BYTES(dest_format_struct);
0532 else
0533 dst_cnt_size = MLX5_ST_SZ_BYTES(extended_dest_format);
0534
0535 inlen = MLX5_ST_SZ_BYTES(set_fte_in) + fte->dests_size * dst_cnt_size;
0536 in = kvzalloc(inlen, GFP_KERNEL);
0537 if (!in)
0538 return -ENOMEM;
0539
0540 MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY);
0541 MLX5_SET(set_fte_in, in, op_mod, opmod);
0542 MLX5_SET(set_fte_in, in, modify_enable_mask, modify_mask);
0543 MLX5_SET(set_fte_in, in, table_type, ft->type);
0544 MLX5_SET(set_fte_in, in, table_id, ft->id);
0545 MLX5_SET(set_fte_in, in, flow_index, fte->index);
0546 MLX5_SET(set_fte_in, in, ignore_flow_level,
0547 !!(fte->action.flags & FLOW_ACT_IGNORE_FLOW_LEVEL));
0548
0549 MLX5_SET(set_fte_in, in, vport_number, ft->vport);
0550 MLX5_SET(set_fte_in, in, other_vport,
0551 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
0552
0553 in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
0554 MLX5_SET(flow_context, in_flow_context, group_id, group_id);
0555
0556 MLX5_SET(flow_context, in_flow_context, flow_tag,
0557 fte->flow_context.flow_tag);
0558 MLX5_SET(flow_context, in_flow_context, flow_source,
0559 fte->flow_context.flow_source);
0560
0561 MLX5_SET(flow_context, in_flow_context, extended_destination,
0562 extended_dest);
0563 if (extended_dest) {
0564 u32 action;
0565
0566 action = fte->action.action &
0567 ~MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
0568 MLX5_SET(flow_context, in_flow_context, action, action);
0569 } else {
0570 MLX5_SET(flow_context, in_flow_context, action,
0571 fte->action.action);
0572 if (fte->action.pkt_reformat)
0573 MLX5_SET(flow_context, in_flow_context, packet_reformat_id,
0574 fte->action.pkt_reformat->id);
0575 }
0576 if (fte->action.modify_hdr)
0577 MLX5_SET(flow_context, in_flow_context, modify_header_id,
0578 fte->action.modify_hdr->id);
0579
0580 MLX5_SET(flow_context, in_flow_context, ipsec_obj_id, fte->action.ipsec_obj_id);
0581
0582 vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan);
0583
0584 MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[0].ethtype);
0585 MLX5_SET(vlan, vlan, vid, fte->action.vlan[0].vid);
0586 MLX5_SET(vlan, vlan, prio, fte->action.vlan[0].prio);
0587
0588 vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan_2);
0589
0590 MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[1].ethtype);
0591 MLX5_SET(vlan, vlan, vid, fte->action.vlan[1].vid);
0592 MLX5_SET(vlan, vlan, prio, fte->action.vlan[1].prio);
0593
0594 in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context,
0595 match_value);
0596 memcpy(in_match_value, &fte->val, sizeof(fte->val));
0597
0598 in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
0599 if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
0600 int list_size = 0;
0601
0602 list_for_each_entry(dst, &fte->node.children, node.list) {
0603 enum mlx5_flow_destination_type type = dst->dest_attr.type;
0604 enum mlx5_ifc_flow_destination_type ifc_type;
0605 unsigned int id;
0606
0607 if (type == MLX5_FLOW_DESTINATION_TYPE_COUNTER)
0608 continue;
0609
0610 switch (type) {
0611 case MLX5_FLOW_DESTINATION_TYPE_NONE:
0612 continue;
0613 case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM:
0614 id = dst->dest_attr.ft_num;
0615 ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_TABLE;
0616 break;
0617 case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE:
0618 id = dst->dest_attr.ft->id;
0619 ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_TABLE;
0620 break;
0621 case MLX5_FLOW_DESTINATION_TYPE_UPLINK:
0622 case MLX5_FLOW_DESTINATION_TYPE_VPORT:
0623 MLX5_SET(dest_format_struct, in_dests,
0624 destination_eswitch_owner_vhca_id_valid,
0625 !!(dst->dest_attr.vport.flags &
0626 MLX5_FLOW_DEST_VPORT_VHCA_ID));
0627 MLX5_SET(dest_format_struct, in_dests,
0628 destination_eswitch_owner_vhca_id,
0629 dst->dest_attr.vport.vhca_id);
0630 if (type == MLX5_FLOW_DESTINATION_TYPE_UPLINK) {
0631
0632 id = 0;
0633 ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_UPLINK;
0634 break;
0635 }
0636 ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_VPORT;
0637 id = dst->dest_attr.vport.num;
0638 if (extended_dest &&
0639 dst->dest_attr.vport.pkt_reformat) {
0640 MLX5_SET(dest_format_struct, in_dests,
0641 packet_reformat,
0642 !!(dst->dest_attr.vport.flags &
0643 MLX5_FLOW_DEST_VPORT_REFORMAT_ID));
0644 MLX5_SET(extended_dest_format, in_dests,
0645 packet_reformat_id,
0646 dst->dest_attr.vport.pkt_reformat->id);
0647 }
0648 break;
0649 case MLX5_FLOW_DESTINATION_TYPE_FLOW_SAMPLER:
0650 id = dst->dest_attr.sampler_id;
0651 ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_SAMPLER;
0652 break;
0653 default:
0654 id = dst->dest_attr.tir_num;
0655 ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_TIR;
0656 }
0657
0658 MLX5_SET(dest_format_struct, in_dests, destination_type,
0659 ifc_type);
0660 MLX5_SET(dest_format_struct, in_dests, destination_id, id);
0661 in_dests += dst_cnt_size;
0662 list_size++;
0663 }
0664
0665 MLX5_SET(flow_context, in_flow_context, destination_list_size,
0666 list_size);
0667 }
0668
0669 if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
0670 int max_list_size = BIT(MLX5_CAP_FLOWTABLE_TYPE(dev,
0671 log_max_flow_counter,
0672 ft->type));
0673 int list_size = 0;
0674
0675 list_for_each_entry(dst, &fte->node.children, node.list) {
0676 if (dst->dest_attr.type !=
0677 MLX5_FLOW_DESTINATION_TYPE_COUNTER)
0678 continue;
0679
0680 MLX5_SET(flow_counter_list, in_dests, flow_counter_id,
0681 dst->dest_attr.counter_id);
0682 in_dests += dst_cnt_size;
0683 list_size++;
0684 }
0685 if (list_size > max_list_size) {
0686 err = -EINVAL;
0687 goto err_out;
0688 }
0689
0690 MLX5_SET(flow_context, in_flow_context, flow_counter_list_size,
0691 list_size);
0692 }
0693
0694 if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_EXECUTE_ASO) {
0695 if (fte->action.exe_aso.type == MLX5_EXE_ASO_FLOW_METER) {
0696 mlx5_cmd_set_fte_flow_meter(fte, in_flow_context);
0697 } else {
0698 err = -EOPNOTSUPP;
0699 goto err_out;
0700 }
0701 }
0702
0703 err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
0704 err_out:
0705 kvfree(in);
0706 return err;
0707 }
0708
0709 static int mlx5_cmd_create_fte(struct mlx5_flow_root_namespace *ns,
0710 struct mlx5_flow_table *ft,
0711 struct mlx5_flow_group *group,
0712 struct fs_fte *fte)
0713 {
0714 struct mlx5_core_dev *dev = ns->dev;
0715 unsigned int group_id = group->id;
0716
0717 return mlx5_cmd_set_fte(dev, 0, 0, ft, group_id, fte);
0718 }
0719
0720 static int mlx5_cmd_update_fte(struct mlx5_flow_root_namespace *ns,
0721 struct mlx5_flow_table *ft,
0722 struct mlx5_flow_group *fg,
0723 int modify_mask,
0724 struct fs_fte *fte)
0725 {
0726 int opmod;
0727 struct mlx5_core_dev *dev = ns->dev;
0728 int atomic_mod_cap = MLX5_CAP_FLOWTABLE(dev,
0729 flow_table_properties_nic_receive.
0730 flow_modify_en);
0731 if (!atomic_mod_cap)
0732 return -EOPNOTSUPP;
0733 opmod = 1;
0734
0735 return mlx5_cmd_set_fte(dev, opmod, modify_mask, ft, fg->id, fte);
0736 }
0737
0738 static int mlx5_cmd_delete_fte(struct mlx5_flow_root_namespace *ns,
0739 struct mlx5_flow_table *ft,
0740 struct fs_fte *fte)
0741 {
0742 u32 in[MLX5_ST_SZ_DW(delete_fte_in)] = {};
0743 struct mlx5_core_dev *dev = ns->dev;
0744
0745 MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY);
0746 MLX5_SET(delete_fte_in, in, table_type, ft->type);
0747 MLX5_SET(delete_fte_in, in, table_id, ft->id);
0748 MLX5_SET(delete_fte_in, in, flow_index, fte->index);
0749 MLX5_SET(delete_fte_in, in, vport_number, ft->vport);
0750 MLX5_SET(delete_fte_in, in, other_vport,
0751 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
0752
0753 return mlx5_cmd_exec_in(dev, delete_fte, in);
0754 }
0755
0756 int mlx5_cmd_fc_bulk_alloc(struct mlx5_core_dev *dev,
0757 enum mlx5_fc_bulk_alloc_bitmask alloc_bitmask,
0758 u32 *id)
0759 {
0760 u32 out[MLX5_ST_SZ_DW(alloc_flow_counter_out)] = {};
0761 u32 in[MLX5_ST_SZ_DW(alloc_flow_counter_in)] = {};
0762 int err;
0763
0764 MLX5_SET(alloc_flow_counter_in, in, opcode,
0765 MLX5_CMD_OP_ALLOC_FLOW_COUNTER);
0766 MLX5_SET(alloc_flow_counter_in, in, flow_counter_bulk, alloc_bitmask);
0767
0768 err = mlx5_cmd_exec_inout(dev, alloc_flow_counter, in, out);
0769 if (!err)
0770 *id = MLX5_GET(alloc_flow_counter_out, out, flow_counter_id);
0771 return err;
0772 }
0773
0774 int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u32 *id)
0775 {
0776 return mlx5_cmd_fc_bulk_alloc(dev, 0, id);
0777 }
0778
0779 int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u32 id)
0780 {
0781 u32 in[MLX5_ST_SZ_DW(dealloc_flow_counter_in)] = {};
0782
0783 MLX5_SET(dealloc_flow_counter_in, in, opcode,
0784 MLX5_CMD_OP_DEALLOC_FLOW_COUNTER);
0785 MLX5_SET(dealloc_flow_counter_in, in, flow_counter_id, id);
0786 return mlx5_cmd_exec_in(dev, dealloc_flow_counter, in);
0787 }
0788
0789 int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u32 id,
0790 u64 *packets, u64 *bytes)
0791 {
0792 u32 out[MLX5_ST_SZ_BYTES(query_flow_counter_out) +
0793 MLX5_ST_SZ_BYTES(traffic_counter)] = {};
0794 u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {};
0795 void *stats;
0796 int err = 0;
0797
0798 MLX5_SET(query_flow_counter_in, in, opcode,
0799 MLX5_CMD_OP_QUERY_FLOW_COUNTER);
0800 MLX5_SET(query_flow_counter_in, in, op_mod, 0);
0801 MLX5_SET(query_flow_counter_in, in, flow_counter_id, id);
0802 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
0803 if (err)
0804 return err;
0805
0806 stats = MLX5_ADDR_OF(query_flow_counter_out, out, flow_statistics);
0807 *packets = MLX5_GET64(traffic_counter, stats, packets);
0808 *bytes = MLX5_GET64(traffic_counter, stats, octets);
0809 return 0;
0810 }
0811
0812 int mlx5_cmd_fc_get_bulk_query_out_len(int bulk_len)
0813 {
0814 return MLX5_ST_SZ_BYTES(query_flow_counter_out) +
0815 MLX5_ST_SZ_BYTES(traffic_counter) * bulk_len;
0816 }
0817
0818 int mlx5_cmd_fc_bulk_query(struct mlx5_core_dev *dev, u32 base_id, int bulk_len,
0819 u32 *out)
0820 {
0821 int outlen = mlx5_cmd_fc_get_bulk_query_out_len(bulk_len);
0822 u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {};
0823
0824 MLX5_SET(query_flow_counter_in, in, opcode,
0825 MLX5_CMD_OP_QUERY_FLOW_COUNTER);
0826 MLX5_SET(query_flow_counter_in, in, flow_counter_id, base_id);
0827 MLX5_SET(query_flow_counter_in, in, num_of_counters, bulk_len);
0828 return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
0829 }
0830
0831 static int mlx5_cmd_packet_reformat_alloc(struct mlx5_flow_root_namespace *ns,
0832 struct mlx5_pkt_reformat_params *params,
0833 enum mlx5_flow_namespace_type namespace,
0834 struct mlx5_pkt_reformat *pkt_reformat)
0835 {
0836 u32 out[MLX5_ST_SZ_DW(alloc_packet_reformat_context_out)] = {};
0837 struct mlx5_core_dev *dev = ns->dev;
0838 void *packet_reformat_context_in;
0839 int max_encap_size;
0840 void *reformat;
0841 int inlen;
0842 int err;
0843 u32 *in;
0844
0845 if (namespace == MLX5_FLOW_NAMESPACE_FDB ||
0846 namespace == MLX5_FLOW_NAMESPACE_FDB_BYPASS)
0847 max_encap_size = MLX5_CAP_ESW(dev, max_encap_header_size);
0848 else
0849 max_encap_size = MLX5_CAP_FLOWTABLE(dev, max_encap_header_size);
0850
0851 if (params->size > max_encap_size) {
0852 mlx5_core_warn(dev, "encap size %zd too big, max supported is %d\n",
0853 params->size, max_encap_size);
0854 return -EINVAL;
0855 }
0856
0857 in = kzalloc(MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in) +
0858 params->size, GFP_KERNEL);
0859 if (!in)
0860 return -ENOMEM;
0861
0862 packet_reformat_context_in = MLX5_ADDR_OF(alloc_packet_reformat_context_in,
0863 in, packet_reformat_context);
0864 reformat = MLX5_ADDR_OF(packet_reformat_context_in,
0865 packet_reformat_context_in,
0866 reformat_data);
0867 inlen = reformat - (void *)in + params->size;
0868
0869 MLX5_SET(alloc_packet_reformat_context_in, in, opcode,
0870 MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT);
0871 MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
0872 reformat_data_size, params->size);
0873 MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
0874 reformat_type, params->type);
0875 MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
0876 reformat_param_0, params->param_0);
0877 MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
0878 reformat_param_1, params->param_1);
0879 if (params->data && params->size)
0880 memcpy(reformat, params->data, params->size);
0881
0882 err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
0883
0884 pkt_reformat->id = MLX5_GET(alloc_packet_reformat_context_out,
0885 out, packet_reformat_id);
0886 kfree(in);
0887 return err;
0888 }
0889
0890 static void mlx5_cmd_packet_reformat_dealloc(struct mlx5_flow_root_namespace *ns,
0891 struct mlx5_pkt_reformat *pkt_reformat)
0892 {
0893 u32 in[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_in)] = {};
0894 struct mlx5_core_dev *dev = ns->dev;
0895
0896 MLX5_SET(dealloc_packet_reformat_context_in, in, opcode,
0897 MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT);
0898 MLX5_SET(dealloc_packet_reformat_context_in, in, packet_reformat_id,
0899 pkt_reformat->id);
0900
0901 mlx5_cmd_exec_in(dev, dealloc_packet_reformat_context, in);
0902 }
0903
0904 static int mlx5_cmd_modify_header_alloc(struct mlx5_flow_root_namespace *ns,
0905 u8 namespace, u8 num_actions,
0906 void *modify_actions,
0907 struct mlx5_modify_hdr *modify_hdr)
0908 {
0909 u32 out[MLX5_ST_SZ_DW(alloc_modify_header_context_out)] = {};
0910 int max_actions, actions_size, inlen, err;
0911 struct mlx5_core_dev *dev = ns->dev;
0912 void *actions_in;
0913 u8 table_type;
0914 u32 *in;
0915
0916 switch (namespace) {
0917 case MLX5_FLOW_NAMESPACE_FDB:
0918 case MLX5_FLOW_NAMESPACE_FDB_BYPASS:
0919 max_actions = MLX5_CAP_ESW_FLOWTABLE_FDB(dev, max_modify_header_actions);
0920 table_type = FS_FT_FDB;
0921 break;
0922 case MLX5_FLOW_NAMESPACE_KERNEL:
0923 case MLX5_FLOW_NAMESPACE_BYPASS:
0924 max_actions = MLX5_CAP_FLOWTABLE_NIC_RX(dev, max_modify_header_actions);
0925 table_type = FS_FT_NIC_RX;
0926 break;
0927 case MLX5_FLOW_NAMESPACE_EGRESS:
0928 case MLX5_FLOW_NAMESPACE_EGRESS_KERNEL:
0929 max_actions = MLX5_CAP_FLOWTABLE_NIC_TX(dev, max_modify_header_actions);
0930 table_type = FS_FT_NIC_TX;
0931 break;
0932 case MLX5_FLOW_NAMESPACE_ESW_INGRESS:
0933 max_actions = MLX5_CAP_ESW_INGRESS_ACL(dev, max_modify_header_actions);
0934 table_type = FS_FT_ESW_INGRESS_ACL;
0935 break;
0936 case MLX5_FLOW_NAMESPACE_RDMA_TX:
0937 max_actions = MLX5_CAP_FLOWTABLE_RDMA_TX(dev, max_modify_header_actions);
0938 table_type = FS_FT_RDMA_TX;
0939 break;
0940 default:
0941 return -EOPNOTSUPP;
0942 }
0943
0944 if (num_actions > max_actions) {
0945 mlx5_core_warn(dev, "too many modify header actions %d, max supported %d\n",
0946 num_actions, max_actions);
0947 return -EOPNOTSUPP;
0948 }
0949
0950 actions_size = MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto) * num_actions;
0951 inlen = MLX5_ST_SZ_BYTES(alloc_modify_header_context_in) + actions_size;
0952
0953 in = kzalloc(inlen, GFP_KERNEL);
0954 if (!in)
0955 return -ENOMEM;
0956
0957 MLX5_SET(alloc_modify_header_context_in, in, opcode,
0958 MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT);
0959 MLX5_SET(alloc_modify_header_context_in, in, table_type, table_type);
0960 MLX5_SET(alloc_modify_header_context_in, in, num_of_actions, num_actions);
0961
0962 actions_in = MLX5_ADDR_OF(alloc_modify_header_context_in, in, actions);
0963 memcpy(actions_in, modify_actions, actions_size);
0964
0965 err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
0966
0967 modify_hdr->id = MLX5_GET(alloc_modify_header_context_out, out, modify_header_id);
0968 kfree(in);
0969 return err;
0970 }
0971
0972 static void mlx5_cmd_modify_header_dealloc(struct mlx5_flow_root_namespace *ns,
0973 struct mlx5_modify_hdr *modify_hdr)
0974 {
0975 u32 in[MLX5_ST_SZ_DW(dealloc_modify_header_context_in)] = {};
0976 struct mlx5_core_dev *dev = ns->dev;
0977
0978 MLX5_SET(dealloc_modify_header_context_in, in, opcode,
0979 MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT);
0980 MLX5_SET(dealloc_modify_header_context_in, in, modify_header_id,
0981 modify_hdr->id);
0982
0983 mlx5_cmd_exec_in(dev, dealloc_modify_header_context, in);
0984 }
0985
0986 static int mlx5_cmd_destroy_match_definer(struct mlx5_flow_root_namespace *ns,
0987 int definer_id)
0988 {
0989 u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};
0990 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
0991
0992 MLX5_SET(general_obj_in_cmd_hdr, in, opcode,
0993 MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
0994 MLX5_SET(general_obj_in_cmd_hdr, in, obj_type,
0995 MLX5_OBJ_TYPE_MATCH_DEFINER);
0996 MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, definer_id);
0997
0998 return mlx5_cmd_exec(ns->dev, in, sizeof(in), out, sizeof(out));
0999 }
1000
1001 static int mlx5_cmd_create_match_definer(struct mlx5_flow_root_namespace *ns,
1002 u16 format_id, u32 *match_mask)
1003 {
1004 u32 out[MLX5_ST_SZ_DW(create_match_definer_out)] = {};
1005 u32 in[MLX5_ST_SZ_DW(create_match_definer_in)] = {};
1006 struct mlx5_core_dev *dev = ns->dev;
1007 void *ptr;
1008 int err;
1009
1010 MLX5_SET(create_match_definer_in, in, general_obj_in_cmd_hdr.opcode,
1011 MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
1012 MLX5_SET(create_match_definer_in, in, general_obj_in_cmd_hdr.obj_type,
1013 MLX5_OBJ_TYPE_MATCH_DEFINER);
1014
1015 ptr = MLX5_ADDR_OF(create_match_definer_in, in, obj_context);
1016 MLX5_SET(match_definer, ptr, format_id, format_id);
1017
1018 ptr = MLX5_ADDR_OF(match_definer, ptr, match_mask);
1019 memcpy(ptr, match_mask, MLX5_FLD_SZ_BYTES(match_definer, match_mask));
1020
1021 err = mlx5_cmd_exec_inout(dev, create_match_definer, in, out);
1022 return err ? err : MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
1023 }
1024
1025 static u32 mlx5_cmd_get_capabilities(struct mlx5_flow_root_namespace *ns,
1026 enum fs_flow_table_type ft_type)
1027 {
1028 return 0;
1029 }
1030
1031 static const struct mlx5_flow_cmds mlx5_flow_cmds = {
1032 .create_flow_table = mlx5_cmd_create_flow_table,
1033 .destroy_flow_table = mlx5_cmd_destroy_flow_table,
1034 .modify_flow_table = mlx5_cmd_modify_flow_table,
1035 .create_flow_group = mlx5_cmd_create_flow_group,
1036 .destroy_flow_group = mlx5_cmd_destroy_flow_group,
1037 .create_fte = mlx5_cmd_create_fte,
1038 .update_fte = mlx5_cmd_update_fte,
1039 .delete_fte = mlx5_cmd_delete_fte,
1040 .update_root_ft = mlx5_cmd_update_root_ft,
1041 .packet_reformat_alloc = mlx5_cmd_packet_reformat_alloc,
1042 .packet_reformat_dealloc = mlx5_cmd_packet_reformat_dealloc,
1043 .modify_header_alloc = mlx5_cmd_modify_header_alloc,
1044 .modify_header_dealloc = mlx5_cmd_modify_header_dealloc,
1045 .create_match_definer = mlx5_cmd_create_match_definer,
1046 .destroy_match_definer = mlx5_cmd_destroy_match_definer,
1047 .set_peer = mlx5_cmd_stub_set_peer,
1048 .create_ns = mlx5_cmd_stub_create_ns,
1049 .destroy_ns = mlx5_cmd_stub_destroy_ns,
1050 .get_capabilities = mlx5_cmd_get_capabilities,
1051 };
1052
1053 static const struct mlx5_flow_cmds mlx5_flow_cmd_stubs = {
1054 .create_flow_table = mlx5_cmd_stub_create_flow_table,
1055 .destroy_flow_table = mlx5_cmd_stub_destroy_flow_table,
1056 .modify_flow_table = mlx5_cmd_stub_modify_flow_table,
1057 .create_flow_group = mlx5_cmd_stub_create_flow_group,
1058 .destroy_flow_group = mlx5_cmd_stub_destroy_flow_group,
1059 .create_fte = mlx5_cmd_stub_create_fte,
1060 .update_fte = mlx5_cmd_stub_update_fte,
1061 .delete_fte = mlx5_cmd_stub_delete_fte,
1062 .update_root_ft = mlx5_cmd_stub_update_root_ft,
1063 .packet_reformat_alloc = mlx5_cmd_stub_packet_reformat_alloc,
1064 .packet_reformat_dealloc = mlx5_cmd_stub_packet_reformat_dealloc,
1065 .modify_header_alloc = mlx5_cmd_stub_modify_header_alloc,
1066 .modify_header_dealloc = mlx5_cmd_stub_modify_header_dealloc,
1067 .create_match_definer = mlx5_cmd_stub_create_match_definer,
1068 .destroy_match_definer = mlx5_cmd_stub_destroy_match_definer,
1069 .set_peer = mlx5_cmd_stub_set_peer,
1070 .create_ns = mlx5_cmd_stub_create_ns,
1071 .destroy_ns = mlx5_cmd_stub_destroy_ns,
1072 .get_capabilities = mlx5_cmd_stub_get_capabilities,
1073 };
1074
1075 const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void)
1076 {
1077 return &mlx5_flow_cmds;
1078 }
1079
1080 static const struct mlx5_flow_cmds *mlx5_fs_cmd_get_stub_cmds(void)
1081 {
1082 return &mlx5_flow_cmd_stubs;
1083 }
1084
1085 const struct mlx5_flow_cmds *mlx5_fs_cmd_get_default(enum fs_flow_table_type type)
1086 {
1087 switch (type) {
1088 case FS_FT_NIC_RX:
1089 case FS_FT_ESW_EGRESS_ACL:
1090 case FS_FT_ESW_INGRESS_ACL:
1091 case FS_FT_FDB:
1092 case FS_FT_SNIFFER_RX:
1093 case FS_FT_SNIFFER_TX:
1094 case FS_FT_NIC_TX:
1095 case FS_FT_RDMA_RX:
1096 case FS_FT_RDMA_TX:
1097 case FS_FT_PORT_SEL:
1098 return mlx5_fs_cmd_get_fw_cmds();
1099 default:
1100 return mlx5_fs_cmd_get_stub_cmds();
1101 }
1102 }