diff options
| author | David S. Miller <davem@davemloft.net> | 2018-03-07 15:28:13 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2018-03-07 15:28:13 -0500 |
| commit | bcde6b725f156a828d129a64d82730b21de9d44f (patch) | |
| tree | 6479506b04ffb333d3a651de4e7d938486ac9ec7 /drivers/net | |
| parent | d1f1b9cbf34c667d06adc44136e448cade8e28d9 (diff) | |
| parent | e810bf5e96e327500cc6334f9d56c8047aaabcff (diff) | |
| download | linux-bcde6b725f156a828d129a64d82730b21de9d44f.tar.gz linux-bcde6b725f156a828d129a64d82730b21de9d44f.tar.bz2 linux-bcde6b725f156a828d129a64d82730b21de9d44f.zip | |
Merge tag 'mlx5-updates-2018-02-28-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux
Saeed Mahameed says:
====================
mlx5-updates-2018-02-28-1 (IPSec-1)
This series consists of some fixes and refactors for the mlx5 drivers,
especially around the FPGA and flow steering. Most of them are trivial
fixes and are the foundation of allowing IPSec acceleration from user-space.
We use flow steering abstraction in order to accelerate IPSec packets.
When a user creates a steering rule, [s]he states that we'll carry an
encrypt/decrypt flow action (using a specific configuration) for every
packet which conforms to a certain match. Since currently offloading these
packets is done via FPGA, we'll add another set of flow steering ops.
These ops will execute the required FPGA commands and then call the
standard steering ops.
In order to achieve this, we need that the commands will get all the
required information. Therefore, we pass the fte object and embed the
flow_action struct inside the fte. In addition, we add the shim layer
that will later be used for alternating between the standard and the
FPGA steering commands.
Some fixes, like " net/mlx5e: Wait for FPGA command responses with a timeout"
are very relevant for user-space applications, as these applications could
be killed, but we still want to wait for the FPGA and update the kernel's
database.
Regards,
Aviad and Matan
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
11 files changed, 339 insertions, 161 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h index d6e20fea9554..67cda8871f5a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h @@ -34,10 +34,10 @@ #ifndef __MLX5_ACCEL_IPSEC_H__ #define __MLX5_ACCEL_IPSEC_H__ -#ifdef CONFIG_MLX5_ACCEL - #include <linux/mlx5/driver.h> +#ifdef CONFIG_MLX5_ACCEL + enum { MLX5_ACCEL_IPSEC_DEVICE = BIT(1), MLX5_ACCEL_IPSEC_IPV6 = BIT(2), diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.c index fd509160c8f6..d93ff567b40d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.c @@ -246,6 +246,9 @@ const char *parse_fs_dst(struct trace_seq *p, case MLX5_FLOW_DESTINATION_TYPE_COUNTER: trace_seq_printf(p, "counter_id=%u\n", counter_id); break; + case MLX5_FLOW_DESTINATION_TYPE_PORT: + trace_seq_printf(p, "port\n"); + break; } trace_seq_putc(p, 0); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h index 80eef4163f52..a6ba57fbb414 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h @@ -163,9 +163,9 @@ TRACE_EVENT(mlx5_fs_set_fte, fs_get_obj(__entry->fg, fte->node.parent); __entry->group_index = __entry->fg->id; __entry->index = fte->index; - __entry->action = fte->action; + __entry->action = fte->action.action; __entry->mask_enable = __entry->fg->mask.match_criteria_enable; - __entry->flow_tag = fte->flow_tag; + __entry->flow_tag = fte->action.flow_tag; memcpy(__entry->mask_outer, MLX5_ADDR_OF(fte_match_param, &__entry->fg->mask.match_criteria, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c index bac5103efad3..1b49afca65c0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -74,18 +74,16 @@ static int mlx5e_ipsec_sadb_rx_add(struct mlx5e_ipsec_sa_entry *sa_entry) unsigned long flags; int ret; - spin_lock_irqsave(&ipsec->sadb_rx_lock, flags); ret = ida_simple_get(&ipsec->halloc, 1, 0, GFP_KERNEL); if (ret < 0) - goto out; + return ret; + spin_lock_irqsave(&ipsec->sadb_rx_lock, flags); sa_entry->handle = ret; hash_add_rcu(ipsec->sadb_rx, &sa_entry->hlist, sa_entry->handle); - ret = 0; - -out: spin_unlock_irqrestore(&ipsec->sadb_rx_lock, flags); - return ret; + + return 0; } static void mlx5e_ipsec_sadb_rx_del(struct mlx5e_ipsec_sa_entry *sa_entry) @@ -101,13 +99,10 @@ static void mlx5e_ipsec_sadb_rx_del(struct mlx5e_ipsec_sa_entry *sa_entry) static void mlx5e_ipsec_sadb_rx_free(struct mlx5e_ipsec_sa_entry *sa_entry) { struct mlx5e_ipsec *ipsec = sa_entry->ipsec; - unsigned long flags; - /* Wait for the hash_del_rcu call in sadb_rx_del to affect data path */ - synchronize_rcu(); - spin_lock_irqsave(&ipsec->sadb_rx_lock, flags); + /* xfrm already doing sync rcu between del and free callbacks */ + ida_simple_remove(&ipsec->halloc, sa_entry->handle); - spin_unlock_irqrestore(&ipsec->sadb_rx_lock, flags); } static enum mlx5_accel_ipsec_enc_mode mlx5e_ipsec_enc_mode(struct xfrm_state *x) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index fa86a1466718..7c33df2034f0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -675,6 +675,7 @@ mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv, struct mlx5_flow_destination dest[2] = {}; struct mlx5_flow_act flow_act = { .action = attr->action, + .has_flow_tag = true, .flow_tag = attr->flow_tag, .encap_id = 0, }; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c index 35d0e33381ca..95f9c5a8619b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c @@ -39,6 +39,7 @@ #include "fpga/core.h" #define SBU_QP_QUEUE_SIZE 8 +#define MLX5_FPGA_IPSEC_CMD_TIMEOUT_MSEC (60 * 1000) enum mlx5_ipsec_response_syndrome { MLX5_IPSEC_RESPONSE_SUCCESS = 0, @@ -217,12 +218,14 @@ void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev, int mlx5_fpga_ipsec_sa_cmd_wait(void *ctx) { struct mlx5_ipsec_command_context *context = ctx; + unsigned long timeout = + msecs_to_jiffies(MLX5_FPGA_IPSEC_CMD_TIMEOUT_MSEC); int res; - res = wait_for_completion_killable(&context->complete); - if (res) { + res = wait_for_completion_timeout(&context->complete, timeout); + if (!res) { mlx5_fpga_warn(context->dev, "Failure waiting for IPSec command response\n"); - return -EINTR; + return -ETIMEDOUT; } if (context->status == MLX5_FPGA_IPSEC_SACMD_COMPLETE) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c index 881e2e55840c..645f83cac34d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c @@ -39,9 +39,81 @@ #include "mlx5_core.h" #include "eswitch.h" -int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, u32 underlay_qpn, - bool disconnect) +static int mlx5_cmd_stub_update_root_ft(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + u32 underlay_qpn, + bool disconnect) +{ + return 0; +} + +static int mlx5_cmd_stub_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 flags) +{ + return 0; +} + +static int mlx5_cmd_stub_destroy_flow_table(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft) +{ + return 0; +} + +static int mlx5_cmd_stub_modify_flow_table(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + struct mlx5_flow_table *next_ft) +{ + return 0; +} + +static int mlx5_cmd_stub_create_flow_group(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + u32 *in, + unsigned int *group_id) +{ + return 0; +} + +static int mlx5_cmd_stub_destroy_flow_group(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + unsigned int group_id) +{ + return 0; +} + +static int mlx5_cmd_stub_create_fte(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + struct mlx5_flow_group *group, + struct fs_fte *fte) +{ + return 0; +} + +static int mlx5_cmd_stub_update_fte(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + unsigned int group_id, + int modify_mask, + struct fs_fte *fte) +{ + return -EOPNOTSUPP; +} + +static int mlx5_cmd_stub_delete_fte(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + struct fs_fte *fte) +{ + return 0; +} + +static int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, u32 underlay_qpn, + bool disconnect) { u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)] = {0}; u32 out[MLX5_ST_SZ_DW(set_flow_table_root_out)] = {0}; @@ -71,12 +143,14 @@ int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev, 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 flags) +static 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 flags) { int en_encap_decap = !!(flags & MLX5_FLOW_TABLE_TUNNEL_EN); u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {0}; @@ -125,8 +199,8 @@ int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev, return err; } -int mlx5_cmd_destroy_flow_table(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft) +static 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)] = {0}; u32 out[MLX5_ST_SZ_DW(destroy_flow_table_out)] = {0}; @@ -143,9 +217,9 @@ int mlx5_cmd_destroy_flow_table(struct mlx5_core_dev *dev, 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) +static 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)] = {0}; u32 out[MLX5_ST_SZ_DW(modify_flow_table_out)] = {0}; @@ -188,10 +262,10 @@ int mlx5_cmd_modify_flow_table(struct mlx5_core_dev *dev, return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); } -int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - u32 *in, - unsigned int *group_id) +static int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + 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); @@ -213,9 +287,9 @@ int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev, return err; } -int mlx5_cmd_destroy_flow_group(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - unsigned int group_id) +static 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)] = {0}; u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)] = {0}; @@ -266,16 +340,17 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev, in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context); MLX5_SET(flow_context, in_flow_context, group_id, group_id); - MLX5_SET(flow_context, in_flow_context, flow_tag, fte->flow_tag); - MLX5_SET(flow_context, in_flow_context, action, fte->action); - MLX5_SET(flow_context, in_flow_context, encap_id, fte->encap_id); - MLX5_SET(flow_context, in_flow_context, modify_header_id, fte->modify_id); + MLX5_SET(flow_context, in_flow_context, flow_tag, fte->action.flow_tag); + MLX5_SET(flow_context, in_flow_context, action, fte->action.action); + MLX5_SET(flow_context, in_flow_context, encap_id, fte->action.encap_id); + MLX5_SET(flow_context, in_flow_context, modify_header_id, + fte->action.modify_id); in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context, match_value); memcpy(in_match_value, &fte->val, sizeof(fte->val)); in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination); - if (fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { + if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { int list_size = 0; list_for_each_entry(dst, &fte->node.children, node.list) { @@ -301,7 +376,7 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev, list_size); } - if (fte->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { + if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { int max_list_size = BIT(MLX5_CAP_FLOWTABLE_TYPE(dev, log_max_flow_counter, ft->type)); @@ -332,19 +407,21 @@ err_out: return err; } -int mlx5_cmd_create_fte(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - unsigned group_id, - struct fs_fte *fte) +static int mlx5_cmd_create_fte(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + struct mlx5_flow_group *group, + struct fs_fte *fte) { + unsigned int group_id = group->id; + return mlx5_cmd_set_fte(dev, 0, 0, ft, group_id, fte); } -int mlx5_cmd_update_fte(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - unsigned group_id, - int modify_mask, - struct fs_fte *fte) +static int mlx5_cmd_update_fte(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + unsigned int group_id, + int modify_mask, + struct fs_fte *fte) { int opmod; int atomic_mod_cap = MLX5_CAP_FLOWTABLE(dev, @@ -357,9 +434,9 @@ int mlx5_cmd_update_fte(struct mlx5_core_dev *dev, return mlx5_cmd_set_fte(dev, opmod, modify_mask, ft, group_id, fte); } -int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - unsigned int index) +static int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + struct fs_fte *fte) { u32 out[MLX5_ST_SZ_DW(delete_fte_out)] = {0}; u32 in[MLX5_ST_SZ_DW(delete_fte_in)] = {0}; @@ -367,7 +444,7 @@ int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev, MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY); MLX5_SET(delete_fte_in, in, table_type, ft->type); MLX5_SET(delete_fte_in, in, table_id, ft->id); - MLX5_SET(delete_fte_in, in, flow_index, index); + MLX5_SET(delete_fte_in, in, flow_index, fte->index); if (ft->vport) { MLX5_SET(delete_fte_in, in, vport_number, ft->vport); MLX5_SET(delete_fte_in, in, other_vport, 1); @@ -610,3 +687,53 @@ void mlx5_modify_header_dealloc(struct mlx5_core_dev *dev, u32 modify_header_id) mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); } + +static const struct mlx5_flow_cmds mlx5_flow_cmds = { + .create_flow_table = mlx5_cmd_create_flow_table, + .destroy_flow_table = mlx5_cmd_destroy_flow_table, + .modify_flow_table = mlx5_cmd_modify_flow_table, + .create_flow_group = mlx5_cmd_create_flow_group, + .destroy_flow_group = mlx5_cmd_destroy_flow_group, + .create_fte = mlx5_cmd_create_fte, + .update_fte = mlx5_cmd_update_fte, + .delete_fte = mlx5_cmd_delete_fte, + .update_root_ft = mlx5_cmd_update_root_ft, +}; + +static const struct mlx5_flow_cmds mlx5_flow_cmd_stubs = { + .create_flow_table = mlx5_cmd_stub_create_flow_table, + .destroy_flow_table = mlx5_cmd_stub_destroy_flow_table, + .modify_flow_table = mlx5_cmd_stub_modify_flow_table, + .create_flow_group = mlx5_cmd_stub_create_flow_group, + .destroy_flow_group = mlx5_cmd_stub_destroy_flow_group, + .create_fte = mlx5_cmd_stub_create_fte, + .update_fte = mlx5_cmd_stub_update_fte, + .delete_fte = mlx5_cmd_stub_delete_fte, + .update_root_ft = mlx5_cmd_stub_update_root_ft, +}; + +static const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void) +{ + return &mlx5_flow_cmds; +} + +static const struct mlx5_flow_cmds *mlx5_fs_cmd_get_stub_cmds(void) +{ + return &mlx5_flow_cmd_stubs; +} + +const struct mlx5_flow_cmds *mlx5_fs_cmd_get_default(enum fs_flow_table_type type) +{ + switch (type) { + case FS_FT_NIC_RX: + case FS_FT_ESW_EGRESS_ACL: + case FS_FT_ESW_INGRESS_ACL: + case FS_FT_FDB: + case FS_FT_SNIFFER_RX: + case FS_FT_SNIFFER_TX: + return mlx5_fs_cmd_get_fw_cmds(); + case FS_FT_NIC_TX: + default: + return mlx5_fs_cmd_get_stub_cmds(); + } +} diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h index 71e2d0f37ad9..6228ba7bfa1a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h @@ -33,46 +33,52 @@ #ifndef _MLX5_FS_CMD_ #define _MLX5_FS_CMD_ -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 flags); +#include "fs_core.h" -int mlx5_cmd_destroy_flow_table(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft); +struct mlx5_flow_cmds { + int (*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 flags); + int (*destroy_flow_table)(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft); -int mlx5_cmd_modify_flow_table(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - struct mlx5_flow_table *next_ft); + int (*modify_flow_table)(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + struct mlx5_flow_table *next_ft); -int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - u32 *in, unsigned int *group_id); + int (*create_flow_group)(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + u32 *in, + unsigned int *group_id); -int mlx5_cmd_destroy_flow_group(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - unsigned int group_id); + int (*destroy_flow_group)(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + unsigned int group_id); -int mlx5_cmd_create_fte(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - unsigned group_id, - struct fs_fte *fte); + int (*create_fte)(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + struct mlx5_flow_group *fg, + struct fs_fte *fte); -int mlx5_cmd_update_fte(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - unsigned group_id, - int modify_mask, - struct fs_fte *fte); + int (*update_fte)(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + unsigned int group_id, + int modify_mask, + struct fs_fte *fte); -int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - unsigned int index); + int (*delete_fte)(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + struct fs_fte *fte); -int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, u32 underlay_qpn, - bool disconnect); + int (*update_root_ft)(struct mlx5_core_dev *dev, + struct mlx5_flow_table *ft, + u32 underlay_qpn, + bool disconnect); +}; int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u32 *id); int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u32 id); @@ -90,4 +96,6 @@ void mlx5_cmd_fc_bulk_get(struct mlx5_core_dev *dev, struct mlx5_cmd_fc_bulk *b, u32 id, u64 *packets, u64 *bytes); +const struct mlx5_flow_cmds *mlx5_fs_cmd_get_default(enum fs_flow_table_type type); + #endif diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 31fc2cfac3b3..f9b82fad2446 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -37,6 +37,7 @@ #include "fs_core.h" #include "fs_cmd.h" #include "diag/fs_tracepoint.h" +#include "accel/ipsec.h" #define INIT_TREE_NODE_ARRAY_SIZE(...) (sizeof((struct init_tree_node[]){__VA_ARGS__}) /\ sizeof(struct init_tree_node)) @@ -425,15 +426,17 @@ static void del_sw_prio(struct fs_node *node) static void del_hw_flow_table(struct fs_node *node) { + struct mlx5_flow_root_namespace *root; struct mlx5_flow_table *ft; struct mlx5_core_dev *dev; int err; fs_get_obj(ft, node); dev = get_dev(&ft->node); + root = find_root(&ft->node); if (node->active) { - err = mlx5_cmd_destroy_flow_table(dev, ft); + err = root->cmds->destroy_flow_table(dev, ft); if (err) mlx5_core_warn(dev, "flow steering can't destroy ft\n"); } @@ -454,6 +457,7 @@ static void del_sw_flow_table(struct fs_node *node) static void del_sw_hw_rule(struct fs_node *node) { + struct mlx5_flow_root_namespace *root; struct mlx5_flow_rule *rule; struct mlx5_flow_table *ft; struct mlx5_flow_group *fg; @@ -477,19 +481,20 @@ static void del_sw_hw_rule(struct fs_node *node) if (rule->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER && --fte->dests_size) { modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION); - fte->action &= ~MLX5_FLOW_CONTEXT_ACTION_COUNT; + fte->action.action &= ~MLX5_FLOW_CONTEXT_ACTION_COUNT; update_fte = true; goto out; } - if ((fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) && + if ((fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) && --fte->dests_size) { modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_DESTINATION_LIST), update_fte = true; } out: + root = find_root(&ft->node); if (update_fte && fte->dests_size) { - err = mlx5_cmd_update_fte(dev, ft, fg->id, modify_mask, fte); + err = root->cmds->update_fte(dev, ft, fg->id, modify_mask, fte); if (err) mlx5_core_warn(dev, "%s can't del rule fg id=%d fte_index=%d\n", @@ -500,6 +505,7 @@ out: static void del_hw_fte(struct fs_node *node) { + struct mlx5_flow_root_namespace *root; struct mlx5_flow_table *ft; struct mlx5_flow_group *fg; struct mlx5_core_dev *dev; @@ -512,9 +518,9 @@ static void del_hw_fte(struct fs_node *node) trace_mlx5_fs_del_fte(fte); dev = get_dev(&ft->node); + root = find_root(&ft->node); if (node->active) { - err = mlx5_cmd_delete_fte(dev, ft, - fte->index); + err = root->cmds->delete_fte(dev, ft, fte); if (err) mlx5_core_warn(dev, "flow steering can't delete fte in index %d of flow group id %d\n", @@ -542,6 +548,7 @@ static void del_sw_fte(struct fs_node *node) static void del_hw_flow_group(struct fs_node *node) { + struct mlx5_flow_root_namespace *root; struct mlx5_flow_group *fg; struct mlx5_flow_table *ft; struct mlx5_core_dev *dev; @@ -551,7 +558,8 @@ static void del_hw_flow_group(struct fs_node *node) dev = get_dev(&ft->node); trace_mlx5_fs_del_fg(fg); - if (fg->node.active && mlx5_cmd_destroy_flow_group(dev, ft, fg->id)) + root = find_root(&ft->node); + if (fg->node.active && root->cmds->destroy_flow_group(dev, ft, fg->id)) mlx5_core_warn(dev, "flow steering can't destroy fg %d of ft %d\n", fg->id, ft->id); } @@ -615,10 +623,7 @@ static struct fs_fte *alloc_fte(struct mlx5_flow_table *ft, memcpy(fte->val, match_value, sizeof(fte->val)); fte->node.type = FS_TYPE_FLOW_ENTRY; - fte->flow_tag = flow_act->flow_tag; - fte->action = flow_act->action; - fte->encap_id = flow_act->encap_id; - fte->modify_id = flow_act->modify_id; + fte->action = *flow_act; tree_init_node(&fte->node, del_hw_fte, del_sw_fte); @@ -797,15 +802,14 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev, struct fs_prio *prio, struct mlx5_flow_table *ft) { + struct mlx5_flow_root_namespace *root = find_root(&prio->node); struct mlx5_flow_table *iter; int i = 0; int err; fs_for_each_ft(iter, prio) { i++; - err = mlx5_cmd_modify_flow_table(dev, - iter, - ft); + err = root->cmds->modify_flow_table(dev, iter, ft); if (err) { mlx5_core_warn(dev, "Failed to modify flow table %d\n", iter->id); @@ -853,12 +857,12 @@ static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio if (list_empty(&root->underlay_qpns)) { /* Don't set any QPN (zero) in case QPN list is empty */ qpn = 0; - err = mlx5_cmd_update_root_ft(root->dev, ft, qpn, false); + err = root->cmds->update_root_ft(root->dev, ft, qpn, false); } else { list_for_each_entry(uqp, &root->underlay_qpns, list) { qpn = uqp->qpn; - err = mlx5_cmd_update_root_ft(root->dev, ft, qpn, - false); + err = root->cmds->update_root_ft(root->dev, ft, + qpn, false); if (err) break; } @@ -877,6 +881,7 @@ static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio static int _mlx5_modify_rule_destination(struct mlx5_flow_rule *rule, struct mlx5_flow_destination *dest) { + struct mlx5_flow_root_namespace *root; struct mlx5_flow_table *ft; struct mlx5_flow_group *fg; struct fs_fte *fte; @@ -884,17 +889,16 @@ static int _mlx5_modify_rule_destination(struct mlx5_flow_rule *rule, int err = 0; fs_get_obj(fte, rule->node.parent); - if (!(fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST)) + if (!(fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST)) return -EINVAL; down_write_ref_node(&fte->node); fs_get_obj(fg, fte->node.parent); fs_get_obj(ft, fg->node.parent); memcpy(&rule->dest_attr, dest, sizeof(*dest)); - err = mlx5_cmd_update_fte(get_dev(&ft->node), - ft, fg->id, - modify_mask, - fte); + root = find_root(&ft->node); + err = root->cmds->update_fte(get_dev(&ft->node), ft, fg->id, + modify_mask, fte); up_write_ref_node(&fte->node); return err; @@ -1035,9 +1039,9 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table); log_table_sz = ft->max_fte ? ilog2(ft->max_fte) : 0; next_ft = find_next_chained_ft(fs_prio); - err = mlx5_cmd_create_flow_table(root->dev, ft->vport, ft->op_mod, ft->type, - ft->level, log_table_sz, next_ft, &ft->id, - ft->flags); + err = root->cmds->create_flow_table(root->dev, ft->vport, ft->op_mod, + ft->type, ft->level, log_table_sz, + next_ft, &ft->id, ft->flags); if (err) goto free_ft; @@ -1053,7 +1057,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa mutex_unlock(&root->chain_lock); return ft; destroy_ft: - mlx5_cmd_destroy_flow_table(root->dev, ft); + root->cmds->destroy_flow_table(root->dev, ft); free_ft: kfree(ft); unlock_root: @@ -1125,6 +1129,7 @@ EXPORT_SYMBOL(mlx5_create_auto_grouped_flow_table); struct mlx5_flow_group *mlx5_create_flow_group(struct mlx5_flow_table *ft, u32 *fg_in) { + struct mlx5_flow_root_namespace *root = find_root(&ft->node); void *match_criteria = MLX5_ADDR_OF(create_flow_group_in, fg_in, match_criteria); u8 match_criteria_enable = MLX5_GET(create_flow_group_in, @@ -1152,7 +1157,7 @@ struct mlx5_flow_group *mlx5_create_flow_group(struct mlx5_flow_table *ft, if (IS_ERR(fg)) return fg; - err = mlx5_cmd_create_flow_group(dev, ft, fg_in, &fg->id); + err = root->cmds->create_flow_group(dev, ft, fg_in, &fg->id); if (err) { tree_put_node(&fg->node); return ERR_PTR(err); @@ -1275,6 +1280,7 @@ add_rule_fte(struct fs_fte *fte, int dest_num, bool update_action) { + struct mlx5_flow_root_namespace *root; struct mlx5_flow_handle *handle; struct mlx5_flow_table *ft; int modify_mask = 0; @@ -1290,12 +1296,13 @@ add_rule_fte(struct fs_fte *fte, modify_mask |= BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION); fs_get_obj(ft, fg->node.parent); + root = find_root(&fg->node); if (!(fte->status & FS_FTE_STATUS_EXISTING)) - err = mlx5_cmd_create_fte(get_dev(&ft->node), - ft, fg->id, fte); + err = root->cmds->create_fte(get_dev(&ft->node), + ft, fg, fte); else - err = mlx5_cmd_update_fte(get_dev(&ft->node), - ft, fg->id, modify_mask, fte); + err = root->cmds->update_fte(get_dev(&ft->node), ft, fg->id, + modify_mask, fte); if (err) goto free_handle; @@ -1360,6 +1367,7 @@ out: static int create_auto_flow_group(struct mlx5_flow_table *ft, struct mlx5_flow_group *fg) { + struct mlx5_flow_root_namespace *root = find_root(&ft->node); struct mlx5_core_dev *dev = get_dev(&ft->node); int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); void *match_criteria_addr; @@ -1380,7 +1388,7 @@ static int create_auto_flow_group(struct mlx5_flow_table *ft, memcpy(match_criteria_addr, fg->mask.match_criteria, sizeof(fg->mask.match_criteria)); - err = mlx5_cmd_create_flow_group(dev, ft, in, &fg->id); + err = root->cmds->create_flow_group(dev, ft, in, &fg->id); if (!err) { fg->node.active = true; trace_mlx5_fs_add_fg(fg); @@ -1438,16 +1446,17 @@ static bool check_conflicting_actions(u32 action1, u32 action2) static int check_conflicting_ftes(struct fs_fte *fte, const struct mlx5_flow_act *flow_act) { - if (check_conflicting_actions(flow_act->action, fte->action)) { + if (check_conflicting_actions(flow_act->action, fte->action.action)) { mlx5_core_warn(get_dev(&fte->node), "Found two FTEs with conflicting actions\n"); return -EEXIST; } - if (fte->flow_tag != flow_act->flow_tag) { + if (flow_act->has_flow_tag && + fte->action.flow_tag != flow_act->flow_tag) { mlx5_core_warn(get_dev(&fte->node), "FTE flow tag %u already exists with different flow tag %u\n", - fte->flow_tag, + fte->action.flow_tag, flow_act->flow_tag); return -EEXIST; } @@ -1471,12 +1480,12 @@ static struct mlx5_flow_handle *add_rule_fg(struct mlx5_flow_group *fg, if (ret) return ERR_PTR(ret); - old_action = fte->action; - fte->action |= flow_act->action; + old_action = fte->action.action; + fte->action.action |= flow_act->action; handle = add_rule_fte(fte, fg, dest, dest_num, old_action != flow_act->action); if (IS_ERR(handle)) { - fte->action = old_action; + fte->action.action = old_action; return handle; } trace_mlx5_fs_set_fte(fte, false); @@ -1919,7 +1928,6 @@ static int update_root_ft_destroy(struct mlx5_flow_table *ft) return 0; new_root_ft = find_next_ft(ft); - if (!new_root_ft) { root->root_ft = NULL; return 0; @@ -1928,13 +1936,14 @@ static int update_root_ft_destroy(struct mlx5_flow_table *ft) |
