165d6b6e5SMaxim Mikityanskiy // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 265d6b6e5SMaxim Mikityanskiy /* Copyright (c) 2021, Mellanox Technologies inc. All rights reserved. */ 365d6b6e5SMaxim Mikityanskiy 465d6b6e5SMaxim Mikityanskiy #include "rx_res.h" 543ec0f41SMaxim Mikityanskiy #include "channels.h" 643ec0f41SMaxim Mikityanskiy #include "params.h" 765d6b6e5SMaxim Mikityanskiy 8f01cc58cSTariq Toukan #define MLX5E_MAX_NUM_RSS 16 9f01cc58cSTariq Toukan 1043ec0f41SMaxim Mikityanskiy struct mlx5e_rx_res { 1143ec0f41SMaxim Mikityanskiy struct mlx5_core_dev *mdev; 1243ec0f41SMaxim Mikityanskiy enum mlx5e_rx_res_features features; 1343ec0f41SMaxim Mikityanskiy unsigned int max_nch; 1443ec0f41SMaxim Mikityanskiy u32 drop_rqn; 1543ec0f41SMaxim Mikityanskiy 16f01cc58cSTariq Toukan struct mlx5e_rss *rss[MLX5E_MAX_NUM_RSS]; 1743ec0f41SMaxim Mikityanskiy bool rss_active; 1843ec0f41SMaxim Mikityanskiy u32 rss_rqns[MLX5E_INDIR_RQT_SIZE]; 1943ec0f41SMaxim Mikityanskiy unsigned int rss_nch; 2043ec0f41SMaxim Mikityanskiy 2143ec0f41SMaxim Mikityanskiy struct { 2243ec0f41SMaxim Mikityanskiy struct mlx5e_rqt direct_rqt; 2343ec0f41SMaxim Mikityanskiy struct mlx5e_tir direct_tir; 2443ec0f41SMaxim Mikityanskiy struct mlx5e_rqt xsk_rqt; 2543ec0f41SMaxim Mikityanskiy struct mlx5e_tir xsk_tir; 263ac90decSMaxim Mikityanskiy } *channels; 2743ec0f41SMaxim Mikityanskiy 2843ec0f41SMaxim Mikityanskiy struct { 2943ec0f41SMaxim Mikityanskiy struct mlx5e_rqt rqt; 3043ec0f41SMaxim Mikityanskiy struct mlx5e_tir tir; 3143ec0f41SMaxim Mikityanskiy } ptp; 3243ec0f41SMaxim Mikityanskiy }; 3343ec0f41SMaxim Mikityanskiy 3425307a91STariq Toukan /* API for rx_res_rss_* */ 35fc651ff9STariq Toukan 36f01cc58cSTariq Toukan static int mlx5e_rx_res_rss_init_def(struct mlx5e_rx_res *res, 37713ba5e5STariq Toukan const struct mlx5e_lro_param *init_lro_param, 38713ba5e5STariq Toukan unsigned int init_nch) 39fc651ff9STariq Toukan { 40fc651ff9STariq Toukan bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 41713ba5e5STariq Toukan struct mlx5e_rss *rss; 42fc651ff9STariq Toukan int err; 43fc651ff9STariq Toukan 44f01cc58cSTariq Toukan if (WARN_ON(res->rss[0])) 45f01cc58cSTariq Toukan return -EINVAL; 46f01cc58cSTariq Toukan 4725307a91STariq Toukan rss = mlx5e_rss_alloc(); 48713ba5e5STariq Toukan if (!rss) 49713ba5e5STariq Toukan return -ENOMEM; 50713ba5e5STariq Toukan 51f01cc58cSTariq Toukan err = mlx5e_rss_init(rss, res->mdev, inner_ft_support, res->drop_rqn, 52f01cc58cSTariq Toukan init_lro_param); 53fc651ff9STariq Toukan if (err) 5425307a91STariq Toukan goto err_rss_free; 55fc651ff9STariq Toukan 5625307a91STariq Toukan mlx5e_rss_set_indir_uniform(rss, init_nch); 57fc651ff9STariq Toukan 58f01cc58cSTariq Toukan res->rss[0] = rss; 59f01cc58cSTariq Toukan 60fc651ff9STariq Toukan return 0; 61fc651ff9STariq Toukan 6225307a91STariq Toukan err_rss_free: 6325307a91STariq Toukan mlx5e_rss_free(rss); 6443ec0f41SMaxim Mikityanskiy return err; 6543ec0f41SMaxim Mikityanskiy } 6643ec0f41SMaxim Mikityanskiy 67f01cc58cSTariq Toukan int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch) 6825307a91STariq Toukan { 69f01cc58cSTariq Toukan bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 70f01cc58cSTariq Toukan struct mlx5e_rss *rss; 71f01cc58cSTariq Toukan int err, i; 7225307a91STariq Toukan 73f01cc58cSTariq Toukan for (i = 1; i < MLX5E_MAX_NUM_RSS; i++) 74f01cc58cSTariq Toukan if (!res->rss[i]) 75f01cc58cSTariq Toukan break; 76f01cc58cSTariq Toukan 77f01cc58cSTariq Toukan if (i == MLX5E_MAX_NUM_RSS) 78f01cc58cSTariq Toukan return -ENOSPC; 79f01cc58cSTariq Toukan 80f01cc58cSTariq Toukan rss = mlx5e_rss_alloc(); 81f01cc58cSTariq Toukan if (!rss) 82f01cc58cSTariq Toukan return -ENOMEM; 83f01cc58cSTariq Toukan 84f01cc58cSTariq Toukan err = mlx5e_rss_init_no_tirs(rss, res->mdev, inner_ft_support, res->drop_rqn); 85f01cc58cSTariq Toukan if (err) 86f01cc58cSTariq Toukan goto err_rss_free; 87f01cc58cSTariq Toukan 88f01cc58cSTariq Toukan mlx5e_rss_set_indir_uniform(rss, init_nch); 89f01cc58cSTariq Toukan if (res->rss_active) 90f01cc58cSTariq Toukan mlx5e_rss_enable(rss, res->rss_rqns, res->rss_nch); 91f01cc58cSTariq Toukan 92f01cc58cSTariq Toukan res->rss[i] = rss; 93f01cc58cSTariq Toukan *rss_idx = i; 94f01cc58cSTariq Toukan 95f01cc58cSTariq Toukan return 0; 96f01cc58cSTariq Toukan 97f01cc58cSTariq Toukan err_rss_free: 9825307a91STariq Toukan mlx5e_rss_free(rss); 99f01cc58cSTariq Toukan return err; 100f01cc58cSTariq Toukan } 101f01cc58cSTariq Toukan 102f01cc58cSTariq Toukan static int __mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx) 103f01cc58cSTariq Toukan { 104f01cc58cSTariq Toukan struct mlx5e_rss *rss = res->rss[rss_idx]; 105f01cc58cSTariq Toukan int err; 106f01cc58cSTariq Toukan 107f01cc58cSTariq Toukan err = mlx5e_rss_cleanup(rss); 108f01cc58cSTariq Toukan if (err) 109f01cc58cSTariq Toukan return err; 110f01cc58cSTariq Toukan 111f01cc58cSTariq Toukan mlx5e_rss_free(rss); 112f01cc58cSTariq Toukan res->rss[rss_idx] = NULL; 113f01cc58cSTariq Toukan 114f01cc58cSTariq Toukan return 0; 115f01cc58cSTariq Toukan } 116f01cc58cSTariq Toukan 117f01cc58cSTariq Toukan int mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx) 118f01cc58cSTariq Toukan { 119f01cc58cSTariq Toukan struct mlx5e_rss *rss; 120f01cc58cSTariq Toukan 121f01cc58cSTariq Toukan if (rss_idx >= MLX5E_MAX_NUM_RSS) 122f01cc58cSTariq Toukan return -EINVAL; 123f01cc58cSTariq Toukan 124f01cc58cSTariq Toukan rss = res->rss[rss_idx]; 125f01cc58cSTariq Toukan if (!rss) 126f01cc58cSTariq Toukan return -EINVAL; 127f01cc58cSTariq Toukan 128f01cc58cSTariq Toukan return __mlx5e_rx_res_rss_destroy(res, rss_idx); 129f01cc58cSTariq Toukan } 130f01cc58cSTariq Toukan 131f01cc58cSTariq Toukan static void mlx5e_rx_res_rss_destroy_all(struct mlx5e_rx_res *res) 132f01cc58cSTariq Toukan { 133f01cc58cSTariq Toukan int i; 134f01cc58cSTariq Toukan 135f01cc58cSTariq Toukan for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) { 136f01cc58cSTariq Toukan struct mlx5e_rss *rss = res->rss[i]; 137f01cc58cSTariq Toukan int err; 138f01cc58cSTariq Toukan 139f01cc58cSTariq Toukan if (!rss) 140f01cc58cSTariq Toukan continue; 141f01cc58cSTariq Toukan 142f01cc58cSTariq Toukan err = __mlx5e_rx_res_rss_destroy(res, i); 143f01cc58cSTariq Toukan if (err) { 144f01cc58cSTariq Toukan unsigned int refcount; 145f01cc58cSTariq Toukan 146f01cc58cSTariq Toukan refcount = mlx5e_rss_refcnt_read(rss); 147f01cc58cSTariq Toukan mlx5_core_warn(res->mdev, 148f01cc58cSTariq Toukan "Failed to destroy RSS context %d, refcount = %u, err = %d\n", 149f01cc58cSTariq Toukan i, refcount, err); 150f01cc58cSTariq Toukan } 151f01cc58cSTariq Toukan } 15225307a91STariq Toukan } 15325307a91STariq Toukan 15425307a91STariq Toukan static void mlx5e_rx_res_rss_enable(struct mlx5e_rx_res *res) 15525307a91STariq Toukan { 156f01cc58cSTariq Toukan int i; 15725307a91STariq Toukan 15825307a91STariq Toukan res->rss_active = true; 15925307a91STariq Toukan 160f01cc58cSTariq Toukan for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) { 161f01cc58cSTariq Toukan struct mlx5e_rss *rss = res->rss[i]; 162f01cc58cSTariq Toukan 163f01cc58cSTariq Toukan if (!rss) 164f01cc58cSTariq Toukan continue; 16525307a91STariq Toukan mlx5e_rss_enable(rss, res->rss_rqns, res->rss_nch); 16625307a91STariq Toukan } 167f01cc58cSTariq Toukan } 16825307a91STariq Toukan 16925307a91STariq Toukan static void mlx5e_rx_res_rss_disable(struct mlx5e_rx_res *res) 17025307a91STariq Toukan { 171f01cc58cSTariq Toukan int i; 17225307a91STariq Toukan 17325307a91STariq Toukan res->rss_active = false; 17425307a91STariq Toukan 175f01cc58cSTariq Toukan for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) { 176f01cc58cSTariq Toukan struct mlx5e_rss *rss = res->rss[i]; 177f01cc58cSTariq Toukan 178f01cc58cSTariq Toukan if (!rss) 179f01cc58cSTariq Toukan continue; 18025307a91STariq Toukan mlx5e_rss_disable(rss); 18125307a91STariq Toukan } 182f01cc58cSTariq Toukan } 18325307a91STariq Toukan 18425307a91STariq Toukan /* Updates the indirection table SW shadow, does not update the HW resources yet */ 18525307a91STariq Toukan void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch) 18625307a91STariq Toukan { 18725307a91STariq Toukan WARN_ON_ONCE(res->rss_active); 188f01cc58cSTariq Toukan mlx5e_rss_set_indir_uniform(res->rss[0], nch); 18925307a91STariq Toukan } 19025307a91STariq Toukan 191f01cc58cSTariq Toukan int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx, 192f01cc58cSTariq Toukan u32 *indir, u8 *key, u8 *hfunc) 19325307a91STariq Toukan { 194f01cc58cSTariq Toukan struct mlx5e_rss *rss; 195f01cc58cSTariq Toukan 196f01cc58cSTariq Toukan if (rss_idx >= MLX5E_MAX_NUM_RSS) 197f01cc58cSTariq Toukan return -EINVAL; 198f01cc58cSTariq Toukan 199f01cc58cSTariq Toukan rss = res->rss[rss_idx]; 200f01cc58cSTariq Toukan if (!rss) 201f01cc58cSTariq Toukan return -ENOENT; 20225307a91STariq Toukan 20325307a91STariq Toukan return mlx5e_rss_get_rxfh(rss, indir, key, hfunc); 20425307a91STariq Toukan } 20525307a91STariq Toukan 206f01cc58cSTariq Toukan int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx, 207f01cc58cSTariq Toukan const u32 *indir, const u8 *key, const u8 *hfunc) 20825307a91STariq Toukan { 209f01cc58cSTariq Toukan struct mlx5e_rss *rss; 210f01cc58cSTariq Toukan 211f01cc58cSTariq Toukan if (rss_idx >= MLX5E_MAX_NUM_RSS) 212f01cc58cSTariq Toukan return -EINVAL; 213f01cc58cSTariq Toukan 214f01cc58cSTariq Toukan rss = res->rss[rss_idx]; 215f01cc58cSTariq Toukan if (!rss) 216f01cc58cSTariq Toukan return -ENOENT; 21725307a91STariq Toukan 21825307a91STariq Toukan return mlx5e_rss_set_rxfh(rss, indir, key, hfunc, res->rss_rqns, res->rss_nch); 21925307a91STariq Toukan } 22025307a91STariq Toukan 22125307a91STariq Toukan u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt) 22225307a91STariq Toukan { 223f01cc58cSTariq Toukan struct mlx5e_rss *rss = res->rss[0]; 22425307a91STariq Toukan 22525307a91STariq Toukan return mlx5e_rss_get_hash_fields(rss, tt); 22625307a91STariq Toukan } 22725307a91STariq Toukan 22825307a91STariq Toukan int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt, 22925307a91STariq Toukan u8 rx_hash_fields) 23025307a91STariq Toukan { 231f01cc58cSTariq Toukan struct mlx5e_rss *rss = res->rss[0]; 23225307a91STariq Toukan 23325307a91STariq Toukan return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields); 23425307a91STariq Toukan } 23525307a91STariq Toukan 236f01cc58cSTariq Toukan int mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res *res) 237f01cc58cSTariq Toukan { 238f01cc58cSTariq Toukan int i, cnt; 239f01cc58cSTariq Toukan 240f01cc58cSTariq Toukan cnt = 0; 241f01cc58cSTariq Toukan for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) 242f01cc58cSTariq Toukan if (res->rss[i]) 243f01cc58cSTariq Toukan cnt++; 244f01cc58cSTariq Toukan 245f01cc58cSTariq Toukan return cnt; 246f01cc58cSTariq Toukan } 247f01cc58cSTariq Toukan 248248d3b4cSTariq Toukan int mlx5e_rx_res_rss_index(struct mlx5e_rx_res *res, struct mlx5e_rss *rss) 249248d3b4cSTariq Toukan { 250248d3b4cSTariq Toukan int i; 251248d3b4cSTariq Toukan 252248d3b4cSTariq Toukan if (!rss) 253248d3b4cSTariq Toukan return -EINVAL; 254248d3b4cSTariq Toukan 255248d3b4cSTariq Toukan for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) 256248d3b4cSTariq Toukan if (rss == res->rss[i]) 257248d3b4cSTariq Toukan return i; 258248d3b4cSTariq Toukan 259248d3b4cSTariq Toukan return -ENOENT; 260248d3b4cSTariq Toukan } 261248d3b4cSTariq Toukan 262248d3b4cSTariq Toukan struct mlx5e_rss *mlx5e_rx_res_rss_get(struct mlx5e_rx_res *res, u32 rss_idx) 263248d3b4cSTariq Toukan { 264248d3b4cSTariq Toukan if (rss_idx >= MLX5E_MAX_NUM_RSS) 265248d3b4cSTariq Toukan return NULL; 266248d3b4cSTariq Toukan 267248d3b4cSTariq Toukan return res->rss[rss_idx]; 268248d3b4cSTariq Toukan } 269248d3b4cSTariq Toukan 27025307a91STariq Toukan /* End of API rx_res_rss_* */ 27125307a91STariq Toukan 27225307a91STariq Toukan struct mlx5e_rx_res *mlx5e_rx_res_alloc(void) 27325307a91STariq Toukan { 27425307a91STariq Toukan return kvzalloc(sizeof(struct mlx5e_rx_res), GFP_KERNEL); 27525307a91STariq Toukan } 27625307a91STariq Toukan 27743ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_channels_init(struct mlx5e_rx_res *res, 27843ec0f41SMaxim Mikityanskiy const struct mlx5e_lro_param *init_lro_param) 27943ec0f41SMaxim Mikityanskiy { 28043ec0f41SMaxim Mikityanskiy bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 28143ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 28243ec0f41SMaxim Mikityanskiy int err = 0; 28343ec0f41SMaxim Mikityanskiy int ix; 28443ec0f41SMaxim Mikityanskiy 28543ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(false); 28643ec0f41SMaxim Mikityanskiy if (!builder) 28743ec0f41SMaxim Mikityanskiy return -ENOMEM; 28843ec0f41SMaxim Mikityanskiy 2893ac90decSMaxim Mikityanskiy res->channels = kvcalloc(res->max_nch, sizeof(*res->channels), GFP_KERNEL); 2903ac90decSMaxim Mikityanskiy if (!res->channels) { 2913ac90decSMaxim Mikityanskiy err = -ENOMEM; 2923ac90decSMaxim Mikityanskiy goto out; 2933ac90decSMaxim Mikityanskiy } 2943ac90decSMaxim Mikityanskiy 29543ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 29643ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_init_direct(&res->channels[ix].direct_rqt, 29743ec0f41SMaxim Mikityanskiy res->mdev, false, res->drop_rqn); 29843ec0f41SMaxim Mikityanskiy if (err) { 29943ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create a direct RQT: err = %d, ix = %u\n", 30043ec0f41SMaxim Mikityanskiy err, ix); 30143ec0f41SMaxim Mikityanskiy goto err_destroy_direct_rqts; 30243ec0f41SMaxim Mikityanskiy } 30343ec0f41SMaxim Mikityanskiy } 30443ec0f41SMaxim Mikityanskiy 30543ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 30643ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 30743ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 30843ec0f41SMaxim Mikityanskiy inner_ft_support); 30943ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, init_lro_param); 31043ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_direct(builder); 31143ec0f41SMaxim Mikityanskiy 31243ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->channels[ix].direct_tir, builder, res->mdev, true); 31343ec0f41SMaxim Mikityanskiy if (err) { 31443ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create a direct TIR: err = %d, ix = %u\n", 31543ec0f41SMaxim Mikityanskiy err, ix); 31643ec0f41SMaxim Mikityanskiy goto err_destroy_direct_tirs; 31743ec0f41SMaxim Mikityanskiy } 31843ec0f41SMaxim Mikityanskiy 31943ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_clear(builder); 32043ec0f41SMaxim Mikityanskiy } 32143ec0f41SMaxim Mikityanskiy 32243ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 32343ec0f41SMaxim Mikityanskiy goto out; 32443ec0f41SMaxim Mikityanskiy 32543ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 32643ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_init_direct(&res->channels[ix].xsk_rqt, 32743ec0f41SMaxim Mikityanskiy res->mdev, false, res->drop_rqn); 32843ec0f41SMaxim Mikityanskiy if (err) { 32943ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create an XSK RQT: err = %d, ix = %u\n", 33043ec0f41SMaxim Mikityanskiy err, ix); 33143ec0f41SMaxim Mikityanskiy goto err_destroy_xsk_rqts; 33243ec0f41SMaxim Mikityanskiy } 33343ec0f41SMaxim Mikityanskiy } 33443ec0f41SMaxim Mikityanskiy 33543ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 33643ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 33743ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 33843ec0f41SMaxim Mikityanskiy inner_ft_support); 33943ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, init_lro_param); 34043ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_direct(builder); 34143ec0f41SMaxim Mikityanskiy 34243ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->channels[ix].xsk_tir, builder, res->mdev, true); 34343ec0f41SMaxim Mikityanskiy if (err) { 34443ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create an XSK TIR: err = %d, ix = %u\n", 34543ec0f41SMaxim Mikityanskiy err, ix); 34643ec0f41SMaxim Mikityanskiy goto err_destroy_xsk_tirs; 34743ec0f41SMaxim Mikityanskiy } 34843ec0f41SMaxim Mikityanskiy 34943ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_clear(builder); 35043ec0f41SMaxim Mikityanskiy } 35143ec0f41SMaxim Mikityanskiy 35243ec0f41SMaxim Mikityanskiy goto out; 35343ec0f41SMaxim Mikityanskiy 35443ec0f41SMaxim Mikityanskiy err_destroy_xsk_tirs: 35543ec0f41SMaxim Mikityanskiy while (--ix >= 0) 35643ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].xsk_tir); 35743ec0f41SMaxim Mikityanskiy 35843ec0f41SMaxim Mikityanskiy ix = res->max_nch; 35943ec0f41SMaxim Mikityanskiy err_destroy_xsk_rqts: 36043ec0f41SMaxim Mikityanskiy while (--ix >= 0) 36143ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt); 36243ec0f41SMaxim Mikityanskiy 36343ec0f41SMaxim Mikityanskiy ix = res->max_nch; 36443ec0f41SMaxim Mikityanskiy err_destroy_direct_tirs: 36543ec0f41SMaxim Mikityanskiy while (--ix >= 0) 36643ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].direct_tir); 36743ec0f41SMaxim Mikityanskiy 36843ec0f41SMaxim Mikityanskiy ix = res->max_nch; 36943ec0f41SMaxim Mikityanskiy err_destroy_direct_rqts: 37043ec0f41SMaxim Mikityanskiy while (--ix >= 0) 37143ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].direct_rqt); 37243ec0f41SMaxim Mikityanskiy 3733ac90decSMaxim Mikityanskiy kvfree(res->channels); 3743ac90decSMaxim Mikityanskiy 37543ec0f41SMaxim Mikityanskiy out: 37643ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 37743ec0f41SMaxim Mikityanskiy 37843ec0f41SMaxim Mikityanskiy return err; 37943ec0f41SMaxim Mikityanskiy } 38043ec0f41SMaxim Mikityanskiy 38143ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_ptp_init(struct mlx5e_rx_res *res) 38243ec0f41SMaxim Mikityanskiy { 38343ec0f41SMaxim Mikityanskiy bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 38443ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 38543ec0f41SMaxim Mikityanskiy int err; 38643ec0f41SMaxim Mikityanskiy 38743ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(false); 38843ec0f41SMaxim Mikityanskiy if (!builder) 38943ec0f41SMaxim Mikityanskiy return -ENOMEM; 39043ec0f41SMaxim Mikityanskiy 39143ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_init_direct(&res->ptp.rqt, res->mdev, false, res->drop_rqn); 39243ec0f41SMaxim Mikityanskiy if (err) 39343ec0f41SMaxim Mikityanskiy goto out; 39443ec0f41SMaxim Mikityanskiy 39543ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 39643ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->ptp.rqt), 39743ec0f41SMaxim Mikityanskiy inner_ft_support); 39843ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_direct(builder); 39943ec0f41SMaxim Mikityanskiy 40043ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->ptp.tir, builder, res->mdev, true); 40143ec0f41SMaxim Mikityanskiy if (err) 40243ec0f41SMaxim Mikityanskiy goto err_destroy_ptp_rqt; 40343ec0f41SMaxim Mikityanskiy 40443ec0f41SMaxim Mikityanskiy goto out; 40543ec0f41SMaxim Mikityanskiy 40643ec0f41SMaxim Mikityanskiy err_destroy_ptp_rqt: 40743ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->ptp.rqt); 40843ec0f41SMaxim Mikityanskiy 40943ec0f41SMaxim Mikityanskiy out: 41043ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 41143ec0f41SMaxim Mikityanskiy return err; 41243ec0f41SMaxim Mikityanskiy } 41343ec0f41SMaxim Mikityanskiy 41443ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res *res) 41543ec0f41SMaxim Mikityanskiy { 41643ec0f41SMaxim Mikityanskiy unsigned int ix; 41743ec0f41SMaxim Mikityanskiy 41843ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 41943ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].direct_tir); 42043ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].direct_rqt); 42143ec0f41SMaxim Mikityanskiy 42243ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 42343ec0f41SMaxim Mikityanskiy continue; 42443ec0f41SMaxim Mikityanskiy 42543ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].xsk_tir); 42643ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt); 42743ec0f41SMaxim Mikityanskiy } 4283ac90decSMaxim Mikityanskiy 4293ac90decSMaxim Mikityanskiy kvfree(res->channels); 43043ec0f41SMaxim Mikityanskiy } 43143ec0f41SMaxim Mikityanskiy 43243ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res *res) 43343ec0f41SMaxim Mikityanskiy { 43443ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->ptp.tir); 43543ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->ptp.rqt); 43643ec0f41SMaxim Mikityanskiy } 43743ec0f41SMaxim Mikityanskiy 43843ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_init(struct mlx5e_rx_res *res, struct mlx5_core_dev *mdev, 43943ec0f41SMaxim Mikityanskiy enum mlx5e_rx_res_features features, unsigned int max_nch, 44043ec0f41SMaxim Mikityanskiy u32 drop_rqn, const struct mlx5e_lro_param *init_lro_param, 44143ec0f41SMaxim Mikityanskiy unsigned int init_nch) 44243ec0f41SMaxim Mikityanskiy { 44343ec0f41SMaxim Mikityanskiy int err; 44443ec0f41SMaxim Mikityanskiy 44543ec0f41SMaxim Mikityanskiy res->mdev = mdev; 44643ec0f41SMaxim Mikityanskiy res->features = features; 44743ec0f41SMaxim Mikityanskiy res->max_nch = max_nch; 44843ec0f41SMaxim Mikityanskiy res->drop_rqn = drop_rqn; 44943ec0f41SMaxim Mikityanskiy 450f01cc58cSTariq Toukan err = mlx5e_rx_res_rss_init_def(res, init_lro_param, init_nch); 45143ec0f41SMaxim Mikityanskiy if (err) 45225307a91STariq Toukan goto err_out; 45343ec0f41SMaxim Mikityanskiy 45443ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_channels_init(res, init_lro_param); 45543ec0f41SMaxim Mikityanskiy if (err) 45643ec0f41SMaxim Mikityanskiy goto err_rss_destroy; 45743ec0f41SMaxim Mikityanskiy 45843ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_ptp_init(res); 45943ec0f41SMaxim Mikityanskiy if (err) 46043ec0f41SMaxim Mikityanskiy goto err_channels_destroy; 46143ec0f41SMaxim Mikityanskiy 46243ec0f41SMaxim Mikityanskiy return 0; 46343ec0f41SMaxim Mikityanskiy 46443ec0f41SMaxim Mikityanskiy err_channels_destroy: 46543ec0f41SMaxim Mikityanskiy mlx5e_rx_res_channels_destroy(res); 46643ec0f41SMaxim Mikityanskiy err_rss_destroy: 467f01cc58cSTariq Toukan __mlx5e_rx_res_rss_destroy(res, 0); 46825307a91STariq Toukan err_out: 46943ec0f41SMaxim Mikityanskiy return err; 47043ec0f41SMaxim Mikityanskiy } 47143ec0f41SMaxim Mikityanskiy 47243ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_destroy(struct mlx5e_rx_res *res) 47343ec0f41SMaxim Mikityanskiy { 47443ec0f41SMaxim Mikityanskiy mlx5e_rx_res_ptp_destroy(res); 47543ec0f41SMaxim Mikityanskiy mlx5e_rx_res_channels_destroy(res); 476f01cc58cSTariq Toukan mlx5e_rx_res_rss_destroy_all(res); 47743ec0f41SMaxim Mikityanskiy } 47843ec0f41SMaxim Mikityanskiy 47943ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_free(struct mlx5e_rx_res *res) 48043ec0f41SMaxim Mikityanskiy { 48143ec0f41SMaxim Mikityanskiy kvfree(res); 48243ec0f41SMaxim Mikityanskiy } 48343ec0f41SMaxim Mikityanskiy 48443ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res *res, unsigned int ix) 48543ec0f41SMaxim Mikityanskiy { 48643ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->channels[ix].direct_tir); 48743ec0f41SMaxim Mikityanskiy } 48843ec0f41SMaxim Mikityanskiy 48943ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_xsk(struct mlx5e_rx_res *res, unsigned int ix) 49043ec0f41SMaxim Mikityanskiy { 49143ec0f41SMaxim Mikityanskiy WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_XSK)); 49243ec0f41SMaxim Mikityanskiy 49343ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->channels[ix].xsk_tir); 49443ec0f41SMaxim Mikityanskiy } 49543ec0f41SMaxim Mikityanskiy 496d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt) 49743ec0f41SMaxim Mikityanskiy { 498f01cc58cSTariq Toukan struct mlx5e_rss *rss = res->rss[0]; 499713ba5e5STariq Toukan 50025307a91STariq Toukan return mlx5e_rss_get_tirn(rss, tt, false); 50143ec0f41SMaxim Mikityanskiy } 50243ec0f41SMaxim Mikityanskiy 503d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt) 50443ec0f41SMaxim Mikityanskiy { 505f01cc58cSTariq Toukan struct mlx5e_rss *rss = res->rss[0]; 506713ba5e5STariq Toukan 50725307a91STariq Toukan return mlx5e_rss_get_tirn(rss, tt, true); 50843ec0f41SMaxim Mikityanskiy } 50943ec0f41SMaxim Mikityanskiy 51043ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res) 51143ec0f41SMaxim Mikityanskiy { 51243ec0f41SMaxim Mikityanskiy WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_PTP)); 51343ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->ptp.tir); 51443ec0f41SMaxim Mikityanskiy } 51543ec0f41SMaxim Mikityanskiy 51643ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix) 51743ec0f41SMaxim Mikityanskiy { 51843ec0f41SMaxim Mikityanskiy return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt); 51943ec0f41SMaxim Mikityanskiy } 52043ec0f41SMaxim Mikityanskiy 52143ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs) 52243ec0f41SMaxim Mikityanskiy { 52343ec0f41SMaxim Mikityanskiy unsigned int nch, ix; 52443ec0f41SMaxim Mikityanskiy int err; 52543ec0f41SMaxim Mikityanskiy 52643ec0f41SMaxim Mikityanskiy nch = mlx5e_channels_get_num(chs); 52743ec0f41SMaxim Mikityanskiy 52843ec0f41SMaxim Mikityanskiy for (ix = 0; ix < chs->num; ix++) 52943ec0f41SMaxim Mikityanskiy mlx5e_channels_get_regular_rqn(chs, ix, &res->rss_rqns[ix]); 53043ec0f41SMaxim Mikityanskiy res->rss_nch = chs->num; 53143ec0f41SMaxim Mikityanskiy 53243ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_enable(res); 53343ec0f41SMaxim Mikityanskiy 53443ec0f41SMaxim Mikityanskiy for (ix = 0; ix < nch; ix++) { 53543ec0f41SMaxim Mikityanskiy u32 rqn; 53643ec0f41SMaxim Mikityanskiy 53743ec0f41SMaxim Mikityanskiy mlx5e_channels_get_regular_rqn(chs, ix, &rqn); 53843ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, rqn); 53943ec0f41SMaxim Mikityanskiy if (err) 54043ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (channel %u): err = %d\n", 54143ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 54243ec0f41SMaxim Mikityanskiy rqn, ix, err); 54343ec0f41SMaxim Mikityanskiy 54443ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 54543ec0f41SMaxim Mikityanskiy continue; 54643ec0f41SMaxim Mikityanskiy 54743ec0f41SMaxim Mikityanskiy if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn)) 54843ec0f41SMaxim Mikityanskiy rqn = res->drop_rqn; 54943ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn); 55043ec0f41SMaxim Mikityanskiy if (err) 55143ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to RQ %#x (channel %u): err = %d\n", 55243ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 55343ec0f41SMaxim Mikityanskiy rqn, ix, err); 55443ec0f41SMaxim Mikityanskiy } 55543ec0f41SMaxim Mikityanskiy for (ix = nch; ix < res->max_nch; ix++) { 55643ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn); 55743ec0f41SMaxim Mikityanskiy if (err) 55843ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n", 55943ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 56043ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 56143ec0f41SMaxim Mikityanskiy 56243ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 56343ec0f41SMaxim Mikityanskiy continue; 56443ec0f41SMaxim Mikityanskiy 56543ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn); 56643ec0f41SMaxim Mikityanskiy if (err) 56743ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n", 56843ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 56943ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 57043ec0f41SMaxim Mikityanskiy } 57143ec0f41SMaxim Mikityanskiy 57243ec0f41SMaxim Mikityanskiy if (res->features & MLX5E_RX_RES_FEATURE_PTP) { 57343ec0f41SMaxim Mikityanskiy u32 rqn; 57443ec0f41SMaxim Mikityanskiy 575*8db6a54fSAya Levin if (!mlx5e_channels_get_ptp_rqn(chs, &rqn)) 57643ec0f41SMaxim Mikityanskiy rqn = res->drop_rqn; 57743ec0f41SMaxim Mikityanskiy 57843ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, rqn); 57943ec0f41SMaxim Mikityanskiy if (err) 58043ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (PTP): err = %d\n", 58143ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->ptp.rqt), 58243ec0f41SMaxim Mikityanskiy rqn, err); 58343ec0f41SMaxim Mikityanskiy } 58443ec0f41SMaxim Mikityanskiy } 58543ec0f41SMaxim Mikityanskiy 58643ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res) 58743ec0f41SMaxim Mikityanskiy { 58843ec0f41SMaxim Mikityanskiy unsigned int ix; 58943ec0f41SMaxim Mikityanskiy int err; 59043ec0f41SMaxim Mikityanskiy 59143ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_disable(res); 59243ec0f41SMaxim Mikityanskiy 59343ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 59443ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn); 59543ec0f41SMaxim Mikityanskiy if (err) 59643ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n", 59743ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 59843ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 59943ec0f41SMaxim Mikityanskiy 60043ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 60143ec0f41SMaxim Mikityanskiy continue; 60243ec0f41SMaxim Mikityanskiy 60343ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn); 60443ec0f41SMaxim Mikityanskiy if (err) 60543ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n", 60643ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 60743ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 60843ec0f41SMaxim Mikityanskiy } 60943ec0f41SMaxim Mikityanskiy 61043ec0f41SMaxim Mikityanskiy if (res->features & MLX5E_RX_RES_FEATURE_PTP) { 61143ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, res->drop_rqn); 61243ec0f41SMaxim Mikityanskiy if (err) 61343ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (PTP): err = %d\n", 61443ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->ptp.rqt), 61543ec0f41SMaxim Mikityanskiy res->drop_rqn, err); 61643ec0f41SMaxim Mikityanskiy } 61743ec0f41SMaxim Mikityanskiy } 61843ec0f41SMaxim Mikityanskiy 61943ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs, 62043ec0f41SMaxim Mikityanskiy unsigned int ix) 62143ec0f41SMaxim Mikityanskiy { 62243ec0f41SMaxim Mikityanskiy u32 rqn; 62343ec0f41SMaxim Mikityanskiy int err; 62443ec0f41SMaxim Mikityanskiy 62543ec0f41SMaxim Mikityanskiy if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn)) 62643ec0f41SMaxim Mikityanskiy return -EINVAL; 62743ec0f41SMaxim Mikityanskiy 62843ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn); 62943ec0f41SMaxim Mikityanskiy if (err) 63043ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to XSK RQ %#x (channel %u): err = %d\n", 63143ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 63243ec0f41SMaxim Mikityanskiy rqn, ix, err); 63343ec0f41SMaxim Mikityanskiy return err; 63443ec0f41SMaxim Mikityanskiy } 63543ec0f41SMaxim Mikityanskiy 63643ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_deactivate(struct mlx5e_rx_res *res, unsigned int ix) 63743ec0f41SMaxim Mikityanskiy { 63843ec0f41SMaxim Mikityanskiy int err; 63943ec0f41SMaxim Mikityanskiy 64043ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn); 64143ec0f41SMaxim Mikityanskiy if (err) 64243ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n", 64343ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 64443ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 64543ec0f41SMaxim Mikityanskiy return err; 64643ec0f41SMaxim Mikityanskiy } 64743ec0f41SMaxim Mikityanskiy 64843ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_lro_set_param(struct mlx5e_rx_res *res, struct mlx5e_lro_param *lro_param) 64943ec0f41SMaxim Mikityanskiy { 65043ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 65143ec0f41SMaxim Mikityanskiy int err, final_err; 65243ec0f41SMaxim Mikityanskiy unsigned int ix; 65343ec0f41SMaxim Mikityanskiy 65443ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(true); 65543ec0f41SMaxim Mikityanskiy if (!builder) 65643ec0f41SMaxim Mikityanskiy return -ENOMEM; 65743ec0f41SMaxim Mikityanskiy 65843ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, lro_param); 65943ec0f41SMaxim Mikityanskiy 66043ec0f41SMaxim Mikityanskiy final_err = 0; 66143ec0f41SMaxim Mikityanskiy 662f01cc58cSTariq Toukan for (ix = 0; ix < MLX5E_MAX_NUM_RSS; ix++) { 663f01cc58cSTariq Toukan struct mlx5e_rss *rss = res->rss[ix]; 664f01cc58cSTariq Toukan 665f01cc58cSTariq Toukan if (!rss) 666f01cc58cSTariq Toukan continue; 667f01cc58cSTariq Toukan 66825307a91STariq Toukan err = mlx5e_rss_lro_set_param(rss, lro_param); 66925307a91STariq Toukan if (err) 67025307a91STariq Toukan final_err = final_err ? : err; 671f01cc58cSTariq Toukan } 67243ec0f41SMaxim Mikityanskiy 67343ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 67443ec0f41SMaxim Mikityanskiy err = mlx5e_tir_modify(&res->channels[ix].direct_tir, builder); 67543ec0f41SMaxim Mikityanskiy if (err) { 67643ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to update LRO state of direct TIR %#x for channel %u: err = %d\n", 67743ec0f41SMaxim Mikityanskiy mlx5e_tir_get_tirn(&res->channels[ix].direct_tir), ix, err); 67843ec0f41SMaxim Mikityanskiy if (!final_err) 67943ec0f41SMaxim Mikityanskiy final_err = err; 68043ec0f41SMaxim Mikityanskiy } 68143ec0f41SMaxim Mikityanskiy } 68243ec0f41SMaxim Mikityanskiy 68343ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 68443ec0f41SMaxim Mikityanskiy return final_err; 68543ec0f41SMaxim Mikityanskiy } 68643ec0f41SMaxim Mikityanskiy 68743ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res) 68843ec0f41SMaxim Mikityanskiy { 689f01cc58cSTariq Toukan return mlx5e_rss_get_hash(res->rss[0]); 69043ec0f41SMaxim Mikityanskiy } 691