diff options
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 95 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h | 7 |
2 files changed, 68 insertions, 34 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c index dd3f18f85466..e23c1e81b98f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c @@ -1590,7 +1590,7 @@ struct mlx5_devcom_comp_dev *mlx5_lag_get_devcom_comp(struct mlx5_lag *ldev) static int mlx5_lag_demux_ft_fg_init(struct mlx5_core_dev *dev, struct mlx5_flow_table_attr *ft_attr, - struct mlx5_lag *ldev) + struct lag_func *pf) { #ifdef CONFIG_MLX5_ESWITCH struct mlx5_flow_namespace *ns; @@ -1601,20 +1601,20 @@ static int mlx5_lag_demux_ft_fg_init(struct mlx5_core_dev *dev, if (!ns) return 0; - ldev->lag_demux_ft = mlx5_create_flow_table(ns, ft_attr); - if (IS_ERR(ldev->lag_demux_ft)) - return PTR_ERR(ldev->lag_demux_ft); + pf->lag_demux_ft = mlx5_create_flow_table(ns, ft_attr); + if (IS_ERR(pf->lag_demux_ft)) + return PTR_ERR(pf->lag_demux_ft); fg = mlx5_esw_lag_demux_fg_create(dev->priv.eswitch, - ldev->lag_demux_ft); + pf->lag_demux_ft); if (IS_ERR(fg)) { err = PTR_ERR(fg); - mlx5_destroy_flow_table(ldev->lag_demux_ft); - ldev->lag_demux_ft = NULL; + mlx5_destroy_flow_table(pf->lag_demux_ft); + pf->lag_demux_ft = NULL; return err; } - ldev->lag_demux_fg = fg; + pf->lag_demux_fg = fg; return 0; #else return -EOPNOTSUPP; @@ -1623,7 +1623,7 @@ static int mlx5_lag_demux_ft_fg_init(struct mlx5_core_dev *dev, static int mlx5_lag_demux_fw_init(struct mlx5_core_dev *dev, struct mlx5_flow_table_attr *ft_attr, - struct mlx5_lag *ldev) + struct lag_func *pf) { struct mlx5_flow_namespace *ns; int err; @@ -1632,12 +1632,12 @@ static int mlx5_lag_demux_fw_init(struct mlx5_core_dev *dev, if (!ns) return 0; - ldev->lag_demux_fg = NULL; + pf->lag_demux_fg = NULL; ft_attr->max_fte = 1; - ldev->lag_demux_ft = mlx5_create_lag_demux_flow_table(ns, ft_attr); - if (IS_ERR(ldev->lag_demux_ft)) { - err = PTR_ERR(ldev->lag_demux_ft); - ldev->lag_demux_ft = NULL; + pf->lag_demux_ft = mlx5_create_lag_demux_flow_table(ns, ft_attr); + if (IS_ERR(pf->lag_demux_ft)) { + err = PTR_ERR(pf->lag_demux_ft); + pf->lag_demux_ft = NULL; return err; } @@ -1648,6 +1648,7 @@ int mlx5_lag_demux_init(struct mlx5_core_dev *dev, struct mlx5_flow_table_attr *ft_attr) { struct mlx5_lag *ldev; + struct lag_func *pf; if (!ft_attr) return -EINVAL; @@ -1656,12 +1657,16 @@ int mlx5_lag_demux_init(struct mlx5_core_dev *dev, if (!ldev) return -ENODEV; - xa_init(&ldev->lag_demux_rules); + pf = mlx5_lag_pf_by_dev(ldev, dev); + if (!pf) + return -ENODEV; + + xa_init(&pf->lag_demux_rules); if (mlx5_get_sd(dev)) - return mlx5_lag_demux_ft_fg_init(dev, ft_attr, ldev); + return mlx5_lag_demux_ft_fg_init(dev, ft_attr, pf); - return mlx5_lag_demux_fw_init(dev, ft_attr, ldev); + return mlx5_lag_demux_fw_init(dev, ft_attr, pf); } EXPORT_SYMBOL(mlx5_lag_demux_init); @@ -1670,40 +1675,63 @@ void mlx5_lag_demux_cleanup(struct mlx5_core_dev *dev) struct mlx5_flow_handle *rule; struct mlx5_lag *ldev; unsigned long vport_num; + struct lag_func *pf; ldev = mlx5_lag_dev(dev); if (!ldev) return; - xa_for_each(&ldev->lag_demux_rules, vport_num, rule) + pf = mlx5_lag_pf_by_dev(ldev, dev); + if (!pf) + return; + + xa_for_each(&pf->lag_demux_rules, vport_num, rule) mlx5_del_flow_rules(rule); - xa_destroy(&ldev->lag_demux_rules); + xa_destroy(&pf->lag_demux_rules); - if (ldev->lag_demux_fg) - mlx5_destroy_flow_group(ldev->lag_demux_fg); - if (ldev->lag_demux_ft) - mlx5_destroy_flow_table(ldev->lag_demux_ft); - ldev->lag_demux_fg = NULL; - ldev->lag_demux_ft = NULL; + if (pf->lag_demux_fg) + mlx5_destroy_flow_group(pf->lag_demux_fg); + if (pf->lag_demux_ft) + mlx5_destroy_flow_table(pf->lag_demux_ft); + pf->lag_demux_fg = NULL; + pf->lag_demux_ft = NULL; } EXPORT_SYMBOL(mlx5_lag_demux_cleanup); +static struct lag_func *mlx5_lag_dev_get_master_pf(struct mlx5_lag *ldev, + struct mlx5_core_dev *dev) +{ + u32 filter = mlx5_lag_get_filter(ldev, dev); + int idx; + + idx = mlx5_lag_get_dev_index_by_seq_filter(ldev, MLX5_LAG_P1, filter); + if (idx < 0) + return NULL; + + return mlx5_lag_pf(ldev, idx); +} + int mlx5_lag_demux_rule_add(struct mlx5_core_dev *vport_dev, u16 vport_num, int index) { struct mlx5_flow_handle *rule; + struct lag_func *master; struct mlx5_lag *ldev; int err; ldev = mlx5_lag_dev(vport_dev); - if (!ldev || !ldev->lag_demux_fg) + if (!ldev) return 0; - if (xa_load(&ldev->lag_demux_rules, index)) + master = mlx5_lag_dev_get_master_pf(ldev, vport_dev); + if (!master || !master->lag_demux_fg) + return 0; + + if (xa_load(&master->lag_demux_rules, index)) return 0; rule = mlx5_esw_lag_demux_rule_create(vport_dev->priv.eswitch, - vport_num, ldev->lag_demux_ft); + vport_num, master->lag_demux_ft); if (IS_ERR(rule)) { err = PTR_ERR(rule); mlx5_core_warn(vport_dev, @@ -1712,7 +1740,7 @@ int mlx5_lag_demux_rule_add(struct mlx5_core_dev *vport_dev, u16 vport_num, return err; } - err = xa_err(xa_store(&ldev->lag_demux_rules, index, rule, + err = xa_err(xa_store(&master->lag_demux_rules, index, rule, GFP_KERNEL)); if (err) { mlx5_del_flow_rules(rule); @@ -1728,13 +1756,18 @@ EXPORT_SYMBOL(mlx5_lag_demux_rule_add); void mlx5_lag_demux_rule_del(struct mlx5_core_dev *dev, int index) { struct mlx5_flow_handle *rule; + struct lag_func *master_pf; struct mlx5_lag *ldev; ldev = mlx5_lag_dev(dev); - if (!ldev || !ldev->lag_demux_fg) + if (!ldev) + return; + + master_pf = mlx5_lag_dev_get_master_pf(ldev, dev); + if (!master_pf || !master_pf->lag_demux_fg) return; - rule = xa_erase(&ldev->lag_demux_rules, index); + rule = xa_erase(&master_pf->lag_demux_rules, index); if (rule) mlx5_del_flow_rules(rule); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h index 0296f752bb4c..d645c2cfca4d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h @@ -59,6 +59,10 @@ struct lag_func { struct mlx5_nb port_change_nb; u32 group_id; /* SD group ID, 0 = not SD */ bool sd_fdb_active; /* set on all SD group members */ + /* Lag demux resources - only populated on master devices */ + struct mlx5_flow_table *lag_demux_ft; + struct mlx5_flow_group *lag_demux_fg; + struct xarray lag_demux_rules; }; /* Used for collection of netdev event info. */ @@ -95,9 +99,6 @@ struct mlx5_lag { /* Protect lag fields/state changes */ struct mutex lock; struct lag_mpesw lag_mpesw; - struct mlx5_flow_table *lag_demux_ft; - struct mlx5_flow_group *lag_demux_fg; - struct xarray lag_demux_rules; }; static inline struct mlx5_lag * |
