Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2025 Huawei Technologies Co., Ltd
3 : : */
4 : :
5 : : #include "base/hinic3_compat.h"
6 : : #include "base/hinic3_hwdev.h"
7 : : #include "base/hinic3_hwif.h"
8 : : #include "base/hinic3_nic_cfg.h"
9 : : #include "hinic3_ethdev.h"
10 : :
11 : : #define HINIC3_UINT1_MAX 0x1
12 : : #define HINIC3_UINT4_MAX 0xf
13 : : #define HINIC3_UINT15_MAX 0x7fff
14 : :
15 : : #define HINIC3_DEV_PRIVATE_TO_TCAM_INFO(nic_dev) \
16 : : (&((struct hinic3_nic_dev *)(nic_dev))->tcam)
17 : :
18 : : /**
19 : : * Perform a bitwise AND operation on the input key value and mask, and stores
20 : : * the result in the key_y array.
21 : : *
22 : : * @param[out] key_y
23 : : * Array for storing results.
24 : : * @param[in] src_input
25 : : * Input key array.
26 : : * @param[in] mask
27 : : * Mask array.
28 : : * @param[in] len
29 : : * Length of the key value and mask.
30 : : */
31 : : static void
32 : : tcam_translate_key_y(uint8_t *key_y, uint8_t *src_input, uint8_t *mask, uint8_t len)
33 : : {
34 : : uint8_t idx;
35 : :
36 [ # # ]: 0 : for (idx = 0; idx < len; idx++)
37 : 0 : key_y[idx] = src_input[idx] & mask[idx];
38 : : }
39 : :
40 : : /**
41 : : * Convert key_y to key_x using the exclusive OR operation.
42 : : *
43 : : * @param[out] key_x
44 : : * Array for storing results.
45 : : * @param[in] key_y
46 : : * Input key array.
47 : : * @param[in] mask
48 : : * Mask array.
49 : : * @param[in] len
50 : : * Length of the key value and mask.
51 : : */
52 : : static void
53 : : tcam_translate_key_x(uint8_t *key_x, uint8_t *key_y, uint8_t *mask, uint8_t len)
54 : : {
55 : : uint8_t idx;
56 : :
57 [ # # ]: 0 : for (idx = 0; idx < len; idx++)
58 : 0 : key_x[idx] = key_y[idx] ^ mask[idx];
59 : : }
60 : :
61 : : static void
62 : 0 : tcam_key_calculate(struct hinic3_tcam_key *tcam_key,
63 : : struct hinic3_tcam_cfg_rule *fdir_tcam_rule)
64 : : {
65 : 0 : tcam_translate_key_y(fdir_tcam_rule->key.y, (uint8_t *)(&tcam_key->key_info),
66 : 0 : (uint8_t *)(&tcam_key->key_mask),
67 : : HINIC3_TCAM_FLOW_KEY_SIZE);
68 : 0 : tcam_translate_key_x(fdir_tcam_rule->key.x, fdir_tcam_rule->key.y,
69 : : (uint8_t *)(&tcam_key->key_mask),
70 : : HINIC3_TCAM_FLOW_KEY_SIZE);
71 : 0 : }
72 : :
73 : : static void
74 : : hinic3_fdir_tcam_ipv4_init(struct hinic3_fdir_filter *rule,
75 : : struct hinic3_tcam_key *tcam_key)
76 : : {
77 : : /* Fill type of ip. */
78 : 0 : tcam_key->key_mask.ip_type = HINIC3_UINT1_MAX;
79 : 0 : tcam_key->key_info.ip_type = HINIC3_FDIR_IP_TYPE_IPV4;
80 : :
81 : : /* Fill src IPv4. */
82 : 0 : tcam_key->key_mask.sipv4_h =
83 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv4.src_ip);
84 : 0 : tcam_key->key_mask.sipv4_l =
85 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv4.src_ip);
86 : 0 : tcam_key->key_info.sipv4_h =
87 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv4.src_ip);
88 : 0 : tcam_key->key_info.sipv4_l =
89 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv4.src_ip);
90 : :
91 : : /* Fill dst IPv4. */
92 : 0 : tcam_key->key_mask.dipv4_h =
93 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv4.dst_ip);
94 : 0 : tcam_key->key_mask.dipv4_l =
95 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv4.dst_ip);
96 : 0 : tcam_key->key_info.dipv4_h =
97 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv4.dst_ip);
98 : 0 : tcam_key->key_info.dipv4_l =
99 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv4.dst_ip);
100 : 0 : }
101 : :
102 : : static void
103 : 0 : hinic3_fdir_tcam_ipv6_init(struct hinic3_fdir_filter *rule,
104 : : struct hinic3_tcam_key *tcam_key)
105 : : {
106 : : /* Fill type of ip. */
107 : 0 : tcam_key->key_mask_ipv6.ip_type = HINIC3_UINT1_MAX;
108 : 0 : tcam_key->key_info_ipv6.ip_type = HINIC3_FDIR_IP_TYPE_IPV6;
109 : :
110 : : /* Fill src IPv6. */
111 : 0 : tcam_key->key_mask_ipv6.sipv6_key0 =
112 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0]);
113 : 0 : tcam_key->key_mask_ipv6.sipv6_key1 =
114 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0]);
115 : 0 : tcam_key->key_mask_ipv6.sipv6_key2 =
116 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0x1]);
117 : 0 : tcam_key->key_mask_ipv6.sipv6_key3 =
118 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0x1]);
119 : 0 : tcam_key->key_mask_ipv6.sipv6_key4 =
120 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0x2]);
121 : 0 : tcam_key->key_mask_ipv6.sipv6_key5 =
122 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0x2]);
123 : 0 : tcam_key->key_mask_ipv6.sipv6_key6 =
124 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0x3]);
125 : 0 : tcam_key->key_mask_ipv6.sipv6_key7 =
126 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0x3]);
127 : 0 : tcam_key->key_info_ipv6.sipv6_key0 =
128 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0]);
129 : 0 : tcam_key->key_info_ipv6.sipv6_key1 =
130 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0]);
131 : 0 : tcam_key->key_info_ipv6.sipv6_key2 =
132 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0x1]);
133 : 0 : tcam_key->key_info_ipv6.sipv6_key3 =
134 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x1]);
135 : 0 : tcam_key->key_info_ipv6.sipv6_key4 =
136 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0x2]);
137 : 0 : tcam_key->key_info_ipv6.sipv6_key5 =
138 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x2]);
139 : 0 : tcam_key->key_info_ipv6.sipv6_key6 =
140 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0x3]);
141 : 0 : tcam_key->key_info_ipv6.sipv6_key7 =
142 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x3]);
143 : :
144 : : /* Fill dst IPv6. */
145 : 0 : tcam_key->key_mask_ipv6.dipv6_key0 =
146 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0]);
147 : 0 : tcam_key->key_mask_ipv6.dipv6_key1 =
148 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0]);
149 : 0 : tcam_key->key_mask_ipv6.dipv6_key2 =
150 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0x1]);
151 : 0 : tcam_key->key_mask_ipv6.dipv6_key3 =
152 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0x1]);
153 : 0 : tcam_key->key_mask_ipv6.dipv6_key4 =
154 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0x2]);
155 : 0 : tcam_key->key_mask_ipv6.dipv6_key5 =
156 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0x2]);
157 : 0 : tcam_key->key_mask_ipv6.dipv6_key6 =
158 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0x3]);
159 : 0 : tcam_key->key_mask_ipv6.dipv6_key7 =
160 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0x3]);
161 : 0 : tcam_key->key_info_ipv6.dipv6_key0 =
162 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0]);
163 : 0 : tcam_key->key_info_ipv6.dipv6_key1 =
164 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0]);
165 : 0 : tcam_key->key_info_ipv6.dipv6_key2 =
166 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0x1]);
167 : 0 : tcam_key->key_info_ipv6.dipv6_key3 =
168 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x1]);
169 : 0 : tcam_key->key_info_ipv6.dipv6_key4 =
170 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0x2]);
171 : 0 : tcam_key->key_info_ipv6.dipv6_key5 =
172 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x2]);
173 : 0 : tcam_key->key_info_ipv6.dipv6_key6 =
174 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0x3]);
175 : 0 : tcam_key->key_info_ipv6.dipv6_key7 =
176 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x3]);
177 : 0 : }
178 : :
179 : : /**
180 : : * Set the TCAM information in notunnel scenario.
181 : : *
182 : : * @param[in] dev
183 : : * Pointer to ethernet device structure.
184 : : * @param[in] rule
185 : : * Pointer to the filtering rule.
186 : : * @param[in] tcam_key
187 : : * Pointer to the TCAM key.
188 : : */
189 : : static void
190 : 0 : hinic3_fdir_tcam_notunnel_init(struct rte_eth_dev *dev,
191 : : struct hinic3_fdir_filter *rule,
192 : : struct hinic3_tcam_key *tcam_key)
193 : : {
194 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
195 : :
196 : : /* Fill tcam_key info. */
197 : 0 : tcam_key->key_mask.sport = rule->key_mask.src_port;
198 : 0 : tcam_key->key_info.sport = rule->key_spec.src_port;
199 : :
200 : 0 : tcam_key->key_mask.dport = rule->key_mask.dst_port;
201 : 0 : tcam_key->key_info.dport = rule->key_spec.dst_port;
202 : :
203 : 0 : tcam_key->key_mask.tunnel_type = HINIC3_UINT4_MAX;
204 : 0 : tcam_key->key_info.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_NORMAL;
205 : :
206 : 0 : tcam_key->key_mask.function_id = HINIC3_UINT15_MAX;
207 : 0 : tcam_key->key_info.function_id = hinic3_global_func_id(nic_dev->hwdev) &
208 : : HINIC3_UINT15_MAX;
209 : :
210 : 0 : tcam_key->key_mask.ip_proto = rule->key_mask.proto;
211 : 0 : tcam_key->key_info.ip_proto = rule->key_spec.proto;
212 : :
213 [ # # ]: 0 : if (rule->ip_type == HINIC3_FDIR_IP_TYPE_IPV4)
214 : : hinic3_fdir_tcam_ipv4_init(rule, tcam_key);
215 [ # # ]: 0 : else if (rule->ip_type == HINIC3_FDIR_IP_TYPE_IPV6)
216 : 0 : hinic3_fdir_tcam_ipv6_init(rule, tcam_key);
217 : 0 : }
218 : :
219 : : static void
220 : : hinic3_fdir_tcam_vxlan_ipv4_init(struct hinic3_fdir_filter *rule,
221 : : struct hinic3_tcam_key *tcam_key)
222 : : {
223 : : /* Fill type of ip. */
224 : 0 : tcam_key->key_mask.ip_type = HINIC3_UINT1_MAX;
225 : 0 : tcam_key->key_info.ip_type = HINIC3_FDIR_IP_TYPE_IPV4;
226 : :
227 : : /* Fill src ipv4. */
228 : 0 : tcam_key->key_mask.sipv4_h =
229 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.inner_ipv4.src_ip);
230 : 0 : tcam_key->key_mask.sipv4_l =
231 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.inner_ipv4.src_ip);
232 : 0 : tcam_key->key_info.sipv4_h =
233 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.inner_ipv4.src_ip);
234 : 0 : tcam_key->key_info.sipv4_l =
235 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.inner_ipv4.src_ip);
236 : :
237 : : /* Fill dst ipv4. */
238 : 0 : tcam_key->key_mask.dipv4_h =
239 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.inner_ipv4.dst_ip);
240 : 0 : tcam_key->key_mask.dipv4_l =
241 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.inner_ipv4.dst_ip);
242 : 0 : tcam_key->key_info.dipv4_h =
243 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.inner_ipv4.dst_ip);
244 : 0 : tcam_key->key_info.dipv4_l =
245 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.inner_ipv4.dst_ip);
246 : 0 : }
247 : :
248 : : static void
249 : 0 : hinic3_fdir_tcam_vxlan_ipv6_init(struct hinic3_fdir_filter *rule,
250 : : struct hinic3_tcam_key *tcam_key)
251 : : {
252 : : /* Fill type of ip. */
253 : 0 : tcam_key->key_mask_vxlan_ipv6.ip_type = HINIC3_UINT1_MAX;
254 : 0 : tcam_key->key_info_vxlan_ipv6.ip_type = HINIC3_FDIR_IP_TYPE_IPV6;
255 : :
256 : : /* Use inner dst ipv6 to fill the dst ipv6 of tcam_key. */
257 : 0 : tcam_key->key_mask_vxlan_ipv6.dipv6_key0 =
258 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.inner_ipv6.dst_ip[0]);
259 : 0 : tcam_key->key_mask_vxlan_ipv6.dipv6_key1 =
260 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.inner_ipv6.dst_ip[0]);
261 : 0 : tcam_key->key_mask_vxlan_ipv6.dipv6_key2 =
262 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.inner_ipv6.dst_ip[0x1]);
263 : 0 : tcam_key->key_mask_vxlan_ipv6.dipv6_key3 =
264 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.inner_ipv6.dst_ip[0x1]);
265 : 0 : tcam_key->key_mask_vxlan_ipv6.dipv6_key4 =
266 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.inner_ipv6.dst_ip[0x2]);
267 : 0 : tcam_key->key_mask_vxlan_ipv6.dipv6_key5 =
268 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.inner_ipv6.dst_ip[0x2]);
269 : 0 : tcam_key->key_mask_vxlan_ipv6.dipv6_key6 =
270 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.inner_ipv6.dst_ip[0x3]);
271 : 0 : tcam_key->key_mask_vxlan_ipv6.dipv6_key7 =
272 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.inner_ipv6.dst_ip[0x3]);
273 : 0 : tcam_key->key_info_vxlan_ipv6.dipv6_key0 =
274 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.inner_ipv6.dst_ip[0]);
275 : 0 : tcam_key->key_info_vxlan_ipv6.dipv6_key1 =
276 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.inner_ipv6.dst_ip[0]);
277 : 0 : tcam_key->key_info_vxlan_ipv6.dipv6_key2 =
278 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.inner_ipv6.dst_ip[0x1]);
279 : 0 : tcam_key->key_info_vxlan_ipv6.dipv6_key3 =
280 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.inner_ipv6.dst_ip[0x1]);
281 : 0 : tcam_key->key_info_vxlan_ipv6.dipv6_key4 =
282 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.inner_ipv6.dst_ip[0x2]);
283 : 0 : tcam_key->key_info_vxlan_ipv6.dipv6_key5 =
284 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.inner_ipv6.dst_ip[0x2]);
285 : 0 : tcam_key->key_info_vxlan_ipv6.dipv6_key6 =
286 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.inner_ipv6.dst_ip[0x3]);
287 : 0 : tcam_key->key_info_vxlan_ipv6.dipv6_key7 =
288 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.inner_ipv6.dst_ip[0x3]);
289 : 0 : }
290 : :
291 : : static void
292 : 0 : hinic3_fdir_tcam_outer_ipv6_init(struct hinic3_fdir_filter *rule,
293 : : struct hinic3_tcam_key *tcam_key)
294 : : {
295 : 0 : tcam_key->key_mask_ipv6.sipv6_key0 =
296 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0]);
297 : 0 : tcam_key->key_mask_ipv6.sipv6_key1 =
298 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0]);
299 : 0 : tcam_key->key_mask_ipv6.sipv6_key2 =
300 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0x1]);
301 : 0 : tcam_key->key_mask_ipv6.sipv6_key3 =
302 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0x1]);
303 : 0 : tcam_key->key_mask_ipv6.sipv6_key4 =
304 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0x2]);
305 : 0 : tcam_key->key_mask_ipv6.sipv6_key5 =
306 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0x2]);
307 : 0 : tcam_key->key_mask_ipv6.sipv6_key6 =
308 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0x3]);
309 : 0 : tcam_key->key_mask_ipv6.sipv6_key7 =
310 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.src_ip[0x3]);
311 : 0 : tcam_key->key_info_ipv6.sipv6_key0 =
312 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0]);
313 : 0 : tcam_key->key_info_ipv6.sipv6_key1 =
314 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0]);
315 : 0 : tcam_key->key_info_ipv6.sipv6_key2 =
316 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0x1]);
317 : 0 : tcam_key->key_info_ipv6.sipv6_key3 =
318 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x1]);
319 : 0 : tcam_key->key_info_ipv6.sipv6_key4 =
320 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0x2]);
321 : 0 : tcam_key->key_info_ipv6.sipv6_key5 =
322 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x2]);
323 : 0 : tcam_key->key_info_ipv6.sipv6_key6 =
324 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.src_ip[0x3]);
325 : 0 : tcam_key->key_info_ipv6.sipv6_key7 =
326 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x3]);
327 : :
328 : 0 : tcam_key->key_mask_ipv6.dipv6_key0 =
329 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0]);
330 : 0 : tcam_key->key_mask_ipv6.dipv6_key1 =
331 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0]);
332 : 0 : tcam_key->key_mask_ipv6.dipv6_key2 =
333 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0x1]);
334 : 0 : tcam_key->key_mask_ipv6.dipv6_key3 =
335 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0x1]);
336 : 0 : tcam_key->key_mask_ipv6.dipv6_key4 =
337 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0x2]);
338 : 0 : tcam_key->key_mask_ipv6.dipv6_key5 =
339 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0x2]);
340 : 0 : tcam_key->key_mask_ipv6.dipv6_key6 =
341 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0x3]);
342 : 0 : tcam_key->key_mask_ipv6.dipv6_key7 =
343 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv6.dst_ip[0x3]);
344 : 0 : tcam_key->key_info_ipv6.dipv6_key0 =
345 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0]);
346 : 0 : tcam_key->key_info_ipv6.dipv6_key1 =
347 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0]);
348 : 0 : tcam_key->key_info_ipv6.dipv6_key2 =
349 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0x1]);
350 : 0 : tcam_key->key_info_ipv6.dipv6_key3 =
351 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x1]);
352 : 0 : tcam_key->key_info_ipv6.dipv6_key4 =
353 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0x2]);
354 : 0 : tcam_key->key_info_ipv6.dipv6_key5 =
355 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x2]);
356 : 0 : tcam_key->key_info_ipv6.dipv6_key6 =
357 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv6.dst_ip[0x3]);
358 : 0 : tcam_key->key_info_ipv6.dipv6_key7 =
359 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x3]);
360 : 0 : }
361 : :
362 : : static void
363 : 0 : hinic3_fdir_tcam_ipv6_vxlan_init(struct rte_eth_dev *dev,
364 : : struct hinic3_fdir_filter *rule,
365 : : struct hinic3_tcam_key *tcam_key)
366 : : {
367 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
368 : :
369 : 0 : tcam_key->key_mask_ipv6.ip_proto = rule->key_mask.proto;
370 : 0 : tcam_key->key_info_ipv6.ip_proto = rule->key_spec.proto;
371 : :
372 : 0 : tcam_key->key_mask_ipv6.tunnel_type = HINIC3_UINT4_MAX;
373 : 0 : tcam_key->key_info_ipv6.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_VXLAN;
374 : :
375 : 0 : tcam_key->key_mask_ipv6.outer_ip_type = HINIC3_UINT1_MAX;
376 : 0 : tcam_key->key_info_ipv6.outer_ip_type = HINIC3_FDIR_IP_TYPE_IPV6;
377 : :
378 : 0 : tcam_key->key_mask_ipv6.function_id = HINIC3_UINT15_MAX;
379 : 0 : tcam_key->key_info_ipv6.function_id =
380 : 0 : hinic3_global_func_id(nic_dev->hwdev) & HINIC3_UINT15_MAX;
381 : :
382 : 0 : tcam_key->key_mask_ipv6.dport = rule->key_mask.dst_port;
383 : 0 : tcam_key->key_info_ipv6.dport = rule->key_spec.dst_port;
384 : :
385 : 0 : tcam_key->key_mask_ipv6.sport = rule->key_mask.src_port;
386 : 0 : tcam_key->key_info_ipv6.sport = rule->key_spec.src_port;
387 : :
388 [ # # ]: 0 : if (rule->ip_type == HINIC3_FDIR_IP_TYPE_ANY)
389 : 0 : hinic3_fdir_tcam_outer_ipv6_init(rule, tcam_key);
390 : 0 : }
391 : :
392 : : /**
393 : : * Sets the TCAM information in the VXLAN scenario.
394 : : *
395 : : * @param[in] dev
396 : : * Pointer to ethernet device structure.
397 : : * @param[in] rule
398 : : * Pointer to the filtering rule.
399 : : * @param[in] tcam_key
400 : : * Pointer to the TCAM key.
401 : : */
402 : : static void
403 : 0 : hinic3_fdir_tcam_vxlan_init(struct rte_eth_dev *dev,
404 : : struct hinic3_fdir_filter *rule,
405 : : struct hinic3_tcam_key *tcam_key)
406 : : {
407 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
408 : :
409 [ # # ]: 0 : if (rule->outer_ip_type == HINIC3_FDIR_IP_TYPE_IPV6) {
410 : 0 : hinic3_fdir_tcam_ipv6_vxlan_init(dev, rule, tcam_key);
411 : 0 : return;
412 : : }
413 : :
414 : 0 : tcam_key->key_mask.ip_proto = rule->key_mask.proto;
415 : 0 : tcam_key->key_info.ip_proto = rule->key_spec.proto;
416 : :
417 : 0 : tcam_key->key_mask.sport = rule->key_mask.src_port;
418 : 0 : tcam_key->key_info.sport = rule->key_spec.src_port;
419 : :
420 : 0 : tcam_key->key_mask.dport = rule->key_mask.dst_port;
421 : 0 : tcam_key->key_info.dport = rule->key_spec.dst_port;
422 : :
423 : 0 : tcam_key->key_mask.outer_sipv4_h =
424 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv4.src_ip);
425 : 0 : tcam_key->key_mask.outer_sipv4_l =
426 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv4.src_ip);
427 : 0 : tcam_key->key_info.outer_sipv4_h =
428 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv4.src_ip);
429 : 0 : tcam_key->key_info.outer_sipv4_l =
430 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv4.src_ip);
431 : :
432 : 0 : tcam_key->key_mask.outer_dipv4_h =
433 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv4.dst_ip);
434 : 0 : tcam_key->key_mask.outer_dipv4_l =
435 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.ipv4.dst_ip);
436 : 0 : tcam_key->key_info.outer_dipv4_h =
437 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.ipv4.dst_ip);
438 : 0 : tcam_key->key_info.outer_dipv4_l =
439 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv4.dst_ip);
440 : :
441 : 0 : tcam_key->key_mask.vni_h =
442 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_mask.tunnel.tunnel_id);
443 : 0 : tcam_key->key_mask.vni_l =
444 : : HINIC3_32_LOWER_16_BITS(rule->key_mask.tunnel.tunnel_id);
445 : 0 : tcam_key->key_info.vni_h =
446 : 0 : HINIC3_32_UPPER_16_BITS(rule->key_spec.tunnel.tunnel_id);
447 : 0 : tcam_key->key_info.vni_l =
448 : : HINIC3_32_LOWER_16_BITS(rule->key_spec.tunnel.tunnel_id);
449 : :
450 : 0 : tcam_key->key_mask.tunnel_type = HINIC3_UINT4_MAX;
451 : 0 : tcam_key->key_info.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_VXLAN;
452 : :
453 : 0 : tcam_key->key_mask.function_id = HINIC3_UINT15_MAX;
454 : 0 : tcam_key->key_info.function_id = hinic3_global_func_id(nic_dev->hwdev) &
455 : : HINIC3_UINT15_MAX;
456 : :
457 [ # # ]: 0 : if (rule->ip_type == HINIC3_FDIR_IP_TYPE_IPV4)
458 : : hinic3_fdir_tcam_vxlan_ipv4_init(rule, tcam_key);
459 : :
460 [ # # ]: 0 : else if (rule->ip_type == HINIC3_FDIR_IP_TYPE_IPV6)
461 : 0 : hinic3_fdir_tcam_vxlan_ipv6_init(rule, tcam_key);
462 : : }
463 : :
464 : : static void
465 : 0 : hinic3_fdir_tcam_info_init(struct rte_eth_dev *dev,
466 : : struct hinic3_fdir_filter *rule,
467 : : struct hinic3_tcam_key *tcam_key,
468 : : struct hinic3_tcam_cfg_rule *fdir_tcam_rule)
469 : : {
470 : : /* Initialize the TCAM based on the tunnel type. */
471 [ # # ]: 0 : if (rule->tunnel_type == HINIC3_FDIR_TUNNEL_MODE_NORMAL)
472 : 0 : hinic3_fdir_tcam_notunnel_init(dev, rule, tcam_key);
473 : : else
474 : 0 : hinic3_fdir_tcam_vxlan_init(dev, rule, tcam_key);
475 : :
476 : : /* Set the queue index. */
477 : 0 : fdir_tcam_rule->data.qid = rule->rq_index;
478 : : /* Calculate key of TCAM. */
479 : 0 : tcam_key_calculate(tcam_key, fdir_tcam_rule);
480 : 0 : }
481 : :
482 : : /**
483 : : * Find filter in given ethertype filter list.
484 : : *
485 : : * @param[in] filter_list
486 : : * Point to the Ether filter list.
487 : : * @param[in] key
488 : : * The tcam key to find.
489 : : * @return
490 : : * If a matching filter is found, the filter is returned, otherwise
491 : : * RTE_ETH_FILTER_NONE.
492 : : */
493 : : static inline uint16_t
494 : : hinic3_ethertype_filter_lookup(struct hinic3_ethertype_filter_list *ethertype_list,
495 : : uint16_t type)
496 : : {
497 : : struct rte_flow *it;
498 : : struct hinic3_filter_t *filter_rules;
499 : :
500 [ # # ]: 0 : TAILQ_FOREACH(it, ethertype_list, node) {
501 : 0 : filter_rules = it->rule;
502 [ # # ]: 0 : if (type == filter_rules->ethertype_filter.ether_type)
503 : : return filter_rules->ethertype_filter.ether_type;
504 : : }
505 : :
506 : : return RTE_ETH_FILTER_NONE;
507 : : }
508 : :
509 : : /**
510 : : * Find the filter that matches the given key in the TCAM filter list.
511 : : *
512 : : * @param[in] filter_list
513 : : * Point to the tcam filter list.
514 : : * @param[in] key
515 : : * The tcam key to find.
516 : : * @return
517 : : * If a matching filter is found, the filter is returned, otherwise NULL.
518 : : */
519 : : static inline struct hinic3_tcam_filter *
520 : : hinic3_tcam_filter_lookup(struct hinic3_tcam_filter_list *filter_list,
521 : : struct hinic3_tcam_key *key)
522 : : {
523 : : struct hinic3_tcam_filter *it;
524 : :
525 [ # # ]: 0 : TAILQ_FOREACH(it, filter_list, entries) {
526 [ # # ]: 0 : if (memcmp(key, &it->tcam_key,
527 : : sizeof(struct hinic3_tcam_key)) == 0) {
528 : : return it;
529 : : }
530 : : }
531 : :
532 : : return NULL;
533 : : }
534 : : /**
535 : : * Allocate memory for dynamic blocks and then add them to the queue.
536 : : *
537 : : * @param[in] tcam_info
538 : : * Point to TCAM information.
539 : : * @param[in] dynamic_block_id
540 : : * Indicate the ID of a dynamic block.
541 : : * @return
542 : : * Return the pointer to the dynamic block, or NULL if the allocation fails.
543 : : */
544 : : static struct hinic3_tcam_dynamic_block *
545 : 0 : hinic3_alloc_dynamic_block_resource(struct hinic3_tcam_info *tcam_info,
546 : : uint16_t dynamic_block_id)
547 : : {
548 : : struct hinic3_tcam_dynamic_block *dynamic_block_ptr = NULL;
549 : :
550 : : dynamic_block_ptr =
551 : 0 : rte_zmalloc("hinic3_tcam_dynamic_mem",
552 : : sizeof(struct hinic3_tcam_dynamic_block), 0);
553 [ # # ]: 0 : if (dynamic_block_ptr == NULL) {
554 : 0 : PMD_DRV_LOG(ERR,
555 : : "Alloc fdir filter dynamic block index %d memory failed!",
556 : : dynamic_block_id);
557 : 0 : return NULL;
558 : : }
559 : :
560 : 0 : dynamic_block_ptr->dynamic_block_id = dynamic_block_id;
561 : :
562 : : /* Add new block to the end of the TCAM dynamic block list. */
563 : 0 : TAILQ_INSERT_TAIL(&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
564 : : dynamic_block_ptr, entries);
565 : :
566 : 0 : tcam_info->tcam_dynamic_info.dynamic_block_cnt++;
567 : :
568 : 0 : return dynamic_block_ptr;
569 : : }
570 : :
571 : : static void
572 : 0 : hinic3_free_dynamic_block_resource(struct hinic3_tcam_info *tcam_info,
573 : : struct hinic3_tcam_dynamic_block *dynamic_block_ptr)
574 : : {
575 [ # # ]: 0 : if (dynamic_block_ptr == NULL)
576 : : return;
577 : :
578 : : /* Remove the incoming dynamic block from the TCAM dynamic list. */
579 [ # # ]: 0 : TAILQ_REMOVE(&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
580 : : dynamic_block_ptr, entries);
581 : 0 : rte_free(dynamic_block_ptr);
582 : :
583 : 0 : tcam_info->tcam_dynamic_info.dynamic_block_cnt--;
584 : : }
585 : :
586 : : /**
587 : : * Check whether there are free positions in the dynamic TCAM filter.
588 : : *
589 : : * @param[in] dev
590 : : * Pointer to ethernet device structure.
591 : : * @param[in] fdir_tcam_rule
592 : : * Indicate the filtering rule to be searched for.
593 : : * @param[in] tcam_info
594 : : * Ternary Content-Addressable Memory (TCAM) information.
595 : : * @param[in] tcam_filter
596 : : * Point to the TCAM filter.
597 : : * @param[out] tcam_index
598 : : * Indicate the TCAM index to be searched for.
599 : : * @result
600 : : * Pointer to the TCAM dynamic block. If the search fails, NULL is returned.
601 : : */
602 : : static struct hinic3_tcam_dynamic_block *
603 : 0 : hinic3_dynamic_lookup_tcam_filter(struct rte_eth_dev *dev,
604 : : struct hinic3_tcam_cfg_rule *fdir_tcam_rule,
605 : : struct hinic3_tcam_info *tcam_info,
606 : : struct hinic3_tcam_filter *tcam_filter,
607 : : uint16_t *tcam_index)
608 : : {
609 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
610 : 0 : uint16_t block_cnt = tcam_info->tcam_dynamic_info.dynamic_block_cnt;
611 : : struct hinic3_tcam_dynamic_block *dynamic_block_ptr = NULL;
612 : : struct hinic3_tcam_dynamic_block *tmp = NULL;
613 : 0 : uint16_t rule_nums = nic_dev->tcam_rule_nums;
614 : : int block_alloc_flag = 0;
615 : 0 : uint16_t dynamic_block_id = 0;
616 : : uint16_t index;
617 : : int err;
618 : :
619 : : /*
620 : : * Check whether the number of filtering rules reaches the maximum
621 : : * capacity of dynamic TCAM blocks.
622 : : */
623 [ # # ]: 0 : if (rule_nums >= block_cnt * HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
624 [ # # ]: 0 : if (block_cnt >= (HINIC3_TCAM_DYNAMIC_MAX_FILTERS /
625 : : HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)) {
626 : 0 : PMD_DRV_LOG(ERR,
627 : : "Dynamic tcam block is full, alloc failed!");
628 : 0 : goto failed;
629 : : }
630 : : /*
631 : : * The TCAM blocks are insufficient.
632 : : * Apply for a new TCAM block.
633 : : */
634 : 0 : err = hinic3_alloc_tcam_block(nic_dev->hwdev, &dynamic_block_id);
635 [ # # ]: 0 : if (err) {
636 : 0 : PMD_DRV_LOG(ERR,
637 : : "Fdir filter dynamic tcam alloc block failed!");
638 : 0 : goto failed;
639 : : }
640 : :
641 : : block_alloc_flag = 1;
642 : :
643 : : /* Applying for Memory. */
644 : : dynamic_block_ptr =
645 : 0 : hinic3_alloc_dynamic_block_resource(tcam_info,
646 : : dynamic_block_id);
647 [ # # ]: 0 : if (dynamic_block_ptr == NULL) {
648 : 0 : PMD_DRV_LOG(ERR, "Fdir filter dynamic alloc block memory failed!");
649 : 0 : goto block_alloc_failed;
650 : : }
651 : : }
652 : :
653 : : /*
654 : : * Find the first dynamic TCAM block that meets dynamci_index_cnt <
655 : : * HINIC3_TCAM_DYNAMIC_BLOCK_SIZE.
656 : : */
657 [ # # ]: 0 : TAILQ_FOREACH(tmp, &tcam_info->tcam_dynamic_info.tcam_dynamic_list,
658 : : entries) {
659 [ # # ]: 0 : if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
660 : : break;
661 : : }
662 : :
663 [ # # ]: 0 : if (tmp == NULL ||
664 [ # # ]: 0 : tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
665 : 0 : PMD_DRV_LOG(ERR,
666 : : "Fdir filter dynamic lookup for index failed!");
667 : 0 : goto look_up_failed;
668 : : }
669 : :
670 [ # # ]: 0 : for (index = 0; index < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE; index++) {
671 [ # # ]: 0 : if (tmp->dynamic_index[index] == 0)
672 : : break;
673 : : }
674 : :
675 : : /* Find the first free position. */
676 [ # # ]: 0 : if (index == HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
677 : 0 : PMD_DRV_LOG(ERR,
678 : : "tcam block 0x%x supports filter rules is full!",
679 : : tmp->dynamic_block_id);
680 : 0 : goto look_up_failed;
681 : : }
682 : :
683 : 0 : tcam_filter->dynamic_block_id = tmp->dynamic_block_id;
684 : 0 : tcam_filter->index = index;
685 : 0 : *tcam_index = index;
686 : :
687 : 0 : fdir_tcam_rule->index =
688 : 0 : HINIC3_PKT_TCAM_DYNAMIC_INDEX_START(tmp->dynamic_block_id) +
689 : : index;
690 : :
691 : 0 : return tmp;
692 : :
693 : 0 : look_up_failed:
694 [ # # ]: 0 : if (dynamic_block_ptr != NULL)
695 : 0 : hinic3_free_dynamic_block_resource(tcam_info, dynamic_block_ptr);
696 : :
697 : 0 : block_alloc_failed:
698 [ # # ]: 0 : if (block_alloc_flag == 1)
699 : 0 : hinic3_free_tcam_block(nic_dev->hwdev, &dynamic_block_id);
700 : :
701 : 0 : failed:
702 : : return NULL;
703 : : }
704 : :
705 : : /**
706 : : * Add a TCAM filter.
707 : : *
708 : : * @param[in] dev
709 : : * Pointer to ethernet device structure.
710 : : * @param[in] tcam_key
711 : : * Pointer to the TCAM key.
712 : : * @param[in] fdir_tcam_rule
713 : : * Pointer to the TCAM filtering rule.
714 : : * @return
715 : : * 0 on success, non-zero on failure.
716 : : */
717 : : static int
718 : 0 : hinic3_add_tcam_filter(struct rte_eth_dev *dev,
719 : : struct hinic3_tcam_key *tcam_key,
720 : : struct hinic3_tcam_cfg_rule *fdir_tcam_rule)
721 : : {
722 : 0 : struct hinic3_tcam_info *tcam_info =
723 : 0 : HINIC3_DEV_PRIVATE_TO_TCAM_INFO(dev->data->dev_private);
724 : : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
725 : : struct hinic3_tcam_dynamic_block *dynamic_block_ptr = NULL;
726 : : struct hinic3_tcam_dynamic_block *tmp = NULL;
727 : : struct hinic3_tcam_filter *tcam_filter;
728 : 0 : uint16_t tcam_block_index = 0;
729 : 0 : uint16_t index = 0;
730 : : int err;
731 : :
732 : : /* Alloc TCAM filter memory. */
733 : 0 : tcam_filter = rte_zmalloc("hinic3_fdir_filter",
734 : : sizeof(struct hinic3_tcam_filter), 0);
735 [ # # ]: 0 : if (tcam_filter == NULL)
736 : : return -ENOMEM;
737 : :
738 : 0 : tcam_filter->tcam_key = *tcam_key;
739 : 0 : tcam_filter->queue = (uint16_t)(fdir_tcam_rule->data.qid);
740 : :
741 : : /* Add new TCAM rules. */
742 [ # # ]: 0 : if (nic_dev->tcam_rule_nums == 0) {
743 : 0 : err = hinic3_alloc_tcam_block(nic_dev->hwdev, &tcam_block_index);
744 [ # # ]: 0 : if (err) {
745 : 0 : PMD_DRV_LOG(ERR,
746 : : "Fdir filter tcam alloc block failed!");
747 : 0 : goto failed;
748 : : }
749 : :
750 : : dynamic_block_ptr =
751 : 0 : hinic3_alloc_dynamic_block_resource(tcam_info,
752 : : tcam_block_index);
753 [ # # ]: 0 : if (dynamic_block_ptr == NULL) {
754 : 0 : PMD_DRV_LOG(ERR, "Fdir filter alloc dynamic first block memory failed!");
755 : 0 : goto alloc_block_failed;
756 : : }
757 : : }
758 : :
759 : : /*
760 : : * Look for an available index in the dynamic block to store the new
761 : : * TCAM filter.
762 : : */
763 : 0 : tmp = hinic3_dynamic_lookup_tcam_filter(dev, fdir_tcam_rule, tcam_info,
764 : : tcam_filter, &index);
765 [ # # ]: 0 : if (tmp == NULL) {
766 : 0 : PMD_DRV_LOG(ERR, "Dynamic lookup tcam filter failed!");
767 : 0 : goto lookup_tcam_index_failed;
768 : : }
769 : :
770 : : /* Add a new TCAM rule to the network device. */
771 : 0 : err = hinic3_add_tcam_rule(nic_dev->hwdev, fdir_tcam_rule,
772 : : TCAM_RULE_FDIR_TYPE);
773 [ # # ]: 0 : if (err) {
774 : 0 : PMD_DRV_LOG(ERR, "Fdir_tcam_rule add failed!");
775 : 0 : goto add_tcam_rules_failed;
776 : : }
777 : :
778 : : /* If there are no rules, TCAM filtering is enabled. */
779 [ # # ]: 0 : if (!(nic_dev->ethertype_rule_nums + nic_dev->tcam_rule_nums)) {
780 : 0 : err = hinic3_set_fdir_tcam_rule_filter(nic_dev->hwdev, true);
781 [ # # ]: 0 : if (err)
782 : 0 : goto enable_failed;
783 : : }
784 : :
785 : : /* Add a filter to the end of the queue. */
786 : 0 : TAILQ_INSERT_TAIL(&tcam_info->tcam_list, tcam_filter, entries);
787 : :
788 : : /* Update dynamic index. */
789 : 0 : tmp->dynamic_index[index] = 1;
790 : 0 : tmp->dynamic_index_cnt++;
791 : :
792 : 0 : nic_dev->tcam_rule_nums++;
793 : :
794 : 0 : PMD_DRV_LOG(INFO,
795 : : "Add fdir tcam rule succeed, function_id: 0x%x",
796 : : hinic3_global_func_id(nic_dev->hwdev));
797 : 0 : PMD_DRV_LOG(INFO,
798 : : "tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d",
799 : : tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
800 : : fdir_tcam_rule->data.qid, nic_dev->tcam_rule_nums);
801 : 0 : return 0;
802 : :
803 : : enable_failed:
804 : 0 : hinic3_del_tcam_rule(nic_dev->hwdev,
805 : : fdir_tcam_rule->index,
806 : : TCAM_RULE_FDIR_TYPE);
807 : :
808 : 0 : add_tcam_rules_failed:
809 : 0 : lookup_tcam_index_failed:
810 [ # # # # ]: 0 : if (nic_dev->tcam_rule_nums == 0 && dynamic_block_ptr != NULL)
811 : 0 : hinic3_free_dynamic_block_resource(tcam_info,
812 : : dynamic_block_ptr);
813 : :
814 : 0 : alloc_block_failed:
815 [ # # ]: 0 : if (nic_dev->tcam_rule_nums == 0)
816 : 0 : hinic3_free_tcam_block(nic_dev->hwdev, &tcam_block_index);
817 : :
818 : 0 : failed:
819 : 0 : rte_free(tcam_filter);
820 : 0 : return -EFAULT;
821 : : }
822 : :
823 : : /**
824 : : * Delete a TCAM filter.
825 : : *
826 : : * @param[in] dev
827 : : * Pointer to ethernet device structure.
828 : : * @param[in] tcam_filter
829 : : * TCAM Filters to Delete.
830 : : * @return
831 : : * 0 on success, non-zero on failure.
832 : : */
833 : : static int
834 : 0 : hinic3_del_dynamic_tcam_filter(struct rte_eth_dev *dev,
835 : : struct hinic3_tcam_filter *tcam_filter)
836 : : {
837 : 0 : struct hinic3_tcam_info *tcam_info =
838 : 0 : HINIC3_DEV_PRIVATE_TO_TCAM_INFO(dev->data->dev_private);
839 : : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
840 : 0 : uint16_t dynamic_block_id = tcam_filter->dynamic_block_id;
841 : : struct hinic3_tcam_dynamic_block *tmp = NULL;
842 : : uint32_t index = 0;
843 : : int err;
844 : :
845 : : /* Traverse to find the block that matches the given ID. */
846 [ # # ]: 0 : TAILQ_FOREACH(tmp, &tcam_info->tcam_dynamic_info.tcam_dynamic_list,
847 : : entries) {
848 [ # # ]: 0 : if (tmp->dynamic_block_id == dynamic_block_id)
849 : : break;
850 : : }
851 : :
852 [ # # # # ]: 0 : if (tmp == NULL || tmp->dynamic_block_id != dynamic_block_id) {
853 : 0 : PMD_DRV_LOG(ERR,
854 : : "Fdir filter del dynamic lookup for block failed!");
855 : 0 : return -EINVAL;
856 : : }
857 : : /* Calculate TCAM index. */
858 : 0 : index = HINIC3_PKT_TCAM_DYNAMIC_INDEX_START(tmp->dynamic_block_id) +
859 : 0 : tcam_filter->index;
860 : :
861 : : /* Delete a specified rule. */
862 : 0 : err = hinic3_del_tcam_rule(nic_dev->hwdev, index, TCAM_RULE_FDIR_TYPE);
863 [ # # ]: 0 : if (err) {
864 : 0 : PMD_DRV_LOG(ERR, "Fdir tcam rule del failed!");
865 : 0 : return -EFAULT;
866 : : }
867 : :
868 : 0 : PMD_DRV_LOG(INFO,
869 : : "Del fdir_tcam_dynamic_rule succeed, function_id: 0x%x",
870 : : hinic3_global_func_id(nic_dev->hwdev));
871 : 0 : PMD_DRV_LOG(INFO,
872 : : "tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d",
873 : : dynamic_block_id, tcam_filter->index, index,
874 : : tmp->dynamic_index_cnt - 1, nic_dev->tcam_rule_nums - 1);
875 : :
876 : 0 : tmp->dynamic_index[tcam_filter->index] = 0;
877 : 0 : tmp->dynamic_index_cnt--;
878 : 0 : nic_dev->tcam_rule_nums--;
879 [ # # ]: 0 : if (tmp->dynamic_index_cnt == 0) {
880 : 0 : hinic3_free_tcam_block(nic_dev->hwdev, &dynamic_block_id);
881 : :
882 : 0 : hinic3_free_dynamic_block_resource(tcam_info, tmp);
883 : : }
884 : :
885 : : /* If the number of rules is 0, the TCAM filter is disabled. */
886 [ # # ]: 0 : if (!(nic_dev->ethertype_rule_nums + nic_dev->tcam_rule_nums))
887 : 0 : hinic3_set_fdir_tcam_rule_filter(nic_dev->hwdev, false);
888 : :
889 : : return 0;
890 : : }
891 : :
892 : : static int
893 : 0 : hinic3_del_tcam_filter(struct rte_eth_dev *dev,
894 : : struct hinic3_tcam_filter *tcam_filter)
895 : : {
896 : : struct hinic3_tcam_info *tcam_info =
897 : 0 : HINIC3_DEV_PRIVATE_TO_TCAM_INFO(dev->data->dev_private);
898 : : int err;
899 : :
900 : 0 : err = hinic3_del_dynamic_tcam_filter(dev, tcam_filter);
901 [ # # ]: 0 : if (err < 0) {
902 : 0 : PMD_DRV_LOG(ERR, "Del dynamic tcam filter failed!");
903 : 0 : return err;
904 : : }
905 : :
906 : : /* Remove the filter from the TCAM list. */
907 [ # # ]: 0 : TAILQ_REMOVE(&tcam_info->tcam_list, tcam_filter, entries);
908 : :
909 : 0 : rte_free(tcam_filter);
910 : :
911 : 0 : return 0;
912 : : }
913 : :
914 : : /**
915 : : * Add or deletes an fdir filter rule. This is the core function for operating
916 : : * filters.
917 : : *
918 : : * @param[in] dev
919 : : * Pointer to ethernet device structure.
920 : : * @param[in] fdir_filter
921 : : * Pointer to the fdir filter.
922 : : * @param[in] add
923 : : * This is a Boolean value (of the bool type) indicating whether the action to
924 : : * be performed is to add (true) or delete (false) the filter rule.
925 : : * @return
926 : : * 0 on success, non-zero on failure.
927 : : */
928 : : int
929 : 0 : hinic3_flow_add_del_fdir_filter(struct rte_eth_dev *dev,
930 : : struct hinic3_fdir_filter *fdir_filter,
931 : : bool add)
932 : : {
933 : : struct hinic3_tcam_info *tcam_info =
934 : 0 : HINIC3_DEV_PRIVATE_TO_TCAM_INFO(dev->data->dev_private);
935 : : struct hinic3_tcam_filter *tcam_filter;
936 : : struct hinic3_tcam_cfg_rule fdir_tcam_rule;
937 : : struct hinic3_tcam_key tcam_key;
938 : : int ret;
939 : :
940 : : memset(&fdir_tcam_rule, 0, sizeof(struct hinic3_tcam_cfg_rule));
941 : : memset((void *)&tcam_key, 0, sizeof(struct hinic3_tcam_key));
942 : :
943 : 0 : hinic3_fdir_tcam_info_init(dev, fdir_filter, &tcam_key,
944 : : &fdir_tcam_rule);
945 : : /* Search for a filter. */
946 : : tcam_filter =
947 : : hinic3_tcam_filter_lookup(&tcam_info->tcam_list, &tcam_key);
948 [ # # ]: 0 : if (tcam_filter != NULL && add) {
949 : 0 : PMD_DRV_LOG(ERR, "Filter exists.");
950 : 0 : return -EEXIST;
951 : : }
952 [ # # ]: 0 : if (tcam_filter == NULL && !add) {
953 : 0 : PMD_DRV_LOG(ERR, "Filter doesn't exist.");
954 : 0 : return -ENOENT;
955 : : }
956 : :
957 : : /*
958 : : * If the value of Add is true, the system performs the adding
959 : : * operation.
960 : : */
961 [ # # ]: 0 : if (add) {
962 : 0 : ret = hinic3_add_tcam_filter(dev, &tcam_key, &fdir_tcam_rule);
963 [ # # ]: 0 : if (ret)
964 : 0 : goto cfg_tcam_filter_err;
965 : :
966 : 0 : fdir_filter->tcam_index = (int)(fdir_tcam_rule.index);
967 : : } else {
968 : 0 : PMD_DRV_LOG(INFO, "begin to del tcam filter");
969 : 0 : ret = hinic3_del_tcam_filter(dev, tcam_filter);
970 [ # # ]: 0 : if (ret)
971 : 0 : goto cfg_tcam_filter_err;
972 : : }
973 : :
974 : : return 0;
975 : :
976 : : cfg_tcam_filter_err:
977 : :
978 : : return ret;
979 : : }
980 : :
981 : : /**
982 : : * Enable or disable the TCAM filter for the receive queue.
983 : : *
984 : : * @param[in] dev
985 : : * Pointer to ethernet device structure.
986 : : * @param[in] able
987 : : * Flag to enable or disable the filter.
988 : : * @return
989 : : * 0 on success, non-zero on failure.
990 : : */
991 : : int
992 : 0 : hinic3_enable_rxq_fdir_filter(struct rte_eth_dev *dev, uint32_t queue_id, uint32_t able)
993 : : {
994 : : struct hinic3_tcam_info *tcam_info =
995 [ # # ]: 0 : HINIC3_DEV_PRIVATE_TO_TCAM_INFO(dev->data->dev_private);
996 : : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
997 : : struct hinic3_tcam_filter *it;
998 : : struct hinic3_tcam_cfg_rule fdir_tcam_rule;
999 : : int ret;
1000 : : uint32_t queue_res;
1001 : : uint16_t index;
1002 : :
1003 : : memset(&fdir_tcam_rule, 0, sizeof(struct hinic3_tcam_cfg_rule));
1004 : :
1005 [ # # ]: 0 : if (able) {
1006 [ # # ]: 0 : TAILQ_FOREACH(it, &tcam_info->tcam_list, entries) {
1007 [ # # ]: 0 : if (queue_id == it->queue) {
1008 : 0 : index = (uint16_t)(HINIC3_PKT_TCAM_DYNAMIC_INDEX_START
1009 : 0 : (it->dynamic_block_id) + it->index);
1010 : :
1011 : : /*
1012 : : * When the rxq is start, find invalid rxq_id
1013 : : * and delete the fdir rule from the tcam.
1014 : : */
1015 : 0 : ret = hinic3_del_tcam_rule(nic_dev->hwdev,
1016 : : index,
1017 : : TCAM_RULE_FDIR_TYPE);
1018 [ # # ]: 0 : if (ret) {
1019 : 0 : PMD_DRV_LOG(ERR, "del invalid tcam rule failed!");
1020 : 0 : return -EFAULT;
1021 : : }
1022 : :
1023 : 0 : fdir_tcam_rule.index = index;
1024 : 0 : fdir_tcam_rule.data.qid = queue_id;
1025 : 0 : tcam_key_calculate(&it->tcam_key,
1026 : : &fdir_tcam_rule);
1027 : :
1028 : : /* To enable a rule, add a rule. */
1029 : 0 : ret = hinic3_add_tcam_rule(nic_dev->hwdev,
1030 : : &fdir_tcam_rule,
1031 : : TCAM_RULE_FDIR_TYPE);
1032 [ # # ]: 0 : if (ret) {
1033 : 0 : PMD_DRV_LOG(ERR, "add correct tcam rule failed!");
1034 : 0 : return -EFAULT;
1035 : : }
1036 : : }
1037 : : }
1038 : : } else {
1039 : 0 : queue_res = HINIC3_INVALID_QID_BASE | queue_id;
1040 : :
1041 [ # # ]: 0 : TAILQ_FOREACH(it, &tcam_info->tcam_list, entries) {
1042 [ # # ]: 0 : if (queue_id == it->queue) {
1043 : 0 : index = (uint16_t)(HINIC3_PKT_TCAM_DYNAMIC_INDEX_START
1044 : 0 : (it->dynamic_block_id) + it->index);
1045 : :
1046 : : /*
1047 : : * When the rxq is stop, delete the fdir rule
1048 : : * from the tcam and add the correct fdir rule
1049 : : * from the tcam.
1050 : : */
1051 : 0 : ret = hinic3_del_tcam_rule(nic_dev->hwdev,
1052 : : index,
1053 : : TCAM_RULE_FDIR_TYPE);
1054 [ # # ]: 0 : if (ret) {
1055 : 0 : PMD_DRV_LOG(ERR, "del correct tcam rule failed!");
1056 : 0 : return -EFAULT;
1057 : : }
1058 : :
1059 : 0 : fdir_tcam_rule.index = index;
1060 : 0 : fdir_tcam_rule.data.qid = queue_res;
1061 : 0 : tcam_key_calculate(&it->tcam_key,
1062 : : &fdir_tcam_rule);
1063 : :
1064 : : /* Add the correct fdir rule from the tcam. */
1065 : 0 : ret = hinic3_add_tcam_rule(nic_dev->hwdev,
1066 : : &fdir_tcam_rule,
1067 : : TCAM_RULE_FDIR_TYPE);
1068 [ # # ]: 0 : if (ret) {
1069 : 0 : PMD_DRV_LOG(ERR, "add invalid tcam rule failed!");
1070 : 0 : return -EFAULT;
1071 : : }
1072 : : }
1073 : : }
1074 : : }
1075 : :
1076 : : return ret;
1077 : : }
1078 : :
1079 : : void
1080 : 0 : hinic3_free_fdir_filter(struct rte_eth_dev *dev)
1081 : : {
1082 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1083 : :
1084 : 0 : hinic3_set_fdir_tcam_rule_filter(nic_dev->hwdev, false);
1085 : :
1086 : 0 : hinic3_flush_tcam_rule(nic_dev->hwdev);
1087 : 0 : }
1088 : :
1089 : : static int
1090 : 0 : hinic3_flow_set_arp_filter(struct rte_eth_dev *dev,
1091 : : struct rte_eth_ethertype_filter *ethertype_filter,
1092 : : bool add)
1093 : : {
1094 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1095 : : int ret;
1096 : :
1097 : : /* Setting the ARP Filter. */
1098 : 0 : ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1099 : : HINIC3_PKT_TYPE_ARP,
1100 : 0 : ethertype_filter->queue, add);
1101 [ # # ]: 0 : if (ret) {
1102 [ # # ]: 0 : PMD_DRV_LOG(ERR, "%s fdir ethertype rule failed, err: %d",
1103 : : add ? "Add" : "Del", ret);
1104 : 0 : return ret;
1105 : : }
1106 : :
1107 : : /* Setting the ARP Request Filter. */
1108 : 0 : ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1109 : : HINIC3_PKT_TYPE_ARP_REQ,
1110 : 0 : ethertype_filter->queue, add);
1111 [ # # ]: 0 : if (ret) {
1112 [ # # ]: 0 : PMD_DRV_LOG(ERR, "%s arp request rule failed, err: %d",
1113 : : add ? "Add" : "Del", ret);
1114 : 0 : goto set_arp_req_failed;
1115 : : }
1116 : :
1117 : : /* Setting the ARP Response Filter. */
1118 : 0 : ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1119 : : HINIC3_PKT_TYPE_ARP_REP,
1120 : 0 : ethertype_filter->queue, add);
1121 [ # # ]: 0 : if (ret) {
1122 [ # # ]: 0 : PMD_DRV_LOG(ERR, "%s arp response rule failed, err: %d",
1123 : : add ? "Add" : "Del", ret);
1124 : 0 : goto set_arp_rep_failed;
1125 : : }
1126 : :
1127 : : return 0;
1128 : :
1129 : : set_arp_rep_failed:
1130 : 0 : hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1131 : : HINIC3_PKT_TYPE_ARP_REQ,
1132 : 0 : ethertype_filter->queue, !add);
1133 : :
1134 : 0 : set_arp_req_failed:
1135 : 0 : hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1136 : : HINIC3_PKT_TYPE_ARP,
1137 : 0 : ethertype_filter->queue, !add);
1138 : :
1139 : 0 : return ret;
1140 : : }
1141 : :
1142 : : static int
1143 : 0 : hinic3_flow_set_slow_filter(struct rte_eth_dev *dev,
1144 : : struct rte_eth_ethertype_filter *ethertype_filter,
1145 : : bool add)
1146 : : {
1147 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1148 : : int ret;
1149 : :
1150 : : /* Setting the LACP Filter. */
1151 : 0 : ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1152 : : HINIC3_PKT_TYPE_LACP,
1153 : 0 : ethertype_filter->queue, add);
1154 [ # # ]: 0 : if (ret) {
1155 [ # # ]: 0 : PMD_DRV_LOG(ERR, "%s lacp fdir rule failed, err: %d",
1156 : : add ? "Add" : "Del", ret);
1157 : 0 : return ret;
1158 : : }
1159 : :
1160 : : /* Setting the OAM Filter. */
1161 : 0 : ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1162 : : HINIC3_PKT_TYPE_OAM,
1163 : 0 : ethertype_filter->queue, add);
1164 [ # # ]: 0 : if (ret) {
1165 [ # # ]: 0 : PMD_DRV_LOG(ERR, "%s oam rule failed, err: %d",
1166 : : add ? "Add" : "Del", ret);
1167 : 0 : goto set_arp_oam_failed;
1168 : : }
1169 : :
1170 : : return 0;
1171 : :
1172 : : set_arp_oam_failed:
1173 : 0 : hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1174 : : HINIC3_PKT_TYPE_LACP,
1175 : 0 : ethertype_filter->queue, !add);
1176 : :
1177 : 0 : return ret;
1178 : : }
1179 : :
1180 : : static int
1181 : 0 : hinic3_flow_set_lldp_filter(struct rte_eth_dev *dev,
1182 : : struct rte_eth_ethertype_filter *ethertype_filter,
1183 : : bool add)
1184 : : {
1185 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1186 : : int ret;
1187 : :
1188 : : /* Setting the LLDP Filter. */
1189 : 0 : ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1190 : : HINIC3_PKT_TYPE_LLDP,
1191 : 0 : ethertype_filter->queue, add);
1192 [ # # ]: 0 : if (ret) {
1193 [ # # ]: 0 : PMD_DRV_LOG(ERR, "%s lldp fdir rule failed, err: %d",
1194 : : add ? "Add" : "Del", ret);
1195 : 0 : return ret;
1196 : : }
1197 : :
1198 : : /* Setting the CDCP Filter. */
1199 : 0 : ret = hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1200 : : HINIC3_PKT_TYPE_CDCP,
1201 : 0 : ethertype_filter->queue, add);
1202 [ # # ]: 0 : if (ret) {
1203 [ # # ]: 0 : PMD_DRV_LOG(ERR, "%s cdcp fdir rule failed, err: %d",
1204 : : add ? "Add" : "Del", ret);
1205 : 0 : goto set_arp_cdcp_failed;
1206 : : }
1207 : :
1208 : : return 0;
1209 : :
1210 : : set_arp_cdcp_failed:
1211 : 0 : hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1212 : : HINIC3_PKT_TYPE_LLDP,
1213 : 0 : ethertype_filter->queue, !add);
1214 : :
1215 : 0 : return ret;
1216 : : }
1217 : :
1218 : : static int
1219 : 0 : hinic3_flow_add_del_ethertype_filter_rule(struct rte_eth_dev *dev,
1220 : : struct rte_eth_ethertype_filter *ethertype_filter,
1221 : : bool add)
1222 : : {
1223 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1224 : : struct hinic3_ethertype_filter_list *ethertype_list =
1225 : : &nic_dev->filter_ethertype_list;
1226 : :
1227 : : /* Check whether the transferred rule exists. */
1228 [ # # ]: 0 : if (hinic3_ethertype_filter_lookup(ethertype_list,
1229 : 0 : ethertype_filter->ether_type)) {
1230 [ # # ]: 0 : if (add) {
1231 : 0 : PMD_DRV_LOG(ERR,
1232 : : "The rule already exists, can not to be added");
1233 : 0 : return -EPERM;
1234 : : }
1235 : : } else {
1236 [ # # ]: 0 : if (!add) {
1237 : 0 : PMD_DRV_LOG(ERR,
1238 : : "The rule not exists, can not to be delete");
1239 : 0 : return -EPERM;
1240 : : }
1241 : : }
1242 : : /* Create a filter based on the protocol type. */
1243 [ # # # # : 0 : switch (ethertype_filter->ether_type) {
# # # ]
1244 : 0 : case RTE_ETHER_TYPE_ARP:
1245 : 0 : return hinic3_flow_set_arp_filter(dev, ethertype_filter, add);
1246 : 0 : case RTE_ETHER_TYPE_RARP:
1247 : 0 : return hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1248 : 0 : HINIC3_PKT_TYPE_RARP, ethertype_filter->queue, add);
1249 : :
1250 : 0 : case RTE_ETHER_TYPE_SLOW:
1251 : 0 : return hinic3_flow_set_slow_filter(dev, ethertype_filter, add);
1252 : :
1253 : 0 : case RTE_ETHER_TYPE_LLDP:
1254 : 0 : return hinic3_flow_set_lldp_filter(dev, ethertype_filter, add);
1255 : :
1256 : 0 : case RTE_ETHER_TYPE_CNM:
1257 : 0 : return hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1258 : 0 : HINIC3_PKT_TYPE_CNM, ethertype_filter->queue, add);
1259 : :
1260 : 0 : case RTE_ETHER_TYPE_ECP:
1261 : 0 : return hinic3_set_fdir_ethertype_filter(nic_dev->hwdev,
1262 : 0 : HINIC3_PKT_TYPE_ECP, ethertype_filter->queue, add);
1263 : :
1264 : 0 : default:
1265 : 0 : PMD_DRV_LOG(ERR, "Unknown ethertype %d queue_id %d",
1266 : : ethertype_filter->ether_type,
1267 : : ethertype_filter->queue);
1268 : 0 : return -EPERM;
1269 : : }
1270 : : }
1271 : :
1272 : : static int
1273 : 0 : hinic3_flow_ethertype_rule_nums(struct rte_eth_ethertype_filter *ethertype_filter)
1274 : : {
1275 [ # # # # : 0 : switch (ethertype_filter->ether_type) {
# # # ]
1276 : : case RTE_ETHER_TYPE_ARP:
1277 : : return HINIC3_ARP_RULE_NUM;
1278 : 0 : case RTE_ETHER_TYPE_RARP:
1279 : 0 : return HINIC3_RARP_RULE_NUM;
1280 : 0 : case RTE_ETHER_TYPE_SLOW:
1281 : 0 : return HINIC3_SLOW_RULE_NUM;
1282 : 0 : case RTE_ETHER_TYPE_LLDP:
1283 : 0 : return HINIC3_LLDP_RULE_NUM;
1284 : 0 : case RTE_ETHER_TYPE_CNM:
1285 : 0 : return HINIC3_CNM_RULE_NUM;
1286 : 0 : case RTE_ETHER_TYPE_ECP:
1287 : 0 : return HINIC3_ECP_RULE_NUM;
1288 : :
1289 : 0 : default:
1290 : 0 : PMD_DRV_LOG(ERR, "Unknown ethertype %d",
1291 : : ethertype_filter->ether_type);
1292 : 0 : return 0;
1293 : : }
1294 : : }
1295 : :
1296 : : /**
1297 : : * Add or delete an Ethernet type filter rule.
1298 : : *
1299 : : * @param[in] dev
1300 : : * Pointer to ethernet device structure.
1301 : : * @param[in] ethertype_filter
1302 : : * Pointer to ethertype filter.
1303 : : * @param[in] add
1304 : : * This is a Boolean value (of the bool type) indicating whether the action to
1305 : : * be performed is to add (true) or delete (false) the Ethernet type filter
1306 : : * rule.
1307 : : * @return
1308 : : * 0 on success, non-zero on failure.
1309 : : */
1310 : : int
1311 : 0 : hinic3_flow_add_del_ethertype_filter(struct rte_eth_dev *dev,
1312 : : struct rte_eth_ethertype_filter *ethertype_filter,
1313 : : bool add)
1314 : : {
1315 : : /* Get dev private info. */
1316 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1317 : : int ret;
1318 : : /* Add or remove an Ethernet type filter rule. */
1319 : 0 : ret = hinic3_flow_add_del_ethertype_filter_rule(dev, ethertype_filter, add);
1320 : :
1321 [ # # ]: 0 : if (ret) {
1322 [ # # ]: 0 : PMD_DRV_LOG(ERR, "%s fdir ethertype rule failed, err: %d",
1323 : : add ? "Add" : "Del", ret);
1324 : 0 : return ret;
1325 : : }
1326 : : /*
1327 : : * If a rule is added and the rule is the first rule, rule filtering is
1328 : : * enabled. If a rule is deleted and the rule is the last one, rule
1329 : : * filtering is disabled.
1330 : : */
1331 [ # # ]: 0 : if (add) {
1332 [ # # ]: 0 : if (nic_dev->ethertype_rule_nums == 0) {
1333 : 0 : ret = hinic3_set_fdir_tcam_rule_filter(nic_dev->hwdev, true);
1334 [ # # ]: 0 : if (ret) {
1335 : 0 : PMD_DRV_LOG(ERR,
1336 : : "enable fdir rule failed, err: %d",
1337 : : ret);
1338 : 0 : goto enable_fdir_failed;
1339 : : }
1340 : : }
1341 : 0 : nic_dev->ethertype_rule_nums =
1342 : 0 : nic_dev->ethertype_rule_nums +
1343 : 0 : hinic3_flow_ethertype_rule_nums(ethertype_filter);
1344 : : } else {
1345 : 0 : nic_dev->ethertype_rule_nums =
1346 : 0 : nic_dev->ethertype_rule_nums -
1347 : 0 : hinic3_flow_ethertype_rule_nums(ethertype_filter);
1348 : :
1349 [ # # ]: 0 : if (!(nic_dev->ethertype_rule_nums + nic_dev->tcam_rule_nums)) {
1350 : 0 : ret = hinic3_set_fdir_tcam_rule_filter(nic_dev->hwdev, false);
1351 [ # # ]: 0 : if (ret) {
1352 : 0 : PMD_DRV_LOG(ERR,
1353 : : "disable fdir rule failed, err: %d",
1354 : : ret);
1355 : : }
1356 : : }
1357 : : }
1358 : :
1359 : : return 0;
1360 : :
1361 : : enable_fdir_failed:
1362 : 0 : hinic3_flow_add_del_ethertype_filter_rule(dev, ethertype_filter, !add);
1363 : 0 : return ret;
1364 : : }
|