This source file includes following definitions.
- mlx5_query_port_tun_entropy
 
- mlx5_set_port_tun_entropy_calc
 
- mlx5_set_port_gre_tun_entropy_calc
 
- mlx5_init_port_tun_entropy
 
- mlx5_set_entropy
 
- mlx5_tun_entropy_refcount_inc
 
- mlx5_tun_entropy_refcount_dec
 
   1 
   2 
   3 
   4 #include <linux/module.h>
   5 #include <linux/mlx5/driver.h>
   6 #include <linux/mlx5/port.h>
   7 #include <linux/mlx5/cmd.h>
   8 #include "mlx5_core.h"
   9 #include "lib/port_tun.h"
  10 
  11 struct mlx5_port_tun_entropy_flags {
  12         bool force_supported, force_enabled;
  13         bool calc_supported, calc_enabled;
  14         bool gre_calc_supported, gre_calc_enabled;
  15 };
  16 
  17 static void mlx5_query_port_tun_entropy(struct mlx5_core_dev *mdev,
  18                                         struct mlx5_port_tun_entropy_flags *entropy_flags)
  19 {
  20         u32 out[MLX5_ST_SZ_DW(pcmr_reg)];
  21         
  22         entropy_flags->force_supported = false;
  23         entropy_flags->calc_supported = false;
  24         entropy_flags->gre_calc_supported = false;
  25         entropy_flags->force_enabled = false;
  26         entropy_flags->calc_enabled = true;
  27         entropy_flags->gre_calc_enabled = true;
  28 
  29         if (!MLX5_CAP_GEN(mdev, ports_check))
  30                 return;
  31 
  32         if (mlx5_query_ports_check(mdev, out, sizeof(out)))
  33                 return;
  34 
  35         entropy_flags->force_supported = !!(MLX5_GET(pcmr_reg, out, entropy_force_cap));
  36         entropy_flags->calc_supported = !!(MLX5_GET(pcmr_reg, out, entropy_calc_cap));
  37         entropy_flags->gre_calc_supported = !!(MLX5_GET(pcmr_reg, out, entropy_gre_calc_cap));
  38         entropy_flags->force_enabled = !!(MLX5_GET(pcmr_reg, out, entropy_force));
  39         entropy_flags->calc_enabled = !!(MLX5_GET(pcmr_reg, out, entropy_calc));
  40         entropy_flags->gre_calc_enabled = !!(MLX5_GET(pcmr_reg, out, entropy_gre_calc));
  41 }
  42 
  43 static int mlx5_set_port_tun_entropy_calc(struct mlx5_core_dev *mdev, u8 enable,
  44                                           u8 force)
  45 {
  46         u32 in[MLX5_ST_SZ_DW(pcmr_reg)] = {0};
  47         int err;
  48 
  49         err = mlx5_query_ports_check(mdev, in, sizeof(in));
  50         if (err)
  51                 return err;
  52         MLX5_SET(pcmr_reg, in, local_port, 1);
  53         MLX5_SET(pcmr_reg, in, entropy_force, force);
  54         MLX5_SET(pcmr_reg, in, entropy_calc, enable);
  55         return mlx5_set_ports_check(mdev, in, sizeof(in));
  56 }
  57 
  58 static int mlx5_set_port_gre_tun_entropy_calc(struct mlx5_core_dev *mdev,
  59                                               u8 enable, u8 force)
  60 {
  61         u32 in[MLX5_ST_SZ_DW(pcmr_reg)] = {0};
  62         int err;
  63 
  64         err = mlx5_query_ports_check(mdev, in, sizeof(in));
  65         if (err)
  66                 return err;
  67         MLX5_SET(pcmr_reg, in, local_port, 1);
  68         MLX5_SET(pcmr_reg, in, entropy_force, force);
  69         MLX5_SET(pcmr_reg, in, entropy_gre_calc, enable);
  70         return mlx5_set_ports_check(mdev, in, sizeof(in));
  71 }
  72 
  73 void mlx5_init_port_tun_entropy(struct mlx5_tun_entropy *tun_entropy,
  74                                 struct mlx5_core_dev *mdev)
  75 {
  76         struct mlx5_port_tun_entropy_flags entropy_flags;
  77 
  78         tun_entropy->mdev = mdev;
  79         mutex_init(&tun_entropy->lock);
  80         mlx5_query_port_tun_entropy(mdev, &entropy_flags);
  81         tun_entropy->num_enabling_entries = 0;
  82         tun_entropy->num_disabling_entries = 0;
  83         tun_entropy->enabled = entropy_flags.calc_supported ?
  84                                entropy_flags.calc_enabled : true;
  85 }
  86 
  87 static int mlx5_set_entropy(struct mlx5_tun_entropy *tun_entropy,
  88                             int reformat_type, bool enable)
  89 {
  90         struct mlx5_port_tun_entropy_flags entropy_flags;
  91         int err;
  92 
  93         mlx5_query_port_tun_entropy(tun_entropy->mdev, &entropy_flags);
  94         
  95 
  96 
  97 
  98 
  99         if (entropy_flags.gre_calc_supported &&
 100             reformat_type == MLX5_REFORMAT_TYPE_L2_TO_NVGRE) {
 101                 if (!entropy_flags.force_supported)
 102                         return 0;
 103                 err = mlx5_set_port_gre_tun_entropy_calc(tun_entropy->mdev,
 104                                                          enable, !enable);
 105                 if (err)
 106                         return err;
 107         } else if (entropy_flags.calc_supported) {
 108                 
 109 
 110 
 111 
 112                 if (entropy_flags.force_enabled &&
 113                     enable == entropy_flags.calc_enabled) {
 114                         mlx5_core_warn(tun_entropy->mdev,
 115                                        "Unexpected entropy calc setting - expected %d",
 116                                        !entropy_flags.calc_enabled);
 117                         return -EOPNOTSUPP;
 118                 }
 119                 
 120 
 121 
 122 
 123                 if (tun_entropy->num_enabling_entries)
 124                         return -EOPNOTSUPP;
 125                 err = mlx5_set_port_tun_entropy_calc(tun_entropy->mdev, enable,
 126                                                      entropy_flags.force_supported);
 127                 if (err)
 128                         return err;
 129                 tun_entropy->enabled = enable;
 130                 
 131                 if (entropy_flags.force_supported && enable) {
 132                         err = mlx5_set_port_tun_entropy_calc(tun_entropy->mdev, 1, 0);
 133                         if (err)
 134                                 return err;
 135                 }
 136         }
 137 
 138         return 0;
 139 }
 140 
 141 
 142 
 143 
 144 
 145 int mlx5_tun_entropy_refcount_inc(struct mlx5_tun_entropy *tun_entropy,
 146                                   int reformat_type)
 147 {
 148         
 149         int err = -EOPNOTSUPP;
 150 
 151         mutex_lock(&tun_entropy->lock);
 152         if (reformat_type == MLX5_REFORMAT_TYPE_L2_TO_VXLAN &&
 153             tun_entropy->enabled) {
 154                 
 155 
 156 
 157 
 158                 tun_entropy->num_enabling_entries++;
 159                 err = 0;
 160         } else if (reformat_type == MLX5_REFORMAT_TYPE_L2_TO_NVGRE) {
 161                 
 162 
 163 
 164 
 165                 if (tun_entropy->num_disabling_entries == 0)
 166                         err = mlx5_set_entropy(tun_entropy, reformat_type, 0);
 167                 else
 168                         err = 0;
 169                 if (!err)
 170                         tun_entropy->num_disabling_entries++;
 171         }
 172         mutex_unlock(&tun_entropy->lock);
 173 
 174         return err;
 175 }
 176 
 177 void mlx5_tun_entropy_refcount_dec(struct mlx5_tun_entropy *tun_entropy,
 178                                    int reformat_type)
 179 {
 180         mutex_lock(&tun_entropy->lock);
 181         if (reformat_type == MLX5_REFORMAT_TYPE_L2_TO_VXLAN)
 182                 tun_entropy->num_enabling_entries--;
 183         else if (reformat_type == MLX5_REFORMAT_TYPE_L2_TO_NVGRE &&
 184                  --tun_entropy->num_disabling_entries == 0)
 185                 mlx5_set_entropy(tun_entropy, reformat_type, 1);
 186         mutex_unlock(&tun_entropy->lock);
 187 }
 188