cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fs_cmd.c (33783B)


      1/*
      2 * Copyright (c) 2015, Mellanox Technologies. All rights reserved.
      3 *
      4 * This software is available to you under a choice of one of two
      5 * licenses.  You may choose to be licensed under the terms of the GNU
      6 * General Public License (GPL) Version 2, available from the file
      7 * COPYING in the main directory of this source tree, or the
      8 * OpenIB.org BSD license below:
      9 *
     10 *     Redistribution and use in source and binary forms, with or
     11 *     without modification, are permitted provided that the following
     12 *     conditions are met:
     13 *
     14 *      - Redistributions of source code must retain the above
     15 *        copyright notice, this list of conditions and the following
     16 *        disclaimer.
     17 *
     18 *      - Redistributions in binary form must reproduce the above
     19 *        copyright notice, this list of conditions and the following
     20 *        disclaimer in the documentation and/or other materials
     21 *        provided with the distribution.
     22 *
     23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     30 * SOFTWARE.
     31 */
     32
     33#include <linux/mlx5/driver.h>
     34#include <linux/mlx5/device.h>
     35#include <linux/mlx5/mlx5_ifc.h>
     36
     37#include "fs_core.h"
     38#include "fs_cmd.h"
     39#include "fs_ft_pool.h"
     40#include "mlx5_core.h"
     41#include "eswitch.h"
     42
     43static int mlx5_cmd_stub_update_root_ft(struct mlx5_flow_root_namespace *ns,
     44					struct mlx5_flow_table *ft,
     45					u32 underlay_qpn,
     46					bool disconnect)
     47{
     48	return 0;
     49}
     50
     51static int mlx5_cmd_stub_create_flow_table(struct mlx5_flow_root_namespace *ns,
     52					   struct mlx5_flow_table *ft,
     53					   unsigned int size,
     54					   struct mlx5_flow_table *next_ft)
     55{
     56	ft->max_fte = size ? roundup_pow_of_two(size) : 1;
     57
     58	return 0;
     59}
     60
     61static int mlx5_cmd_stub_destroy_flow_table(struct mlx5_flow_root_namespace *ns,
     62					    struct mlx5_flow_table *ft)
     63{
     64	return 0;
     65}
     66
     67static int mlx5_cmd_stub_modify_flow_table(struct mlx5_flow_root_namespace *ns,
     68					   struct mlx5_flow_table *ft,
     69					   struct mlx5_flow_table *next_ft)
     70{
     71	return 0;
     72}
     73
     74static int mlx5_cmd_stub_create_flow_group(struct mlx5_flow_root_namespace *ns,
     75					   struct mlx5_flow_table *ft,
     76					   u32 *in,
     77					   struct mlx5_flow_group *fg)
     78{
     79	return 0;
     80}
     81
     82static int mlx5_cmd_stub_destroy_flow_group(struct mlx5_flow_root_namespace *ns,
     83					    struct mlx5_flow_table *ft,
     84					    struct mlx5_flow_group *fg)
     85{
     86	return 0;
     87}
     88
     89static int mlx5_cmd_stub_create_fte(struct mlx5_flow_root_namespace *ns,
     90				    struct mlx5_flow_table *ft,
     91				    struct mlx5_flow_group *group,
     92				    struct fs_fte *fte)
     93{
     94	return 0;
     95}
     96
     97static int mlx5_cmd_stub_update_fte(struct mlx5_flow_root_namespace *ns,
     98				    struct mlx5_flow_table *ft,
     99				    struct mlx5_flow_group *group,
    100				    int modify_mask,
    101				    struct fs_fte *fte)
    102{
    103	return -EOPNOTSUPP;
    104}
    105
    106static int mlx5_cmd_stub_delete_fte(struct mlx5_flow_root_namespace *ns,
    107				    struct mlx5_flow_table *ft,
    108				    struct fs_fte *fte)
    109{
    110	return 0;
    111}
    112
    113static int mlx5_cmd_stub_packet_reformat_alloc(struct mlx5_flow_root_namespace *ns,
    114					       struct mlx5_pkt_reformat_params *params,
    115					       enum mlx5_flow_namespace_type namespace,
    116					       struct mlx5_pkt_reformat *pkt_reformat)
    117{
    118	return 0;
    119}
    120
    121static void mlx5_cmd_stub_packet_reformat_dealloc(struct mlx5_flow_root_namespace *ns,
    122						  struct mlx5_pkt_reformat *pkt_reformat)
    123{
    124}
    125
    126static int mlx5_cmd_stub_modify_header_alloc(struct mlx5_flow_root_namespace *ns,
    127					     u8 namespace, u8 num_actions,
    128					     void *modify_actions,
    129					     struct mlx5_modify_hdr *modify_hdr)
    130{
    131	return 0;
    132}
    133
    134static void mlx5_cmd_stub_modify_header_dealloc(struct mlx5_flow_root_namespace *ns,
    135						struct mlx5_modify_hdr *modify_hdr)
    136{
    137}
    138
    139static int mlx5_cmd_stub_set_peer(struct mlx5_flow_root_namespace *ns,
    140				  struct mlx5_flow_root_namespace *peer_ns)
    141{
    142	return 0;
    143}
    144
    145static int mlx5_cmd_stub_create_ns(struct mlx5_flow_root_namespace *ns)
    146{
    147	return 0;
    148}
    149
    150static int mlx5_cmd_stub_destroy_ns(struct mlx5_flow_root_namespace *ns)
    151{
    152	return 0;
    153}
    154
    155static u32 mlx5_cmd_stub_get_capabilities(struct mlx5_flow_root_namespace *ns,
    156					  enum fs_flow_table_type ft_type)
    157{
    158	return 0;
    159}
    160
    161static int mlx5_cmd_set_slave_root_fdb(struct mlx5_core_dev *master,
    162				       struct mlx5_core_dev *slave,
    163				       bool ft_id_valid,
    164				       u32 ft_id)
    165{
    166	u32 out[MLX5_ST_SZ_DW(set_flow_table_root_out)] = {};
    167	u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)] = {};
    168	struct mlx5_flow_root_namespace *root;
    169	struct mlx5_flow_namespace *ns;
    170
    171	MLX5_SET(set_flow_table_root_in, in, opcode,
    172		 MLX5_CMD_OP_SET_FLOW_TABLE_ROOT);
    173	MLX5_SET(set_flow_table_root_in, in, table_type,
    174		 FS_FT_FDB);
    175	if (ft_id_valid) {
    176		MLX5_SET(set_flow_table_root_in, in,
    177			 table_eswitch_owner_vhca_id_valid, 1);
    178		MLX5_SET(set_flow_table_root_in, in,
    179			 table_eswitch_owner_vhca_id,
    180			 MLX5_CAP_GEN(master, vhca_id));
    181		MLX5_SET(set_flow_table_root_in, in, table_id,
    182			 ft_id);
    183	} else {
    184		ns = mlx5_get_flow_namespace(slave,
    185					     MLX5_FLOW_NAMESPACE_FDB);
    186		root = find_root(&ns->node);
    187		MLX5_SET(set_flow_table_root_in, in, table_id,
    188			 root->root_ft->id);
    189	}
    190
    191	return mlx5_cmd_exec(slave, in, sizeof(in), out, sizeof(out));
    192}
    193
    194static int
    195mlx5_cmd_stub_destroy_match_definer(struct mlx5_flow_root_namespace *ns,
    196				    int definer_id)
    197{
    198	return 0;
    199}
    200
    201static int
    202mlx5_cmd_stub_create_match_definer(struct mlx5_flow_root_namespace *ns,
    203				   u16 format_id, u32 *match_mask)
    204{
    205	return 0;
    206}
    207
    208static int mlx5_cmd_update_root_ft(struct mlx5_flow_root_namespace *ns,
    209				   struct mlx5_flow_table *ft, u32 underlay_qpn,
    210				   bool disconnect)
    211{
    212	u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)] = {};
    213	struct mlx5_core_dev *dev = ns->dev;
    214	int err;
    215
    216	if ((MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_IB) &&
    217	    underlay_qpn == 0)
    218		return 0;
    219
    220	if (ft->type == FS_FT_FDB &&
    221	    mlx5_lag_is_shared_fdb(dev) &&
    222	    !mlx5_lag_is_master(dev))
    223		return 0;
    224
    225	MLX5_SET(set_flow_table_root_in, in, opcode,
    226		 MLX5_CMD_OP_SET_FLOW_TABLE_ROOT);
    227	MLX5_SET(set_flow_table_root_in, in, table_type, ft->type);
    228
    229	if (disconnect)
    230		MLX5_SET(set_flow_table_root_in, in, op_mod, 1);
    231	else
    232		MLX5_SET(set_flow_table_root_in, in, table_id, ft->id);
    233
    234	MLX5_SET(set_flow_table_root_in, in, underlay_qpn, underlay_qpn);
    235	MLX5_SET(set_flow_table_root_in, in, vport_number, ft->vport);
    236	MLX5_SET(set_flow_table_root_in, in, other_vport,
    237		 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
    238
    239	err = mlx5_cmd_exec_in(dev, set_flow_table_root, in);
    240	if (!err &&
    241	    ft->type == FS_FT_FDB &&
    242	    mlx5_lag_is_shared_fdb(dev) &&
    243	    mlx5_lag_is_master(dev)) {
    244		err = mlx5_cmd_set_slave_root_fdb(dev,
    245						  mlx5_lag_get_peer_mdev(dev),
    246						  !disconnect, (!disconnect) ?
    247						  ft->id : 0);
    248		if (err && !disconnect) {
    249			MLX5_SET(set_flow_table_root_in, in, op_mod, 0);
    250			MLX5_SET(set_flow_table_root_in, in, table_id,
    251				 ns->root_ft->id);
    252			mlx5_cmd_exec_in(dev, set_flow_table_root, in);
    253		}
    254	}
    255
    256	return err;
    257}
    258
    259static int mlx5_cmd_create_flow_table(struct mlx5_flow_root_namespace *ns,
    260				      struct mlx5_flow_table *ft,
    261				      unsigned int size,
    262				      struct mlx5_flow_table *next_ft)
    263{
    264	int en_encap = !!(ft->flags & MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT);
    265	int en_decap = !!(ft->flags & MLX5_FLOW_TABLE_TUNNEL_EN_DECAP);
    266	int term = !!(ft->flags & MLX5_FLOW_TABLE_TERMINATION);
    267	u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {};
    268	u32 in[MLX5_ST_SZ_DW(create_flow_table_in)] = {};
    269	struct mlx5_core_dev *dev = ns->dev;
    270	int err;
    271
    272	if (size != POOL_NEXT_SIZE)
    273		size = roundup_pow_of_two(size);
    274	size = mlx5_ft_pool_get_avail_sz(dev, ft->type, size);
    275	if (!size)
    276		return -ENOSPC;
    277
    278	MLX5_SET(create_flow_table_in, in, opcode,
    279		 MLX5_CMD_OP_CREATE_FLOW_TABLE);
    280
    281	MLX5_SET(create_flow_table_in, in, table_type, ft->type);
    282	MLX5_SET(create_flow_table_in, in, flow_table_context.level, ft->level);
    283	MLX5_SET(create_flow_table_in, in, flow_table_context.log_size, size ? ilog2(size) : 0);
    284	MLX5_SET(create_flow_table_in, in, vport_number, ft->vport);
    285	MLX5_SET(create_flow_table_in, in, other_vport,
    286		 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
    287
    288	MLX5_SET(create_flow_table_in, in, flow_table_context.decap_en,
    289		 en_decap);
    290	MLX5_SET(create_flow_table_in, in, flow_table_context.reformat_en,
    291		 en_encap);
    292	MLX5_SET(create_flow_table_in, in, flow_table_context.termination_table,
    293		 term);
    294
    295	switch (ft->op_mod) {
    296	case FS_FT_OP_MOD_NORMAL:
    297		if (next_ft) {
    298			MLX5_SET(create_flow_table_in, in,
    299				 flow_table_context.table_miss_action,
    300				 MLX5_FLOW_TABLE_MISS_ACTION_FWD);
    301			MLX5_SET(create_flow_table_in, in,
    302				 flow_table_context.table_miss_id, next_ft->id);
    303		} else {
    304			MLX5_SET(create_flow_table_in, in,
    305				 flow_table_context.table_miss_action,
    306				 ft->def_miss_action);
    307		}
    308		break;
    309
    310	case FS_FT_OP_MOD_LAG_DEMUX:
    311		MLX5_SET(create_flow_table_in, in, op_mod, 0x1);
    312		if (next_ft)
    313			MLX5_SET(create_flow_table_in, in,
    314				 flow_table_context.lag_master_next_table_id,
    315				 next_ft->id);
    316		break;
    317	}
    318
    319	err = mlx5_cmd_exec_inout(dev, create_flow_table, in, out);
    320	if (!err) {
    321		ft->id = MLX5_GET(create_flow_table_out, out,
    322				  table_id);
    323		ft->max_fte = size;
    324	} else {
    325		mlx5_ft_pool_put_sz(ns->dev, size);
    326	}
    327
    328	return err;
    329}
    330
    331static int mlx5_cmd_destroy_flow_table(struct mlx5_flow_root_namespace *ns,
    332				       struct mlx5_flow_table *ft)
    333{
    334	u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)] = {};
    335	struct mlx5_core_dev *dev = ns->dev;
    336	int err;
    337
    338	MLX5_SET(destroy_flow_table_in, in, opcode,
    339		 MLX5_CMD_OP_DESTROY_FLOW_TABLE);
    340	MLX5_SET(destroy_flow_table_in, in, table_type, ft->type);
    341	MLX5_SET(destroy_flow_table_in, in, table_id, ft->id);
    342	MLX5_SET(destroy_flow_table_in, in, vport_number, ft->vport);
    343	MLX5_SET(destroy_flow_table_in, in, other_vport,
    344		 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
    345
    346	err = mlx5_cmd_exec_in(dev, destroy_flow_table, in);
    347	if (!err)
    348		mlx5_ft_pool_put_sz(ns->dev, ft->max_fte);
    349
    350	return err;
    351}
    352
    353static int mlx5_cmd_modify_flow_table(struct mlx5_flow_root_namespace *ns,
    354				      struct mlx5_flow_table *ft,
    355				      struct mlx5_flow_table *next_ft)
    356{
    357	u32 in[MLX5_ST_SZ_DW(modify_flow_table_in)] = {};
    358	struct mlx5_core_dev *dev = ns->dev;
    359
    360	MLX5_SET(modify_flow_table_in, in, opcode,
    361		 MLX5_CMD_OP_MODIFY_FLOW_TABLE);
    362	MLX5_SET(modify_flow_table_in, in, table_type, ft->type);
    363	MLX5_SET(modify_flow_table_in, in, table_id, ft->id);
    364
    365	if (ft->op_mod == FS_FT_OP_MOD_LAG_DEMUX) {
    366		MLX5_SET(modify_flow_table_in, in, modify_field_select,
    367			 MLX5_MODIFY_FLOW_TABLE_LAG_NEXT_TABLE_ID);
    368		if (next_ft) {
    369			MLX5_SET(modify_flow_table_in, in,
    370				 flow_table_context.lag_master_next_table_id, next_ft->id);
    371		} else {
    372			MLX5_SET(modify_flow_table_in, in,
    373				 flow_table_context.lag_master_next_table_id, 0);
    374		}
    375	} else {
    376		MLX5_SET(modify_flow_table_in, in, vport_number, ft->vport);
    377		MLX5_SET(modify_flow_table_in, in, other_vport,
    378			 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
    379		MLX5_SET(modify_flow_table_in, in, modify_field_select,
    380			 MLX5_MODIFY_FLOW_TABLE_MISS_TABLE_ID);
    381		if (next_ft) {
    382			MLX5_SET(modify_flow_table_in, in,
    383				 flow_table_context.table_miss_action,
    384				 MLX5_FLOW_TABLE_MISS_ACTION_FWD);
    385			MLX5_SET(modify_flow_table_in, in,
    386				 flow_table_context.table_miss_id,
    387				 next_ft->id);
    388		} else {
    389			MLX5_SET(modify_flow_table_in, in,
    390				 flow_table_context.table_miss_action,
    391				 ft->def_miss_action);
    392		}
    393	}
    394
    395	return mlx5_cmd_exec_in(dev, modify_flow_table, in);
    396}
    397
    398static int mlx5_cmd_create_flow_group(struct mlx5_flow_root_namespace *ns,
    399				      struct mlx5_flow_table *ft,
    400				      u32 *in,
    401				      struct mlx5_flow_group *fg)
    402{
    403	u32 out[MLX5_ST_SZ_DW(create_flow_group_out)] = {};
    404	struct mlx5_core_dev *dev = ns->dev;
    405	int err;
    406
    407	MLX5_SET(create_flow_group_in, in, opcode,
    408		 MLX5_CMD_OP_CREATE_FLOW_GROUP);
    409	MLX5_SET(create_flow_group_in, in, table_type, ft->type);
    410	MLX5_SET(create_flow_group_in, in, table_id, ft->id);
    411	if (ft->vport) {
    412		MLX5_SET(create_flow_group_in, in, vport_number, ft->vport);
    413		MLX5_SET(create_flow_group_in, in, other_vport, 1);
    414	}
    415
    416	MLX5_SET(create_flow_group_in, in, vport_number, ft->vport);
    417	MLX5_SET(create_flow_group_in, in, other_vport,
    418		 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
    419	err = mlx5_cmd_exec_inout(dev, create_flow_group, in, out);
    420	if (!err)
    421		fg->id = MLX5_GET(create_flow_group_out, out,
    422				  group_id);
    423	return err;
    424}
    425
    426static int mlx5_cmd_destroy_flow_group(struct mlx5_flow_root_namespace *ns,
    427				       struct mlx5_flow_table *ft,
    428				       struct mlx5_flow_group *fg)
    429{
    430	u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)] = {};
    431	struct mlx5_core_dev *dev = ns->dev;
    432
    433	MLX5_SET(destroy_flow_group_in, in, opcode,
    434		 MLX5_CMD_OP_DESTROY_FLOW_GROUP);
    435	MLX5_SET(destroy_flow_group_in, in, table_type, ft->type);
    436	MLX5_SET(destroy_flow_group_in, in, table_id, ft->id);
    437	MLX5_SET(destroy_flow_group_in, in, group_id, fg->id);
    438	MLX5_SET(destroy_flow_group_in, in, vport_number, ft->vport);
    439	MLX5_SET(destroy_flow_group_in, in, other_vport,
    440		 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
    441	return mlx5_cmd_exec_in(dev, destroy_flow_group, in);
    442}
    443
    444static int mlx5_set_extended_dest(struct mlx5_core_dev *dev,
    445				  struct fs_fte *fte, bool *extended_dest)
    446{
    447	int fw_log_max_fdb_encap_uplink =
    448		MLX5_CAP_ESW(dev, log_max_fdb_encap_uplink);
    449	int num_fwd_destinations = 0;
    450	struct mlx5_flow_rule *dst;
    451	int num_encap = 0;
    452
    453	*extended_dest = false;
    454	if (!(fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST))
    455		return 0;
    456
    457	list_for_each_entry(dst, &fte->node.children, node.list) {
    458		if (dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER ||
    459		    dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_NONE)
    460			continue;
    461		if ((dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_VPORT ||
    462		     dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_UPLINK) &&
    463		    dst->dest_attr.vport.flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID)
    464			num_encap++;
    465		num_fwd_destinations++;
    466	}
    467	if (num_fwd_destinations > 1 && num_encap > 0)
    468		*extended_dest = true;
    469
    470	if (*extended_dest && !fw_log_max_fdb_encap_uplink) {
    471		mlx5_core_warn(dev, "FW does not support extended destination");
    472		return -EOPNOTSUPP;
    473	}
    474	if (num_encap > (1 << fw_log_max_fdb_encap_uplink)) {
    475		mlx5_core_warn(dev, "FW does not support more than %d encaps",
    476			       1 << fw_log_max_fdb_encap_uplink);
    477		return -EOPNOTSUPP;
    478	}
    479
    480	return 0;
    481}
    482static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
    483			    int opmod, int modify_mask,
    484			    struct mlx5_flow_table *ft,
    485			    unsigned group_id,
    486			    struct fs_fte *fte)
    487{
    488	u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {0};
    489	bool extended_dest = false;
    490	struct mlx5_flow_rule *dst;
    491	void *in_flow_context, *vlan;
    492	void *in_match_value;
    493	unsigned int inlen;
    494	int dst_cnt_size;
    495	void *in_dests;
    496	u32 *in;
    497	int err;
    498
    499	if (mlx5_set_extended_dest(dev, fte, &extended_dest))
    500		return -EOPNOTSUPP;
    501
    502	if (!extended_dest)
    503		dst_cnt_size = MLX5_ST_SZ_BYTES(dest_format_struct);
    504	else
    505		dst_cnt_size = MLX5_ST_SZ_BYTES(extended_dest_format);
    506
    507	inlen = MLX5_ST_SZ_BYTES(set_fte_in) + fte->dests_size * dst_cnt_size;
    508	in = kvzalloc(inlen, GFP_KERNEL);
    509	if (!in)
    510		return -ENOMEM;
    511
    512	MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY);
    513	MLX5_SET(set_fte_in, in, op_mod, opmod);
    514	MLX5_SET(set_fte_in, in, modify_enable_mask, modify_mask);
    515	MLX5_SET(set_fte_in, in, table_type, ft->type);
    516	MLX5_SET(set_fte_in, in, table_id,   ft->id);
    517	MLX5_SET(set_fte_in, in, flow_index, fte->index);
    518	MLX5_SET(set_fte_in, in, ignore_flow_level,
    519		 !!(fte->action.flags & FLOW_ACT_IGNORE_FLOW_LEVEL));
    520
    521	MLX5_SET(set_fte_in, in, vport_number, ft->vport);
    522	MLX5_SET(set_fte_in, in, other_vport,
    523		 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
    524
    525	in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
    526	MLX5_SET(flow_context, in_flow_context, group_id, group_id);
    527
    528	MLX5_SET(flow_context, in_flow_context, flow_tag,
    529		 fte->flow_context.flow_tag);
    530	MLX5_SET(flow_context, in_flow_context, flow_source,
    531		 fte->flow_context.flow_source);
    532
    533	MLX5_SET(flow_context, in_flow_context, extended_destination,
    534		 extended_dest);
    535	if (extended_dest) {
    536		u32 action;
    537
    538		action = fte->action.action &
    539			~MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
    540		MLX5_SET(flow_context, in_flow_context, action, action);
    541	} else {
    542		MLX5_SET(flow_context, in_flow_context, action,
    543			 fte->action.action);
    544		if (fte->action.pkt_reformat)
    545			MLX5_SET(flow_context, in_flow_context, packet_reformat_id,
    546				 fte->action.pkt_reformat->id);
    547	}
    548	if (fte->action.modify_hdr)
    549		MLX5_SET(flow_context, in_flow_context, modify_header_id,
    550			 fte->action.modify_hdr->id);
    551
    552	MLX5_SET(flow_context, in_flow_context, ipsec_obj_id, fte->action.ipsec_obj_id);
    553
    554	vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan);
    555
    556	MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[0].ethtype);
    557	MLX5_SET(vlan, vlan, vid, fte->action.vlan[0].vid);
    558	MLX5_SET(vlan, vlan, prio, fte->action.vlan[0].prio);
    559
    560	vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan_2);
    561
    562	MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[1].ethtype);
    563	MLX5_SET(vlan, vlan, vid, fte->action.vlan[1].vid);
    564	MLX5_SET(vlan, vlan, prio, fte->action.vlan[1].prio);
    565
    566	in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context,
    567				      match_value);
    568	memcpy(in_match_value, &fte->val, sizeof(fte->val));
    569
    570	in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
    571	if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
    572		int list_size = 0;
    573
    574		list_for_each_entry(dst, &fte->node.children, node.list) {
    575			enum mlx5_flow_destination_type type = dst->dest_attr.type;
    576			enum mlx5_ifc_flow_destination_type ifc_type;
    577			unsigned int id;
    578
    579			if (type == MLX5_FLOW_DESTINATION_TYPE_COUNTER)
    580				continue;
    581
    582			switch (type) {
    583			case MLX5_FLOW_DESTINATION_TYPE_NONE:
    584				continue;
    585			case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM:
    586				id = dst->dest_attr.ft_num;
    587				ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_TABLE;
    588				break;
    589			case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE:
    590				id = dst->dest_attr.ft->id;
    591				ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_TABLE;
    592				break;
    593			case MLX5_FLOW_DESTINATION_TYPE_UPLINK:
    594			case MLX5_FLOW_DESTINATION_TYPE_VPORT:
    595				MLX5_SET(dest_format_struct, in_dests,
    596					 destination_eswitch_owner_vhca_id_valid,
    597					 !!(dst->dest_attr.vport.flags &
    598					    MLX5_FLOW_DEST_VPORT_VHCA_ID));
    599				MLX5_SET(dest_format_struct, in_dests,
    600					 destination_eswitch_owner_vhca_id,
    601					 dst->dest_attr.vport.vhca_id);
    602				if (type == MLX5_FLOW_DESTINATION_TYPE_UPLINK) {
    603					/* destination_id is reserved */
    604					id = 0;
    605					ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_UPLINK;
    606					break;
    607				}
    608				ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_VPORT;
    609				id = dst->dest_attr.vport.num;
    610				if (extended_dest &&
    611				    dst->dest_attr.vport.pkt_reformat) {
    612					MLX5_SET(dest_format_struct, in_dests,
    613						 packet_reformat,
    614						 !!(dst->dest_attr.vport.flags &
    615						    MLX5_FLOW_DEST_VPORT_REFORMAT_ID));
    616					MLX5_SET(extended_dest_format, in_dests,
    617						 packet_reformat_id,
    618						 dst->dest_attr.vport.pkt_reformat->id);
    619				}
    620				break;
    621			case MLX5_FLOW_DESTINATION_TYPE_FLOW_SAMPLER:
    622				id = dst->dest_attr.sampler_id;
    623				ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_SAMPLER;
    624				break;
    625			default:
    626				id = dst->dest_attr.tir_num;
    627				ifc_type = MLX5_IFC_FLOW_DESTINATION_TYPE_TIR;
    628			}
    629
    630			MLX5_SET(dest_format_struct, in_dests, destination_type,
    631				 ifc_type);
    632			MLX5_SET(dest_format_struct, in_dests, destination_id, id);
    633			in_dests += dst_cnt_size;
    634			list_size++;
    635		}
    636
    637		MLX5_SET(flow_context, in_flow_context, destination_list_size,
    638			 list_size);
    639	}
    640
    641	if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
    642		int max_list_size = BIT(MLX5_CAP_FLOWTABLE_TYPE(dev,
    643					log_max_flow_counter,
    644					ft->type));
    645		int list_size = 0;
    646
    647		list_for_each_entry(dst, &fte->node.children, node.list) {
    648			if (dst->dest_attr.type !=
    649			    MLX5_FLOW_DESTINATION_TYPE_COUNTER)
    650				continue;
    651
    652			MLX5_SET(flow_counter_list, in_dests, flow_counter_id,
    653				 dst->dest_attr.counter_id);
    654			in_dests += dst_cnt_size;
    655			list_size++;
    656		}
    657		if (list_size > max_list_size) {
    658			err = -EINVAL;
    659			goto err_out;
    660		}
    661
    662		MLX5_SET(flow_context, in_flow_context, flow_counter_list_size,
    663			 list_size);
    664	}
    665
    666	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
    667err_out:
    668	kvfree(in);
    669	return err;
    670}
    671
    672static int mlx5_cmd_create_fte(struct mlx5_flow_root_namespace *ns,
    673			       struct mlx5_flow_table *ft,
    674			       struct mlx5_flow_group *group,
    675			       struct fs_fte *fte)
    676{
    677	struct mlx5_core_dev *dev = ns->dev;
    678	unsigned int group_id = group->id;
    679
    680	return mlx5_cmd_set_fte(dev, 0, 0, ft, group_id, fte);
    681}
    682
    683static int mlx5_cmd_update_fte(struct mlx5_flow_root_namespace *ns,
    684			       struct mlx5_flow_table *ft,
    685			       struct mlx5_flow_group *fg,
    686			       int modify_mask,
    687			       struct fs_fte *fte)
    688{
    689	int opmod;
    690	struct mlx5_core_dev *dev = ns->dev;
    691	int atomic_mod_cap = MLX5_CAP_FLOWTABLE(dev,
    692						flow_table_properties_nic_receive.
    693						flow_modify_en);
    694	if (!atomic_mod_cap)
    695		return -EOPNOTSUPP;
    696	opmod = 1;
    697
    698	return	mlx5_cmd_set_fte(dev, opmod, modify_mask, ft, fg->id, fte);
    699}
    700
    701static int mlx5_cmd_delete_fte(struct mlx5_flow_root_namespace *ns,
    702			       struct mlx5_flow_table *ft,
    703			       struct fs_fte *fte)
    704{
    705	u32 in[MLX5_ST_SZ_DW(delete_fte_in)] = {};
    706	struct mlx5_core_dev *dev = ns->dev;
    707
    708	MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY);
    709	MLX5_SET(delete_fte_in, in, table_type, ft->type);
    710	MLX5_SET(delete_fte_in, in, table_id, ft->id);
    711	MLX5_SET(delete_fte_in, in, flow_index, fte->index);
    712	MLX5_SET(delete_fte_in, in, vport_number, ft->vport);
    713	MLX5_SET(delete_fte_in, in, other_vport,
    714		 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
    715
    716	return mlx5_cmd_exec_in(dev, delete_fte, in);
    717}
    718
    719int mlx5_cmd_fc_bulk_alloc(struct mlx5_core_dev *dev,
    720			   enum mlx5_fc_bulk_alloc_bitmask alloc_bitmask,
    721			   u32 *id)
    722{
    723	u32 out[MLX5_ST_SZ_DW(alloc_flow_counter_out)] = {};
    724	u32 in[MLX5_ST_SZ_DW(alloc_flow_counter_in)] = {};
    725	int err;
    726
    727	MLX5_SET(alloc_flow_counter_in, in, opcode,
    728		 MLX5_CMD_OP_ALLOC_FLOW_COUNTER);
    729	MLX5_SET(alloc_flow_counter_in, in, flow_counter_bulk, alloc_bitmask);
    730
    731	err = mlx5_cmd_exec_inout(dev, alloc_flow_counter, in, out);
    732	if (!err)
    733		*id = MLX5_GET(alloc_flow_counter_out, out, flow_counter_id);
    734	return err;
    735}
    736
    737int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u32 *id)
    738{
    739	return mlx5_cmd_fc_bulk_alloc(dev, 0, id);
    740}
    741
    742int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u32 id)
    743{
    744	u32 in[MLX5_ST_SZ_DW(dealloc_flow_counter_in)] = {};
    745
    746	MLX5_SET(dealloc_flow_counter_in, in, opcode,
    747		 MLX5_CMD_OP_DEALLOC_FLOW_COUNTER);
    748	MLX5_SET(dealloc_flow_counter_in, in, flow_counter_id, id);
    749	return mlx5_cmd_exec_in(dev, dealloc_flow_counter, in);
    750}
    751
    752int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u32 id,
    753		      u64 *packets, u64 *bytes)
    754{
    755	u32 out[MLX5_ST_SZ_BYTES(query_flow_counter_out) +
    756		MLX5_ST_SZ_BYTES(traffic_counter)] = {};
    757	u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {};
    758	void *stats;
    759	int err = 0;
    760
    761	MLX5_SET(query_flow_counter_in, in, opcode,
    762		 MLX5_CMD_OP_QUERY_FLOW_COUNTER);
    763	MLX5_SET(query_flow_counter_in, in, op_mod, 0);
    764	MLX5_SET(query_flow_counter_in, in, flow_counter_id, id);
    765	err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
    766	if (err)
    767		return err;
    768
    769	stats = MLX5_ADDR_OF(query_flow_counter_out, out, flow_statistics);
    770	*packets = MLX5_GET64(traffic_counter, stats, packets);
    771	*bytes = MLX5_GET64(traffic_counter, stats, octets);
    772	return 0;
    773}
    774
    775int mlx5_cmd_fc_get_bulk_query_out_len(int bulk_len)
    776{
    777	return MLX5_ST_SZ_BYTES(query_flow_counter_out) +
    778		MLX5_ST_SZ_BYTES(traffic_counter) * bulk_len;
    779}
    780
    781int mlx5_cmd_fc_bulk_query(struct mlx5_core_dev *dev, u32 base_id, int bulk_len,
    782			   u32 *out)
    783{
    784	int outlen = mlx5_cmd_fc_get_bulk_query_out_len(bulk_len);
    785	u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {};
    786
    787	MLX5_SET(query_flow_counter_in, in, opcode,
    788		 MLX5_CMD_OP_QUERY_FLOW_COUNTER);
    789	MLX5_SET(query_flow_counter_in, in, flow_counter_id, base_id);
    790	MLX5_SET(query_flow_counter_in, in, num_of_counters, bulk_len);
    791	return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
    792}
    793
    794static int mlx5_cmd_packet_reformat_alloc(struct mlx5_flow_root_namespace *ns,
    795					  struct mlx5_pkt_reformat_params *params,
    796					  enum mlx5_flow_namespace_type namespace,
    797					  struct mlx5_pkt_reformat *pkt_reformat)
    798{
    799	u32 out[MLX5_ST_SZ_DW(alloc_packet_reformat_context_out)] = {};
    800	struct mlx5_core_dev *dev = ns->dev;
    801	void *packet_reformat_context_in;
    802	int max_encap_size;
    803	void *reformat;
    804	int inlen;
    805	int err;
    806	u32 *in;
    807
    808	if (namespace == MLX5_FLOW_NAMESPACE_FDB ||
    809	    namespace == MLX5_FLOW_NAMESPACE_FDB_BYPASS)
    810		max_encap_size = MLX5_CAP_ESW(dev, max_encap_header_size);
    811	else
    812		max_encap_size = MLX5_CAP_FLOWTABLE(dev, max_encap_header_size);
    813
    814	if (params->size > max_encap_size) {
    815		mlx5_core_warn(dev, "encap size %zd too big, max supported is %d\n",
    816			       params->size, max_encap_size);
    817		return -EINVAL;
    818	}
    819
    820	in = kzalloc(MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in) +
    821		     params->size, GFP_KERNEL);
    822	if (!in)
    823		return -ENOMEM;
    824
    825	packet_reformat_context_in = MLX5_ADDR_OF(alloc_packet_reformat_context_in,
    826						  in, packet_reformat_context);
    827	reformat = MLX5_ADDR_OF(packet_reformat_context_in,
    828				packet_reformat_context_in,
    829				reformat_data);
    830	inlen = reformat - (void *)in + params->size;
    831
    832	MLX5_SET(alloc_packet_reformat_context_in, in, opcode,
    833		 MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT);
    834	MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
    835		 reformat_data_size, params->size);
    836	MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
    837		 reformat_type, params->type);
    838	MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
    839		 reformat_param_0, params->param_0);
    840	MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
    841		 reformat_param_1, params->param_1);
    842	if (params->data && params->size)
    843		memcpy(reformat, params->data, params->size);
    844
    845	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
    846
    847	pkt_reformat->id = MLX5_GET(alloc_packet_reformat_context_out,
    848				    out, packet_reformat_id);
    849	kfree(in);
    850	return err;
    851}
    852
    853static void mlx5_cmd_packet_reformat_dealloc(struct mlx5_flow_root_namespace *ns,
    854					     struct mlx5_pkt_reformat *pkt_reformat)
    855{
    856	u32 in[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_in)] = {};
    857	struct mlx5_core_dev *dev = ns->dev;
    858
    859	MLX5_SET(dealloc_packet_reformat_context_in, in, opcode,
    860		 MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT);
    861	MLX5_SET(dealloc_packet_reformat_context_in, in, packet_reformat_id,
    862		 pkt_reformat->id);
    863
    864	mlx5_cmd_exec_in(dev, dealloc_packet_reformat_context, in);
    865}
    866
    867static int mlx5_cmd_modify_header_alloc(struct mlx5_flow_root_namespace *ns,
    868					u8 namespace, u8 num_actions,
    869					void *modify_actions,
    870					struct mlx5_modify_hdr *modify_hdr)
    871{
    872	u32 out[MLX5_ST_SZ_DW(alloc_modify_header_context_out)] = {};
    873	int max_actions, actions_size, inlen, err;
    874	struct mlx5_core_dev *dev = ns->dev;
    875	void *actions_in;
    876	u8 table_type;
    877	u32 *in;
    878
    879	switch (namespace) {
    880	case MLX5_FLOW_NAMESPACE_FDB:
    881	case MLX5_FLOW_NAMESPACE_FDB_BYPASS:
    882		max_actions = MLX5_CAP_ESW_FLOWTABLE_FDB(dev, max_modify_header_actions);
    883		table_type = FS_FT_FDB;
    884		break;
    885	case MLX5_FLOW_NAMESPACE_KERNEL:
    886	case MLX5_FLOW_NAMESPACE_BYPASS:
    887		max_actions = MLX5_CAP_FLOWTABLE_NIC_RX(dev, max_modify_header_actions);
    888		table_type = FS_FT_NIC_RX;
    889		break;
    890	case MLX5_FLOW_NAMESPACE_EGRESS:
    891	case MLX5_FLOW_NAMESPACE_EGRESS_KERNEL:
    892		max_actions = MLX5_CAP_FLOWTABLE_NIC_TX(dev, max_modify_header_actions);
    893		table_type = FS_FT_NIC_TX;
    894		break;
    895	case MLX5_FLOW_NAMESPACE_ESW_INGRESS:
    896		max_actions = MLX5_CAP_ESW_INGRESS_ACL(dev, max_modify_header_actions);
    897		table_type = FS_FT_ESW_INGRESS_ACL;
    898		break;
    899	case MLX5_FLOW_NAMESPACE_RDMA_TX:
    900		max_actions = MLX5_CAP_FLOWTABLE_RDMA_TX(dev, max_modify_header_actions);
    901		table_type = FS_FT_RDMA_TX;
    902		break;
    903	default:
    904		return -EOPNOTSUPP;
    905	}
    906
    907	if (num_actions > max_actions) {
    908		mlx5_core_warn(dev, "too many modify header actions %d, max supported %d\n",
    909			       num_actions, max_actions);
    910		return -EOPNOTSUPP;
    911	}
    912
    913	actions_size = MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto) * num_actions;
    914	inlen = MLX5_ST_SZ_BYTES(alloc_modify_header_context_in) + actions_size;
    915
    916	in = kzalloc(inlen, GFP_KERNEL);
    917	if (!in)
    918		return -ENOMEM;
    919
    920	MLX5_SET(alloc_modify_header_context_in, in, opcode,
    921		 MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT);
    922	MLX5_SET(alloc_modify_header_context_in, in, table_type, table_type);
    923	MLX5_SET(alloc_modify_header_context_in, in, num_of_actions, num_actions);
    924
    925	actions_in = MLX5_ADDR_OF(alloc_modify_header_context_in, in, actions);
    926	memcpy(actions_in, modify_actions, actions_size);
    927
    928	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
    929
    930	modify_hdr->id = MLX5_GET(alloc_modify_header_context_out, out, modify_header_id);
    931	kfree(in);
    932	return err;
    933}
    934
    935static void mlx5_cmd_modify_header_dealloc(struct mlx5_flow_root_namespace *ns,
    936					   struct mlx5_modify_hdr *modify_hdr)
    937{
    938	u32 in[MLX5_ST_SZ_DW(dealloc_modify_header_context_in)] = {};
    939	struct mlx5_core_dev *dev = ns->dev;
    940
    941	MLX5_SET(dealloc_modify_header_context_in, in, opcode,
    942		 MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT);
    943	MLX5_SET(dealloc_modify_header_context_in, in, modify_header_id,
    944		 modify_hdr->id);
    945
    946	mlx5_cmd_exec_in(dev, dealloc_modify_header_context, in);
    947}
    948
    949static int mlx5_cmd_destroy_match_definer(struct mlx5_flow_root_namespace *ns,
    950					  int definer_id)
    951{
    952	u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};
    953	u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
    954
    955	MLX5_SET(general_obj_in_cmd_hdr, in, opcode,
    956		 MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
    957	MLX5_SET(general_obj_in_cmd_hdr, in, obj_type,
    958		 MLX5_OBJ_TYPE_MATCH_DEFINER);
    959	MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, definer_id);
    960
    961	return mlx5_cmd_exec(ns->dev, in, sizeof(in), out, sizeof(out));
    962}
    963
    964static int mlx5_cmd_create_match_definer(struct mlx5_flow_root_namespace *ns,
    965					 u16 format_id, u32 *match_mask)
    966{
    967	u32 out[MLX5_ST_SZ_DW(create_match_definer_out)] = {};
    968	u32 in[MLX5_ST_SZ_DW(create_match_definer_in)] = {};
    969	struct mlx5_core_dev *dev = ns->dev;
    970	void *ptr;
    971	int err;
    972
    973	MLX5_SET(create_match_definer_in, in, general_obj_in_cmd_hdr.opcode,
    974		 MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
    975	MLX5_SET(create_match_definer_in, in, general_obj_in_cmd_hdr.obj_type,
    976		 MLX5_OBJ_TYPE_MATCH_DEFINER);
    977
    978	ptr = MLX5_ADDR_OF(create_match_definer_in, in, obj_context);
    979	MLX5_SET(match_definer, ptr, format_id, format_id);
    980
    981	ptr = MLX5_ADDR_OF(match_definer, ptr, match_mask);
    982	memcpy(ptr, match_mask, MLX5_FLD_SZ_BYTES(match_definer, match_mask));
    983
    984	err = mlx5_cmd_exec_inout(dev, create_match_definer, in, out);
    985	return err ? err : MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
    986}
    987
    988static u32 mlx5_cmd_get_capabilities(struct mlx5_flow_root_namespace *ns,
    989				     enum fs_flow_table_type ft_type)
    990{
    991	return 0;
    992}
    993
    994static const struct mlx5_flow_cmds mlx5_flow_cmds = {
    995	.create_flow_table = mlx5_cmd_create_flow_table,
    996	.destroy_flow_table = mlx5_cmd_destroy_flow_table,
    997	.modify_flow_table = mlx5_cmd_modify_flow_table,
    998	.create_flow_group = mlx5_cmd_create_flow_group,
    999	.destroy_flow_group = mlx5_cmd_destroy_flow_group,
   1000	.create_fte = mlx5_cmd_create_fte,
   1001	.update_fte = mlx5_cmd_update_fte,
   1002	.delete_fte = mlx5_cmd_delete_fte,
   1003	.update_root_ft = mlx5_cmd_update_root_ft,
   1004	.packet_reformat_alloc = mlx5_cmd_packet_reformat_alloc,
   1005	.packet_reformat_dealloc = mlx5_cmd_packet_reformat_dealloc,
   1006	.modify_header_alloc = mlx5_cmd_modify_header_alloc,
   1007	.modify_header_dealloc = mlx5_cmd_modify_header_dealloc,
   1008	.create_match_definer = mlx5_cmd_create_match_definer,
   1009	.destroy_match_definer = mlx5_cmd_destroy_match_definer,
   1010	.set_peer = mlx5_cmd_stub_set_peer,
   1011	.create_ns = mlx5_cmd_stub_create_ns,
   1012	.destroy_ns = mlx5_cmd_stub_destroy_ns,
   1013	.get_capabilities = mlx5_cmd_get_capabilities,
   1014};
   1015
   1016static const struct mlx5_flow_cmds mlx5_flow_cmd_stubs = {
   1017	.create_flow_table = mlx5_cmd_stub_create_flow_table,
   1018	.destroy_flow_table = mlx5_cmd_stub_destroy_flow_table,
   1019	.modify_flow_table = mlx5_cmd_stub_modify_flow_table,
   1020	.create_flow_group = mlx5_cmd_stub_create_flow_group,
   1021	.destroy_flow_group = mlx5_cmd_stub_destroy_flow_group,
   1022	.create_fte = mlx5_cmd_stub_create_fte,
   1023	.update_fte = mlx5_cmd_stub_update_fte,
   1024	.delete_fte = mlx5_cmd_stub_delete_fte,
   1025	.update_root_ft = mlx5_cmd_stub_update_root_ft,
   1026	.packet_reformat_alloc = mlx5_cmd_stub_packet_reformat_alloc,
   1027	.packet_reformat_dealloc = mlx5_cmd_stub_packet_reformat_dealloc,
   1028	.modify_header_alloc = mlx5_cmd_stub_modify_header_alloc,
   1029	.modify_header_dealloc = mlx5_cmd_stub_modify_header_dealloc,
   1030	.create_match_definer = mlx5_cmd_stub_create_match_definer,
   1031	.destroy_match_definer = mlx5_cmd_stub_destroy_match_definer,
   1032	.set_peer = mlx5_cmd_stub_set_peer,
   1033	.create_ns = mlx5_cmd_stub_create_ns,
   1034	.destroy_ns = mlx5_cmd_stub_destroy_ns,
   1035	.get_capabilities = mlx5_cmd_stub_get_capabilities,
   1036};
   1037
   1038const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void)
   1039{
   1040	return &mlx5_flow_cmds;
   1041}
   1042
   1043static const struct mlx5_flow_cmds *mlx5_fs_cmd_get_stub_cmds(void)
   1044{
   1045	return &mlx5_flow_cmd_stubs;
   1046}
   1047
   1048const struct mlx5_flow_cmds *mlx5_fs_cmd_get_default(enum fs_flow_table_type type)
   1049{
   1050	switch (type) {
   1051	case FS_FT_NIC_RX:
   1052	case FS_FT_ESW_EGRESS_ACL:
   1053	case FS_FT_ESW_INGRESS_ACL:
   1054	case FS_FT_FDB:
   1055	case FS_FT_SNIFFER_RX:
   1056	case FS_FT_SNIFFER_TX:
   1057	case FS_FT_NIC_TX:
   1058	case FS_FT_RDMA_RX:
   1059	case FS_FT_RDMA_TX:
   1060	case FS_FT_PORT_SEL:
   1061		return mlx5_fs_cmd_get_fw_cmds();
   1062	default:
   1063		return mlx5_fs_cmd_get_stub_cmds();
   1064	}
   1065}