1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 /* Copyright (c) 2019 Mellanox Technologies. */ 3 4 #include "en/params.h" 5 6 u32 mlx5e_rx_get_linear_frag_sz(struct mlx5e_params *params) 7 { 8 u16 hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); 9 u16 linear_rq_headroom = params->xdp_prog ? 10 XDP_PACKET_HEADROOM : MLX5_RX_HEADROOM; 11 u32 frag_sz; 12 13 linear_rq_headroom += NET_IP_ALIGN; 14 15 frag_sz = MLX5_SKB_FRAG_SZ(linear_rq_headroom + hw_mtu); 16 17 if (params->xdp_prog && frag_sz < PAGE_SIZE) 18 frag_sz = PAGE_SIZE; 19 20 return frag_sz; 21 } 22 23 u8 mlx5e_mpwqe_log_pkts_per_wqe(struct mlx5e_params *params) 24 { 25 u32 linear_frag_sz = mlx5e_rx_get_linear_frag_sz(params); 26 27 return MLX5_MPWRQ_LOG_WQE_SZ - order_base_2(linear_frag_sz); 28 } 29 30 bool mlx5e_rx_is_linear_skb(struct mlx5e_params *params) 31 { 32 u32 frag_sz = mlx5e_rx_get_linear_frag_sz(params); 33 34 return !params->lro_en && frag_sz <= PAGE_SIZE; 35 } 36 37 #define MLX5_MAX_MPWQE_LOG_WQE_STRIDE_SZ ((BIT(__mlx5_bit_sz(wq, log_wqe_stride_size)) - 1) + \ 38 MLX5_MPWQE_LOG_STRIDE_SZ_BASE) 39 bool mlx5e_rx_mpwqe_is_linear_skb(struct mlx5_core_dev *mdev, 40 struct mlx5e_params *params) 41 { 42 u32 frag_sz = mlx5e_rx_get_linear_frag_sz(params); 43 s8 signed_log_num_strides_param; 44 u8 log_num_strides; 45 46 if (!mlx5e_rx_is_linear_skb(params)) 47 return false; 48 49 if (order_base_2(frag_sz) > MLX5_MAX_MPWQE_LOG_WQE_STRIDE_SZ) 50 return false; 51 52 if (MLX5_CAP_GEN(mdev, ext_stride_num_range)) 53 return true; 54 55 log_num_strides = MLX5_MPWRQ_LOG_WQE_SZ - order_base_2(frag_sz); 56 signed_log_num_strides_param = 57 (s8)log_num_strides - MLX5_MPWQE_LOG_NUM_STRIDES_BASE; 58 59 return signed_log_num_strides_param >= 0; 60 } 61 62 u8 mlx5e_mpwqe_get_log_rq_size(struct mlx5e_params *params) 63 { 64 u8 log_pkts_per_wqe = mlx5e_mpwqe_log_pkts_per_wqe(params); 65 66 /* Numbers are unsigned, don't subtract to avoid underflow. */ 67 if (params->log_rq_mtu_frames < 68 log_pkts_per_wqe + MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW) 69 return MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW; 70 71 return params->log_rq_mtu_frames - log_pkts_per_wqe; 72 } 73 74 u8 mlx5e_mpwqe_get_log_stride_size(struct mlx5_core_dev *mdev, 75 struct mlx5e_params *params) 76 { 77 if (mlx5e_rx_mpwqe_is_linear_skb(mdev, params)) 78 return order_base_2(mlx5e_rx_get_linear_frag_sz(params)); 79 80 return MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev); 81 } 82 83 u8 mlx5e_mpwqe_get_log_num_strides(struct mlx5_core_dev *mdev, 84 struct mlx5e_params *params) 85 { 86 return MLX5_MPWRQ_LOG_WQE_SZ - 87 mlx5e_mpwqe_get_log_stride_size(mdev, params); 88 } 89 90 u16 mlx5e_get_rq_headroom(struct mlx5_core_dev *mdev, 91 struct mlx5e_params *params) 92 { 93 u16 linear_rq_headroom = params->xdp_prog ? 94 XDP_PACKET_HEADROOM : MLX5_RX_HEADROOM; 95 bool is_linear_skb; 96 97 linear_rq_headroom += NET_IP_ALIGN; 98 99 is_linear_skb = (params->rq_wq_type == MLX5_WQ_TYPE_CYCLIC) ? 100 mlx5e_rx_is_linear_skb(params) : 101 mlx5e_rx_mpwqe_is_linear_skb(mdev, params); 102 103 return is_linear_skb ? linear_rq_headroom : 0; 104 } 105