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 843ec0f41SMaxim Mikityanskiy struct mlx5e_rx_res { 943ec0f41SMaxim Mikityanskiy struct mlx5_core_dev *mdev; 1043ec0f41SMaxim Mikityanskiy enum mlx5e_rx_res_features features; 1143ec0f41SMaxim Mikityanskiy unsigned int max_nch; 1243ec0f41SMaxim Mikityanskiy u32 drop_rqn; 1343ec0f41SMaxim Mikityanskiy 14713ba5e5STariq Toukan struct mlx5e_rss *rss; 1543ec0f41SMaxim Mikityanskiy bool rss_active; 1643ec0f41SMaxim Mikityanskiy u32 rss_rqns[MLX5E_INDIR_RQT_SIZE]; 1743ec0f41SMaxim Mikityanskiy unsigned int rss_nch; 1843ec0f41SMaxim Mikityanskiy 1943ec0f41SMaxim Mikityanskiy struct { 2043ec0f41SMaxim Mikityanskiy struct mlx5e_rqt direct_rqt; 2143ec0f41SMaxim Mikityanskiy struct mlx5e_tir direct_tir; 2243ec0f41SMaxim Mikityanskiy struct mlx5e_rqt xsk_rqt; 2343ec0f41SMaxim Mikityanskiy struct mlx5e_tir xsk_tir; 243ac90decSMaxim Mikityanskiy } *channels; 2543ec0f41SMaxim Mikityanskiy 2643ec0f41SMaxim Mikityanskiy struct { 2743ec0f41SMaxim Mikityanskiy struct mlx5e_rqt rqt; 2843ec0f41SMaxim Mikityanskiy struct mlx5e_tir tir; 2943ec0f41SMaxim Mikityanskiy } ptp; 3043ec0f41SMaxim Mikityanskiy }; 3143ec0f41SMaxim Mikityanskiy 32*25307a91STariq Toukan /* API for rx_res_rss_* */ 33fc651ff9STariq Toukan 34fc651ff9STariq Toukan static int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, 35713ba5e5STariq Toukan const struct mlx5e_lro_param *init_lro_param, 36713ba5e5STariq Toukan unsigned int init_nch) 37fc651ff9STariq Toukan { 38fc651ff9STariq Toukan bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 39713ba5e5STariq Toukan struct mlx5e_rss *rss; 40fc651ff9STariq Toukan int err; 41fc651ff9STariq Toukan 42*25307a91STariq Toukan rss = mlx5e_rss_alloc(); 43713ba5e5STariq Toukan if (!rss) 44713ba5e5STariq Toukan return -ENOMEM; 45713ba5e5STariq Toukan 46713ba5e5STariq Toukan res->rss = rss; 47713ba5e5STariq Toukan 48*25307a91STariq Toukan err = mlx5e_rss_init(rss, res->mdev, inner_ft_support, res->drop_rqn, init_lro_param); 49fc651ff9STariq Toukan if (err) 50*25307a91STariq Toukan goto err_rss_free; 51fc651ff9STariq Toukan 52*25307a91STariq Toukan mlx5e_rss_set_indir_uniform(rss, init_nch); 53fc651ff9STariq Toukan 54fc651ff9STariq Toukan return 0; 55fc651ff9STariq Toukan 56*25307a91STariq Toukan err_rss_free: 57*25307a91STariq Toukan mlx5e_rss_free(rss); 58713ba5e5STariq Toukan res->rss = NULL; 5943ec0f41SMaxim Mikityanskiy return err; 6043ec0f41SMaxim Mikityanskiy } 6143ec0f41SMaxim Mikityanskiy 62*25307a91STariq Toukan static void mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res) 63*25307a91STariq Toukan { 64*25307a91STariq Toukan struct mlx5e_rss *rss = res->rss; 65*25307a91STariq Toukan 66*25307a91STariq Toukan mlx5e_rss_cleanup(rss); 67*25307a91STariq Toukan mlx5e_rss_free(rss); 68*25307a91STariq Toukan res->rss = NULL; 69*25307a91STariq Toukan } 70*25307a91STariq Toukan 71*25307a91STariq Toukan static void mlx5e_rx_res_rss_enable(struct mlx5e_rx_res *res) 72*25307a91STariq Toukan { 73*25307a91STariq Toukan struct mlx5e_rss *rss = res->rss; 74*25307a91STariq Toukan 75*25307a91STariq Toukan res->rss_active = true; 76*25307a91STariq Toukan 77*25307a91STariq Toukan mlx5e_rss_enable(rss, res->rss_rqns, res->rss_nch); 78*25307a91STariq Toukan } 79*25307a91STariq Toukan 80*25307a91STariq Toukan static void mlx5e_rx_res_rss_disable(struct mlx5e_rx_res *res) 81*25307a91STariq Toukan { 82*25307a91STariq Toukan struct mlx5e_rss *rss = res->rss; 83*25307a91STariq Toukan 84*25307a91STariq Toukan res->rss_active = false; 85*25307a91STariq Toukan 86*25307a91STariq Toukan mlx5e_rss_disable(rss); 87*25307a91STariq Toukan } 88*25307a91STariq Toukan 89*25307a91STariq Toukan /* Updates the indirection table SW shadow, does not update the HW resources yet */ 90*25307a91STariq Toukan void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch) 91*25307a91STariq Toukan { 92*25307a91STariq Toukan WARN_ON_ONCE(res->rss_active); 93*25307a91STariq Toukan mlx5e_rss_set_indir_uniform(res->rss, nch); 94*25307a91STariq Toukan } 95*25307a91STariq Toukan 96*25307a91STariq Toukan int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 *indir, u8 *key, u8 *hfunc) 97*25307a91STariq Toukan { 98*25307a91STariq Toukan struct mlx5e_rss *rss = res->rss; 99*25307a91STariq Toukan 100*25307a91STariq Toukan return mlx5e_rss_get_rxfh(rss, indir, key, hfunc); 101*25307a91STariq Toukan } 102*25307a91STariq Toukan 103*25307a91STariq Toukan int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, const u32 *indir, 104*25307a91STariq Toukan const u8 *key, const u8 *hfunc) 105*25307a91STariq Toukan { 106*25307a91STariq Toukan struct mlx5e_rss *rss = res->rss; 107*25307a91STariq Toukan 108*25307a91STariq Toukan return mlx5e_rss_set_rxfh(rss, indir, key, hfunc, res->rss_rqns, res->rss_nch); 109*25307a91STariq Toukan } 110*25307a91STariq Toukan 111*25307a91STariq Toukan u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt) 112*25307a91STariq Toukan { 113*25307a91STariq Toukan struct mlx5e_rss *rss = res->rss; 114*25307a91STariq Toukan 115*25307a91STariq Toukan return mlx5e_rss_get_hash_fields(rss, tt); 116*25307a91STariq Toukan } 117*25307a91STariq Toukan 118*25307a91STariq Toukan int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt, 119*25307a91STariq Toukan u8 rx_hash_fields) 120*25307a91STariq Toukan { 121*25307a91STariq Toukan struct mlx5e_rss *rss = res->rss; 122*25307a91STariq Toukan 123*25307a91STariq Toukan return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields); 124*25307a91STariq Toukan } 125*25307a91STariq Toukan 126*25307a91STariq Toukan /* End of API rx_res_rss_* */ 127*25307a91STariq Toukan 128*25307a91STariq Toukan struct mlx5e_rx_res *mlx5e_rx_res_alloc(void) 129*25307a91STariq Toukan { 130*25307a91STariq Toukan return kvzalloc(sizeof(struct mlx5e_rx_res), GFP_KERNEL); 131*25307a91STariq Toukan } 132*25307a91STariq Toukan 13343ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_channels_init(struct mlx5e_rx_res *res, 13443ec0f41SMaxim Mikityanskiy const struct mlx5e_lro_param *init_lro_param) 13543ec0f41SMaxim Mikityanskiy { 13643ec0f41SMaxim Mikityanskiy bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 13743ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 13843ec0f41SMaxim Mikityanskiy int err = 0; 13943ec0f41SMaxim Mikityanskiy int ix; 14043ec0f41SMaxim Mikityanskiy 14143ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(false); 14243ec0f41SMaxim Mikityanskiy if (!builder) 14343ec0f41SMaxim Mikityanskiy return -ENOMEM; 14443ec0f41SMaxim Mikityanskiy 1453ac90decSMaxim Mikityanskiy res->channels = kvcalloc(res->max_nch, sizeof(*res->channels), GFP_KERNEL); 1463ac90decSMaxim Mikityanskiy if (!res->channels) { 1473ac90decSMaxim Mikityanskiy err = -ENOMEM; 1483ac90decSMaxim Mikityanskiy goto out; 1493ac90decSMaxim Mikityanskiy } 1503ac90decSMaxim Mikityanskiy 15143ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 15243ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_init_direct(&res->channels[ix].direct_rqt, 15343ec0f41SMaxim Mikityanskiy res->mdev, false, res->drop_rqn); 15443ec0f41SMaxim Mikityanskiy if (err) { 15543ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create a direct RQT: err = %d, ix = %u\n", 15643ec0f41SMaxim Mikityanskiy err, ix); 15743ec0f41SMaxim Mikityanskiy goto err_destroy_direct_rqts; 15843ec0f41SMaxim Mikityanskiy } 15943ec0f41SMaxim Mikityanskiy } 16043ec0f41SMaxim Mikityanskiy 16143ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 16243ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 16343ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 16443ec0f41SMaxim Mikityanskiy inner_ft_support); 16543ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, init_lro_param); 16643ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_direct(builder); 16743ec0f41SMaxim Mikityanskiy 16843ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->channels[ix].direct_tir, builder, res->mdev, true); 16943ec0f41SMaxim Mikityanskiy if (err) { 17043ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create a direct TIR: err = %d, ix = %u\n", 17143ec0f41SMaxim Mikityanskiy err, ix); 17243ec0f41SMaxim Mikityanskiy goto err_destroy_direct_tirs; 17343ec0f41SMaxim Mikityanskiy } 17443ec0f41SMaxim Mikityanskiy 17543ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_clear(builder); 17643ec0f41SMaxim Mikityanskiy } 17743ec0f41SMaxim Mikityanskiy 17843ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 17943ec0f41SMaxim Mikityanskiy goto out; 18043ec0f41SMaxim Mikityanskiy 18143ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 18243ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_init_direct(&res->channels[ix].xsk_rqt, 18343ec0f41SMaxim Mikityanskiy res->mdev, false, res->drop_rqn); 18443ec0f41SMaxim Mikityanskiy if (err) { 18543ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create an XSK RQT: err = %d, ix = %u\n", 18643ec0f41SMaxim Mikityanskiy err, ix); 18743ec0f41SMaxim Mikityanskiy goto err_destroy_xsk_rqts; 18843ec0f41SMaxim Mikityanskiy } 18943ec0f41SMaxim Mikityanskiy } 19043ec0f41SMaxim Mikityanskiy 19143ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 19243ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 19343ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 19443ec0f41SMaxim Mikityanskiy inner_ft_support); 19543ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, init_lro_param); 19643ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_direct(builder); 19743ec0f41SMaxim Mikityanskiy 19843ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->channels[ix].xsk_tir, builder, res->mdev, true); 19943ec0f41SMaxim Mikityanskiy if (err) { 20043ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create an XSK TIR: err = %d, ix = %u\n", 20143ec0f41SMaxim Mikityanskiy err, ix); 20243ec0f41SMaxim Mikityanskiy goto err_destroy_xsk_tirs; 20343ec0f41SMaxim Mikityanskiy } 20443ec0f41SMaxim Mikityanskiy 20543ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_clear(builder); 20643ec0f41SMaxim Mikityanskiy } 20743ec0f41SMaxim Mikityanskiy 20843ec0f41SMaxim Mikityanskiy goto out; 20943ec0f41SMaxim Mikityanskiy 21043ec0f41SMaxim Mikityanskiy err_destroy_xsk_tirs: 21143ec0f41SMaxim Mikityanskiy while (--ix >= 0) 21243ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].xsk_tir); 21343ec0f41SMaxim Mikityanskiy 21443ec0f41SMaxim Mikityanskiy ix = res->max_nch; 21543ec0f41SMaxim Mikityanskiy err_destroy_xsk_rqts: 21643ec0f41SMaxim Mikityanskiy while (--ix >= 0) 21743ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt); 21843ec0f41SMaxim Mikityanskiy 21943ec0f41SMaxim Mikityanskiy ix = res->max_nch; 22043ec0f41SMaxim Mikityanskiy err_destroy_direct_tirs: 22143ec0f41SMaxim Mikityanskiy while (--ix >= 0) 22243ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].direct_tir); 22343ec0f41SMaxim Mikityanskiy 22443ec0f41SMaxim Mikityanskiy ix = res->max_nch; 22543ec0f41SMaxim Mikityanskiy err_destroy_direct_rqts: 22643ec0f41SMaxim Mikityanskiy while (--ix >= 0) 22743ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].direct_rqt); 22843ec0f41SMaxim Mikityanskiy 2293ac90decSMaxim Mikityanskiy kvfree(res->channels); 2303ac90decSMaxim Mikityanskiy 23143ec0f41SMaxim Mikityanskiy out: 23243ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 23343ec0f41SMaxim Mikityanskiy 23443ec0f41SMaxim Mikityanskiy return err; 23543ec0f41SMaxim Mikityanskiy } 23643ec0f41SMaxim Mikityanskiy 23743ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_ptp_init(struct mlx5e_rx_res *res) 23843ec0f41SMaxim Mikityanskiy { 23943ec0f41SMaxim Mikityanskiy bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 24043ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 24143ec0f41SMaxim Mikityanskiy int err; 24243ec0f41SMaxim Mikityanskiy 24343ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(false); 24443ec0f41SMaxim Mikityanskiy if (!builder) 24543ec0f41SMaxim Mikityanskiy return -ENOMEM; 24643ec0f41SMaxim Mikityanskiy 24743ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_init_direct(&res->ptp.rqt, res->mdev, false, res->drop_rqn); 24843ec0f41SMaxim Mikityanskiy if (err) 24943ec0f41SMaxim Mikityanskiy goto out; 25043ec0f41SMaxim Mikityanskiy 25143ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 25243ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->ptp.rqt), 25343ec0f41SMaxim Mikityanskiy inner_ft_support); 25443ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_direct(builder); 25543ec0f41SMaxim Mikityanskiy 25643ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->ptp.tir, builder, res->mdev, true); 25743ec0f41SMaxim Mikityanskiy if (err) 25843ec0f41SMaxim Mikityanskiy goto err_destroy_ptp_rqt; 25943ec0f41SMaxim Mikityanskiy 26043ec0f41SMaxim Mikityanskiy goto out; 26143ec0f41SMaxim Mikityanskiy 26243ec0f41SMaxim Mikityanskiy err_destroy_ptp_rqt: 26343ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->ptp.rqt); 26443ec0f41SMaxim Mikityanskiy 26543ec0f41SMaxim Mikityanskiy out: 26643ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 26743ec0f41SMaxim Mikityanskiy return err; 26843ec0f41SMaxim Mikityanskiy } 26943ec0f41SMaxim Mikityanskiy 27043ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res *res) 27143ec0f41SMaxim Mikityanskiy { 27243ec0f41SMaxim Mikityanskiy unsigned int ix; 27343ec0f41SMaxim Mikityanskiy 27443ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 27543ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].direct_tir); 27643ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].direct_rqt); 27743ec0f41SMaxim Mikityanskiy 27843ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 27943ec0f41SMaxim Mikityanskiy continue; 28043ec0f41SMaxim Mikityanskiy 28143ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].xsk_tir); 28243ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt); 28343ec0f41SMaxim Mikityanskiy } 2843ac90decSMaxim Mikityanskiy 2853ac90decSMaxim Mikityanskiy kvfree(res->channels); 28643ec0f41SMaxim Mikityanskiy } 28743ec0f41SMaxim Mikityanskiy 28843ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res *res) 28943ec0f41SMaxim Mikityanskiy { 29043ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->ptp.tir); 29143ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->ptp.rqt); 29243ec0f41SMaxim Mikityanskiy } 29343ec0f41SMaxim Mikityanskiy 29443ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_init(struct mlx5e_rx_res *res, struct mlx5_core_dev *mdev, 29543ec0f41SMaxim Mikityanskiy enum mlx5e_rx_res_features features, unsigned int max_nch, 29643ec0f41SMaxim Mikityanskiy u32 drop_rqn, const struct mlx5e_lro_param *init_lro_param, 29743ec0f41SMaxim Mikityanskiy unsigned int init_nch) 29843ec0f41SMaxim Mikityanskiy { 29943ec0f41SMaxim Mikityanskiy int err; 30043ec0f41SMaxim Mikityanskiy 30143ec0f41SMaxim Mikityanskiy res->mdev = mdev; 30243ec0f41SMaxim Mikityanskiy res->features = features; 30343ec0f41SMaxim Mikityanskiy res->max_nch = max_nch; 30443ec0f41SMaxim Mikityanskiy res->drop_rqn = drop_rqn; 30543ec0f41SMaxim Mikityanskiy 306713ba5e5STariq Toukan err = mlx5e_rx_res_rss_init(res, init_lro_param, init_nch); 30743ec0f41SMaxim Mikityanskiy if (err) 308*25307a91STariq Toukan goto err_out; 30943ec0f41SMaxim Mikityanskiy 31043ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_channels_init(res, init_lro_param); 31143ec0f41SMaxim Mikityanskiy if (err) 31243ec0f41SMaxim Mikityanskiy goto err_rss_destroy; 31343ec0f41SMaxim Mikityanskiy 31443ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_ptp_init(res); 31543ec0f41SMaxim Mikityanskiy if (err) 31643ec0f41SMaxim Mikityanskiy goto err_channels_destroy; 31743ec0f41SMaxim Mikityanskiy 31843ec0f41SMaxim Mikityanskiy return 0; 31943ec0f41SMaxim Mikityanskiy 32043ec0f41SMaxim Mikityanskiy err_channels_destroy: 32143ec0f41SMaxim Mikityanskiy mlx5e_rx_res_channels_destroy(res); 32243ec0f41SMaxim Mikityanskiy err_rss_destroy: 32343ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_destroy(res); 324*25307a91STariq Toukan err_out: 32543ec0f41SMaxim Mikityanskiy return err; 32643ec0f41SMaxim Mikityanskiy } 32743ec0f41SMaxim Mikityanskiy 32843ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_destroy(struct mlx5e_rx_res *res) 32943ec0f41SMaxim Mikityanskiy { 33043ec0f41SMaxim Mikityanskiy mlx5e_rx_res_ptp_destroy(res); 33143ec0f41SMaxim Mikityanskiy mlx5e_rx_res_channels_destroy(res); 33243ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_destroy(res); 33343ec0f41SMaxim Mikityanskiy } 33443ec0f41SMaxim Mikityanskiy 33543ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_free(struct mlx5e_rx_res *res) 33643ec0f41SMaxim Mikityanskiy { 33743ec0f41SMaxim Mikityanskiy kvfree(res); 33843ec0f41SMaxim Mikityanskiy } 33943ec0f41SMaxim Mikityanskiy 34043ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res *res, unsigned int ix) 34143ec0f41SMaxim Mikityanskiy { 34243ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->channels[ix].direct_tir); 34343ec0f41SMaxim Mikityanskiy } 34443ec0f41SMaxim Mikityanskiy 34543ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_xsk(struct mlx5e_rx_res *res, unsigned int ix) 34643ec0f41SMaxim Mikityanskiy { 34743ec0f41SMaxim Mikityanskiy WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_XSK)); 34843ec0f41SMaxim Mikityanskiy 34943ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->channels[ix].xsk_tir); 35043ec0f41SMaxim Mikityanskiy } 35143ec0f41SMaxim Mikityanskiy 352d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt) 35343ec0f41SMaxim Mikityanskiy { 354713ba5e5STariq Toukan struct mlx5e_rss *rss = res->rss; 355713ba5e5STariq Toukan 356*25307a91STariq Toukan return mlx5e_rss_get_tirn(rss, tt, false); 35743ec0f41SMaxim Mikityanskiy } 35843ec0f41SMaxim Mikityanskiy 359d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt) 36043ec0f41SMaxim Mikityanskiy { 361713ba5e5STariq Toukan struct mlx5e_rss *rss = res->rss; 362713ba5e5STariq Toukan 363*25307a91STariq Toukan return mlx5e_rss_get_tirn(rss, tt, true); 36443ec0f41SMaxim Mikityanskiy } 36543ec0f41SMaxim Mikityanskiy 36643ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res) 36743ec0f41SMaxim Mikityanskiy { 36843ec0f41SMaxim Mikityanskiy WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_PTP)); 36943ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->ptp.tir); 37043ec0f41SMaxim Mikityanskiy } 37143ec0f41SMaxim Mikityanskiy 37243ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix) 37343ec0f41SMaxim Mikityanskiy { 37443ec0f41SMaxim Mikityanskiy return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt); 37543ec0f41SMaxim Mikityanskiy } 37643ec0f41SMaxim Mikityanskiy 37743ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs) 37843ec0f41SMaxim Mikityanskiy { 37943ec0f41SMaxim Mikityanskiy unsigned int nch, ix; 38043ec0f41SMaxim Mikityanskiy int err; 38143ec0f41SMaxim Mikityanskiy 38243ec0f41SMaxim Mikityanskiy nch = mlx5e_channels_get_num(chs); 38343ec0f41SMaxim Mikityanskiy 38443ec0f41SMaxim Mikityanskiy for (ix = 0; ix < chs->num; ix++) 38543ec0f41SMaxim Mikityanskiy mlx5e_channels_get_regular_rqn(chs, ix, &res->rss_rqns[ix]); 38643ec0f41SMaxim Mikityanskiy res->rss_nch = chs->num; 38743ec0f41SMaxim Mikityanskiy 38843ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_enable(res); 38943ec0f41SMaxim Mikityanskiy 39043ec0f41SMaxim Mikityanskiy for (ix = 0; ix < nch; ix++) { 39143ec0f41SMaxim Mikityanskiy u32 rqn; 39243ec0f41SMaxim Mikityanskiy 39343ec0f41SMaxim Mikityanskiy mlx5e_channels_get_regular_rqn(chs, ix, &rqn); 39443ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, rqn); 39543ec0f41SMaxim Mikityanskiy if (err) 39643ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (channel %u): err = %d\n", 39743ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 39843ec0f41SMaxim Mikityanskiy rqn, ix, err); 39943ec0f41SMaxim Mikityanskiy 40043ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 40143ec0f41SMaxim Mikityanskiy continue; 40243ec0f41SMaxim Mikityanskiy 40343ec0f41SMaxim Mikityanskiy if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn)) 40443ec0f41SMaxim Mikityanskiy rqn = res->drop_rqn; 40543ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn); 40643ec0f41SMaxim Mikityanskiy if (err) 40743ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to RQ %#x (channel %u): err = %d\n", 40843ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 40943ec0f41SMaxim Mikityanskiy rqn, ix, err); 41043ec0f41SMaxim Mikityanskiy } 41143ec0f41SMaxim Mikityanskiy for (ix = nch; ix < res->max_nch; ix++) { 41243ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn); 41343ec0f41SMaxim Mikityanskiy if (err) 41443ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n", 41543ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 41643ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 41743ec0f41SMaxim Mikityanskiy 41843ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 41943ec0f41SMaxim Mikityanskiy continue; 42043ec0f41SMaxim Mikityanskiy 42143ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn); 42243ec0f41SMaxim Mikityanskiy if (err) 42343ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n", 42443ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 42543ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 42643ec0f41SMaxim Mikityanskiy } 42743ec0f41SMaxim Mikityanskiy 42843ec0f41SMaxim Mikityanskiy if (res->features & MLX5E_RX_RES_FEATURE_PTP) { 42943ec0f41SMaxim Mikityanskiy u32 rqn; 43043ec0f41SMaxim Mikityanskiy 43143ec0f41SMaxim Mikityanskiy if (mlx5e_channels_get_ptp_rqn(chs, &rqn)) 43243ec0f41SMaxim Mikityanskiy rqn = res->drop_rqn; 43343ec0f41SMaxim Mikityanskiy 43443ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, rqn); 43543ec0f41SMaxim Mikityanskiy if (err) 43643ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (PTP): err = %d\n", 43743ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->ptp.rqt), 43843ec0f41SMaxim Mikityanskiy rqn, err); 43943ec0f41SMaxim Mikityanskiy } 44043ec0f41SMaxim Mikityanskiy } 44143ec0f41SMaxim Mikityanskiy 44243ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res) 44343ec0f41SMaxim Mikityanskiy { 44443ec0f41SMaxim Mikityanskiy unsigned int ix; 44543ec0f41SMaxim Mikityanskiy int err; 44643ec0f41SMaxim Mikityanskiy 44743ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_disable(res); 44843ec0f41SMaxim Mikityanskiy 44943ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 45043ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn); 45143ec0f41SMaxim Mikityanskiy if (err) 45243ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n", 45343ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 45443ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 45543ec0f41SMaxim Mikityanskiy 45643ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 45743ec0f41SMaxim Mikityanskiy continue; 45843ec0f41SMaxim Mikityanskiy 45943ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn); 46043ec0f41SMaxim Mikityanskiy if (err) 46143ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n", 46243ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 46343ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 46443ec0f41SMaxim Mikityanskiy } 46543ec0f41SMaxim Mikityanskiy 46643ec0f41SMaxim Mikityanskiy if (res->features & MLX5E_RX_RES_FEATURE_PTP) { 46743ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, res->drop_rqn); 46843ec0f41SMaxim Mikityanskiy if (err) 46943ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (PTP): err = %d\n", 47043ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->ptp.rqt), 47143ec0f41SMaxim Mikityanskiy res->drop_rqn, err); 47243ec0f41SMaxim Mikityanskiy } 47343ec0f41SMaxim Mikityanskiy } 47443ec0f41SMaxim Mikityanskiy 47543ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs, 47643ec0f41SMaxim Mikityanskiy unsigned int ix) 47743ec0f41SMaxim Mikityanskiy { 47843ec0f41SMaxim Mikityanskiy u32 rqn; 47943ec0f41SMaxim Mikityanskiy int err; 48043ec0f41SMaxim Mikityanskiy 48143ec0f41SMaxim Mikityanskiy if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn)) 48243ec0f41SMaxim Mikityanskiy return -EINVAL; 48343ec0f41SMaxim Mikityanskiy 48443ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn); 48543ec0f41SMaxim Mikityanskiy if (err) 48643ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to XSK RQ %#x (channel %u): err = %d\n", 48743ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 48843ec0f41SMaxim Mikityanskiy rqn, ix, err); 48943ec0f41SMaxim Mikityanskiy return err; 49043ec0f41SMaxim Mikityanskiy } 49143ec0f41SMaxim Mikityanskiy 49243ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_deactivate(struct mlx5e_rx_res *res, unsigned int ix) 49343ec0f41SMaxim Mikityanskiy { 49443ec0f41SMaxim Mikityanskiy int err; 49543ec0f41SMaxim Mikityanskiy 49643ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn); 49743ec0f41SMaxim Mikityanskiy if (err) 49843ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n", 49943ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 50043ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 50143ec0f41SMaxim Mikityanskiy return err; 50243ec0f41SMaxim Mikityanskiy } 50343ec0f41SMaxim Mikityanskiy 50443ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_lro_set_param(struct mlx5e_rx_res *res, struct mlx5e_lro_param *lro_param) 50543ec0f41SMaxim Mikityanskiy { 506713ba5e5STariq Toukan struct mlx5e_rss *rss = res->rss; 50743ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 50843ec0f41SMaxim Mikityanskiy int err, final_err; 50943ec0f41SMaxim Mikityanskiy unsigned int ix; 51043ec0f41SMaxim Mikityanskiy 51143ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(true); 51243ec0f41SMaxim Mikityanskiy if (!builder) 51343ec0f41SMaxim Mikityanskiy return -ENOMEM; 51443ec0f41SMaxim Mikityanskiy 51543ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, lro_param); 51643ec0f41SMaxim Mikityanskiy 51743ec0f41SMaxim Mikityanskiy final_err = 0; 51843ec0f41SMaxim Mikityanskiy 519*25307a91STariq Toukan err = mlx5e_rss_lro_set_param(rss, lro_param); 520*25307a91STariq Toukan if (err) 521*25307a91STariq Toukan final_err = final_err ? : err; 52243ec0f41SMaxim Mikityanskiy 52343ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 52443ec0f41SMaxim Mikityanskiy err = mlx5e_tir_modify(&res->channels[ix].direct_tir, builder); 52543ec0f41SMaxim Mikityanskiy if (err) { 52643ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to update LRO state of direct TIR %#x for channel %u: err = %d\n", 52743ec0f41SMaxim Mikityanskiy mlx5e_tir_get_tirn(&res->channels[ix].direct_tir), ix, err); 52843ec0f41SMaxim Mikityanskiy if (!final_err) 52943ec0f41SMaxim Mikityanskiy final_err = err; 53043ec0f41SMaxim Mikityanskiy } 53143ec0f41SMaxim Mikityanskiy } 53243ec0f41SMaxim Mikityanskiy 53343ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 53443ec0f41SMaxim Mikityanskiy return final_err; 53543ec0f41SMaxim Mikityanskiy } 53643ec0f41SMaxim Mikityanskiy 53743ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res) 53843ec0f41SMaxim Mikityanskiy { 539*25307a91STariq Toukan return mlx5e_rss_get_hash(res->rss); 54043ec0f41SMaxim Mikityanskiy } 541