Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / fs_cmd.c
index 287ade1..113c323 100644 (file)
 int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
                            struct mlx5_flow_table *ft)
 {
-       u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)];
-       u32 out[MLX5_ST_SZ_DW(set_flow_table_root_out)];
-
-       memset(in, 0, sizeof(in));
+       u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)]   = {0};
+       u32 out[MLX5_ST_SZ_DW(set_flow_table_root_out)] = {0};
 
        MLX5_SET(set_flow_table_root_in, in, opcode,
                 MLX5_CMD_OP_SET_FLOW_TABLE_ROOT);
@@ -55,30 +53,23 @@ int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
                MLX5_SET(set_flow_table_root_in, in, other_vport, 1);
        }
 
-       memset(out, 0, sizeof(out));
-       return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
-                                         sizeof(out));
+       return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
 int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev,
                               u16 vport,
+                              enum fs_flow_table_op_mod op_mod,
                               enum fs_flow_table_type type, unsigned int level,
                               unsigned int log_size, struct mlx5_flow_table
                               *next_ft, unsigned int *table_id)
 {
-       u32 out[MLX5_ST_SZ_DW(create_flow_table_out)];
-       u32 in[MLX5_ST_SZ_DW(create_flow_table_in)];
+       u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {0};
+       u32 in[MLX5_ST_SZ_DW(create_flow_table_in)]   = {0};
        int err;
 
-       memset(in, 0, sizeof(in));
-
        MLX5_SET(create_flow_table_in, in, opcode,
                 MLX5_CMD_OP_CREATE_FLOW_TABLE);
 
-       if (next_ft) {
-               MLX5_SET(create_flow_table_in, in, table_miss_mode, 1);
-               MLX5_SET(create_flow_table_in, in, table_miss_id, next_ft->id);
-       }
        MLX5_SET(create_flow_table_in, in, table_type, type);
        MLX5_SET(create_flow_table_in, in, level, level);
        MLX5_SET(create_flow_table_in, in, log_size, log_size);
@@ -87,10 +78,23 @@ int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev,
                MLX5_SET(create_flow_table_in, in, other_vport, 1);
        }
 
-       memset(out, 0, sizeof(out));
-       err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
-                                        sizeof(out));
+       switch (op_mod) {
+       case FS_FT_OP_MOD_NORMAL:
+               if (next_ft) {
+                       MLX5_SET(create_flow_table_in, in, table_miss_mode, 1);
+                       MLX5_SET(create_flow_table_in, in, table_miss_id, next_ft->id);
+               }
+               break;
+
+       case FS_FT_OP_MOD_LAG_DEMUX:
+               MLX5_SET(create_flow_table_in, in, op_mod, 0x1);
+               if (next_ft)
+                       MLX5_SET(create_flow_table_in, in, lag_master_next_table_id,
+                                next_ft->id);
+               break;
+       }
 
+       err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
        if (!err)
                *table_id = MLX5_GET(create_flow_table_out, out,
                                     table_id);
@@ -100,11 +104,8 @@ int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev,
 int mlx5_cmd_destroy_flow_table(struct mlx5_core_dev *dev,
                                struct mlx5_flow_table *ft)
 {
-       u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)];
-       u32 out[MLX5_ST_SZ_DW(destroy_flow_table_out)];
-
-       memset(in, 0, sizeof(in));
-       memset(out, 0, sizeof(out));
+       u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)]   = {0};
+       u32 out[MLX5_ST_SZ_DW(destroy_flow_table_out)] = {0};
 
        MLX5_SET(destroy_flow_table_in, in, opcode,
                 MLX5_CMD_OP_DESTROY_FLOW_TABLE);
@@ -115,39 +116,49 @@ int mlx5_cmd_destroy_flow_table(struct mlx5_core_dev *dev,
                MLX5_SET(destroy_flow_table_in, in, other_vport, 1);
        }
 
