diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx5/core/en/rss.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en/rss.c | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rss.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rss.c index 34c5b8f0d100..d2c4ace7c8ba 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rss.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rss.c @@ -78,6 +78,7 @@ struct mlx5e_rss { u32 drop_rqn; bool inner_ft_support; bool enabled; + refcount_t refcnt; }; struct mlx5e_rss *mlx5e_rss_alloc(void) @@ -281,19 +282,26 @@ static int mlx5e_rss_update_tirs(struct mlx5e_rss *rss) return retval; } -int mlx5e_rss_init(struct mlx5e_rss *rss, struct mlx5_core_dev *mdev, - bool inner_ft_support, u32 drop_rqn, - const struct mlx5e_lro_param *init_lro_param) +int mlx5e_rss_init_no_tirs(struct mlx5e_rss *rss, struct mlx5_core_dev *mdev, + bool inner_ft_support, u32 drop_rqn) { - int err; - rss->mdev = mdev; rss->inner_ft_support = inner_ft_support; rss->drop_rqn = drop_rqn; mlx5e_rss_params_init(rss); + refcount_set(&rss->refcnt, 1); + + return mlx5e_rqt_init_direct(&rss->rqt, mdev, true, drop_rqn); +} + +int mlx5e_rss_init(struct mlx5e_rss *rss, struct mlx5_core_dev *mdev, + bool inner_ft_support, u32 drop_rqn, + const struct mlx5e_lro_param *init_lro_param) +{ + int err; - err = mlx5e_rqt_init_direct(&rss->rqt, mdev, true, drop_rqn); + err = mlx5e_rss_init_no_tirs(rss, mdev, inner_ft_support, drop_rqn); if (err) goto err_out; @@ -317,14 +325,34 @@ err_out: return err; } -void mlx5e_rss_cleanup(struct mlx5e_rss *rss) +int mlx5e_rss_cleanup(struct mlx5e_rss *rss) { + if (!refcount_dec_if_one(&rss->refcnt)) + return -EBUSY; + mlx5e_rss_destroy_tirs(rss, false); if (rss->inner_ft_support) mlx5e_rss_destroy_tirs(rss, true); mlx5e_rqt_destroy(&rss->rqt); + + return 0; +} + +void mlx5e_rss_refcnt_inc(struct mlx5e_rss *rss) +{ + refcount_inc(&rss->refcnt); +} + +void mlx5e_rss_refcnt_dec(struct mlx5e_rss *rss) +{ + refcount_dec(&rss->refcnt); +} + +unsigned int mlx5e_rss_refcnt_read(struct mlx5e_rss *rss) +{ + return refcount_read(&rss->refcnt); } u32 mlx5e_rss_get_tirn(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, @@ -384,22 +412,27 @@ int mlx5e_rss_lro_set_param(struct mlx5e_rss *rss, struct mlx5e_lro_param *lro_p struct mlx5e_tir *tir; tir = rss_get_tir(rss, tt, false); + if (!tir) + goto inner_tir; err = mlx5e_tir_modify(tir, builder); if (err) { mlx5e_rss_warn(rss->mdev, "Failed to update LRO state of indirect TIR %#x for traffic type %d: err = %d\n", - mlx5e_tir_get_tirn(rss->tir[tt]), tt, err); + mlx5e_tir_get_tirn(tir), tt, err); if (!final_err) final_err = err; } +inner_tir: if (!rss->inner_ft_support) continue; tir = rss_get_tir(rss, tt, true); + if (!tir) + continue; err = mlx5e_tir_modify(tir, builder); if (err) { mlx5e_rss_warn(rss->mdev, "Failed to update LRO state of inner indirect TIR %#x for traffic type %d: err = %d\n", - mlx5e_tir_get_tirn(rss->inner_tir[tt]), tt, err); + mlx5e_tir_get_tirn(tir), tt, err); if (!final_err) final_err = err; } |