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" 5*43ec0f41SMaxim Mikityanskiy #include "channels.h" 6*43ec0f41SMaxim Mikityanskiy #include "params.h" 765d6b6e5SMaxim Mikityanskiy 865d6b6e5SMaxim Mikityanskiy static const struct mlx5e_rss_params_traffic_type rss_default_config[MLX5E_NUM_INDIR_TIRS] = { 965d6b6e5SMaxim Mikityanskiy [MLX5E_TT_IPV4_TCP] = { 1065d6b6e5SMaxim Mikityanskiy .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4, 1165d6b6e5SMaxim Mikityanskiy .l4_prot_type = MLX5_L4_PROT_TYPE_TCP, 1265d6b6e5SMaxim Mikityanskiy .rx_hash_fields = MLX5_HASH_IP_L4PORTS, 1365d6b6e5SMaxim Mikityanskiy }, 1465d6b6e5SMaxim Mikityanskiy [MLX5E_TT_IPV6_TCP] = { 1565d6b6e5SMaxim Mikityanskiy .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6, 1665d6b6e5SMaxim Mikityanskiy .l4_prot_type = MLX5_L4_PROT_TYPE_TCP, 1765d6b6e5SMaxim Mikityanskiy .rx_hash_fields = MLX5_HASH_IP_L4PORTS, 1865d6b6e5SMaxim Mikityanskiy }, 1965d6b6e5SMaxim Mikityanskiy [MLX5E_TT_IPV4_UDP] = { 2065d6b6e5SMaxim Mikityanskiy .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4, 2165d6b6e5SMaxim Mikityanskiy .l4_prot_type = MLX5_L4_PROT_TYPE_UDP, 2265d6b6e5SMaxim Mikityanskiy .rx_hash_fields = MLX5_HASH_IP_L4PORTS, 2365d6b6e5SMaxim Mikityanskiy }, 2465d6b6e5SMaxim Mikityanskiy [MLX5E_TT_IPV6_UDP] = { 2565d6b6e5SMaxim Mikityanskiy .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6, 2665d6b6e5SMaxim Mikityanskiy .l4_prot_type = MLX5_L4_PROT_TYPE_UDP, 2765d6b6e5SMaxim Mikityanskiy .rx_hash_fields = MLX5_HASH_IP_L4PORTS, 2865d6b6e5SMaxim Mikityanskiy }, 2965d6b6e5SMaxim Mikityanskiy [MLX5E_TT_IPV4_IPSEC_AH] = { 3065d6b6e5SMaxim Mikityanskiy .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4, 3165d6b6e5SMaxim Mikityanskiy .l4_prot_type = 0, 3265d6b6e5SMaxim Mikityanskiy .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI, 3365d6b6e5SMaxim Mikityanskiy }, 3465d6b6e5SMaxim Mikityanskiy [MLX5E_TT_IPV6_IPSEC_AH] = { 3565d6b6e5SMaxim Mikityanskiy .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6, 3665d6b6e5SMaxim Mikityanskiy .l4_prot_type = 0, 3765d6b6e5SMaxim Mikityanskiy .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI, 3865d6b6e5SMaxim Mikityanskiy }, 3965d6b6e5SMaxim Mikityanskiy [MLX5E_TT_IPV4_IPSEC_ESP] = { 4065d6b6e5SMaxim Mikityanskiy .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4, 4165d6b6e5SMaxim Mikityanskiy .l4_prot_type = 0, 4265d6b6e5SMaxim Mikityanskiy .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI, 4365d6b6e5SMaxim Mikityanskiy }, 4465d6b6e5SMaxim Mikityanskiy [MLX5E_TT_IPV6_IPSEC_ESP] = { 4565d6b6e5SMaxim Mikityanskiy .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6, 4665d6b6e5SMaxim Mikityanskiy .l4_prot_type = 0, 4765d6b6e5SMaxim Mikityanskiy .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI, 4865d6b6e5SMaxim Mikityanskiy }, 4965d6b6e5SMaxim Mikityanskiy [MLX5E_TT_IPV4] = { 5065d6b6e5SMaxim Mikityanskiy .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4, 5165d6b6e5SMaxim Mikityanskiy .l4_prot_type = 0, 5265d6b6e5SMaxim Mikityanskiy .rx_hash_fields = MLX5_HASH_IP, 5365d6b6e5SMaxim Mikityanskiy }, 5465d6b6e5SMaxim Mikityanskiy [MLX5E_TT_IPV6] = { 5565d6b6e5SMaxim Mikityanskiy .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6, 5665d6b6e5SMaxim Mikityanskiy .l4_prot_type = 0, 5765d6b6e5SMaxim Mikityanskiy .rx_hash_fields = MLX5_HASH_IP, 5865d6b6e5SMaxim Mikityanskiy }, 5965d6b6e5SMaxim Mikityanskiy }; 6065d6b6e5SMaxim Mikityanskiy 6165d6b6e5SMaxim Mikityanskiy struct mlx5e_rss_params_traffic_type 6265d6b6e5SMaxim Mikityanskiy mlx5e_rss_get_default_tt_config(enum mlx5e_traffic_types tt) 6365d6b6e5SMaxim Mikityanskiy { 6465d6b6e5SMaxim Mikityanskiy return rss_default_config[tt]; 6565d6b6e5SMaxim Mikityanskiy } 6665d6b6e5SMaxim Mikityanskiy 67*43ec0f41SMaxim Mikityanskiy struct mlx5e_rx_res { 68*43ec0f41SMaxim Mikityanskiy struct mlx5_core_dev *mdev; 69*43ec0f41SMaxim Mikityanskiy enum mlx5e_rx_res_features features; 70*43ec0f41SMaxim Mikityanskiy unsigned int max_nch; 71*43ec0f41SMaxim Mikityanskiy u32 drop_rqn; 72*43ec0f41SMaxim Mikityanskiy 73*43ec0f41SMaxim Mikityanskiy struct { 74*43ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_hash hash; 75*43ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_indir indir; 76*43ec0f41SMaxim Mikityanskiy u32 rx_hash_fields[MLX5E_NUM_INDIR_TIRS]; 77*43ec0f41SMaxim Mikityanskiy } rss_params; 78*43ec0f41SMaxim Mikityanskiy 79*43ec0f41SMaxim Mikityanskiy struct mlx5e_rqt indir_rqt; 80*43ec0f41SMaxim Mikityanskiy struct { 81*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir indir_tir; 82*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir inner_indir_tir; 83*43ec0f41SMaxim Mikityanskiy } rss[MLX5E_NUM_INDIR_TIRS]; 84*43ec0f41SMaxim Mikityanskiy 85*43ec0f41SMaxim Mikityanskiy bool rss_active; 86*43ec0f41SMaxim Mikityanskiy u32 rss_rqns[MLX5E_INDIR_RQT_SIZE]; 87*43ec0f41SMaxim Mikityanskiy unsigned int rss_nch; 88*43ec0f41SMaxim Mikityanskiy 89*43ec0f41SMaxim Mikityanskiy struct { 90*43ec0f41SMaxim Mikityanskiy struct mlx5e_rqt direct_rqt; 91*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir direct_tir; 92*43ec0f41SMaxim Mikityanskiy struct mlx5e_rqt xsk_rqt; 93*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir xsk_tir; 94*43ec0f41SMaxim Mikityanskiy } channels[MLX5E_MAX_NUM_CHANNELS]; 95*43ec0f41SMaxim Mikityanskiy 96*43ec0f41SMaxim Mikityanskiy struct { 97*43ec0f41SMaxim Mikityanskiy struct mlx5e_rqt rqt; 98*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir tir; 99*43ec0f41SMaxim Mikityanskiy } ptp; 100*43ec0f41SMaxim Mikityanskiy }; 101*43ec0f41SMaxim Mikityanskiy 102*43ec0f41SMaxim Mikityanskiy struct mlx5e_rx_res *mlx5e_rx_res_alloc(void) 103*43ec0f41SMaxim Mikityanskiy { 104*43ec0f41SMaxim Mikityanskiy return kvzalloc(sizeof(struct mlx5e_rx_res), GFP_KERNEL); 105*43ec0f41SMaxim Mikityanskiy } 106*43ec0f41SMaxim Mikityanskiy 107*43ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_rss_params_init(struct mlx5e_rx_res *res, unsigned int init_nch) 108*43ec0f41SMaxim Mikityanskiy { 109*43ec0f41SMaxim Mikityanskiy enum mlx5e_traffic_types tt; 110*43ec0f41SMaxim Mikityanskiy 111*43ec0f41SMaxim Mikityanskiy res->rss_params.hash.hfunc = ETH_RSS_HASH_TOP; 112*43ec0f41SMaxim Mikityanskiy netdev_rss_key_fill(res->rss_params.hash.toeplitz_hash_key, 113*43ec0f41SMaxim Mikityanskiy sizeof(res->rss_params.hash.toeplitz_hash_key)); 114*43ec0f41SMaxim Mikityanskiy mlx5e_rss_params_indir_init_uniform(&res->rss_params.indir, init_nch); 115*43ec0f41SMaxim Mikityanskiy for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) 116*43ec0f41SMaxim Mikityanskiy res->rss_params.rx_hash_fields[tt] = 117*43ec0f41SMaxim Mikityanskiy mlx5e_rss_get_default_tt_config(tt).rx_hash_fields; 118*43ec0f41SMaxim Mikityanskiy } 119*43ec0f41SMaxim Mikityanskiy 120*43ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, 121*43ec0f41SMaxim Mikityanskiy const struct mlx5e_lro_param *init_lro_param) 122*43ec0f41SMaxim Mikityanskiy { 123*43ec0f41SMaxim Mikityanskiy bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 124*43ec0f41SMaxim Mikityanskiy enum mlx5e_traffic_types tt, max_tt; 125*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 126*43ec0f41SMaxim Mikityanskiy u32 indir_rqtn; 127*43ec0f41SMaxim Mikityanskiy int err; 128*43ec0f41SMaxim Mikityanskiy 129*43ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(false); 130*43ec0f41SMaxim Mikityanskiy if (!builder) 131*43ec0f41SMaxim Mikityanskiy return -ENOMEM; 132*43ec0f41SMaxim Mikityanskiy 133*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_init_direct(&res->indir_rqt, res->mdev, true, res->drop_rqn); 134*43ec0f41SMaxim Mikityanskiy if (err) 135*43ec0f41SMaxim Mikityanskiy goto out; 136*43ec0f41SMaxim Mikityanskiy 137*43ec0f41SMaxim Mikityanskiy indir_rqtn = mlx5e_rqt_get_rqtn(&res->indir_rqt); 138*43ec0f41SMaxim Mikityanskiy 139*43ec0f41SMaxim Mikityanskiy for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { 140*43ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_traffic_type rss_tt; 141*43ec0f41SMaxim Mikityanskiy 142*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 143*43ec0f41SMaxim Mikityanskiy indir_rqtn, inner_ft_support); 144*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, init_lro_param); 145*43ec0f41SMaxim Mikityanskiy rss_tt = mlx5e_rx_res_rss_get_current_tt_config(res, tt); 146*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rss(builder, &res->rss_params.hash, &rss_tt, false); 147*43ec0f41SMaxim Mikityanskiy 148*43ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->rss[tt].indir_tir, builder, res->mdev, true); 149*43ec0f41SMaxim Mikityanskiy if (err) { 150*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create an indirect TIR: err = %d, tt = %d\n", 151*43ec0f41SMaxim Mikityanskiy err, tt); 152*43ec0f41SMaxim Mikityanskiy goto err_destroy_tirs; 153*43ec0f41SMaxim Mikityanskiy } 154*43ec0f41SMaxim Mikityanskiy 155*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_clear(builder); 156*43ec0f41SMaxim Mikityanskiy } 157*43ec0f41SMaxim Mikityanskiy 158*43ec0f41SMaxim Mikityanskiy if (!inner_ft_support) 159*43ec0f41SMaxim Mikityanskiy goto out; 160*43ec0f41SMaxim Mikityanskiy 161*43ec0f41SMaxim Mikityanskiy for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { 162*43ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_traffic_type rss_tt; 163*43ec0f41SMaxim Mikityanskiy 164*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 165*43ec0f41SMaxim Mikityanskiy indir_rqtn, inner_ft_support); 166*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, init_lro_param); 167*43ec0f41SMaxim Mikityanskiy rss_tt = mlx5e_rx_res_rss_get_current_tt_config(res, tt); 168*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rss(builder, &res->rss_params.hash, &rss_tt, true); 169*43ec0f41SMaxim Mikityanskiy 170*43ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->rss[tt].inner_indir_tir, builder, res->mdev, true); 171*43ec0f41SMaxim Mikityanskiy if (err) { 172*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create an inner indirect TIR: err = %d, tt = %d\n", 173*43ec0f41SMaxim Mikityanskiy err, tt); 174*43ec0f41SMaxim Mikityanskiy goto err_destroy_inner_tirs; 175*43ec0f41SMaxim Mikityanskiy } 176*43ec0f41SMaxim Mikityanskiy 177*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_clear(builder); 178*43ec0f41SMaxim Mikityanskiy } 179*43ec0f41SMaxim Mikityanskiy 180*43ec0f41SMaxim Mikityanskiy goto out; 181*43ec0f41SMaxim Mikityanskiy 182*43ec0f41SMaxim Mikityanskiy err_destroy_inner_tirs: 183*43ec0f41SMaxim Mikityanskiy max_tt = tt; 184*43ec0f41SMaxim Mikityanskiy for (tt = 0; tt < max_tt; tt++) 185*43ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->rss[tt].inner_indir_tir); 186*43ec0f41SMaxim Mikityanskiy 187*43ec0f41SMaxim Mikityanskiy tt = MLX5E_NUM_INDIR_TIRS; 188*43ec0f41SMaxim Mikityanskiy err_destroy_tirs: 189*43ec0f41SMaxim Mikityanskiy max_tt = tt; 190*43ec0f41SMaxim Mikityanskiy for (tt = 0; tt < max_tt; tt++) 191*43ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->rss[tt].indir_tir); 192*43ec0f41SMaxim Mikityanskiy 193*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->indir_rqt); 194*43ec0f41SMaxim Mikityanskiy 195*43ec0f41SMaxim Mikityanskiy out: 196*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 197*43ec0f41SMaxim Mikityanskiy 198*43ec0f41SMaxim Mikityanskiy return err; 199*43ec0f41SMaxim Mikityanskiy } 200*43ec0f41SMaxim Mikityanskiy 201*43ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_channels_init(struct mlx5e_rx_res *res, 202*43ec0f41SMaxim Mikityanskiy const struct mlx5e_lro_param *init_lro_param) 203*43ec0f41SMaxim Mikityanskiy { 204*43ec0f41SMaxim Mikityanskiy bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 205*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 206*43ec0f41SMaxim Mikityanskiy int err = 0; 207*43ec0f41SMaxim Mikityanskiy int ix; 208*43ec0f41SMaxim Mikityanskiy 209*43ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(false); 210*43ec0f41SMaxim Mikityanskiy if (!builder) 211*43ec0f41SMaxim Mikityanskiy return -ENOMEM; 212*43ec0f41SMaxim Mikityanskiy 213*43ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 214*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_init_direct(&res->channels[ix].direct_rqt, 215*43ec0f41SMaxim Mikityanskiy res->mdev, false, res->drop_rqn); 216*43ec0f41SMaxim Mikityanskiy if (err) { 217*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create a direct RQT: err = %d, ix = %u\n", 218*43ec0f41SMaxim Mikityanskiy err, ix); 219*43ec0f41SMaxim Mikityanskiy goto err_destroy_direct_rqts; 220*43ec0f41SMaxim Mikityanskiy } 221*43ec0f41SMaxim Mikityanskiy } 222*43ec0f41SMaxim Mikityanskiy 223*43ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 224*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 225*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 226*43ec0f41SMaxim Mikityanskiy inner_ft_support); 227*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, init_lro_param); 228*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_direct(builder); 229*43ec0f41SMaxim Mikityanskiy 230*43ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->channels[ix].direct_tir, builder, res->mdev, true); 231*43ec0f41SMaxim Mikityanskiy if (err) { 232*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create a direct TIR: err = %d, ix = %u\n", 233*43ec0f41SMaxim Mikityanskiy err, ix); 234*43ec0f41SMaxim Mikityanskiy goto err_destroy_direct_tirs; 235*43ec0f41SMaxim Mikityanskiy } 236*43ec0f41SMaxim Mikityanskiy 237*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_clear(builder); 238*43ec0f41SMaxim Mikityanskiy } 239*43ec0f41SMaxim Mikityanskiy 240*43ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 241*43ec0f41SMaxim Mikityanskiy goto out; 242*43ec0f41SMaxim Mikityanskiy 243*43ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 244*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_init_direct(&res->channels[ix].xsk_rqt, 245*43ec0f41SMaxim Mikityanskiy res->mdev, false, res->drop_rqn); 246*43ec0f41SMaxim Mikityanskiy if (err) { 247*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create an XSK RQT: err = %d, ix = %u\n", 248*43ec0f41SMaxim Mikityanskiy err, ix); 249*43ec0f41SMaxim Mikityanskiy goto err_destroy_xsk_rqts; 250*43ec0f41SMaxim Mikityanskiy } 251*43ec0f41SMaxim Mikityanskiy } 252*43ec0f41SMaxim Mikityanskiy 253*43ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 254*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 255*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 256*43ec0f41SMaxim Mikityanskiy inner_ft_support); 257*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, init_lro_param); 258*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_direct(builder); 259*43ec0f41SMaxim Mikityanskiy 260*43ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->channels[ix].xsk_tir, builder, res->mdev, true); 261*43ec0f41SMaxim Mikityanskiy if (err) { 262*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to create an XSK TIR: err = %d, ix = %u\n", 263*43ec0f41SMaxim Mikityanskiy err, ix); 264*43ec0f41SMaxim Mikityanskiy goto err_destroy_xsk_tirs; 265*43ec0f41SMaxim Mikityanskiy } 266*43ec0f41SMaxim Mikityanskiy 267*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_clear(builder); 268*43ec0f41SMaxim Mikityanskiy } 269*43ec0f41SMaxim Mikityanskiy 270*43ec0f41SMaxim Mikityanskiy goto out; 271*43ec0f41SMaxim Mikityanskiy 272*43ec0f41SMaxim Mikityanskiy err_destroy_xsk_tirs: 273*43ec0f41SMaxim Mikityanskiy while (--ix >= 0) 274*43ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].xsk_tir); 275*43ec0f41SMaxim Mikityanskiy 276*43ec0f41SMaxim Mikityanskiy ix = res->max_nch; 277*43ec0f41SMaxim Mikityanskiy err_destroy_xsk_rqts: 278*43ec0f41SMaxim Mikityanskiy while (--ix >= 0) 279*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt); 280*43ec0f41SMaxim Mikityanskiy 281*43ec0f41SMaxim Mikityanskiy ix = res->max_nch; 282*43ec0f41SMaxim Mikityanskiy err_destroy_direct_tirs: 283*43ec0f41SMaxim Mikityanskiy while (--ix >= 0) 284*43ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].direct_tir); 285*43ec0f41SMaxim Mikityanskiy 286*43ec0f41SMaxim Mikityanskiy ix = res->max_nch; 287*43ec0f41SMaxim Mikityanskiy err_destroy_direct_rqts: 288*43ec0f41SMaxim Mikityanskiy while (--ix >= 0) 289*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].direct_rqt); 290*43ec0f41SMaxim Mikityanskiy 291*43ec0f41SMaxim Mikityanskiy out: 292*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 293*43ec0f41SMaxim Mikityanskiy 294*43ec0f41SMaxim Mikityanskiy return err; 295*43ec0f41SMaxim Mikityanskiy } 296*43ec0f41SMaxim Mikityanskiy 297*43ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_ptp_init(struct mlx5e_rx_res *res) 298*43ec0f41SMaxim Mikityanskiy { 299*43ec0f41SMaxim Mikityanskiy bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 300*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 301*43ec0f41SMaxim Mikityanskiy int err; 302*43ec0f41SMaxim Mikityanskiy 303*43ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(false); 304*43ec0f41SMaxim Mikityanskiy if (!builder) 305*43ec0f41SMaxim Mikityanskiy return -ENOMEM; 306*43ec0f41SMaxim Mikityanskiy 307*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_init_direct(&res->ptp.rqt, res->mdev, false, res->drop_rqn); 308*43ec0f41SMaxim Mikityanskiy if (err) 309*43ec0f41SMaxim Mikityanskiy goto out; 310*43ec0f41SMaxim Mikityanskiy 311*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, 312*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->ptp.rqt), 313*43ec0f41SMaxim Mikityanskiy inner_ft_support); 314*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_direct(builder); 315*43ec0f41SMaxim Mikityanskiy 316*43ec0f41SMaxim Mikityanskiy err = mlx5e_tir_init(&res->ptp.tir, builder, res->mdev, true); 317*43ec0f41SMaxim Mikityanskiy if (err) 318*43ec0f41SMaxim Mikityanskiy goto err_destroy_ptp_rqt; 319*43ec0f41SMaxim Mikityanskiy 320*43ec0f41SMaxim Mikityanskiy goto out; 321*43ec0f41SMaxim Mikityanskiy 322*43ec0f41SMaxim Mikityanskiy err_destroy_ptp_rqt: 323*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->ptp.rqt); 324*43ec0f41SMaxim Mikityanskiy 325*43ec0f41SMaxim Mikityanskiy out: 326*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 327*43ec0f41SMaxim Mikityanskiy return err; 328*43ec0f41SMaxim Mikityanskiy } 329*43ec0f41SMaxim Mikityanskiy 330*43ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res) 331*43ec0f41SMaxim Mikityanskiy { 332*43ec0f41SMaxim Mikityanskiy enum mlx5e_traffic_types tt; 333*43ec0f41SMaxim Mikityanskiy 334*43ec0f41SMaxim Mikityanskiy for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) 335*43ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->rss[tt].indir_tir); 336*43ec0f41SMaxim Mikityanskiy 337*43ec0f41SMaxim Mikityanskiy if (res->features & MLX5E_RX_RES_FEATURE_INNER_FT) 338*43ec0f41SMaxim Mikityanskiy for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) 339*43ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->rss[tt].inner_indir_tir); 340*43ec0f41SMaxim Mikityanskiy 341*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->indir_rqt); 342*43ec0f41SMaxim Mikityanskiy } 343*43ec0f41SMaxim Mikityanskiy 344*43ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res *res) 345*43ec0f41SMaxim Mikityanskiy { 346*43ec0f41SMaxim Mikityanskiy unsigned int ix; 347*43ec0f41SMaxim Mikityanskiy 348*43ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 349*43ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].direct_tir); 350*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].direct_rqt); 351*43ec0f41SMaxim Mikityanskiy 352*43ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 353*43ec0f41SMaxim Mikityanskiy continue; 354*43ec0f41SMaxim Mikityanskiy 355*43ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->channels[ix].xsk_tir); 356*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt); 357*43ec0f41SMaxim Mikityanskiy } 358*43ec0f41SMaxim Mikityanskiy } 359*43ec0f41SMaxim Mikityanskiy 360*43ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res *res) 361*43ec0f41SMaxim Mikityanskiy { 362*43ec0f41SMaxim Mikityanskiy mlx5e_tir_destroy(&res->ptp.tir); 363*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_destroy(&res->ptp.rqt); 364*43ec0f41SMaxim Mikityanskiy } 365*43ec0f41SMaxim Mikityanskiy 366*43ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_init(struct mlx5e_rx_res *res, struct mlx5_core_dev *mdev, 367*43ec0f41SMaxim Mikityanskiy enum mlx5e_rx_res_features features, unsigned int max_nch, 368*43ec0f41SMaxim Mikityanskiy u32 drop_rqn, const struct mlx5e_lro_param *init_lro_param, 369*43ec0f41SMaxim Mikityanskiy unsigned int init_nch) 370*43ec0f41SMaxim Mikityanskiy { 371*43ec0f41SMaxim Mikityanskiy int err; 372*43ec0f41SMaxim Mikityanskiy 373*43ec0f41SMaxim Mikityanskiy res->mdev = mdev; 374*43ec0f41SMaxim Mikityanskiy res->features = features; 375*43ec0f41SMaxim Mikityanskiy res->max_nch = max_nch; 376*43ec0f41SMaxim Mikityanskiy res->drop_rqn = drop_rqn; 377*43ec0f41SMaxim Mikityanskiy 378*43ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_params_init(res, init_nch); 379*43ec0f41SMaxim Mikityanskiy 380*43ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_rss_init(res, init_lro_param); 381*43ec0f41SMaxim Mikityanskiy if (err) 382*43ec0f41SMaxim Mikityanskiy return err; 383*43ec0f41SMaxim Mikityanskiy 384*43ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_channels_init(res, init_lro_param); 385*43ec0f41SMaxim Mikityanskiy if (err) 386*43ec0f41SMaxim Mikityanskiy goto err_rss_destroy; 387*43ec0f41SMaxim Mikityanskiy 388*43ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_ptp_init(res); 389*43ec0f41SMaxim Mikityanskiy if (err) 390*43ec0f41SMaxim Mikityanskiy goto err_channels_destroy; 391*43ec0f41SMaxim Mikityanskiy 392*43ec0f41SMaxim Mikityanskiy return 0; 393*43ec0f41SMaxim Mikityanskiy 394*43ec0f41SMaxim Mikityanskiy err_channels_destroy: 395*43ec0f41SMaxim Mikityanskiy mlx5e_rx_res_channels_destroy(res); 396*43ec0f41SMaxim Mikityanskiy err_rss_destroy: 397*43ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_destroy(res); 398*43ec0f41SMaxim Mikityanskiy return err; 399*43ec0f41SMaxim Mikityanskiy } 400*43ec0f41SMaxim Mikityanskiy 401*43ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_destroy(struct mlx5e_rx_res *res) 402*43ec0f41SMaxim Mikityanskiy { 403*43ec0f41SMaxim Mikityanskiy mlx5e_rx_res_ptp_destroy(res); 404*43ec0f41SMaxim Mikityanskiy mlx5e_rx_res_channels_destroy(res); 405*43ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_destroy(res); 406*43ec0f41SMaxim Mikityanskiy } 407*43ec0f41SMaxim Mikityanskiy 408*43ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_free(struct mlx5e_rx_res *res) 409*43ec0f41SMaxim Mikityanskiy { 410*43ec0f41SMaxim Mikityanskiy kvfree(res); 411*43ec0f41SMaxim Mikityanskiy } 412*43ec0f41SMaxim Mikityanskiy 413*43ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res *res, unsigned int ix) 414*43ec0f41SMaxim Mikityanskiy { 415*43ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->channels[ix].direct_tir); 416*43ec0f41SMaxim Mikityanskiy } 417*43ec0f41SMaxim Mikityanskiy 418*43ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_xsk(struct mlx5e_rx_res *res, unsigned int ix) 419*43ec0f41SMaxim Mikityanskiy { 420*43ec0f41SMaxim Mikityanskiy WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_XSK)); 421*43ec0f41SMaxim Mikityanskiy 422*43ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->channels[ix].xsk_tir); 423*43ec0f41SMaxim Mikityanskiy } 424*43ec0f41SMaxim Mikityanskiy 425*43ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res *res, enum mlx5e_traffic_types tt) 426*43ec0f41SMaxim Mikityanskiy { 427*43ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->rss[tt].indir_tir); 428*43ec0f41SMaxim Mikityanskiy } 429*43ec0f41SMaxim Mikityanskiy 430*43ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5e_traffic_types tt) 431*43ec0f41SMaxim Mikityanskiy { 432*43ec0f41SMaxim Mikityanskiy WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_INNER_FT)); 433*43ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->rss[tt].inner_indir_tir); 434*43ec0f41SMaxim Mikityanskiy } 435*43ec0f41SMaxim Mikityanskiy 436*43ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res) 437*43ec0f41SMaxim Mikityanskiy { 438*43ec0f41SMaxim Mikityanskiy WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_PTP)); 439*43ec0f41SMaxim Mikityanskiy return mlx5e_tir_get_tirn(&res->ptp.tir); 440*43ec0f41SMaxim Mikityanskiy } 441*43ec0f41SMaxim Mikityanskiy 442*43ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix) 443*43ec0f41SMaxim Mikityanskiy { 444*43ec0f41SMaxim Mikityanskiy return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt); 445*43ec0f41SMaxim Mikityanskiy } 446*43ec0f41SMaxim Mikityanskiy 447*43ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_rss_enable(struct mlx5e_rx_res *res) 448*43ec0f41SMaxim Mikityanskiy { 449*43ec0f41SMaxim Mikityanskiy int err; 450*43ec0f41SMaxim Mikityanskiy 451*43ec0f41SMaxim Mikityanskiy res->rss_active = true; 452*43ec0f41SMaxim Mikityanskiy 453*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_indir(&res->indir_rqt, res->rss_rqns, res->rss_nch, 454*43ec0f41SMaxim Mikityanskiy res->rss_params.hash.hfunc, 455*43ec0f41SMaxim Mikityanskiy &res->rss_params.indir); 456*43ec0f41SMaxim Mikityanskiy if (err) 457*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect indirect RQT %#x to channels: err = %d\n", 458*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->indir_rqt), err); 459*43ec0f41SMaxim Mikityanskiy } 460*43ec0f41SMaxim Mikityanskiy 461*43ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_rss_disable(struct mlx5e_rx_res *res) 462*43ec0f41SMaxim Mikityanskiy { 463*43ec0f41SMaxim Mikityanskiy int err; 464*43ec0f41SMaxim Mikityanskiy 465*43ec0f41SMaxim Mikityanskiy res->rss_active = false; 466*43ec0f41SMaxim Mikityanskiy 467*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->indir_rqt, res->drop_rqn); 468*43ec0f41SMaxim Mikityanskiy if (err) 469*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect indirect RQT %#x to drop RQ %#x: err = %d\n", 470*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->indir_rqt), res->drop_rqn, err); 471*43ec0f41SMaxim Mikityanskiy } 472*43ec0f41SMaxim Mikityanskiy 473*43ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs) 474*43ec0f41SMaxim Mikityanskiy { 475*43ec0f41SMaxim Mikityanskiy unsigned int nch, ix; 476*43ec0f41SMaxim Mikityanskiy int err; 477*43ec0f41SMaxim Mikityanskiy 478*43ec0f41SMaxim Mikityanskiy nch = mlx5e_channels_get_num(chs); 479*43ec0f41SMaxim Mikityanskiy 480*43ec0f41SMaxim Mikityanskiy for (ix = 0; ix < chs->num; ix++) 481*43ec0f41SMaxim Mikityanskiy mlx5e_channels_get_regular_rqn(chs, ix, &res->rss_rqns[ix]); 482*43ec0f41SMaxim Mikityanskiy res->rss_nch = chs->num; 483*43ec0f41SMaxim Mikityanskiy 484*43ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_enable(res); 485*43ec0f41SMaxim Mikityanskiy 486*43ec0f41SMaxim Mikityanskiy for (ix = 0; ix < nch; ix++) { 487*43ec0f41SMaxim Mikityanskiy u32 rqn; 488*43ec0f41SMaxim Mikityanskiy 489*43ec0f41SMaxim Mikityanskiy mlx5e_channels_get_regular_rqn(chs, ix, &rqn); 490*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, rqn); 491*43ec0f41SMaxim Mikityanskiy if (err) 492*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (channel %u): err = %d\n", 493*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 494*43ec0f41SMaxim Mikityanskiy rqn, ix, err); 495*43ec0f41SMaxim Mikityanskiy 496*43ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 497*43ec0f41SMaxim Mikityanskiy continue; 498*43ec0f41SMaxim Mikityanskiy 499*43ec0f41SMaxim Mikityanskiy if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn)) 500*43ec0f41SMaxim Mikityanskiy rqn = res->drop_rqn; 501*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn); 502*43ec0f41SMaxim Mikityanskiy if (err) 503*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to RQ %#x (channel %u): err = %d\n", 504*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 505*43ec0f41SMaxim Mikityanskiy rqn, ix, err); 506*43ec0f41SMaxim Mikityanskiy } 507*43ec0f41SMaxim Mikityanskiy for (ix = nch; ix < res->max_nch; ix++) { 508*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn); 509*43ec0f41SMaxim Mikityanskiy if (err) 510*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n", 511*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 512*43ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 513*43ec0f41SMaxim Mikityanskiy 514*43ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 515*43ec0f41SMaxim Mikityanskiy continue; 516*43ec0f41SMaxim Mikityanskiy 517*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn); 518*43ec0f41SMaxim Mikityanskiy if (err) 519*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n", 520*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 521*43ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 522*43ec0f41SMaxim Mikityanskiy } 523*43ec0f41SMaxim Mikityanskiy 524*43ec0f41SMaxim Mikityanskiy if (res->features & MLX5E_RX_RES_FEATURE_PTP) { 525*43ec0f41SMaxim Mikityanskiy u32 rqn; 526*43ec0f41SMaxim Mikityanskiy 527*43ec0f41SMaxim Mikityanskiy if (mlx5e_channels_get_ptp_rqn(chs, &rqn)) 528*43ec0f41SMaxim Mikityanskiy rqn = res->drop_rqn; 529*43ec0f41SMaxim Mikityanskiy 530*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, rqn); 531*43ec0f41SMaxim Mikityanskiy if (err) 532*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (PTP): err = %d\n", 533*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->ptp.rqt), 534*43ec0f41SMaxim Mikityanskiy rqn, err); 535*43ec0f41SMaxim Mikityanskiy } 536*43ec0f41SMaxim Mikityanskiy } 537*43ec0f41SMaxim Mikityanskiy 538*43ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res) 539*43ec0f41SMaxim Mikityanskiy { 540*43ec0f41SMaxim Mikityanskiy unsigned int ix; 541*43ec0f41SMaxim Mikityanskiy int err; 542*43ec0f41SMaxim Mikityanskiy 543*43ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_disable(res); 544*43ec0f41SMaxim Mikityanskiy 545*43ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 546*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn); 547*43ec0f41SMaxim Mikityanskiy if (err) 548*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n", 549*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt), 550*43ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 551*43ec0f41SMaxim Mikityanskiy 552*43ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_XSK)) 553*43ec0f41SMaxim Mikityanskiy continue; 554*43ec0f41SMaxim Mikityanskiy 555*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn); 556*43ec0f41SMaxim Mikityanskiy if (err) 557*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n", 558*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 559*43ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 560*43ec0f41SMaxim Mikityanskiy } 561*43ec0f41SMaxim Mikityanskiy 562*43ec0f41SMaxim Mikityanskiy if (res->features & MLX5E_RX_RES_FEATURE_PTP) { 563*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, res->drop_rqn); 564*43ec0f41SMaxim Mikityanskiy if (err) 565*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (PTP): err = %d\n", 566*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->ptp.rqt), 567*43ec0f41SMaxim Mikityanskiy res->drop_rqn, err); 568*43ec0f41SMaxim Mikityanskiy } 569*43ec0f41SMaxim Mikityanskiy } 570*43ec0f41SMaxim Mikityanskiy 571*43ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs, 572*43ec0f41SMaxim Mikityanskiy unsigned int ix) 573*43ec0f41SMaxim Mikityanskiy { 574*43ec0f41SMaxim Mikityanskiy u32 rqn; 575*43ec0f41SMaxim Mikityanskiy int err; 576*43ec0f41SMaxim Mikityanskiy 577*43ec0f41SMaxim Mikityanskiy if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn)) 578*43ec0f41SMaxim Mikityanskiy return -EINVAL; 579*43ec0f41SMaxim Mikityanskiy 580*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn); 581*43ec0f41SMaxim Mikityanskiy if (err) 582*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to XSK RQ %#x (channel %u): err = %d\n", 583*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 584*43ec0f41SMaxim Mikityanskiy rqn, ix, err); 585*43ec0f41SMaxim Mikityanskiy return err; 586*43ec0f41SMaxim Mikityanskiy } 587*43ec0f41SMaxim Mikityanskiy 588*43ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_deactivate(struct mlx5e_rx_res *res, unsigned int ix) 589*43ec0f41SMaxim Mikityanskiy { 590*43ec0f41SMaxim Mikityanskiy int err; 591*43ec0f41SMaxim Mikityanskiy 592*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn); 593*43ec0f41SMaxim Mikityanskiy if (err) 594*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n", 595*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt), 596*43ec0f41SMaxim Mikityanskiy res->drop_rqn, ix, err); 597*43ec0f41SMaxim Mikityanskiy return err; 598*43ec0f41SMaxim Mikityanskiy } 599*43ec0f41SMaxim Mikityanskiy 60065d6b6e5SMaxim Mikityanskiy struct mlx5e_rss_params_traffic_type 60165d6b6e5SMaxim Mikityanskiy mlx5e_rx_res_rss_get_current_tt_config(struct mlx5e_rx_res *res, enum mlx5e_traffic_types tt) 60265d6b6e5SMaxim Mikityanskiy { 60365d6b6e5SMaxim Mikityanskiy struct mlx5e_rss_params_traffic_type rss_tt; 60465d6b6e5SMaxim Mikityanskiy 60565d6b6e5SMaxim Mikityanskiy rss_tt = mlx5e_rss_get_default_tt_config(tt); 60665d6b6e5SMaxim Mikityanskiy rss_tt.rx_hash_fields = res->rss_params.rx_hash_fields[tt]; 60765d6b6e5SMaxim Mikityanskiy return rss_tt; 60865d6b6e5SMaxim Mikityanskiy } 609*43ec0f41SMaxim Mikityanskiy 610*43ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch) 611*43ec0f41SMaxim Mikityanskiy { 612*43ec0f41SMaxim Mikityanskiy mlx5e_rss_params_indir_init_uniform(&res->rss_params.indir, nch); 613*43ec0f41SMaxim Mikityanskiy 614*43ec0f41SMaxim Mikityanskiy if (!res->rss_active) 615*43ec0f41SMaxim Mikityanskiy return; 616*43ec0f41SMaxim Mikityanskiy 617*43ec0f41SMaxim Mikityanskiy mlx5e_rx_res_rss_enable(res); 618*43ec0f41SMaxim Mikityanskiy } 619*43ec0f41SMaxim Mikityanskiy 620*43ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 *indir, u8 *key, u8 *hfunc) 621*43ec0f41SMaxim Mikityanskiy { 622*43ec0f41SMaxim Mikityanskiy unsigned int i; 623*43ec0f41SMaxim Mikityanskiy 624*43ec0f41SMaxim Mikityanskiy if (indir) 625*43ec0f41SMaxim Mikityanskiy for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++) 626*43ec0f41SMaxim Mikityanskiy indir[i] = res->rss_params.indir.table[i]; 627*43ec0f41SMaxim Mikityanskiy 628*43ec0f41SMaxim Mikityanskiy if (key) 629*43ec0f41SMaxim Mikityanskiy memcpy(key, res->rss_params.hash.toeplitz_hash_key, 630*43ec0f41SMaxim Mikityanskiy sizeof(res->rss_params.hash.toeplitz_hash_key)); 631*43ec0f41SMaxim Mikityanskiy 632*43ec0f41SMaxim Mikityanskiy if (hfunc) 633*43ec0f41SMaxim Mikityanskiy *hfunc = res->rss_params.hash.hfunc; 634*43ec0f41SMaxim Mikityanskiy } 635*43ec0f41SMaxim Mikityanskiy 636*43ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_rss_update_tir(struct mlx5e_rx_res *res, enum mlx5e_traffic_types tt, 637*43ec0f41SMaxim Mikityanskiy bool inner) 638*43ec0f41SMaxim Mikityanskiy { 639*43ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_traffic_type rss_tt; 640*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 641*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir *tir; 642*43ec0f41SMaxim Mikityanskiy int err; 643*43ec0f41SMaxim Mikityanskiy 644*43ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(true); 645*43ec0f41SMaxim Mikityanskiy if (!builder) 646*43ec0f41SMaxim Mikityanskiy return -ENOMEM; 647*43ec0f41SMaxim Mikityanskiy 648*43ec0f41SMaxim Mikityanskiy rss_tt = mlx5e_rx_res_rss_get_current_tt_config(res, tt); 649*43ec0f41SMaxim Mikityanskiy 650*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_rss(builder, &res->rss_params.hash, &rss_tt, inner); 651*43ec0f41SMaxim Mikityanskiy tir = inner ? &res->rss[tt].inner_indir_tir : &res->rss[tt].indir_tir; 652*43ec0f41SMaxim Mikityanskiy err = mlx5e_tir_modify(tir, builder); 653*43ec0f41SMaxim Mikityanskiy 654*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 655*43ec0f41SMaxim Mikityanskiy return err; 656*43ec0f41SMaxim Mikityanskiy } 657*43ec0f41SMaxim Mikityanskiy 658*43ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, const u32 *indir, 659*43ec0f41SMaxim Mikityanskiy const u8 *key, const u8 *hfunc) 660*43ec0f41SMaxim Mikityanskiy { 661*43ec0f41SMaxim Mikityanskiy enum mlx5e_traffic_types tt; 662*43ec0f41SMaxim Mikityanskiy bool changed_indir = false; 663*43ec0f41SMaxim Mikityanskiy bool changed_hash = false; 664*43ec0f41SMaxim Mikityanskiy int err; 665*43ec0f41SMaxim Mikityanskiy 666*43ec0f41SMaxim Mikityanskiy if (hfunc && *hfunc != res->rss_params.hash.hfunc) { 667*43ec0f41SMaxim Mikityanskiy switch (*hfunc) { 668*43ec0f41SMaxim Mikityanskiy case ETH_RSS_HASH_XOR: 669*43ec0f41SMaxim Mikityanskiy case ETH_RSS_HASH_TOP: 670*43ec0f41SMaxim Mikityanskiy break; 671*43ec0f41SMaxim Mikityanskiy default: 672*43ec0f41SMaxim Mikityanskiy return -EINVAL; 673*43ec0f41SMaxim Mikityanskiy } 674*43ec0f41SMaxim Mikityanskiy changed_hash = true; 675*43ec0f41SMaxim Mikityanskiy changed_indir = true; 676*43ec0f41SMaxim Mikityanskiy res->rss_params.hash.hfunc = *hfunc; 677*43ec0f41SMaxim Mikityanskiy } 678*43ec0f41SMaxim Mikityanskiy 679*43ec0f41SMaxim Mikityanskiy if (key) { 680*43ec0f41SMaxim Mikityanskiy if (res->rss_params.hash.hfunc == ETH_RSS_HASH_TOP) 681*43ec0f41SMaxim Mikityanskiy changed_hash = true; 682*43ec0f41SMaxim Mikityanskiy memcpy(res->rss_params.hash.toeplitz_hash_key, key, 683*43ec0f41SMaxim Mikityanskiy sizeof(res->rss_params.hash.toeplitz_hash_key)); 684*43ec0f41SMaxim Mikityanskiy } 685*43ec0f41SMaxim Mikityanskiy 686*43ec0f41SMaxim Mikityanskiy if (indir) { 687*43ec0f41SMaxim Mikityanskiy unsigned int i; 688*43ec0f41SMaxim Mikityanskiy 689*43ec0f41SMaxim Mikityanskiy changed_indir = true; 690*43ec0f41SMaxim Mikityanskiy 691*43ec0f41SMaxim Mikityanskiy for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++) 692*43ec0f41SMaxim Mikityanskiy res->rss_params.indir.table[i] = indir[i]; 693*43ec0f41SMaxim Mikityanskiy } 694*43ec0f41SMaxim Mikityanskiy 695*43ec0f41SMaxim Mikityanskiy if (changed_indir && res->rss_active) { 696*43ec0f41SMaxim Mikityanskiy err = mlx5e_rqt_redirect_indir(&res->indir_rqt, res->rss_rqns, res->rss_nch, 697*43ec0f41SMaxim Mikityanskiy res->rss_params.hash.hfunc, 698*43ec0f41SMaxim Mikityanskiy &res->rss_params.indir); 699*43ec0f41SMaxim Mikityanskiy if (err) 700*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to redirect indirect RQT %#x to channels: err = %d\n", 701*43ec0f41SMaxim Mikityanskiy mlx5e_rqt_get_rqtn(&res->indir_rqt), err); 702*43ec0f41SMaxim Mikityanskiy } 703*43ec0f41SMaxim Mikityanskiy 704*43ec0f41SMaxim Mikityanskiy if (changed_hash) 705*43ec0f41SMaxim Mikityanskiy for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { 706*43ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_rss_update_tir(res, tt, false); 707*43ec0f41SMaxim Mikityanskiy if (err) 708*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to update RSS hash of indirect TIR for traffic type %d: err = %d\n", 709*43ec0f41SMaxim Mikityanskiy tt, err); 710*43ec0f41SMaxim Mikityanskiy 711*43ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_INNER_FT)) 712*43ec0f41SMaxim Mikityanskiy continue; 713*43ec0f41SMaxim Mikityanskiy 714*43ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_rss_update_tir(res, tt, true); 715*43ec0f41SMaxim Mikityanskiy if (err) 716*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to update RSS hash of inner indirect TIR for traffic type %d: err = %d\n", 717*43ec0f41SMaxim Mikityanskiy tt, err); 718*43ec0f41SMaxim Mikityanskiy } 719*43ec0f41SMaxim Mikityanskiy 720*43ec0f41SMaxim Mikityanskiy return 0; 721*43ec0f41SMaxim Mikityanskiy } 722*43ec0f41SMaxim Mikityanskiy 723*43ec0f41SMaxim Mikityanskiy u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5e_traffic_types tt) 724*43ec0f41SMaxim Mikityanskiy { 725*43ec0f41SMaxim Mikityanskiy return res->rss_params.rx_hash_fields[tt]; 726*43ec0f41SMaxim Mikityanskiy } 727*43ec0f41SMaxim Mikityanskiy 728*43ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5e_traffic_types tt, 729*43ec0f41SMaxim Mikityanskiy u8 rx_hash_fields) 730*43ec0f41SMaxim Mikityanskiy { 731*43ec0f41SMaxim Mikityanskiy u8 old_rx_hash_fields; 732*43ec0f41SMaxim Mikityanskiy int err; 733*43ec0f41SMaxim Mikityanskiy 734*43ec0f41SMaxim Mikityanskiy old_rx_hash_fields = res->rss_params.rx_hash_fields[tt]; 735*43ec0f41SMaxim Mikityanskiy 736*43ec0f41SMaxim Mikityanskiy if (old_rx_hash_fields == rx_hash_fields) 737*43ec0f41SMaxim Mikityanskiy return 0; 738*43ec0f41SMaxim Mikityanskiy 739*43ec0f41SMaxim Mikityanskiy res->rss_params.rx_hash_fields[tt] = rx_hash_fields; 740*43ec0f41SMaxim Mikityanskiy 741*43ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_rss_update_tir(res, tt, false); 742*43ec0f41SMaxim Mikityanskiy if (err) { 743*43ec0f41SMaxim Mikityanskiy res->rss_params.rx_hash_fields[tt] = old_rx_hash_fields; 744*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to update RSS hash fields of indirect TIR for traffic type %d: err = %d\n", 745*43ec0f41SMaxim Mikityanskiy tt, err); 746*43ec0f41SMaxim Mikityanskiy return err; 747*43ec0f41SMaxim Mikityanskiy } 748*43ec0f41SMaxim Mikityanskiy 749*43ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_INNER_FT)) 750*43ec0f41SMaxim Mikityanskiy return 0; 751*43ec0f41SMaxim Mikityanskiy 752*43ec0f41SMaxim Mikityanskiy err = mlx5e_rx_res_rss_update_tir(res, tt, true); 753*43ec0f41SMaxim Mikityanskiy if (err) { 754*43ec0f41SMaxim Mikityanskiy /* Partial update happened. Try to revert - it may fail too, but 755*43ec0f41SMaxim Mikityanskiy * there is nothing more we can do. 756*43ec0f41SMaxim Mikityanskiy */ 757*43ec0f41SMaxim Mikityanskiy res->rss_params.rx_hash_fields[tt] = old_rx_hash_fields; 758*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to update RSS hash fields of inner indirect TIR for traffic type %d: err = %d\n", 759*43ec0f41SMaxim Mikityanskiy tt, err); 760*43ec0f41SMaxim Mikityanskiy if (mlx5e_rx_res_rss_update_tir(res, tt, false)) 761*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Partial update of RSS hash fields happened: failed to revert indirect TIR for traffic type %d to the old values\n", 762*43ec0f41SMaxim Mikityanskiy tt); 763*43ec0f41SMaxim Mikityanskiy } 764*43ec0f41SMaxim Mikityanskiy 765*43ec0f41SMaxim Mikityanskiy return err; 766*43ec0f41SMaxim Mikityanskiy } 767*43ec0f41SMaxim Mikityanskiy 768*43ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_lro_set_param(struct mlx5e_rx_res *res, struct mlx5e_lro_param *lro_param) 769*43ec0f41SMaxim Mikityanskiy { 770*43ec0f41SMaxim Mikityanskiy struct mlx5e_tir_builder *builder; 771*43ec0f41SMaxim Mikityanskiy enum mlx5e_traffic_types tt; 772*43ec0f41SMaxim Mikityanskiy int err, final_err; 773*43ec0f41SMaxim Mikityanskiy unsigned int ix; 774*43ec0f41SMaxim Mikityanskiy 775*43ec0f41SMaxim Mikityanskiy builder = mlx5e_tir_builder_alloc(true); 776*43ec0f41SMaxim Mikityanskiy if (!builder) 777*43ec0f41SMaxim Mikityanskiy return -ENOMEM; 778*43ec0f41SMaxim Mikityanskiy 779*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_build_lro(builder, lro_param); 780*43ec0f41SMaxim Mikityanskiy 781*43ec0f41SMaxim Mikityanskiy final_err = 0; 782*43ec0f41SMaxim Mikityanskiy 783*43ec0f41SMaxim Mikityanskiy for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { 784*43ec0f41SMaxim Mikityanskiy err = mlx5e_tir_modify(&res->rss[tt].indir_tir, builder); 785*43ec0f41SMaxim Mikityanskiy if (err) { 786*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to update LRO state of indirect TIR %#x for traffic type %d: err = %d\n", 787*43ec0f41SMaxim Mikityanskiy mlx5e_tir_get_tirn(&res->rss[tt].indir_tir), tt, err); 788*43ec0f41SMaxim Mikityanskiy if (!final_err) 789*43ec0f41SMaxim Mikityanskiy final_err = err; 790*43ec0f41SMaxim Mikityanskiy } 791*43ec0f41SMaxim Mikityanskiy 792*43ec0f41SMaxim Mikityanskiy if (!(res->features & MLX5E_RX_RES_FEATURE_INNER_FT)) 793*43ec0f41SMaxim Mikityanskiy continue; 794*43ec0f41SMaxim Mikityanskiy 795*43ec0f41SMaxim Mikityanskiy err = mlx5e_tir_modify(&res->rss[tt].inner_indir_tir, builder); 796*43ec0f41SMaxim Mikityanskiy if (err) { 797*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to update LRO state of inner indirect TIR %#x for traffic type %d: err = %d\n", 798*43ec0f41SMaxim Mikityanskiy mlx5e_tir_get_tirn(&res->rss[tt].inner_indir_tir), tt, err); 799*43ec0f41SMaxim Mikityanskiy if (!final_err) 800*43ec0f41SMaxim Mikityanskiy final_err = err; 801*43ec0f41SMaxim Mikityanskiy } 802*43ec0f41SMaxim Mikityanskiy } 803*43ec0f41SMaxim Mikityanskiy 804*43ec0f41SMaxim Mikityanskiy for (ix = 0; ix < res->max_nch; ix++) { 805*43ec0f41SMaxim Mikityanskiy err = mlx5e_tir_modify(&res->channels[ix].direct_tir, builder); 806*43ec0f41SMaxim Mikityanskiy if (err) { 807*43ec0f41SMaxim Mikityanskiy mlx5_core_warn(res->mdev, "Failed to update LRO state of direct TIR %#x for channel %u: err = %d\n", 808*43ec0f41SMaxim Mikityanskiy mlx5e_tir_get_tirn(&res->channels[ix].direct_tir), ix, err); 809*43ec0f41SMaxim Mikityanskiy if (!final_err) 810*43ec0f41SMaxim Mikityanskiy final_err = err; 811*43ec0f41SMaxim Mikityanskiy } 812*43ec0f41SMaxim Mikityanskiy } 813*43ec0f41SMaxim Mikityanskiy 814*43ec0f41SMaxim Mikityanskiy mlx5e_tir_builder_free(builder); 815*43ec0f41SMaxim Mikityanskiy return final_err; 816*43ec0f41SMaxim Mikityanskiy } 817*43ec0f41SMaxim Mikityanskiy 818*43ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res) 819*43ec0f41SMaxim Mikityanskiy { 820*43ec0f41SMaxim Mikityanskiy return res->rss_params.hash; 821*43ec0f41SMaxim Mikityanskiy } 822