Commit f52f2fae authored by Lama Kayal's avatar Lama Kayal Committed by Saeed Mahameed
Browse files

net/mlx5e: Introduce flow steering API



Move mlx5e_flow_steering struct to fs_en.c to make it private.
Introduce flow_steering API and let other files go through it.

Signed-off-by: default avatarLama Kayal <lkayal@nvidia.com>
Reviewed-by: default avatarTariq Toukan <tariqt@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 97d29b92
Loading
Loading
Loading
Loading
+30 −25
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include "lib/fs_ttc.h"

struct mlx5e_post_act;
struct mlx5e_tc_table;

enum {
	MLX5E_TC_FT_LEVEL = 0,
@@ -83,6 +84,7 @@ enum {
#endif
};

struct mlx5e_flow_steering;
struct mlx5e_priv;

#ifdef CONFIG_MLX5_EN_RXNFC
@@ -142,31 +144,6 @@ struct mlx5e_fs_udp;
struct mlx5e_fs_any;
struct mlx5e_ptp_fs;

struct mlx5e_flow_steering {
	bool				state_destroy;
	bool				vlan_strip_disable;
	struct mlx5_core_dev		*mdev;
	struct mlx5_flow_namespace      *ns;
#ifdef CONFIG_MLX5_EN_RXNFC
	struct mlx5e_ethtool_steering   ethtool;
#endif
	struct mlx5e_tc_table           *tc;
	struct mlx5e_promisc_table      promisc;
	struct mlx5e_vlan_table         *vlan;
	struct mlx5e_l2_table           l2;
	struct mlx5_ttc_table           *ttc;
	struct mlx5_ttc_table           *inner_ttc;
#ifdef CONFIG_MLX5_EN_ARFS
	struct mlx5e_arfs_tables       *arfs;
#endif
#ifdef CONFIG_MLX5_EN_TLS
	struct mlx5e_accel_fs_tcp      *accel_tcp;
#endif
	struct mlx5e_fs_udp            *udp;
	struct mlx5e_fs_any            *any;
	struct mlx5e_ptp_fs            *ptp_fs;
};

void mlx5e_set_ttc_params(struct mlx5e_priv *priv,
			  struct ttc_params *ttc_params, bool tunnel);

@@ -185,7 +162,35 @@ struct mlx5e_flow_steering *mlx5e_fs_init(const struct mlx5e_profile *profile,
					  struct mlx5_core_dev *mdev,
					  bool state_destroy);
void mlx5e_fs_cleanup(struct mlx5e_flow_steering *fs);
struct mlx5e_vlan_table *mlx5e_fs_get_vlan(struct mlx5e_flow_steering *fs);
void mlx5e_fs_set_tc(struct mlx5e_flow_steering *fs, struct mlx5e_tc_table *tc);
struct mlx5e_tc_table *mlx5e_fs_get_tc(struct mlx5e_flow_steering *fs);
struct mlx5e_l2_table *mlx5e_fs_get_l2(struct mlx5e_flow_steering *fs);
struct mlx5_flow_namespace *mlx5e_fs_get_ns(struct mlx5e_flow_steering *fs, bool egress);
void mlx5e_fs_set_ns(struct mlx5e_flow_steering *fs, struct mlx5_flow_namespace *ns, bool egress);
#ifdef CONFIG_MLX5_EN_RXNFC
struct mlx5e_ethtool_steering *mlx5e_fs_get_ethtool(struct mlx5e_flow_steering *fs);
#endif
struct mlx5_ttc_table *mlx5e_fs_get_ttc(struct mlx5e_flow_steering *fs, bool inner);
void mlx5e_fs_set_ttc(struct mlx5e_flow_steering *fs, struct mlx5_ttc_table *ttc, bool inner);
#ifdef CONFIG_MLX5_EN_ARFS
struct mlx5e_arfs_tables *mlx5e_fs_get_arfs(struct mlx5e_flow_steering *fs);
void mlx5e_fs_set_arfs(struct mlx5e_flow_steering *fs, struct mlx5e_arfs_tables *arfs);
#endif
struct mlx5e_ptp_fs *mlx5e_fs_get_ptp(struct mlx5e_flow_steering *fs);
void mlx5e_fs_set_ptp(struct mlx5e_flow_steering *fs, struct mlx5e_ptp_fs *ptp_fs);
struct mlx5e_fs_any *mlx5e_fs_get_any(struct mlx5e_flow_steering *fs);
void mlx5e_fs_set_any(struct mlx5e_flow_steering *fs, struct mlx5e_fs_any *any);
struct mlx5e_fs_udp *mlx5e_fs_get_udp(struct mlx5e_flow_steering *fs);
void mlx5e_fs_set_udp(struct mlx5e_flow_steering *fs, struct mlx5e_fs_udp *udp);
#ifdef CONFIG_MLX5_EN_TLS
struct mlx5e_accel_fs_tcp *mlx5e_fs_get_accel_tcp(struct mlx5e_flow_steering *fs);
void mlx5e_fs_set_accel_tcp(struct mlx5e_flow_steering *fs, struct mlx5e_accel_fs_tcp *accel_tcp);
#endif
void mlx5e_fs_set_state_destroy(struct mlx5e_flow_steering *fs, bool state_destroy);
void mlx5e_fs_set_vlan_strip_disable(struct mlx5e_flow_steering *fs, bool vlan_strip_disable);

struct mlx5_core_dev *mlx5e_fs_get_mdev(struct mlx5e_flow_steering *fs);
int mlx5e_add_vlan_trap(struct mlx5e_priv *priv, int  trap_id, int tir_num);
void mlx5e_remove_vlan_trap(struct mlx5e_priv *priv);
int mlx5e_add_mac_trap(struct mlx5e_priv *priv, int  trap_id, int tir_num);
+52 −41
Original line number Diff line number Diff line
@@ -78,13 +78,13 @@ mlx5e_fs_tt_redirect_udp_add_rule(struct mlx5e_priv *priv,
				  enum mlx5_traffic_types ttc_type,
				  u32 tir_num, u16 d_port)
{
	struct mlx5e_fs_udp *fs_udp = mlx5e_fs_get_udp(priv->fs);
	enum fs_udp_type type = tt2fs_udp(ttc_type);
	struct mlx5_flow_destination dest = {};
	struct mlx5_flow_table *ft = NULL;
	MLX5_DECLARE_FLOW_ACT(flow_act);
	struct mlx5_flow_handle *rule;
	struct mlx5_flow_spec *spec;
	struct mlx5e_fs_udp *fs_udp;
	int err;

	if (type == FS_UDP_NUM_TYPES)
@@ -94,7 +94,6 @@ mlx5e_fs_tt_redirect_udp_add_rule(struct mlx5e_priv *priv,
	if (!spec)
		return ERR_PTR(-ENOMEM);

	fs_udp = priv->fs->udp;
	ft = fs_udp->tables[type].t;

	fs_udp_set_dport_flow(spec, type, d_port);
@@ -114,17 +113,17 @@ mlx5e_fs_tt_redirect_udp_add_rule(struct mlx5e_priv *priv,

static int fs_udp_add_default_rule(struct mlx5e_priv *priv, enum fs_udp_type type)
{
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(priv->fs, false);
	struct mlx5e_fs_udp *fs_udp = mlx5e_fs_get_udp(priv->fs);
	struct mlx5e_flow_table *fs_udp_t;
	struct mlx5_flow_destination dest;
	MLX5_DECLARE_FLOW_ACT(flow_act);
	struct mlx5_flow_handle *rule;
	struct mlx5e_fs_udp *fs_udp;
	int err;

	fs_udp = priv->fs->udp;
	fs_udp_t = &fs_udp->tables[type];

	dest = mlx5_ttc_get_default_dest(priv->fs->ttc, fs_udp2tt(type));
	dest = mlx5_ttc_get_default_dest(ttc, fs_udp2tt(type));
	rule = mlx5_add_flow_rules(fs_udp_t->t, NULL, &flow_act, &dest, 1);
	if (IS_ERR(rule)) {
		err = PTR_ERR(rule);
@@ -208,7 +207,9 @@ static int fs_udp_create_groups(struct mlx5e_flow_table *ft, enum fs_udp_type ty

static int fs_udp_create_table(struct mlx5e_priv *priv, enum fs_udp_type type)
{
	struct mlx5e_flow_table *ft = &priv->fs->udp->tables[type];
	struct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(priv->fs, false);
	struct mlx5e_fs_udp *fs_udp = mlx5e_fs_get_udp(priv->fs);
	struct mlx5e_flow_table *ft = &fs_udp->tables[type];
	struct mlx5_flow_table_attr ft_attr = {};
	int err;

@@ -218,7 +219,7 @@ static int fs_udp_create_table(struct mlx5e_priv *priv, enum fs_udp_type type)
	ft_attr.level = MLX5E_FS_TT_UDP_FT_LEVEL;
	ft_attr.prio = MLX5E_NIC_PRIO;

	ft->t = mlx5_create_flow_table(priv->fs->ns, &ft_attr);
	ft->t = mlx5_create_flow_table(ns, &ft_attr);
	if (IS_ERR(ft->t)) {
		err = PTR_ERR(ft->t);
		ft->t = NULL;
@@ -255,11 +256,12 @@ static void fs_udp_destroy_table(struct mlx5e_fs_udp *fs_udp, int i)

static int fs_udp_disable(struct mlx5e_priv *priv)
{
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(priv->fs, false);
	int err, i;

	for (i = 0; i < FS_UDP_NUM_TYPES; i++) {
		/* Modify ttc rules destination to point back to the indir TIRs */
		err = mlx5_ttc_fwd_default_dest(priv->fs->ttc, fs_udp2tt(i));
		err = mlx5_ttc_fwd_default_dest(ttc, fs_udp2tt(i));
		if (err) {
			netdev_err(priv->netdev,
				   "%s: modify ttc[%d] default destination failed, err(%d)\n",
@@ -273,15 +275,17 @@ static int fs_udp_disable(struct mlx5e_priv *priv)

static int fs_udp_enable(struct mlx5e_priv *priv)
{
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(priv->fs, false);
	struct mlx5e_fs_udp *udp = mlx5e_fs_get_udp(priv->fs);
	struct mlx5_flow_destination dest = {};
	int err, i;

	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
	for (i = 0; i < FS_UDP_NUM_TYPES; i++) {
		dest.ft = priv->fs->udp->tables[i].t;
		dest.ft = udp->tables[i].t;

		/* Modify ttc rules destination to point on the accel_fs FTs */
		err = mlx5_ttc_fwd_dest(priv->fs->ttc, fs_udp2tt(i), &dest);
		err = mlx5_ttc_fwd_dest(ttc, fs_udp2tt(i), &dest);
		if (err) {
			netdev_err(priv->netdev,
				   "%s: modify ttc[%d] destination to accel failed, err(%d)\n",
@@ -294,7 +298,7 @@ static int fs_udp_enable(struct mlx5e_priv *priv)

void mlx5e_fs_tt_redirect_udp_destroy(struct mlx5e_priv *priv)
{
	struct mlx5e_fs_udp *fs_udp = priv->fs->udp;
	struct mlx5e_fs_udp *fs_udp = mlx5e_fs_get_udp(priv->fs);
	int i;

	if (!fs_udp)
@@ -309,21 +313,23 @@ void mlx5e_fs_tt_redirect_udp_destroy(struct mlx5e_priv *priv)
		fs_udp_destroy_table(fs_udp, i);

	kfree(fs_udp);
	priv->fs->udp = NULL;
	mlx5e_fs_set_udp(priv->fs, NULL);
}

int mlx5e_fs_tt_redirect_udp_create(struct mlx5e_priv *priv)
{
	struct mlx5e_fs_udp *udp = mlx5e_fs_get_udp(priv->fs);
	int i, err;

	if (priv->fs->udp) {
		priv->fs->udp->ref_cnt++;
	if (udp) {
		udp->ref_cnt++;
		return 0;
	}

	priv->fs->udp = kzalloc(sizeof(*priv->fs->udp), GFP_KERNEL);
	if (!priv->fs->udp)
	udp = kzalloc(sizeof(*udp), GFP_KERNEL);
	if (!udp)
		return -ENOMEM;
	mlx5e_fs_set_udp(priv->fs, udp);

	for (i = 0; i < FS_UDP_NUM_TYPES; i++) {
		err = fs_udp_create_table(priv, i);
@@ -335,16 +341,16 @@ int mlx5e_fs_tt_redirect_udp_create(struct mlx5e_priv *priv)
	if (err)
		goto err_destroy_tables;

	priv->fs->udp->ref_cnt = 1;
	udp->ref_cnt = 1;

	return 0;

err_destroy_tables:
	while (--i >= 0)
		fs_udp_destroy_table(priv->fs->udp, i);
		fs_udp_destroy_table(udp, i);

	kfree(priv->fs->udp);
	priv->fs->udp = NULL;
	kfree(udp);
	mlx5e_fs_set_udp(priv->fs, NULL);
	return err;
}

@@ -359,19 +365,18 @@ struct mlx5_flow_handle *
mlx5e_fs_tt_redirect_any_add_rule(struct mlx5e_priv *priv,
				  u32 tir_num, u16 ether_type)
{
	struct mlx5e_fs_any *fs_any = mlx5e_fs_get_any(priv->fs);
	struct mlx5_flow_destination dest = {};
	struct mlx5_flow_table *ft = NULL;
	MLX5_DECLARE_FLOW_ACT(flow_act);
	struct mlx5_flow_handle *rule;
	struct mlx5_flow_spec *spec;
	struct mlx5e_fs_any *fs_any;
	int err;

	spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
	if (!spec)
		return ERR_PTR(-ENOMEM);

	fs_any = priv->fs->any;
	ft = fs_any->table.t;

	fs_any_set_ethertype_flow(spec, ether_type);
@@ -391,17 +396,16 @@ mlx5e_fs_tt_redirect_any_add_rule(struct mlx5e_priv *priv,

static int fs_any_add_default_rule(struct mlx5e_priv *priv)
{
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(priv->fs, false);
	struct mlx5e_fs_any *fs_any = mlx5e_fs_get_any(priv->fs);
	struct mlx5e_flow_table *fs_any_t;
	struct mlx5_flow_destination dest;
	MLX5_DECLARE_FLOW_ACT(flow_act);
	struct mlx5_flow_handle *rule;
	struct mlx5e_fs_any *fs_any;
	int err;

	fs_any = priv->fs->any;
	fs_any_t = &fs_any->table;

	dest = mlx5_ttc_get_default_dest(priv->fs->ttc, MLX5_TT_ANY);
	dest = mlx5_ttc_get_default_dest(ttc, MLX5_TT_ANY);
	rule = mlx5_add_flow_rules(fs_any_t->t, NULL, &flow_act, &dest, 1);
	if (IS_ERR(rule)) {
		err = PTR_ERR(rule);
@@ -474,7 +478,9 @@ static int fs_any_create_groups(struct mlx5e_flow_table *ft)

static int fs_any_create_table(struct mlx5e_priv *priv)
{
	struct mlx5e_flow_table *ft = &priv->fs->any->table;
	struct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(priv->fs, false);
	struct mlx5e_fs_any *fs_any = mlx5e_fs_get_any(priv->fs);
	struct mlx5e_flow_table *ft = &fs_any->table;
	struct mlx5_flow_table_attr ft_attr = {};
	int err;

@@ -484,7 +490,7 @@ static int fs_any_create_table(struct mlx5e_priv *priv)
	ft_attr.level = MLX5E_FS_TT_ANY_FT_LEVEL;
	ft_attr.prio = MLX5E_NIC_PRIO;

	ft->t = mlx5_create_flow_table(priv->fs->ns, &ft_attr);
	ft->t = mlx5_create_flow_table(ns, &ft_attr);
	if (IS_ERR(ft->t)) {
		err = PTR_ERR(ft->t);
		ft->t = NULL;
@@ -511,10 +517,11 @@ static int fs_any_create_table(struct mlx5e_priv *priv)

static int fs_any_disable(struct mlx5e_priv *priv)
{
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(priv->fs, false);
	int err;

	/* Modify ttc rules destination to point back to the indir TIRs */
	err = mlx5_ttc_fwd_default_dest(priv->fs->ttc, MLX5_TT_ANY);
	err = mlx5_ttc_fwd_default_dest(ttc, MLX5_TT_ANY);
	if (err) {
		netdev_err(priv->netdev,
			   "%s: modify ttc[%d] default destination failed, err(%d)\n",
@@ -526,14 +533,16 @@ static int fs_any_disable(struct mlx5e_priv *priv)

static int fs_any_enable(struct mlx5e_priv *priv)
{
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(priv->fs, false);
	struct mlx5e_fs_any *any = mlx5e_fs_get_any(priv->fs);
	struct mlx5_flow_destination dest = {};
	int err;

	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
	dest.ft = priv->fs->any->table.t;
	dest.ft = any->table.t;

	/* Modify ttc rules destination to point on the accel_fs FTs */
	err = mlx5_ttc_fwd_dest(priv->fs->ttc, MLX5_TT_ANY, &dest);
	err = mlx5_ttc_fwd_dest(ttc, MLX5_TT_ANY, &dest);
	if (err) {
		netdev_err(priv->netdev,
			   "%s: modify ttc[%d] destination to accel failed, err(%d)\n",
@@ -555,7 +564,7 @@ static void fs_any_destroy_table(struct mlx5e_fs_any *fs_any)

void mlx5e_fs_tt_redirect_any_destroy(struct mlx5e_priv *priv)
{
	struct mlx5e_fs_any *fs_any = priv->fs->any;
	struct mlx5e_fs_any *fs_any = mlx5e_fs_get_any(priv->fs);

	if (!fs_any)
		return;
@@ -568,21 +577,23 @@ void mlx5e_fs_tt_redirect_any_destroy(struct mlx5e_priv *priv)
	fs_any_destroy_table(fs_any);

	kfree(fs_any);
	priv->fs->any = NULL;
	mlx5e_fs_set_any(priv->fs, NULL);
}

int mlx5e_fs_tt_redirect_any_create(struct mlx5e_priv *priv)
{
	struct mlx5e_fs_any *fs_any = mlx5e_fs_get_any(priv->fs);
	int err;

	if (priv->fs->any) {
		priv->fs->any->ref_cnt++;
	if (fs_any) {
		fs_any->ref_cnt++;
		return 0;
	}

	priv->fs->any = kzalloc(sizeof(*priv->fs->any), GFP_KERNEL);
	if (!priv->fs->any)
	fs_any = kzalloc(sizeof(*fs_any), GFP_KERNEL);
	if (!fs_any)
		return -ENOMEM;
	mlx5e_fs_set_any(priv->fs, fs_any);

	err = fs_any_create_table(priv);
	if (err)
@@ -592,14 +603,14 @@ int mlx5e_fs_tt_redirect_any_create(struct mlx5e_priv *priv)
	if (err)
		goto err_destroy_table;

	priv->fs->any->ref_cnt = 1;
	fs_any->ref_cnt = 1;

	return 0;

err_destroy_table:
	fs_any_destroy_table(priv->fs->any);
	fs_any_destroy_table(fs_any);

	kfree(priv->fs->any);
	priv->fs->any = NULL;
	kfree(fs_any);
	mlx5e_fs_set_any(priv->fs, NULL);
	return err;
}
+4 −4
Original line number Diff line number Diff line
@@ -624,7 +624,7 @@ static int mlx5e_ptp_set_state(struct mlx5e_ptp *c, struct mlx5e_params *params)

static void mlx5e_ptp_rx_unset_fs(struct mlx5e_priv *priv)
{
	struct mlx5e_ptp_fs *ptp_fs = priv->fs->ptp_fs;
	struct mlx5e_ptp_fs *ptp_fs = mlx5e_fs_get_ptp(priv->fs);

	if (!ptp_fs->valid)
		return;
@@ -640,8 +640,8 @@ static void mlx5e_ptp_rx_unset_fs(struct mlx5e_priv *priv)

static int mlx5e_ptp_rx_set_fs(struct mlx5e_priv *priv)
{
	struct mlx5e_ptp_fs *ptp_fs = mlx5e_fs_get_ptp(priv->fs);
	u32 tirn = mlx5e_rx_res_get_tirn_ptp(priv->rx_res);
	struct mlx5e_ptp_fs *ptp_fs = priv->fs->ptp_fs;
	struct mlx5_flow_handle *rule;
	int err;

@@ -807,14 +807,14 @@ int mlx5e_ptp_alloc_rx_fs(struct mlx5e_priv *priv)
	ptp_fs = kzalloc(sizeof(*ptp_fs), GFP_KERNEL);
	if (!ptp_fs)
		return -ENOMEM;
	mlx5e_fs_set_ptp(priv->fs, ptp_fs);

	priv->fs->ptp_fs = ptp_fs;
	return 0;
}

void mlx5e_ptp_free_rx_fs(struct mlx5e_priv *priv)
{
	struct mlx5e_ptp_fs *ptp_fs = priv->fs->ptp_fs;
	struct mlx5e_ptp_fs *ptp_fs = mlx5e_fs_get_ptp(priv->fs);

	if (!mlx5e_profile_feature_cap(priv->profile, PTP_RX))
		return;
+2 −1
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ validate_goto_chain(struct mlx5e_priv *priv,
		    const struct flow_action_entry *act,
		    struct netlink_ext_ack *extack)
{
	struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs);
	bool is_esw = mlx5e_is_eswitch_flow(flow);
	bool ft_flow = mlx5e_is_ft_flow(flow);
	u32 dest_chain = act->chain_index;
@@ -21,7 +22,7 @@ validate_goto_chain(struct mlx5e_priv *priv,
	u32 max_chain;

	esw = priv->mdev->priv.eswitch;
	chains = is_esw ? esw_chains(esw) : mlx5e_nic_chains(priv->fs->tc);
	chains = is_esw ? esw_chains(esw) : mlx5e_nic_chains(tc);
	max_chain = mlx5_chains_get_chain_range(chains);
	reformat_and_fwd = is_esw ?
			   MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev, reformat_and_fwd_to_table) :
+25 −21
Original line number Diff line number Diff line
@@ -75,9 +75,9 @@ struct mlx5_flow_handle *mlx5e_accel_fs_add_sk(struct mlx5e_priv *priv,
					       struct sock *sk, u32 tirn,
					       uint32_t flow_tag)
{
	struct mlx5e_accel_fs_tcp *fs_tcp = mlx5e_fs_get_accel_tcp(priv->fs);
	struct mlx5_flow_destination dest = {};
	struct mlx5e_flow_table *ft = NULL;
	struct mlx5e_accel_fs_tcp *fs_tcp;
	MLX5_DECLARE_FLOW_ACT(flow_act);
	struct mlx5_flow_handle *flow;
	struct mlx5_flow_spec *spec;
@@ -86,8 +86,6 @@ struct mlx5_flow_handle *mlx5e_accel_fs_add_sk(struct mlx5e_priv *priv,
	if (!spec)
		return ERR_PTR(-ENOMEM);

	fs_tcp = priv->fs->accel_tcp;

	spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;

	switch (sk->sk_family) {
@@ -151,17 +149,17 @@ struct mlx5_flow_handle *mlx5e_accel_fs_add_sk(struct mlx5e_priv *priv,
static int accel_fs_tcp_add_default_rule(struct mlx5e_priv *priv,
					 enum accel_fs_tcp_type type)
{
	struct mlx5e_accel_fs_tcp *fs_tcp = mlx5e_fs_get_accel_tcp(priv->fs);
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(priv->fs, false);
	struct mlx5e_flow_table *accel_fs_t;
	struct mlx5_flow_destination dest;
	struct mlx5e_accel_fs_tcp *fs_tcp;
	MLX5_DECLARE_FLOW_ACT(flow_act);
	struct mlx5_flow_handle *rule;
	int err = 0;

	fs_tcp = priv->fs->accel_tcp;
	accel_fs_t = &fs_tcp->tables[type];

	dest = mlx5_ttc_get_default_dest(priv->fs->ttc, fs_accel2tt(type));
	dest = mlx5_ttc_get_default_dest(ttc, fs_accel2tt(type));
	rule = mlx5_add_flow_rules(accel_fs_t->t, NULL, &flow_act, &dest, 1);
	if (IS_ERR(rule)) {
		err = PTR_ERR(rule);
@@ -267,7 +265,9 @@ static int accel_fs_tcp_create_groups(struct mlx5e_flow_table *ft,

static int accel_fs_tcp_create_table(struct mlx5e_priv *priv, enum accel_fs_tcp_type type)
{
	struct mlx5e_flow_table *ft = &priv->fs->accel_tcp->tables[type];
	struct mlx5e_accel_fs_tcp *accel_tcp = mlx5e_fs_get_accel_tcp(priv->fs);
	struct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(priv->fs, false);
	struct mlx5e_flow_table *ft = &accel_tcp->tables[type];
	struct mlx5_flow_table_attr ft_attr = {};
	int err;

@@ -277,7 +277,7 @@ static int accel_fs_tcp_create_table(struct mlx5e_priv *priv, enum accel_fs_tcp_
	ft_attr.level = MLX5E_ACCEL_FS_TCP_FT_LEVEL;
	ft_attr.prio = MLX5E_NIC_PRIO;

	ft->t = mlx5_create_flow_table(priv->fs->ns, &ft_attr);
	ft->t = mlx5_create_flow_table(ns, &ft_attr);
	if (IS_ERR(ft->t)) {
		err = PTR_ERR(ft->t);
		ft->t = NULL;
@@ -303,11 +303,12 @@ static int accel_fs_tcp_create_table(struct mlx5e_priv *priv, enum accel_fs_tcp_

static int accel_fs_tcp_disable(struct mlx5e_priv *priv)
{
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(priv->fs, false);
	int err, i;

	for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++) {
		/* Modify ttc rules destination to point back to the indir TIRs */
		err = mlx5_ttc_fwd_default_dest(priv->fs->ttc, fs_accel2tt(i));
		err = mlx5_ttc_fwd_default_dest(ttc, fs_accel2tt(i));
		if (err) {
			netdev_err(priv->netdev,
				   "%s: modify ttc[%d] default destination failed, err(%d)\n",
@@ -321,15 +322,17 @@ static int accel_fs_tcp_disable(struct mlx5e_priv *priv)

static int accel_fs_tcp_enable(struct mlx5e_priv *priv)
{
	struct mlx5e_accel_fs_tcp *accel_tcp = mlx5e_fs_get_accel_tcp(priv->fs);
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(priv->fs, false);
	struct mlx5_flow_destination dest = {};
	int err, i;

	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
	for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++) {
		dest.ft = priv->fs->accel_tcp->tables[i].t;
		dest.ft = accel_tcp->tables[i].t;

		/* Modify ttc rules destination to point on the accel_fs FTs */
		err = mlx5_ttc_fwd_dest(priv->fs->ttc, fs_accel2tt(i), &dest);
		err = mlx5_ttc_fwd_dest(ttc, fs_accel2tt(i), &dest);
		if (err) {
			netdev_err(priv->netdev,
				   "%s: modify ttc[%d] destination to accel failed, err(%d)\n",
@@ -342,9 +345,8 @@ static int accel_fs_tcp_enable(struct mlx5e_priv *priv)

static void accel_fs_tcp_destroy_table(struct mlx5e_priv *priv, int i)
{
	struct mlx5e_accel_fs_tcp *fs_tcp;
	struct mlx5e_accel_fs_tcp *fs_tcp = mlx5e_fs_get_accel_tcp(priv->fs);

	fs_tcp = priv->fs->accel_tcp;
	if (IS_ERR_OR_NULL(fs_tcp->tables[i].t))
		return;

@@ -355,9 +357,10 @@ static void accel_fs_tcp_destroy_table(struct mlx5e_priv *priv, int i)

void mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *priv)
{
	struct mlx5e_accel_fs_tcp *accel_tcp = mlx5e_fs_get_accel_tcp(priv->fs);
	int i;

	if (!priv->fs->accel_tcp)
	if (!accel_tcp)
		return;

	accel_fs_tcp_disable(priv);
@@ -365,20 +368,22 @@ void mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *priv)
	for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++)
		accel_fs_tcp_destroy_table(priv, i);

	kfree(priv->fs->accel_tcp);
	priv->fs->accel_tcp = NULL;
	kfree(accel_tcp);
	mlx5e_fs_set_accel_tcp(priv->fs, NULL);
}

int mlx5e_accel_fs_tcp_create(struct mlx5e_priv *priv)
{
	struct mlx5e_accel_fs_tcp *accel_tcp;
	int i, err;

	if (!MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version))
		return -EOPNOTSUPP;

	priv->fs->accel_tcp = kzalloc(sizeof(*priv->fs->accel_tcp), GFP_KERNEL);
	if (!priv->fs->accel_tcp)
	accel_tcp = kvzalloc(sizeof(*accel_tcp), GFP_KERNEL);
	if (!accel_tcp)
		return -ENOMEM;
	mlx5e_fs_set_accel_tcp(priv->fs, accel_tcp);

	for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++) {
		err = accel_fs_tcp_create_table(priv, i);
@@ -395,8 +400,7 @@ int mlx5e_accel_fs_tcp_create(struct mlx5e_priv *priv)
err_destroy_tables:
	while (--i >= 0)
		accel_fs_tcp_destroy_table(priv, i);

	kfree(priv->fs->accel_tcp);
	priv->fs->accel_tcp = NULL;
	kfree(accel_tcp);
	mlx5e_fs_set_accel_tcp(priv->fs, NULL);
	return err;
}
Loading