-       return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
-                                         sizeof(out));
+       return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
 int mlx5_cmd_modify_flow_table(struct mlx5_core_dev *dev,
                               struct mlx5_flow_table *ft,
                               struct mlx5_flow_table *next_ft)
 {
-       u32 in[MLX5_ST_SZ_DW(modify_flow_table_in)];
-       u32 out[MLX5_ST_SZ_DW(modify_flow_table_out)];
-
-       memset(in, 0, sizeof(in));
-       memset(out, 0, sizeof(out));
+       u32 in[MLX5_ST_SZ_DW(modify_flow_table_in)]   = {0};
+       u32 out[MLX5_ST_SZ_DW(modify_flow_table_out)] = {0};
 
        MLX5_SET(modify_flow_table_in, in, opcode,
                 MLX5_CMD_OP_MODIFY_FLOW_TABLE);
        MLX5_SET(modify_flow_table_in, in, table_type, ft->type);
        MLX5_SET(modify_flow_table_in, in, table_id, ft->id);
-       if (ft->vport) {
-               MLX5_SET(modify_flow_table_in, in, vport_number, ft->vport);
-               MLX5_SET(modify_flow_table_in, in, other_vport, 1);
-       }
-       MLX5_SET(modify_flow_table_in, in, modify_field_select,
-                MLX5_MODIFY_FLOW_TABLE_MISS_TABLE_ID);
-       if (next_ft) {
-               MLX5_SET(modify_flow_table_in, in, table_miss_mode, 1);
-               MLX5_SET(modify_flow_table_in, in, table_miss_id, next_ft->id);
+
+       if (ft->op_mod == FS_FT_OP_MOD_LAG_DEMUX) {
+               MLX5_SET(modify_flow_table_in, in, modify_field_select,
+                        MLX5_MODIFY_FLOW_TABLE_LAG_NEXT_TABLE_ID);
+               if (next_ft) {
+                       MLX5_SET(modify_flow_table_in, in,
+                                lag_master_next_table_id, next_ft->id);
+               } else {
+                       MLX5_SET(modify_flow_table_in, in,
+                                lag_master_next_table_id, 0);
+               }
        } else {
-               MLX5_SET(modify_flow_table_in, in, table_miss_mode, 0);
+               if (ft->vport) {
+                       MLX5_SET(modify_flow_table_in, in, vport_number,
+                                ft->vport);
+                       MLX5_SET(modify_flow_table_in, in, other_vport, 1);
+               }
+               MLX5_SET(modify_flow_table_in, in, modify_field_select,
+                        MLX5_MODIFY_FLOW_TABLE_MISS_TABLE_ID);
+               if (next_ft) {
+                       MLX5_SET(modify_flow_table_in, in, table_miss_mode, 1);
+                       MLX5_SET(modify_flow_table_in, in, table_miss_id,
+                                next_ft->id);
+               } else {
+                       MLX5_SET(modify_flow_table_in, in, table_miss_mode, 0);
+               }
        }
 
-       return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
-                                         sizeof(out));
+       return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
 int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev,
@@ -155,12 +166,10 @@ int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev,
                               u32 *in,
                               unsigned int *group_id)
 {
+       u32 out[MLX5_ST_SZ_DW(create_flow_group_out)] = {0};
        int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
-       u32 out[MLX5_ST_SZ_DW(create_flow_group_out)];
        int err;
 
-       memset(out, 0, sizeof(out));
-
        MLX5_SET(create_flow_group_in, in, opcode,
                 MLX5_CMD_OP_CREATE_FLOW_GROUP);
        MLX5_SET(create_flow_group_in, in, table_type, ft->type);
@@ -170,13 +179,10 @@ int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev,
                MLX5_SET(create_flow_group_in, in, other_vport, 1);
        }
 
-       err = mlx5_cmd_exec_check_status(dev, in,
-                                        inlen, out,
-                                        sizeof(out));
+       err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
        if (!err)
                *group_id = MLX5_GET(create_flow_group_out, out,
                                     group_id);
-
        return err;
 }
 
@@ -184,11 +190,8 @@ int mlx5_cmd_destroy_flow_group(struct mlx5_core_dev *dev,
                                struct mlx5_flow_table *ft,
                                unsigned int group_id)
 {
-       u32 out[MLX5_ST_SZ_DW(destroy_flow_group_out)];
-       u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)];
-
-       memset(in, 0, sizeof(in));
-       memset(out, 0, sizeof(out));
+       u32 out[MLX5_ST_SZ_DW(destroy_flow_group_out)] = {0};
+       u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)]   = {0};
 
        MLX5_SET(destroy_flow_group_in, in, opcode,
                 MLX5_CMD_OP_DESTROY_FLOW_GROUP);
