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