root/drivers/net/ethernet/mellanox/mlx5/core/en/params.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mlx5e_rx_is_xdp
  2. mlx5e_get_linear_rq_headroom
  3. mlx5e_rx_get_min_frag_sz
  4. mlx5e_rx_get_linear_frag_sz
  5. mlx5e_mpwqe_log_pkts_per_wqe
  6. mlx5e_rx_is_linear_skb
  7. mlx5e_rx_mpwqe_is_linear_skb
  8. mlx5e_mpwqe_get_log_rq_size
  9. mlx5e_mpwqe_get_log_stride_size
  10. mlx5e_mpwqe_get_log_num_strides
  11. mlx5e_get_rq_headroom

   1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
   2 /* Copyright (c) 2019 Mellanox Technologies. */
   3 
   4 #include "en/params.h"
   5 
   6 static inline bool mlx5e_rx_is_xdp(struct mlx5e_params *params,
   7                                    struct mlx5e_xsk_param *xsk)
   8 {
   9         return params->xdp_prog || xsk;
  10 }
  11 
  12 u16 mlx5e_get_linear_rq_headroom(struct mlx5e_params *params,
  13                                  struct mlx5e_xsk_param *xsk)
  14 {
  15         u16 headroom = NET_IP_ALIGN;
  16 
  17         if (mlx5e_rx_is_xdp(params, xsk)) {
  18                 headroom += XDP_PACKET_HEADROOM;
  19                 if (xsk)
  20                         headroom += xsk->headroom;
  21         } else {
  22                 headroom += MLX5_RX_HEADROOM;
  23         }
  24 
  25         return headroom;
  26 }
  27 
  28 u32 mlx5e_rx_get_min_frag_sz(struct mlx5e_params *params,
  29                              struct mlx5e_xsk_param *xsk)
  30 {
  31         u32 hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
  32         u16 linear_rq_headroom = mlx5e_get_linear_rq_headroom(params, xsk);
  33 
  34         return linear_rq_headroom + hw_mtu;
  35 }
  36 
  37 u32 mlx5e_rx_get_linear_frag_sz(struct mlx5e_params *params,
  38                                 struct mlx5e_xsk_param *xsk)
  39 {
  40         u32 frag_sz = mlx5e_rx_get_min_frag_sz(params, xsk);
  41 
  42         /* AF_XDP doesn't build SKBs in place. */
  43         if (!xsk)
  44                 frag_sz = MLX5_SKB_FRAG_SZ(frag_sz);
  45 
  46         /* XDP in mlx5e doesn't support multiple packets per page. AF_XDP is a
  47          * special case. It can run with frames smaller than a page, as it
  48          * doesn't allocate pages dynamically. However, here we pretend that
  49          * fragments are page-sized: it allows to treat XSK frames like pages
  50          * by redirecting alloc and free operations to XSK rings and by using
  51          * the fact there are no multiple packets per "page" (which is a frame).
  52          * The latter is important, because frames may come in a random order,
  53          * and we will have trouble assemblying a real page of multiple frames.
  54          */
  55         if (mlx5e_rx_is_xdp(params, xsk))
  56                 frag_sz = max_t(u32, frag_sz, PAGE_SIZE);
  57 
  58         /* Even if we can go with a smaller fragment size, we must not put
  59          * multiple packets into a single frame.
  60          */
  61         if (xsk)
  62                 frag_sz = max_t(u32, frag_sz, xsk->chunk_size);
  63 
  64         return frag_sz;
  65 }
  66 
  67 u8 mlx5e_mpwqe_log_pkts_per_wqe(struct mlx5e_params *params,
  68                                 struct mlx5e_xsk_param *xsk)
  69 {
  70         u32 linear_frag_sz = mlx5e_rx_get_linear_frag_sz(params, xsk);
  71 
  72         return MLX5_MPWRQ_LOG_WQE_SZ - order_base_2(linear_frag_sz);
  73 }
  74 
  75 bool mlx5e_rx_is_linear_skb(struct mlx5e_params *params,
  76                             struct mlx5e_xsk_param *xsk)
  77 {
  78         /* AF_XDP allocates SKBs on XDP_PASS - ensure they don't occupy more
  79          * than one page. For this, check both with and without xsk.
  80          */
  81         u32 linear_frag_sz = max(mlx5e_rx_get_linear_frag_sz(params, xsk),
  82                                  mlx5e_rx_get_linear_frag_sz(params, NULL));
  83 
  84         return !params->lro_en && linear_frag_sz <= PAGE_SIZE;
  85 }
  86 
  87 #define MLX5_MAX_MPWQE_LOG_WQE_STRIDE_SZ ((BIT(__mlx5_bit_sz(wq, log_wqe_stride_size)) - 1) + \
  88                                           MLX5_MPWQE_LOG_STRIDE_SZ_BASE)
  89 bool mlx5e_rx_mpwqe_is_linear_skb(struct mlx5_core_dev *mdev,
  90                                   struct mlx5e_params *params,
  91                                   struct mlx5e_xsk_param *xsk)
  92 {
  93         u32 linear_frag_sz = mlx5e_rx_get_linear_frag_sz(params, xsk);
  94         s8 signed_log_num_strides_param;
  95         u8 log_num_strides;
  96 
  97         if (!mlx5e_rx_is_linear_skb(params, xsk))
  98                 return false;
  99 
 100         if (order_base_2(linear_frag_sz) > MLX5_MAX_MPWQE_LOG_WQE_STRIDE_SZ)
 101                 return false;
 102 
 103         if (MLX5_CAP_GEN(mdev, ext_stride_num_range))
 104                 return true;
 105 
 106         log_num_strides = MLX5_MPWRQ_LOG_WQE_SZ - order_base_2(linear_frag_sz);
 107         signed_log_num_strides_param =
 108                 (s8)log_num_strides - MLX5_MPWQE_LOG_NUM_STRIDES_BASE;
 109 
 110         return signed_log_num_strides_param >= 0;
 111 }
 112 
 113 u8 mlx5e_mpwqe_get_log_rq_size(struct mlx5e_params *params,
 114                                struct mlx5e_xsk_param *xsk)
 115 {
 116         u8 log_pkts_per_wqe = mlx5e_mpwqe_log_pkts_per_wqe(params, xsk);
 117 
 118         /* Numbers are unsigned, don't subtract to avoid underflow. */
 119         if (params->log_rq_mtu_frames <
 120             log_pkts_per_wqe + MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW)
 121                 return MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW;
 122 
 123         return params->log_rq_mtu_frames - log_pkts_per_wqe;
 124 }
 125 
 126 u8 mlx5e_mpwqe_get_log_stride_size(struct mlx5_core_dev *mdev,
 127                                    struct mlx5e_params *params,
 128                                    struct mlx5e_xsk_param *xsk)
 129 {
 130         if (mlx5e_rx_mpwqe_is_linear_skb(mdev, params, xsk))
 131                 return order_base_2(mlx5e_rx_get_linear_frag_sz(params, xsk));
 132 
 133         return MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev);
 134 }
 135 
 136 u8 mlx5e_mpwqe_get_log_num_strides(struct mlx5_core_dev *mdev,
 137                                    struct mlx5e_params *params,
 138                                    struct mlx5e_xsk_param *xsk)
 139 {
 140         return MLX5_MPWRQ_LOG_WQE_SZ -
 141                 mlx5e_mpwqe_get_log_stride_size(mdev, params, xsk);
 142 }
 143 
 144 u16 mlx5e_get_rq_headroom(struct mlx5_core_dev *mdev,
 145                           struct mlx5e_params *params,
 146                           struct mlx5e_xsk_param *xsk)
 147 {
 148         bool is_linear_skb = (params->rq_wq_type == MLX5_WQ_TYPE_CYCLIC) ?
 149                 mlx5e_rx_is_linear_skb(params, xsk) :
 150                 mlx5e_rx_mpwqe_is_linear_skb(mdev, params, xsk);
 151 
 152         return is_linear_skb ? mlx5e_get_linear_rq_headroom(params, xsk) : 0;
 153 }

/* [<][>][^][v][top][bottom][index][help] */