@@ -200,8 +203,7 @@ int mlx5_cmd_destroy_flow_group(struct mlx5_core_dev *dev,
                MLX5_SET(destroy_flow_group_in, in, other_vport, 1);
        }
 
-       return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
-                                         sizeof(out));
+       return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
 static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
@@ -212,7 +214,7 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
 {
        unsigned int inlen = MLX5_ST_SZ_BYTES(set_fte_in) +
                fte->dests_size * MLX5_ST_SZ_BYTES(dest_format_struct);
-       u32 out[MLX5_ST_SZ_DW(set_fte_out)];
+       u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {0};
        struct mlx5_flow_rule *dst;
        void *in_flow_context;
        void *in_match_value;
@@ -290,11 +292,8 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
                         list_size);
        }
 
-       memset(out, 0, sizeof(out));
-       err = mlx5_cmd_exec_check_status(dev, in, inlen, out,
-                                        sizeof(out));
+       err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
        kvfree(in);
-
        return err;
 }
 
@@ -303,7 +302,7 @@ int mlx5_cmd_create_fte(struct mlx5_core_dev *dev,
                        unsigned group_id,
                        struct fs_fte *fte)
 {
-       return  mlx5_cmd_set_fte(dev, 0, 0, ft, group_id, fte);
+       return mlx5_cmd_set_fte(dev, 0, 0, ft, group_id, fte);
 }
 
 int mlx5_cmd_update_fte(struct mlx5_core_dev *dev,
@@ -327,12 +326,8 @@ int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev,
                        struct mlx5_flow_table *ft,
                        unsigned int index)
 {
-       u32 out[MLX5_ST_SZ_DW(delete_fte_out)];
-       u32 in[MLX5_ST_SZ_DW(delete_fte_in)];
-       int err;
-
-       memset(in, 0, sizeof(in));
-       memset(out, 0, sizeof(out));
+       u32 out[MLX5_ST_SZ_DW(delete_fte_out)] = {0};
+       u32 in[MLX5_ST_SZ_DW(delete_fte_in)]   = {0};
 
        MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY);
        MLX5_SET(delete_fte_in, in, table_type, ft->type);
@@ -343,74 +338,55 @@ int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev,
                MLX5_SET(delete_fte_in, in, other_vport, 1);
        }
 
-       err =  mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
-
-       return err;
+       return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
 int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u16 *id)
 {
-       u32 in[MLX5_ST_SZ_DW(alloc_flow_counter_in)];
-       u32 out[MLX5_ST_SZ_DW(alloc_flow_counter_out)];
+       u32 in[MLX5_ST_SZ_DW(alloc_flow_counter_in)]   = {0};
+       u32 out[MLX5_ST_SZ_DW(alloc_flow_counter_out)] = {0};
        int err;
 
-       memset(in, 0, sizeof(in));
-       memset(out, 0, sizeof(out));
-
        MLX5_SET(alloc_flow_counter_in, in, opcode,
                 MLX5_CMD_OP_ALLOC_FLOW_COUNTER);
 
-       err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
-                                        sizeof(out));
-       if (err)
-               return err;
-
-       *id = MLX5_GET(alloc_flow_counter_out, out, flow_counter_id);
-
-       return 0;
+       err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+       if (!err)
+               *id = MLX5_GET(alloc_flow_counter_out, out, flow_counter_id);
+       return err;
 }
 
 int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u16 id)
 {
-       u32 in[MLX5_ST_SZ_DW(dealloc_flow_counter_in)];
-       u32 out[MLX5_ST_SZ_DW(dealloc_flow_counter_out)];
-
-       memset(in, 0, sizeof(in));
-       memset(out, 0, sizeof(out));
+       u32 in[MLX5_ST_SZ_DW(dealloc_flow_counter_in)]   = {0};
+       u32 out[MLX5_ST_SZ_DW(dealloc_flow_counter_out)] = {0};
 
        MLX5_SET(dealloc_flow_counter_in, in, opcode,
                 MLX5_CMD_OP_DEALLOC_FLOW_COUNTER);
        MLX5_SET(dealloc_flow_counter_in, in, flow_counter_id, id);
-
-       return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
-                                         sizeof(out));
+       return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
 int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u16 id,
                      u64 *packets, u64 *bytes)
 {
        u32 out[MLX5_ST_SZ_BYTES(query_flow_counter_out) +
-               MLX5_ST_SZ_BYTES(traffic_counter)];
-       u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)];
+               MLX5_ST_SZ_BYTES(traffic_counter)]   = {0};
+       u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {0};
        void *stats;
        int err = 0;
 
