Commit b8922a73 authored by Saeed Mahameed's avatar Saeed Mahameed

net/mlx5e: API to manipulate TTC rules destinations

Store the default destinations of the on-load generated TTC
(Traffic Type Classifier) rules in the ttc rules table.

Introduce TTC API functions to manipulate/restore and get the TTC rule
destination and use these API functions in arfs implementation.

This will allow a better decoupling between TTC implementation and its
users.
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarTariq Toukan <tariqt@mellanox.com>
Reviewed-by: default avatarMaxim Mikityanskiy <maximmi@mellanox.com>
parent c293ac92
...@@ -105,11 +105,16 @@ enum mlx5e_tunnel_types { ...@@ -105,11 +105,16 @@ enum mlx5e_tunnel_types {
bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev); bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev);
struct mlx5e_ttc_rule {
struct mlx5_flow_handle *rule;
struct mlx5_flow_destination default_dest;
};
/* L3/L4 traffic type classifier */ /* L3/L4 traffic type classifier */
struct mlx5e_ttc_table { struct mlx5e_ttc_table {
struct mlx5e_flow_table ft; struct mlx5e_flow_table ft;
struct mlx5_flow_handle *rules[MLX5E_NUM_TT]; struct mlx5e_ttc_rule rules[MLX5E_NUM_TT];
struct mlx5_flow_handle *tunnel_rules[MLX5E_NUM_TUNNEL_TT]; struct mlx5_flow_handle *tunnel_rules[MLX5E_NUM_TUNNEL_TT];
}; };
/* NIC prio FTS */ /* NIC prio FTS */
...@@ -248,6 +253,11 @@ void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv, ...@@ -248,6 +253,11 @@ void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv,
struct mlx5e_ttc_table *ttc); struct mlx5e_ttc_table *ttc);
void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft); void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft);
int mlx5e_ttc_fwd_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type,
struct mlx5_flow_destination *new_dest);
struct mlx5_flow_destination
mlx5e_ttc_get_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type);
int mlx5e_ttc_fwd_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type);
void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv); void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv);
void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv); void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv);
......
...@@ -90,23 +90,15 @@ static enum mlx5e_traffic_types arfs_get_tt(enum arfs_type type) ...@@ -90,23 +90,15 @@ static enum mlx5e_traffic_types arfs_get_tt(enum arfs_type type)
static int arfs_disable(struct mlx5e_priv *priv) static int arfs_disable(struct mlx5e_priv *priv)
{ {
struct mlx5_flow_destination dest = {}; int err, i;
struct mlx5e_tir *tir = priv->indir_tir;
int err = 0;
int tt;
int i;
dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
for (i = 0; i < ARFS_NUM_TYPES; i++) { for (i = 0; i < ARFS_NUM_TYPES; i++) {
dest.tir_num = tir[i].tirn; /* Modify ttc rules destination back to their default */
tt = arfs_get_tt(i); err = mlx5e_ttc_fwd_default_dest(priv, arfs_get_tt(i));
/* Modify ttc rules destination to bypass the aRFS tables*/
err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt],
&dest, NULL);
if (err) { if (err) {
netdev_err(priv->netdev, netdev_err(priv->netdev,
"%s: modify ttc destination failed\n", "%s: modify ttc[%d] default destination failed, err(%d)\n",
__func__); __func__, arfs_get_tt(i), err);
return err; return err;
} }
} }
...@@ -125,21 +117,17 @@ int mlx5e_arfs_disable(struct mlx5e_priv *priv) ...@@ -125,21 +117,17 @@ int mlx5e_arfs_disable(struct mlx5e_priv *priv)
int mlx5e_arfs_enable(struct mlx5e_priv *priv) int mlx5e_arfs_enable(struct mlx5e_priv *priv)
{ {
struct mlx5_flow_destination dest = {}; struct mlx5_flow_destination dest = {};
int err = 0; int err, i;
int tt;
int i;
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
for (i = 0; i < ARFS_NUM_TYPES; i++) { for (i = 0; i < ARFS_NUM_TYPES; i++) {
dest.ft = priv->fs.arfs.arfs_tables[i].ft.t; dest.ft = priv->fs.arfs.arfs_tables[i].ft.t;
tt = arfs_get_tt(i);
/* Modify ttc rules destination to point on the aRFS FTs */ /* Modify ttc rules destination to point on the aRFS FTs */
err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt], err = mlx5e_ttc_fwd_dest(priv, arfs_get_tt(i), &dest);
&dest, NULL);
if (err) { if (err) {
netdev_err(priv->netdev, netdev_err(priv->netdev,
"%s: modify ttc destination failed err=%d\n", "%s: modify ttc[%d] dest to arfs, failed err(%d)\n",
__func__, err); __func__, arfs_get_tt(i), err);
arfs_disable(priv); arfs_disable(priv);
return err; return err;
} }
...@@ -186,8 +174,10 @@ static int arfs_add_default_rule(struct mlx5e_priv *priv, ...@@ -186,8 +174,10 @@ static int arfs_add_default_rule(struct mlx5e_priv *priv,
return -EINVAL; return -EINVAL;
} }
/* FIXME: Must use mlx5e_ttc_get_default_dest(),
* but can't since TTC default is not setup yet !
*/
dest.tir_num = tir[tt].tirn; dest.tir_num = tir[tt].tirn;
arfs_t->default_rule = mlx5_add_flow_rules(arfs_t->ft.t, NULL, arfs_t->default_rule = mlx5_add_flow_rules(arfs_t->ft.t, NULL,
&flow_act, &flow_act,
&dest, 1); &dest, 1);
......
...@@ -672,9 +672,9 @@ static void mlx5e_cleanup_ttc_rules(struct mlx5e_ttc_table *ttc) ...@@ -672,9 +672,9 @@ static void mlx5e_cleanup_ttc_rules(struct mlx5e_ttc_table *ttc)
int i; int i;
for (i = 0; i < MLX5E_NUM_TT; i++) { for (i = 0; i < MLX5E_NUM_TT; i++) {
if (!IS_ERR_OR_NULL(ttc->rules[i])) { if (!IS_ERR_OR_NULL(ttc->rules[i].rule)) {
mlx5_del_flow_rules(ttc->rules[i]); mlx5_del_flow_rules(ttc->rules[i].rule);
ttc->rules[i] = NULL; ttc->rules[i].rule = NULL;
} }
} }
...@@ -857,7 +857,8 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv, ...@@ -857,7 +857,8 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv,
struct mlx5e_ttc_table *ttc) struct mlx5e_ttc_table *ttc)
{ {
struct mlx5_flow_destination dest = {}; struct mlx5_flow_destination dest = {};
struct mlx5_flow_handle **rules; struct mlx5_flow_handle **trules;
struct mlx5e_ttc_rule *rules;
struct mlx5_flow_table *ft; struct mlx5_flow_table *ft;
int tt; int tt;
int err; int err;
...@@ -867,39 +868,47 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv, ...@@ -867,39 +868,47 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv,
dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
for (tt = 0; tt < MLX5E_NUM_TT; tt++) { for (tt = 0; tt < MLX5E_NUM_TT; tt++) {
struct mlx5e_ttc_rule *rule = &rules[tt];
if (tt == MLX5E_TT_ANY) if (tt == MLX5E_TT_ANY)
dest.tir_num = params->any_tt_tirn; dest.tir_num = params->any_tt_tirn;
else else
dest.tir_num = params->indir_tirn[tt]; dest.tir_num = params->indir_tirn[tt];
rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
ttc_rules[tt].etype, rule->rule = mlx5e_generate_ttc_rule(priv, ft, &dest,
ttc_rules[tt].proto); ttc_rules[tt].etype,
if (IS_ERR(rules[tt])) ttc_rules[tt].proto);
if (IS_ERR(rule->rule)) {
err = PTR_ERR(rule->rule);
rule->rule = NULL;
goto del_rules; goto del_rules;
}
rule->default_dest = dest;
} }
if (!params->inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev)) if (!params->inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev))
return 0; return 0;
rules = ttc->tunnel_rules; trules = ttc->tunnel_rules;
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
dest.ft = params->inner_ttc->ft.t; dest.ft = params->inner_ttc->ft.t;
for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) { for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) {
if (!mlx5e_tunnel_proto_supported(priv->mdev, if (!mlx5e_tunnel_proto_supported(priv->mdev,
ttc_tunnel_rules[tt].proto)) ttc_tunnel_rules[tt].proto))
continue; continue;
rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest, trules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
ttc_tunnel_rules[tt].etype, ttc_tunnel_rules[tt].etype,
ttc_tunnel_rules[tt].proto); ttc_tunnel_rules[tt].proto);
if (IS_ERR(rules[tt])) if (IS_ERR(trules[tt])) {
err = PTR_ERR(trules[tt]);
trules[tt] = NULL;
goto del_rules; goto del_rules;
}
} }
return 0; return 0;
del_rules: del_rules:
err = PTR_ERR(rules[tt]);
rules[tt] = NULL;
mlx5e_cleanup_ttc_rules(ttc); mlx5e_cleanup_ttc_rules(ttc);
return err; return err;
} }
...@@ -1015,33 +1024,38 @@ static int mlx5e_generate_inner_ttc_table_rules(struct mlx5e_priv *priv, ...@@ -1015,33 +1024,38 @@ static int mlx5e_generate_inner_ttc_table_rules(struct mlx5e_priv *priv,
struct mlx5e_ttc_table *ttc) struct mlx5e_ttc_table *ttc)
{ {
struct mlx5_flow_destination dest = {}; struct mlx5_flow_destination dest = {};
struct mlx5_flow_handle **rules; struct mlx5e_ttc_rule *rules;
struct mlx5_flow_table *ft; struct mlx5_flow_table *ft;
int err; int err;
int tt; int tt;
ft = ttc->ft.t; ft = ttc->ft.t;
rules = ttc->rules; rules = ttc->rules;
dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
for (tt = 0; tt < MLX5E_NUM_TT; tt++) { for (tt = 0; tt < MLX5E_NUM_TT; tt++) {
struct mlx5e_ttc_rule *rule = &rules[tt];
if (tt == MLX5E_TT_ANY) if (tt == MLX5E_TT_ANY)
dest.tir_num = params->any_tt_tirn; dest.tir_num = params->any_tt_tirn;
else else
dest.tir_num = params->indir_tirn[tt]; dest.tir_num = params->indir_tirn[tt];
rules[tt] = mlx5e_generate_inner_ttc_rule(priv, ft, &dest, rule->rule = mlx5e_generate_inner_ttc_rule(priv, ft, &dest,
ttc_rules[tt].etype, ttc_rules[tt].etype,
ttc_rules[tt].proto); ttc_rules[tt].proto);
if (IS_ERR(rules[tt])) if (IS_ERR(rule->rule)) {
err = PTR_ERR(rule->rule);
rule->rule = NULL;
goto del_rules; goto del_rules;
}
rule->default_dest = dest;
} }
return 0; return 0;
del_rules: del_rules:
err = PTR_ERR(rules[tt]);
rules[tt] = NULL;
mlx5e_cleanup_ttc_rules(ttc); mlx5e_cleanup_ttc_rules(ttc);
return err; return err;
} }
...@@ -1210,6 +1224,30 @@ int mlx5e_create_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, ...@@ -1210,6 +1224,30 @@ int mlx5e_create_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params,
return err; return err;
} }
int mlx5e_ttc_fwd_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type,
struct mlx5_flow_destination *new_dest)
{
return mlx5_modify_rule_destination(priv->fs.ttc.rules[type].rule, new_dest, NULL);
}
struct mlx5_flow_destination
mlx5e_ttc_get_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type)
{
struct mlx5_flow_destination *dest = &priv->fs.ttc.rules[type].default_dest;
WARN_ONCE(dest->type != MLX5_FLOW_DESTINATION_TYPE_TIR,
"TTC[%d] default dest is not setup yet", type);
return *dest;
}
int mlx5e_ttc_fwd_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type)
{
struct mlx5_flow_destination dest = mlx5e_ttc_get_default_dest(priv, type);
return mlx5e_ttc_fwd_dest(priv, type, &dest);
}
static void mlx5e_del_l2_flow_rule(struct mlx5e_priv *priv, static void mlx5e_del_l2_flow_rule(struct mlx5e_priv *priv,
struct mlx5e_l2_rule *ai) struct mlx5e_l2_rule *ai)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment