Commit 6d5b7321 authored by Shay Drory's avatar Shay Drory Committed by Saeed Mahameed

net/mlx5: DR, handle more than one peer domain

Currently, DR domain is using the assumption that each domain can only
have a single peer.
In order to support VF LAG of more then two ports, expand peer domain
to use an array of peers, and align the code accordingly.
Signed-off-by: default avatarShay Drory <shayd@nvidia.com>
Reviewed-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 014e4d48
...@@ -2778,7 +2778,9 @@ static int mlx5_esw_offloads_set_ns_peer(struct mlx5_eswitch *esw, ...@@ -2778,7 +2778,9 @@ static int mlx5_esw_offloads_set_ns_peer(struct mlx5_eswitch *esw,
struct mlx5_eswitch *peer_esw, struct mlx5_eswitch *peer_esw,
bool pair) bool pair)
{ {
u8 peer_idx = mlx5_get_dev_index(peer_esw->dev);
struct mlx5_flow_root_namespace *peer_ns; struct mlx5_flow_root_namespace *peer_ns;
u8 idx = mlx5_get_dev_index(esw->dev);
struct mlx5_flow_root_namespace *ns; struct mlx5_flow_root_namespace *ns;
int err; int err;
...@@ -2786,18 +2788,18 @@ static int mlx5_esw_offloads_set_ns_peer(struct mlx5_eswitch *esw, ...@@ -2786,18 +2788,18 @@ static int mlx5_esw_offloads_set_ns_peer(struct mlx5_eswitch *esw,
ns = esw->dev->priv.steering->fdb_root_ns; ns = esw->dev->priv.steering->fdb_root_ns;
if (pair) { if (pair) {
err = mlx5_flow_namespace_set_peer(ns, peer_ns); err = mlx5_flow_namespace_set_peer(ns, peer_ns, peer_idx);
if (err) if (err)
return err; return err;
err = mlx5_flow_namespace_set_peer(peer_ns, ns); err = mlx5_flow_namespace_set_peer(peer_ns, ns, idx);
if (err) { if (err) {
mlx5_flow_namespace_set_peer(ns, NULL); mlx5_flow_namespace_set_peer(ns, NULL, peer_idx);
return err; return err;
} }
} else { } else {
mlx5_flow_namespace_set_peer(ns, NULL); mlx5_flow_namespace_set_peer(ns, NULL, peer_idx);
mlx5_flow_namespace_set_peer(peer_ns, NULL); mlx5_flow_namespace_set_peer(peer_ns, NULL, idx);
} }
return 0; return 0;
......
...@@ -139,7 +139,8 @@ static void mlx5_cmd_stub_modify_header_dealloc(struct mlx5_flow_root_namespace ...@@ -139,7 +139,8 @@ static void mlx5_cmd_stub_modify_header_dealloc(struct mlx5_flow_root_namespace
} }
static int mlx5_cmd_stub_set_peer(struct mlx5_flow_root_namespace *ns, static int mlx5_cmd_stub_set_peer(struct mlx5_flow_root_namespace *ns,
struct mlx5_flow_root_namespace *peer_ns) struct mlx5_flow_root_namespace *peer_ns,
u8 peer_idx)
{ {
return 0; return 0;
} }
......
...@@ -93,7 +93,8 @@ struct mlx5_flow_cmds { ...@@ -93,7 +93,8 @@ struct mlx5_flow_cmds {
struct mlx5_modify_hdr *modify_hdr); struct mlx5_modify_hdr *modify_hdr);
int (*set_peer)(struct mlx5_flow_root_namespace *ns, int (*set_peer)(struct mlx5_flow_root_namespace *ns,
struct mlx5_flow_root_namespace *peer_ns); struct mlx5_flow_root_namespace *peer_ns,
u8 peer_idx);
int (*create_ns)(struct mlx5_flow_root_namespace *ns); int (*create_ns)(struct mlx5_flow_root_namespace *ns);
int (*destroy_ns)(struct mlx5_flow_root_namespace *ns); int (*destroy_ns)(struct mlx5_flow_root_namespace *ns);
......
...@@ -3620,7 +3620,8 @@ void mlx5_destroy_match_definer(struct mlx5_core_dev *dev, ...@@ -3620,7 +3620,8 @@ void mlx5_destroy_match_definer(struct mlx5_core_dev *dev,
} }
int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns, int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns,
struct mlx5_flow_root_namespace *peer_ns) struct mlx5_flow_root_namespace *peer_ns,
u8 peer_idx)
{ {
if (peer_ns && ns->mode != peer_ns->mode) { if (peer_ns && ns->mode != peer_ns->mode) {
mlx5_core_err(ns->dev, mlx5_core_err(ns->dev,
...@@ -3628,7 +3629,7 @@ int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns, ...@@ -3628,7 +3629,7 @@ int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns,
return -EINVAL; return -EINVAL;
} }
return ns->cmds->set_peer(ns, peer_ns); return ns->cmds->set_peer(ns, peer_ns, peer_idx);
} }
/* This function should be called only at init stage of the namespace. /* This function should be called only at init stage of the namespace.
......
...@@ -295,7 +295,8 @@ void mlx5_fc_update_sampling_interval(struct mlx5_core_dev *dev, ...@@ -295,7 +295,8 @@ void mlx5_fc_update_sampling_interval(struct mlx5_core_dev *dev,
const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void); const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void);
int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns, int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns,
struct mlx5_flow_root_namespace *peer_ns); struct mlx5_flow_root_namespace *peer_ns,
u8 peer_idx);
int mlx5_flow_namespace_set_mode(struct mlx5_flow_namespace *ns, int mlx5_flow_namespace_set_mode(struct mlx5_flow_namespace *ns,
enum mlx5_flow_steering_mode mode); enum mlx5_flow_steering_mode mode);
......
...@@ -2071,8 +2071,9 @@ mlx5dr_action_create_dest_vport(struct mlx5dr_domain *dmn, ...@@ -2071,8 +2071,9 @@ mlx5dr_action_create_dest_vport(struct mlx5dr_domain *dmn,
struct mlx5dr_action *action; struct mlx5dr_action *action;
u8 peer_vport; u8 peer_vport;
peer_vport = vhca_id_valid && (vhca_id != dmn->info.caps.gvmi); peer_vport = vhca_id_valid && mlx5_core_is_pf(dmn->mdev) &&
vport_dmn = peer_vport ? dmn->peer_dmn : dmn; (vhca_id != dmn->info.caps.gvmi);
vport_dmn = peer_vport ? dmn->peer_dmn[vhca_id] : dmn;
if (!vport_dmn) { if (!vport_dmn) {
mlx5dr_dbg(dmn, "No peer vport domain for given vhca_id\n"); mlx5dr_dbg(dmn, "No peer vport domain for given vhca_id\n");
return NULL; return NULL;
......
...@@ -555,17 +555,18 @@ int mlx5dr_domain_destroy(struct mlx5dr_domain *dmn) ...@@ -555,17 +555,18 @@ int mlx5dr_domain_destroy(struct mlx5dr_domain *dmn)
} }
void mlx5dr_domain_set_peer(struct mlx5dr_domain *dmn, void mlx5dr_domain_set_peer(struct mlx5dr_domain *dmn,
struct mlx5dr_domain *peer_dmn) struct mlx5dr_domain *peer_dmn,
u8 peer_idx)
{ {
mlx5dr_domain_lock(dmn); mlx5dr_domain_lock(dmn);
if (dmn->peer_dmn) if (dmn->peer_dmn[peer_idx])
refcount_dec(&dmn->peer_dmn->refcount); refcount_dec(&dmn->peer_dmn[peer_idx]->refcount);
dmn->peer_dmn = peer_dmn; dmn->peer_dmn[peer_idx] = peer_dmn;
if (dmn->peer_dmn) if (dmn->peer_dmn[peer_idx])
refcount_inc(&dmn->peer_dmn->refcount); refcount_inc(&dmn->peer_dmn[peer_idx]->refcount);
mlx5dr_domain_unlock(dmn); mlx5dr_domain_unlock(dmn);
} }
...@@ -1647,6 +1647,7 @@ dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, ...@@ -1647,6 +1647,7 @@ dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
u8 *tag) u8 *tag)
{ {
struct mlx5dr_match_misc *misc = &value->misc; struct mlx5dr_match_misc *misc = &value->misc;
int id = misc->source_eswitch_owner_vhca_id;
struct mlx5dr_cmd_vport_cap *vport_cap; struct mlx5dr_cmd_vport_cap *vport_cap;
struct mlx5dr_domain *dmn = sb->dmn; struct mlx5dr_domain *dmn = sb->dmn;
struct mlx5dr_domain *vport_dmn; struct mlx5dr_domain *vport_dmn;
...@@ -1657,11 +1658,11 @@ dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, ...@@ -1657,11 +1658,11 @@ dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
if (sb->vhca_id_valid) { if (sb->vhca_id_valid) {
/* Find port GVMI based on the eswitch_owner_vhca_id */ /* Find port GVMI based on the eswitch_owner_vhca_id */
if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi) if (id == dmn->info.caps.gvmi)
vport_dmn = dmn; vport_dmn = dmn;
else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id == else if (id < MLX5_MAX_PORTS && dmn->peer_dmn[id] &&
dmn->peer_dmn->info.caps.gvmi)) (id == dmn->peer_dmn[id]->info.caps.gvmi))
vport_dmn = dmn->peer_dmn; vport_dmn = dmn->peer_dmn[id];
else else
return -EINVAL; return -EINVAL;
......
...@@ -1979,6 +1979,7 @@ static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, ...@@ -1979,6 +1979,7 @@ static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
u8 *tag) u8 *tag)
{ {
struct mlx5dr_match_misc *misc = &value->misc; struct mlx5dr_match_misc *misc = &value->misc;
int id = misc->source_eswitch_owner_vhca_id;
struct mlx5dr_cmd_vport_cap *vport_cap; struct mlx5dr_cmd_vport_cap *vport_cap;
struct mlx5dr_domain *dmn = sb->dmn; struct mlx5dr_domain *dmn = sb->dmn;
struct mlx5dr_domain *vport_dmn; struct mlx5dr_domain *vport_dmn;
...@@ -1988,11 +1989,11 @@ static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, ...@@ -1988,11 +1989,11 @@ static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
if (sb->vhca_id_valid) { if (sb->vhca_id_valid) {
/* Find port GVMI based on the eswitch_owner_vhca_id */ /* Find port GVMI based on the eswitch_owner_vhca_id */
if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi) if (id == dmn->info.caps.gvmi)
vport_dmn = dmn; vport_dmn = dmn;
else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id == else if (id < MLX5_MAX_PORTS && dmn->peer_dmn[id] &&
dmn->peer_dmn->info.caps.gvmi)) (id == dmn->peer_dmn[id]->info.caps.gvmi))
vport_dmn = dmn->peer_dmn; vport_dmn = dmn->peer_dmn[id];
else else
return -EINVAL; return -EINVAL;
......
...@@ -935,7 +935,7 @@ struct mlx5dr_domain_info { ...@@ -935,7 +935,7 @@ struct mlx5dr_domain_info {
}; };
struct mlx5dr_domain { struct mlx5dr_domain {
struct mlx5dr_domain *peer_dmn; struct mlx5dr_domain *peer_dmn[MLX5_MAX_PORTS];
struct mlx5_core_dev *mdev; struct mlx5_core_dev *mdev;
u32 pdn; u32 pdn;
struct mlx5_uars_page *uar; struct mlx5_uars_page *uar;
......
...@@ -770,14 +770,15 @@ static int mlx5_cmd_dr_update_fte(struct mlx5_flow_root_namespace *ns, ...@@ -770,14 +770,15 @@ static int mlx5_cmd_dr_update_fte(struct mlx5_flow_root_namespace *ns,
} }
static int mlx5_cmd_dr_set_peer(struct mlx5_flow_root_namespace *ns, static int mlx5_cmd_dr_set_peer(struct mlx5_flow_root_namespace *ns,
struct mlx5_flow_root_namespace *peer_ns) struct mlx5_flow_root_namespace *peer_ns,
u8 peer_idx)
{ {
struct mlx5dr_domain *peer_domain = NULL; struct mlx5dr_domain *peer_domain = NULL;
if (peer_ns) if (peer_ns)
peer_domain = peer_ns->fs_dr_domain.dr_domain; peer_domain = peer_ns->fs_dr_domain.dr_domain;
mlx5dr_domain_set_peer(ns->fs_dr_domain.dr_domain, mlx5dr_domain_set_peer(ns->fs_dr_domain.dr_domain,
peer_domain); peer_domain, peer_idx);
return 0; return 0;
} }
......
...@@ -48,7 +48,8 @@ int mlx5dr_domain_destroy(struct mlx5dr_domain *domain); ...@@ -48,7 +48,8 @@ int mlx5dr_domain_destroy(struct mlx5dr_domain *domain);
int mlx5dr_domain_sync(struct mlx5dr_domain *domain, u32 flags); int mlx5dr_domain_sync(struct mlx5dr_domain *domain, u32 flags);
void mlx5dr_domain_set_peer(struct mlx5dr_domain *dmn, void mlx5dr_domain_set_peer(struct mlx5dr_domain *dmn,
struct mlx5dr_domain *peer_dmn); struct mlx5dr_domain *peer_dmn,
u8 peer_idx);
struct mlx5dr_table * struct mlx5dr_table *
mlx5dr_table_create(struct mlx5dr_domain *domain, u32 level, u32 flags, mlx5dr_table_create(struct mlx5dr_domain *domain, u32 level, u32 flags,
......
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