-       memset(in, 0, sizeof(in));
-       memset(out, 0, sizeof(out));
-
        MLX5_SET(query_flow_counter_in, in, opcode,
                 MLX5_CMD_OP_QUERY_FLOW_COUNTER);
        MLX5_SET(query_flow_counter_in, in, op_mod, 0);
        MLX5_SET(query_flow_counter_in, in, flow_counter_id, id);
-
-       err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
+       err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
        if (err)
                return err;
 
        stats = MLX5_ADDR_OF(query_flow_counter_out, out, flow_statistics);
        *packets = MLX5_GET64(traffic_counter, stats, packets);
        *bytes = MLX5_GET64(traffic_counter, stats, octets);
-
        return 0;
 }
 
@@ -448,18 +424,14 @@ void mlx5_cmd_fc_bulk_free(struct mlx5_cmd_fc_bulk *b)
 int
 mlx5_cmd_fc_bulk_query(struct mlx5_core_dev *dev, struct mlx5_cmd_fc_bulk *b)
 {
-       u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)];
-
-       memset(in, 0, sizeof(in));
+       u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {0};
 
        MLX5_SET(query_flow_counter_in, in, opcode,
                 MLX5_CMD_OP_QUERY_FLOW_COUNTER);
        MLX5_SET(query_flow_counter_in, in, op_mod, 0);
        MLX5_SET(query_flow_counter_in, in, flow_counter_id, b->id);
        MLX5_SET(query_flow_counter_in, in, num_of_counters, b->num);
-
-       return mlx5_cmd_exec_check_status(dev, in, sizeof(in),
-                                         b->out, b->outlen);
+       return mlx5_cmd_exec(dev, in, sizeof(in), b->out, b->outlen);
 }
 
 void mlx5_cmd_fc_bulk_get(struct mlx5_core_dev *dev,
@@ -480,3 +452,51 @@ void mlx5_cmd_fc_bulk_get(struct mlx5_core_dev *dev,
        *packets = MLX5_GET64(traffic_counter, stats, packets);
        *bytes = MLX5_GET64(traffic_counter, stats, octets);
 }
+
+#define MAX_ENCAP_SIZE (128)
+
+int mlx5_cmd_alloc_encap(struct mlx5_core_dev *dev,
+                        int header_type,
+                        size_t size,
+                        void *encap_header,
+                        u32 *encap_id)
+{
+       u32 out[MLX5_ST_SZ_DW(alloc_encap_header_out)];
+       u32 in[MLX5_ST_SZ_DW(alloc_encap_header_in) +
+             (MAX_ENCAP_SIZE / sizeof(u32))];
+       void *encap_header_in = MLX5_ADDR_OF(alloc_encap_header_in, in,
+                                            encap_header);
+       void *header = MLX5_ADDR_OF(encap_header_in, encap_header_in,
+                                   encap_header);
+       int inlen = header - (void *)in  + size;
+       int err;
+
+       if (size > MAX_ENCAP_SIZE)
+               return -EINVAL;
+
+       memset(in, 0, inlen);
+       MLX5_SET(alloc_encap_header_in, in, opcode,
+                MLX5_CMD_OP_ALLOC_ENCAP_HEADER);
+       MLX5_SET(encap_header_in, encap_header_in, encap_header_size, size);
+       MLX5_SET(encap_header_in, encap_header_in, header_type, header_type);
+       memcpy(header, encap_header, size);
+
+       memset(out, 0, sizeof(out));
+       err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
+
+       *encap_id = MLX5_GET(alloc_encap_header_out, out, encap_id);
+       return err;
+}
+
+void mlx5_cmd_dealloc_encap(struct mlx5_core_dev *dev, u32 encap_id)
+{
+       u32 in[MLX5_ST_SZ_DW(dealloc_encap_header_in)];
+       u32 out[MLX5_ST_SZ_DW(dealloc_encap_header_out)];
+
+       memset(in, 0, sizeof(in));
+       MLX5_SET(dealloc_encap_header_in, in, opcode,
+                MLX5_CMD_OP_DEALLOC_ENCAP_HEADER);
+       MLX5_SET(dealloc_encap_header_in, in, encap_id, encap_id);
+
+       mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+}