Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
3 : : */
4 : :
5 : : #include <sys/queue.h>
6 : : #include <unistd.h>
7 : : #include "sxe2_ethdev.h"
8 : : #include "sxe2_flow.h"
9 : : #include "sxe2_flow_parse_pattern.h"
10 : : #include "sxe2_flow_parse_action.h"
11 : : #include "sxe2_flow_parse_engine.h"
12 : : #include "sxe2_cmd_chnl.h"
13 : : #include "sxe2_flow_public.h"
14 : : #include "sxe2_common_log.h"
15 : :
16 : 0 : static int32_t sxe2_check_para(const struct rte_flow_attr *attr,
17 : : const struct rte_flow_item pattern[],
18 : : const struct rte_flow_action actions[],
19 : : struct rte_flow_error *error)
20 : : {
21 : 0 : int32_t ret = 0;
22 [ # # ]: 0 : if (!pattern) {
23 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
24 : : NULL, "NULL pattern.");
25 : 0 : ret = -rte_errno;
26 : 0 : goto l_end;
27 : : }
28 : :
29 [ # # ]: 0 : if (!actions) {
30 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
31 : : NULL, "NULL action.");
32 : 0 : ret = -rte_errno;
33 : 0 : goto l_end;
34 : : }
35 : :
36 [ # # ]: 0 : if (!attr) {
37 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR,
38 : : NULL, "NULL attribute.");
39 : 0 : ret = -rte_errno;
40 : 0 : goto l_end;
41 : : }
42 : :
43 : 0 : l_end:
44 : 0 : return ret;
45 : : }
46 : :
47 : 0 : static int32_t sxe2_flow_valid_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error)
48 : : {
49 : 0 : int32_t ret = 0;
50 : :
51 [ # # ]: 0 : if (!attr->ingress) {
52 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
53 : : attr, "Only support ingress.");
54 : 0 : ret = -rte_errno;
55 : 0 : goto l_end;
56 : : }
57 : :
58 [ # # ]: 0 : if (attr->egress) {
59 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
60 : : attr, "Not support egress.");
61 : 0 : ret = -rte_errno;
62 : 0 : goto l_end;
63 : : }
64 : :
65 [ # # ]: 0 : if (attr->group >= 4) {
66 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
67 : : attr, "Not support group >= 4.");
68 : 0 : ret = -rte_errno;
69 : 0 : goto l_end;
70 : : }
71 : 0 : l_end:
72 : 0 : return ret;
73 : : }
74 : :
75 : 0 : static int32_t sxe2_flow_check_hdr_duplicate(struct sxe2_flow_item *item_new,
76 : : struct sxe2_flow_item *item_exist)
77 : : {
78 : 0 : int32_t ret = 0;
79 : 0 : uint16_t i = 0;
80 : 0 : uint16_t size = sizeof(struct sxe2_flow_item);
81 : 0 : union sxe2_flow_item_raw item_raw_new;
82 : 0 : union sxe2_flow_item_raw item_raw_exist;
83 [ # # ]: 0 : rte_memcpy(&item_raw_new.item, item_new, size);
84 [ # # ]: 0 : rte_memcpy(&item_raw_exist.item, item_exist, size);
85 : :
86 [ # # ]: 0 : for (i = 0; i < size; i++) {
87 [ # # ]: 0 : if (item_raw_new.raw[i] != item_raw_exist.raw[i])
88 : 0 : goto l_end;
89 : : }
90 : : ret = -EEXIST;
91 : 0 : l_end:
92 : 0 : return ret;
93 : : }
94 : :
95 : 0 : static int32_t sxe2_flow_check_flow_duplicate(struct sxe2_flow *flow_new,
96 : : struct sxe2_flow *flow_exist)
97 : : {
98 : 0 : int32_t ret = 0;
99 : 0 : int32_t ret_mask1 = 0;
100 : 0 : int32_t ret_mask2 = 0;
101 : 0 : int32_t ret_spec1 = 0;
102 : 0 : int32_t ret_spec2 = 0;
103 : :
104 [ # # ]: 0 : if (flow_new->engine_type != flow_exist->engine_type)
105 : 0 : goto l_end;
106 [ # # ]: 0 : if (flow_new->meta.flow_type != flow_exist->meta.flow_type)
107 : 0 : goto l_end;
108 [ # # ]: 0 : if (!sxe2_bitmap_equal(flow_new->flow_type, flow_exist->flow_type,
109 : : SXE2_EXPANSION_MAX))
110 : 0 : goto l_end;
111 [ # # ]: 0 : if (flow_new->meta.flow_prio != flow_exist->meta.flow_prio)
112 : 0 : goto l_end;
113 : :
114 : 0 : ret_mask1 = sxe2_flow_check_hdr_duplicate(&flow_new->pattern_outer.item_mask,
115 : : &flow_exist->pattern_outer.item_mask);
116 : 0 : ret_mask2 = sxe2_flow_check_hdr_duplicate(&flow_new->pattern_inner.item_mask,
117 : : &flow_exist->pattern_inner.item_mask);
118 : :
119 : 0 : ret_spec1 = sxe2_flow_check_hdr_duplicate(&flow_new->pattern_outer.item_spec,
120 : : &flow_exist->pattern_outer.item_spec);
121 : 0 : ret_spec2 = sxe2_flow_check_hdr_duplicate(&flow_new->pattern_inner.item_spec,
122 : : &flow_exist->pattern_inner.item_spec);
123 : :
124 [ # # ]: 0 : if (flow_new->engine_type == SXE2_FLOW_ENGINE_FNAV) {
125 [ # # ]: 0 : if (ret_mask1 == 0 || ret_mask2 == 0) {
126 : 0 : ret = -EEXIST;
127 : 0 : goto l_end;
128 : : }
129 : :
130 [ # # ]: 0 : if (ret_spec1 == -EEXIST && ret_spec2 == -EEXIST) {
131 : 0 : ret = -EEXIST;
132 : 0 : goto l_end;
133 : : }
134 : : } else {
135 [ # # ]: 0 : if (ret_mask1 == -EEXIST && ret_mask2 == -EEXIST &&
136 [ # # ]: 0 : ret_spec1 == -EEXIST && ret_spec2 == -EEXIST) {
137 : 0 : ret = -EEXIST;
138 : 0 : goto l_end;
139 : : }
140 : : }
141 : :
142 : 0 : l_end:
143 : 0 : return ret;
144 : : }
145 : :
146 : 0 : static int32_t sxe2_flow_check_flow_list_duplicate(struct rte_eth_dev *dev,
147 : : struct rte_flow *flow_list)
148 : : {
149 : 0 : int32_t ret = 0;
150 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
151 : 0 : struct sxe2_flow *sxe2_flow_new = NULL;
152 : 0 : struct rte_flow *rte_flow_exist = NULL;
153 : 0 : struct sxe2_flow *sxe2_flow_exist = NULL;
154 [ # # ]: 0 : TAILQ_FOREACH(sxe2_flow_new, &flow_list->sxe2_flow_list, next) {
155 [ # # ]: 0 : TAILQ_FOREACH(rte_flow_exist, &adapter->flow_ctxt.rte_flow_list, next) {
156 [ # # ]: 0 : TAILQ_FOREACH(sxe2_flow_exist, &rte_flow_exist->sxe2_flow_list, next) {
157 : 0 : ret = sxe2_flow_check_flow_duplicate(sxe2_flow_new,
158 : : sxe2_flow_exist);
159 [ # # ]: 0 : if (ret != 0)
160 : 0 : goto l_end;
161 : : }
162 : : }
163 : : }
164 : 0 : l_end:
165 : 0 : return ret;
166 : : }
167 : :
168 : 0 : static int32_t sxe2_flow_check_function(struct rte_eth_dev *dev,
169 : : struct rte_flow *flow_list,
170 : : struct rte_flow_error *error)
171 : : {
172 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
173 : 0 : struct sxe2_flow_list_t *sxe2_flow_list = &flow_list->sxe2_flow_list;
174 : 0 : struct sxe2_flow *flow = TAILQ_FIRST(sxe2_flow_list);
175 : 0 : int32_t ret = 0;
176 : :
177 : 0 : uint16_t flow_dst_vsi = UINT16_MAX;
178 : :
179 [ # # ]: 0 : if (adapter->dev_type == SXE2_DEV_T_VF) {
180 [ # # ]: 0 : if (sxe2_test_bit(SXE2_FLOW_ACTION_TO_VSI, flow->action.act_types)) {
181 : 0 : flow_dst_vsi = flow->action.vsi.vsi_index;
182 : :
183 [ # # ]: 0 : if (adapter->vsi_ctxt.dpdk_vsi_id != flow_dst_vsi &&
184 [ # # ]: 0 : adapter->vsi_ctxt.kernel_vsi_id != flow_dst_vsi) {
185 : 0 : PMD_LOG_ERR(DRV, "Failed to redirect other function");
186 : 0 : rte_flow_error_set(error, ENOTSUP,
187 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
188 : : "Failed to redirect other function");
189 : 0 : ret = -ENOTSUP;
190 : 0 : goto l_end;
191 : : }
192 : : }
193 : :
194 [ # # ]: 0 : if (sxe2_test_bit(SXE2_FLOW_ACTION_TO_VSI_LIST, flow->action.act_types)) {
195 : 0 : PMD_LOG_ERR(DRV,
196 : : "Failed to redirect multiple driver or function");
197 : 0 : rte_flow_error_set(error, ENOTSUP,
198 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
199 : : "Failed to redirect multiple driver or function");
200 : 0 : ret = -ENOTSUP;
201 : 0 : goto l_end;
202 : : }
203 : :
204 [ # # ]: 0 : if (!adapter->flow_isolated &&
205 [ # # ]: 0 : flow->engine_type == SXE2_FLOW_ENGINE_SWITCH) {
206 : 0 : PMD_LOG_ERR(DRV,
207 : : "Failed to switch engine rules in a non-flow-isolated state");
208 : 0 : rte_flow_error_set(error, ENOTSUP,
209 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
210 : : "Failed to switch engine rules in a non-flow-isolated state");
211 : 0 : ret = -ENOTSUP;
212 : 0 : goto l_end;
213 : : }
214 : :
215 [ # # ]: 0 : if (adapter->switchdev_info.is_switchdev &&
216 [ # # ]: 0 : flow->engine_type == SXE2_FLOW_ENGINE_SWITCH) {
217 : 0 : PMD_LOG_ERR(DRV,
218 : : "Failed to switch engine rules in a switchdev mode state");
219 : 0 : rte_flow_error_set(error, ENOTSUP,
220 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
221 : : "Failed to switch engine rules in a switchdev mode state");
222 : 0 : ret = -ENOTSUP;
223 : 0 : goto l_end;
224 : : }
225 : : }
226 : :
227 [ # # ]: 0 : if (adapter->is_dev_repr) {
228 [ # # ]: 0 : if (flow->engine_type != SXE2_FLOW_ENGINE_SWITCH) {
229 : 0 : PMD_LOG_ERR(DRV,
230 : : "Failed to config non switch engine rules in representor dev");
231 : 0 : rte_flow_error_set(error, ENOTSUP,
232 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
233 : : "Failed to config non switch engine rules in representor dev");
234 : 0 : ret = -ENOTSUP;
235 : 0 : goto l_end;
236 : : }
237 : :
238 [ # # # # ]: 0 : if (sxe2_test_bit(SXE2_FLOW_ACTION_QUEUE, flow->action.act_types) ||
239 [ # # ]: 0 : sxe2_test_bit(SXE2_FLOW_ACTION_Q_REGION, flow->action.act_types)) {
240 : 0 : PMD_LOG_ERR(DRV,
241 : : "Failed to config queue rules in representor dev");
242 : 0 : rte_flow_error_set(error, ENOTSUP,
243 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
244 : : "Failed to config queue rules in representor dev");
245 : 0 : ret = -ENOTSUP;
246 : 0 : goto l_end;
247 : : }
248 : : }
249 : :
250 [ # # # # ]: 0 : if (adapter->switchdev_info.is_switchdev &&
251 [ # # ]: 0 : adapter->dev_type == SXE2_DEV_T_PF &&
252 : 0 : !adapter->is_dev_repr &&
253 [ # # ]: 0 : !adapter->flow_isolated) {
254 [ # # ]: 0 : if (sxe2_test_bit(SXE2_FLOW_ACTION_TO_VSI, flow->action.act_types)) {
255 [ # # ]: 0 : if (flow->action.vsi.vsi_index == adapter->vsi_ctxt.dpdk_vsi_id) {
256 : 0 : PMD_LOG_ERR(DRV,
257 : : "Failed to config rx fwd rule to current uplink dev");
258 : 0 : rte_flow_error_set(error, ENOTSUP,
259 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
260 : : "Failed to config rx fwd rule to current uplink dev");
261 : 0 : ret = -ENOTSUP;
262 : 0 : goto l_end;
263 : : }
264 : : }
265 : : }
266 : :
267 : 0 : l_end:
268 : 0 : return ret;
269 : : }
270 : :
271 : 0 : static int32_t sxe2_flow_meta_proc(struct rte_eth_dev *dev,
272 : : const struct rte_flow_attr *attr,
273 : : struct rte_flow *flow_list,
274 : : struct rte_flow_error *error)
275 : : {
276 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
277 : 0 : struct sxe2_flow_list_t *sxe2_flow_list = &flow_list->sxe2_flow_list;
278 : 0 : struct sxe2_flow *flow = TAILQ_FIRST(sxe2_flow_list);
279 : 0 : int32_t ret = 0;
280 : :
281 [ # # ]: 0 : if (attr->priority >= 1) {
282 [ # # ]: 0 : if (flow->engine_type != SXE2_FLOW_ENGINE_SWITCH) {
283 : 0 : PMD_LOG_ERR(DRV, "Only support priority 0.");
284 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
285 : : attr, "Only support priority 0.");
286 : 0 : ret = -rte_errno;
287 : 0 : goto l_end;
288 [ # # ]: 0 : } else if (!adapter->switchdev_info.is_switchdev) {
289 : 0 : PMD_LOG_ERR(DRV, "Legacy mode only support priority 0.");
290 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
291 : : attr, "Legacy mode only priority 0.");
292 : 0 : ret = -rte_errno;
293 : 0 : goto l_end;
294 : : } else {
295 : 0 : flow->meta.flow_prio = attr->priority;
296 : : }
297 : : }
298 : :
299 : 0 : flow->meta.flow_src_vsi = adapter->vsi_ctxt.dpdk_vsi_id;
300 : :
301 [ # # # # ]: 0 : if (adapter->is_dev_repr && adapter->repr_priv_data &&
302 [ # # ]: 0 : adapter->repr_priv_data->parent_adapter) {
303 : 0 : flow->meta.flow_rule_vsi =
304 : 0 : adapter->repr_priv_data->parent_adapter->vsi_ctxt.dpdk_vsi_id;
305 : : } else {
306 : 0 : flow->meta.flow_rule_vsi = adapter->vsi_ctxt.dpdk_vsi_id;
307 : : }
308 : :
309 [ # # ]: 0 : if (flow->engine_type == SXE2_FLOW_ENGINE_SWITCH) {
310 : 0 : flow->meta.switch_pattern_dup_allow =
311 : 0 : adapter->devargs.flow_dup_pattern_mode;
312 : :
313 : 0 : flow->meta.switch_src_direct = SXE2_FLOW_SW_DIRECT_RX;
314 : :
315 [ # # # # ]: 0 : if (adapter->switchdev_info.is_switchdev && adapter->is_dev_repr) {
316 : 0 : flow->meta.switch_src_direct = SXE2_FLOW_SW_DIRECT_TX;
317 : 0 : flow->meta.flow_src_vsi = adapter->repr_priv_data->repr_vf_vsi_id;
318 : : }
319 : : }
320 : :
321 : 0 : l_end:
322 : 0 : return ret;
323 : : }
324 : :
325 : 0 : static int32_t sxe2_flow_src_split_proc(struct rte_eth_dev *dev,
326 : : struct rte_flow *flow_list,
327 : : struct rte_flow_error *error)
328 : : {
329 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
330 : 0 : struct sxe2_flow_list_t *sxe2_flow_list = &flow_list->sxe2_flow_list;
331 : 0 : struct sxe2_flow *flow = TAILQ_FIRST(sxe2_flow_list);
332 : 0 : int32_t ret = 0;
333 : :
334 : 0 : int32_t idx = 0;
335 : 0 : uint8_t flow_cnt = 0;
336 : 0 : uint8_t flow_create_cnt = 0;
337 : 0 : uint8_t flow_bond_num = 1;
338 : 0 : uint16_t flow_src_vsi[SXE2_MAX_DRV_TYPE_CNT][SXE2_MAX_BOND_MEMBER_CNT];
339 : 0 : uint16_t flow_dst_vsi = UINT16_MAX;
340 : 0 : struct sxe2_flow *flow_new = NULL;
341 : :
342 [ # # ]: 0 : if (sxe2_test_bit(SXE2_FLOW_ACTION_TO_VSI, flow->action.act_types))
343 : 0 : flow_dst_vsi = flow->action.vsi.vsi_index;
344 : :
345 : 0 : for (idx = 0; idx < SXE2_MAX_BOND_MEMBER_CNT; idx++) {
346 : : flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][idx] = UINT16_MAX;
347 : : flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] = UINT16_MAX;
348 : : }
349 : :
350 : 0 : flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] = adapter->vsi_ctxt.dpdk_vsi_id;
351 : 0 : flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] = adapter->vsi_ctxt.kernel_vsi_id;
352 [ # # ]: 0 : if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV ||
353 : : flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
354 [ # # ]: 0 : if (!adapter->devargs.func_flow_direct_en &&
355 [ # # ]: 0 : adapter->dev_type != SXE2_DEV_T_PF_BOND) {
356 [ # # ]: 0 : if (adapter->flow_isolated) {
357 [ # # ]: 0 : for (idx = 0; idx < flow_bond_num; idx++) {
358 [ # # ]: 0 : if (flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] !=
359 : : UINT16_MAX)
360 : 0 : flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][idx] =
361 : : UINT16_MAX;
362 : : }
363 : : } else {
364 [ # # ]: 0 : for (idx = 0; idx < flow_bond_num; idx++)
365 : 0 : flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] = UINT16_MAX;
366 : : }
367 : : }
368 : :
369 [ # # ]: 0 : for (idx = 0; idx < flow_bond_num; idx++) {
370 [ # # ]: 0 : if (flow_dst_vsi == flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx])
371 : 0 : flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] = UINT16_MAX;
372 [ # # ]: 0 : if (flow_dst_vsi == flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][idx])
373 : 0 : flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][idx] = UINT16_MAX;
374 : : }
375 : : } else {
376 [ # # ]: 0 : for (idx = 0; idx < flow_bond_num; idx++)
377 : 0 : flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] = UINT16_MAX;
378 : : }
379 : :
380 [ # # # # ]: 0 : if (adapter->switchdev_info.is_switchdev && adapter->is_dev_repr) {
381 : 0 : flow_bond_num = 1;
382 : 0 : flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] =
383 : 0 : adapter->repr_priv_data->repr_vf_u_vsi_id;
384 : 0 : flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] =
385 : 0 : adapter->repr_priv_data->repr_vf_k_vsi_id;
386 : : }
387 : :
388 [ # # ]: 0 : for (idx = 0; idx < flow_bond_num; idx++) {
389 [ # # ]: 0 : if (flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] != UINT16_MAX)
390 : 0 : flow_cnt++;
391 [ # # ]: 0 : if (flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][idx] != UINT16_MAX)
392 : 0 : flow_cnt++;
393 : : }
394 : :
395 [ # # ]: 0 : if (flow_cnt == 0) {
396 : 0 : PMD_LOG_ERR(DRV, "Failed to redirect same device.");
397 : 0 : rte_flow_error_set(error, ENOTSUP,
398 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
399 : : "Failed to redirect same device");
400 : 0 : ret = -EINVAL;
401 : 0 : goto l_end;
402 : : }
403 : :
404 [ # # ]: 0 : for (idx = 0; idx < flow_bond_num; idx++) {
405 [ # # ]: 0 : if (flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][idx] != UINT16_MAX) {
406 [ # # ]: 0 : if (flow_create_cnt == 0) {
407 : 0 : flow->meta.flow_src_vsi =
408 : : flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][idx];
409 : 0 : flow_create_cnt++;
410 : : } else {
411 : 0 : flow_new = rte_zmalloc("sxe2_flow", sizeof(*flow), 0);
412 [ # # ]: 0 : if (!flow_new) {
413 : 0 : rte_flow_error_set(error, ENOMEM,
414 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
415 : : "Failed to alloc memory for flow rule");
416 : 0 : ret = -ENOMEM;
417 : 0 : goto l_end;
418 : : }
419 [ # # ]: 0 : rte_memcpy(flow_new, flow, sizeof(struct sxe2_flow));
420 : 0 : TAILQ_INSERT_TAIL(sxe2_flow_list, flow_new, next);
421 : 0 : flow_new->meta.flow_src_vsi =
422 : : flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][idx];
423 : 0 : flow_create_cnt++;
424 : : }
425 : : }
426 [ # # ]: 0 : if (flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] != UINT16_MAX) {
427 [ # # ]: 0 : if (flow_create_cnt == 0) {
428 : 0 : flow->meta.flow_src_vsi =
429 : : flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx];
430 : 0 : flow_create_cnt++;
431 : : } else {
432 : 0 : flow_new = rte_zmalloc("sxe2_flow", sizeof(*flow), 0);
433 [ # # ]: 0 : if (!flow_new) {
434 : 0 : rte_flow_error_set(error, ENOMEM,
435 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
436 : : "Failed to alloc memory for flow rule");
437 : 0 : ret = -ENOMEM;
438 : 0 : goto l_end;
439 : : }
440 [ # # ]: 0 : rte_memcpy(flow_new, flow, sizeof(struct sxe2_flow));
441 : 0 : TAILQ_INSERT_TAIL(sxe2_flow_list, flow_new, next);
442 : 0 : flow_new->meta.flow_src_vsi =
443 : : flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx];
444 : 0 : flow_create_cnt++;
445 : : }
446 : : }
447 : : }
448 : :
449 : 0 : l_end:
450 : 0 : return ret;
451 : : }
452 : :
453 : 0 : static int32_t sxe2_flow_adjust_action(struct rte_eth_dev *dev __rte_unused,
454 : : struct rte_flow *flow_list,
455 : : struct rte_flow_error *error __rte_unused)
456 : : {
457 : 0 : struct sxe2_flow_list_t *sxe2_flow_list = &flow_list->sxe2_flow_list;
458 : 0 : struct sxe2_flow *flow = NULL;
459 : 0 : int32_t ret = 0;
460 : 0 : int32_t dest_num = 0;
461 : 0 : int32_t pass_num = 0;
462 : 0 : int32_t mark_num = 0;
463 : 0 : int32_t count_num = 0;
464 : 0 : int32_t drop_num = 0;
465 : :
466 [ # # ]: 0 : TAILQ_FOREACH(flow, sxe2_flow_list, next) {
467 [ # # ]: 0 : if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
468 : 0 : dest_num = sxe2_test_bit(SXE2_FLOW_ACTION_Q_REGION,
469 [ # # ]: 0 : flow->action.act_types) +
470 : 0 : sxe2_test_bit(SXE2_FLOW_ACTION_QUEUE,
471 : 0 : flow->action.act_types);
472 : 0 : pass_num = sxe2_test_bit(SXE2_FLOW_ACTION_PASSTHRU,
473 : 0 : flow->action.act_types);
474 : 0 : mark_num = sxe2_test_bit(SXE2_FLOW_ACTION_MARK,
475 : 0 : flow->action.act_types);
476 : 0 : count_num = sxe2_test_bit(SXE2_FLOW_ACTION_COUNT,
477 : 0 : flow->action.act_types);
478 : 0 : drop_num = sxe2_test_bit(SXE2_FLOW_ACTION_DROP,
479 : 0 : flow->action.act_types);
480 : :
481 [ # # ]: 0 : if (dest_num) {
482 : 0 : sxe2_clear_bit(SXE2_FLOW_ACTION_PASSTHRU,
483 : 0 : flow->action.act_types);
484 : 0 : pass_num = 0;
485 : 0 : sxe2_clear_bit(SXE2_FLOW_ACTION_TO_VSI,
486 : 0 : flow->action.act_types);
487 : : }
488 : :
489 [ # # ]: 0 : if (pass_num)
490 : 0 : flow->action.passthru.vsi_index = flow->meta.flow_src_vsi;
491 : :
492 [ # # ]: 0 : if (mark_num) {
493 [ # # ]: 0 : if (dest_num == 0) {
494 : 0 : flow->action.q_region.q_index = 0;
495 : 0 : flow->action.q_region.region = 7;
496 : 0 : flow->action.q_region.vsi_index = flow->meta.flow_src_vsi;
497 : 0 : sxe2_set_bit(SXE2_FLOW_ACTION_Q_REGION,
498 : 0 : flow->action.act_types);
499 : 0 : dest_num++;
500 : : }
501 : 0 : sxe2_clear_bit(SXE2_FLOW_ACTION_PASSTHRU,
502 : 0 : flow->action.act_types);
503 : 0 : pass_num = 0;
504 : : }
505 [ # # ]: 0 : if (count_num) {
506 [ # # ]: 0 : if (dest_num == 0 && drop_num == 0) {
507 [ # # ]: 0 : if (pass_num == 0) {
508 : 0 : sxe2_set_bit(SXE2_FLOW_ACTION_PASSTHRU,
509 : 0 : flow->action.act_types);
510 : 0 : flow->action.passthru.vsi_index =
511 : 0 : flow->meta.flow_src_vsi;
512 : 0 : pass_num++;
513 : : }
514 : : }
515 : : }
516 : 0 : PMD_LOG_DEBUG(DRV, "dest_num: %d, pass_num: %d, mark_num: %d, count_num: "
517 : : "%d, drop_num: %d", dest_num, pass_num, mark_num, count_num,
518 : : drop_num);
519 : 0 : PMD_LOG_DEBUG(DRV, "src_vsi: %d", flow->meta.flow_src_vsi);
520 : : }
521 : : }
522 : :
523 : 0 : return ret;
524 : : }
525 : :
526 : 0 : int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev)
527 : : {
528 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
529 : 0 : int32_t ret = 0;
530 : 0 : uint16_t i = 0;
531 : 0 : uint16_t *flow_udp_tunnel_port = NULL;
532 : :
533 : 0 : memset(adapter->flow_ctxt.tunnel_port_list, 0,
534 : : sizeof(adapter->flow_ctxt.tunnel_port_list));
535 : :
536 : 0 : flow_udp_tunnel_port = adapter->flow_ctxt.tunnel_port_list;
537 [ # # ]: 0 : for (i = 0; i < SXE2_FLOW_UDP_TUNNEL_MAX; i++) {
538 [ # # ]: 0 : if (flow_udp_tunnel_port[i] == 0) {
539 : 0 : ret = sxe2_drv_get_udp_tunnel_port(adapter, i,
540 : : &flow_udp_tunnel_port[i]);
541 [ # # ]: 0 : if (ret != 0) {
542 : 0 : PMD_LOG_ERR(DRV, "Failed to get udp tunnel port, proto: %d,"
543 : : "ret: %d", i, ret);
544 : 0 : goto l_end;
545 : : }
546 : : }
547 : : }
548 : :
549 : 0 : l_end:
550 : 0 : return ret;
551 : : }
552 : :
553 : 0 : static int32_t sxe2_flowlist_add_tunnel_port(struct rte_eth_dev *dev,
554 : : struct rte_flow *flow_list,
555 : : struct rte_flow_error *error)
556 : : {
557 : 0 : struct sxe2_flow_list_t *sxe2_flow_list = &flow_list->sxe2_flow_list;
558 : 0 : struct sxe2_flow *flow = TAILQ_FIRST(sxe2_flow_list);
559 : 0 : enum sxe2_flow_tunnel_type tunnel_type = flow->meta.tunnel_type;
560 : 0 : DECLARE_BITMAP(flow_type, SXE2_EXPANSION_MAX);
561 [ # # ]: 0 : sxe2_bitmap_zero(flow_type, SXE2_EXPANSION_MAX);
562 [ # # ]: 0 : sxe2_bitmap_copy(flow_type, flow->flow_type, SXE2_EXPANSION_MAX);
563 : 0 : int32_t ret = 0;
564 : :
565 [ # # ]: 0 : if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
566 : 0 : return sxe2_flow_add_tunnel_port(dev, error, flow, flow_type, tunnel_type);
567 : :
568 : : return ret;
569 : : }
570 : :
571 : 0 : static int32_t sxe2_flow_check_item_empty(uint8_t *item, uint16_t size)
572 : : {
573 : 0 : uint16_t i = 0;
574 : :
575 [ # # # # : 0 : for (i = 0; i < size; i++) {
# # # # ]
576 [ # # # # : 0 : if (item[i] != 0)
# # # # ]
577 : : return -1;
578 : : }
579 : : return 0;
580 : : }
581 : :
582 : 0 : static int32_t sxe2_flowlist_add_proto_type(struct rte_eth_dev *dev __rte_unused,
583 : : struct rte_flow *flow_list,
584 : : struct rte_flow_error *error)
585 : : {
586 : 0 : struct sxe2_flow_list_t *sxe2_flow_list = &flow_list->sxe2_flow_list;
587 : 0 : struct sxe2_flow *flow = TAILQ_FIRST(sxe2_flow_list);
588 : 0 : struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
589 : 0 : int32_t ret = 0;
590 : :
591 [ # # ]: 0 : if (flow->engine_type == SXE2_FLOW_ENGINE_SWITCH) {
592 [ # # ]: 0 : if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow->flow_type) &&
593 [ # # ]: 0 : sxe2_flow_check_item_empty((uint8_t *)&pattern->item_mask.ipv4,
594 : : sizeof(pattern->item_mask.ipv4)) == 0) {
595 : 0 : sxe2_set_bit(SXE2_FLOW_FLD_ID_ETH_TYPE, pattern->map_spec);
596 : 0 : pattern->item_spec.eth.ether_type =
597 : 0 : rte_cpu_to_be_16(SXE2_FLOW_ETH_TYPE_IPV4);
598 : 0 : pattern->item_mask.eth.ether_type = 0xffff;
599 : : }
600 [ # # ]: 0 : if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow->flow_type) &&
601 [ # # ]: 0 : sxe2_flow_check_item_empty((uint8_t *)&pattern->item_mask.ipv6,
602 : : sizeof(pattern->item_mask.ipv6)) == 0) {
603 : 0 : sxe2_set_bit(SXE2_FLOW_FLD_ID_ETH_TYPE, pattern->map_spec);
604 : 0 : pattern->item_spec.eth.ether_type =
605 : 0 : rte_cpu_to_be_16(SXE2_FLOW_ETH_TYPE_IPV6);
606 : 0 : pattern->item_mask.eth.ether_type = 0xffff;
607 : : }
608 : :
609 [ # # ]: 0 : if (flow->meta.tunnel_type == SXE2_FLOW_TUNNEL_TYPE_NONE) {
610 [ # # ]: 0 : if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow->flow_type) &&
611 [ # # ]: 0 : sxe2_flow_check_item_empty((uint8_t *)&pattern->item_mask.udp,
612 : : sizeof(pattern->item_mask.udp)) == 0) {
613 : 0 : if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4,
614 [ # # ]: 0 : flow->flow_type)) {
615 : 0 : sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
616 : 0 : pattern->item_spec.ipv4.protocol =
617 : : SXE2_FLOW_IP_PROTOCOL_UDP;
618 : 0 : pattern->item_mask.ipv4.protocol = 0xff;
619 : : }
620 : 0 : if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6,
621 [ # # ]: 0 : flow->flow_type)) {
622 : 0 : ret = -EINVAL;
623 : 0 : rte_flow_error_set(error, ENOENT,
624 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
625 : : "UDP after IPv6 must has pattern item.");
626 : 0 : PMD_LOG_ERR(DRV,
627 : : "UDP after IPv6 must has pattern item.");
628 : 0 : goto l_end;
629 : : }
630 : : }
631 [ # # ]: 0 : if (sxe2_test_bit(SXE2_EXPANSION_OUTER_TCP, flow->flow_type) &&
632 [ # # ]: 0 : sxe2_flow_check_item_empty((uint8_t *)&pattern->item_mask.tcp,
633 : : sizeof(pattern->item_mask.tcp)) == 0) {
634 : 0 : if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4,
635 [ # # ]: 0 : flow->flow_type)) {
636 : 0 : sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT,
637 : 0 : pattern->map_spec);
638 : 0 : pattern->item_spec.ipv4.protocol =
639 : : SXE2_FLOW_IP_PROTOCOL_TCP;
640 : 0 : pattern->item_mask.ipv4.protocol = 0xff;
641 : : }
642 : 0 : if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6,
643 [ # # ]: 0 : flow->flow_type)) {
644 : 0 : ret = -EINVAL;
645 : 0 : rte_flow_error_set(error, ENOENT,
646 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
647 : : "TCP after IPv6 must has pattern item.");
648 : 0 : PMD_LOG_ERR(DRV,
649 : : "TCP after IPv6 must has pattern item.");
650 : 0 : goto l_end;
651 : : }
652 : : }
653 : 0 : if (sxe2_test_bit(SXE2_EXPANSION_OUTER_SCTP,
654 [ # # ]: 0 : flow->flow_type)) {
655 : 0 : ret = -EINVAL;
656 : 0 : rte_flow_error_set(error, ENOENT,
657 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
658 : : "SWITCH not support SCTP.");
659 : 0 : PMD_LOG_ERR(DRV, "SWITCH not support SCTP.");
660 : 0 : goto l_end;
661 : : }
662 : : }
663 : : }
664 : 0 : l_end:
665 : 0 : return ret;
666 : : }
667 : :
668 : 0 : static int32_t sxe2_flow_tunnel_split_proc(struct rte_eth_dev *dev __rte_unused,
669 : : struct rte_flow *flow_list,
670 : : struct rte_flow_error *error)
671 : : {
672 : 0 : struct sxe2_flow_list_t *sxe2_flow_list = &flow_list->sxe2_flow_list;
673 : 0 : struct sxe2_flow_list_t tunnel_flow_list;
674 : 0 : struct sxe2_flow *sxe2_flow_exist = NULL;
675 : 0 : struct sxe2_flow *sxe2_flow_new = NULL;
676 : 0 : struct sxe2_flow_pattern *pattern = NULL;
677 : 0 : int32_t ret = 0;
678 : :
679 : 0 : TAILQ_INIT(&tunnel_flow_list);
680 : :
681 [ # # ]: 0 : TAILQ_FOREACH(sxe2_flow_exist, sxe2_flow_list, next) {
682 [ # # ]: 0 : if (sxe2_flow_exist->engine_type != SXE2_FLOW_ENGINE_SWITCH)
683 : 0 : continue;
684 : 0 : if (sxe2_test_bit(SXE2_FLOW_FLD_ID_IPV4_PROT,
685 [ # # ]: 0 : sxe2_flow_exist->pattern_outer.map_spec)) {
686 : 0 : pattern = &sxe2_flow_exist->pattern_outer;
687 : 0 : if ((pattern->item_spec.ipv4.protocol &
688 [ # # ]: 0 : pattern->item_mask.ipv4.protocol) ==
689 : : (SXE2_FLOW_IP_PROTOCOL_GRE &
690 : : pattern->item_mask.ipv4.protocol)) {
691 : 0 : sxe2_flow_new = rte_zmalloc("sxe2_flow",
692 : : sizeof(struct sxe2_flow), 0);
693 [ # # ]: 0 : if (!sxe2_flow_new) {
694 : 0 : rte_flow_error_set(error, ENOMEM,
695 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
696 : : "Failed to alloc memory for flow rule");
697 : 0 : ret = -ENOMEM;
698 : 0 : goto l_end;
699 : : }
700 [ # # ]: 0 : rte_memcpy(sxe2_flow_new, sxe2_flow_exist,
701 : : sizeof(struct sxe2_flow));
702 : 0 : pattern = &sxe2_flow_new->pattern_outer;
703 : 0 : sxe2_flow_new->meta.tunnel_type =
704 : : SXE2_FLOW_TUNNEL_TYPE_GRE;
705 : 0 : sxe2_set_bit(SXE2_FLOW_HDR_GRE, pattern->hdrs);
706 : 0 : pattern->item_spec.ipv4.protocol =
707 : : SXE2_FLOW_IP_PROTOCOL_GRE;
708 : 0 : pattern->item_mask.ipv4.protocol = 0xff;
709 : 0 : TAILQ_INSERT_TAIL(&tunnel_flow_list, sxe2_flow_new, next);
710 : : }
711 : : }
712 : : }
713 [ # # ]: 0 : TAILQ_FOREACH(sxe2_flow_exist, &tunnel_flow_list, next)
714 : 0 : TAILQ_INSERT_TAIL(sxe2_flow_list, sxe2_flow_exist, next);
715 : :
716 : 0 : l_end:
717 : 0 : return ret;
718 : : }
719 : :
720 : 0 : static int32_t sxe2_flow_post_proc(struct rte_eth_dev *dev,
721 : : const struct rte_flow_attr *attr,
722 : : struct rte_flow *flow_list,
723 : : struct rte_flow_error *error)
724 : : {
725 : 0 : int32_t ret = 0;
726 : :
727 : 0 : ret = sxe2_flowlist_add_tunnel_port(dev, flow_list, error);
728 [ # # ]: 0 : if (ret)
729 : 0 : goto l_end;
730 : :
731 : 0 : ret = sxe2_flowlist_add_proto_type(dev, flow_list, error);
732 [ # # ]: 0 : if (ret)
733 : 0 : goto l_end;
734 : :
735 : 0 : ret = sxe2_flow_check_function(dev, flow_list, error);
736 [ # # ]: 0 : if (ret)
737 : 0 : goto l_end;
738 : :
739 : 0 : ret = sxe2_flow_meta_proc(dev, attr, flow_list, error);
740 [ # # ]: 0 : if (ret)
741 : 0 : goto l_end;
742 : :
743 : 0 : ret = sxe2_flow_src_split_proc(dev, flow_list, error);
744 [ # # ]: 0 : if (ret)
745 : 0 : goto l_end;
746 : :
747 : 0 : ret = sxe2_flow_adjust_action(dev, flow_list, error);
748 [ # # ]: 0 : if (ret)
749 : 0 : goto l_end;
750 : :
751 : 0 : ret = sxe2_flow_tunnel_split_proc(dev, flow_list, error);
752 [ # # ]: 0 : if (ret)
753 : 0 : goto l_end;
754 : 0 : l_end:
755 : 0 : return ret;
756 : : }
757 : :
758 : 0 : static int32_t sxe2_flow_validate_with_flow(struct rte_eth_dev *dev,
759 : : struct rte_flow *flow_list,
760 : : const struct rte_flow_attr *attr,
761 : : const struct rte_flow_item pattern[],
762 : : const struct rte_flow_action actions[],
763 : : struct rte_flow_error *error)
764 : : {
765 : 0 : int32_t ret = 0;
766 : 0 : struct sxe2_flow *flow = NULL;
767 : :
768 : 0 : ret = sxe2_check_para(attr, pattern, actions, error);
769 [ # # ]: 0 : if (ret != 0)
770 : 0 : goto l_end;
771 : :
772 : 0 : ret = sxe2_flow_valid_attr(attr, error);
773 [ # # ]: 0 : if (ret != 0)
774 : 0 : goto l_end;
775 : :
776 : 0 : flow = rte_zmalloc("sxe2_flow", sizeof(*flow), 0);
777 [ # # ]: 0 : if (!flow) {
778 : 0 : rte_flow_error_set(error, ENOMEM,
779 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
780 : : "Failed to alloc memory for flow rule");
781 : 0 : PMD_LOG_ERR(DRV, "Failed to alloc memory for flow rule.");
782 : 0 : ret = -ENOMEM;
783 : 0 : goto l_end;
784 : : }
785 : :
786 : 0 : TAILQ_INSERT_TAIL(&flow_list->sxe2_flow_list, flow, next);
787 : 0 : flow->create_err = -1;
788 : :
789 : 0 : ret = sxe2_flow_parse_pattern(dev, pattern, error, flow);
790 [ # # ]: 0 : if (ret != 0)
791 : 0 : goto l_end;
792 : :
793 : 0 : ret = sxe2_flow_parse_engine(dev, attr, actions, error, flow);
794 [ # # ]: 0 : if (ret != 0)
795 : 0 : goto l_end;
796 : :
797 : 0 : ret = sxe2_flow_parse_action(dev, actions, error, flow);
798 [ # # ]: 0 : if (ret != 0)
799 : 0 : goto l_end;
800 : :
801 : 0 : ret = sxe2_flow_post_proc(dev, attr, flow_list, error);
802 [ # # ]: 0 : if (ret != 0)
803 : 0 : goto l_end;
804 : :
805 : 0 : ret = sxe2_flow_check_flow_list_duplicate(dev, flow_list);
806 [ # # ]: 0 : if (ret != 0) {
807 : 0 : rte_flow_error_set(error, EEXIST, RTE_FLOW_ERROR_TYPE_ITEM,
808 : : NULL, "Duplicate flow.");
809 : 0 : PMD_LOG_ERR(DRV, "Duplicate flow.");
810 : 0 : goto l_end;
811 : : }
812 : 0 : l_end:
813 : 0 : return ret;
814 : : }
815 : :
816 : 0 : static const char *sxe2_flow_convert_ret_to_flow_msg(int32_t ret)
817 : : {
818 : 0 : const char *msg = NULL;
819 [ # # ]: 0 : if (ret > 0)
820 : 0 : ret = -ret;
821 [ # # # # : 0 : switch (ret) {
# # # # ]
822 : : case -ENOMEM:
823 : : msg = "no memory";
824 : : break;
825 : 0 : case -ENOTSUP:
826 : 0 : msg = "not support";
827 : 0 : break;
828 : 0 : case -EEXIST:
829 : 0 : msg = "rule already exist";
830 : 0 : break;
831 : 0 : case -ETIMEDOUT:
832 : 0 : msg = "timeout";
833 : 0 : break;
834 : 0 : case -EINVAL:
835 : 0 : msg = "invalid parameter";
836 : 0 : break;
837 : 0 : case -ENOSPC:
838 : 0 : msg = "no space";
839 : 0 : break;
840 : 0 : case -ENOENT:
841 : 0 : msg = "no such rule";
842 : 0 : break;
843 : 0 : default:
844 : 0 : msg = "unknown error";
845 : 0 : break;
846 : : }
847 : 0 : return msg;
848 : : }
849 : :
850 : 0 : static int32_t sxe2_flow_rte_list_free(struct sxe2_adapter *adapter,
851 : : struct rte_flow **flow_ptr,
852 : : struct rte_flow_error *error)
853 : : {
854 : 0 : int32_t ret = 0;
855 : 0 : int32_t ret1 = 0;
856 : 0 : struct rte_flow *flow = *flow_ptr;
857 : 0 : struct rte_flow *flow_temp = NULL;
858 : 0 : struct sxe2_flow *hw_flow = NULL;
859 : 0 : struct sxe2_flow *hw_flow_temp = NULL;
860 : 0 : struct sxe2_fnav_cid_mgr *mgr = NULL;
861 : 0 : rte_spinlock_lock(&adapter->flow_ctxt.flow_list_lock);
862 [ # # ]: 0 : TAILQ_FOREACH(flow_temp, &adapter->flow_ctxt.rte_flow_list, next) {
863 [ # # ]: 0 : if (flow_temp == flow)
864 [ # # ]: 0 : TAILQ_REMOVE(&adapter->flow_ctxt.rte_flow_list, flow, next);
865 : : }
866 : :
867 [ # # ]: 0 : TAILQ_FOREACH_SAFE(hw_flow, &flow->sxe2_flow_list, next, hw_flow_temp) {
868 [ # # ]: 0 : if (hw_flow->create_err == 0) {
869 [ # # ]: 0 : if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, hw_flow->action.act_types)) {
870 : 0 : ret = sxe2_flow_query_mgr(adapter, hw_flow, &mgr, error);
871 [ # # ]: 0 : if (ret) {
872 : 0 : PMD_LOG_ERR(DRV,
873 : : "Failed to query flow count, flow id: %u, ret: %d.",
874 : : hw_flow->flow_id, ret);
875 : 0 : rte_flow_error_set(error, EIO,
876 : : RTE_FLOW_ERROR_TYPE_ACTION, NULL,
877 : : "Failed to query flow count");
878 : 0 : ret1 = ret;
879 : : }
880 : : }
881 : :
882 : 0 : ret = sxe2_drv_flow_filter_del(adapter, hw_flow);
883 [ # # ]: 0 : if (ret) {
884 : 0 : PMD_LOG_ERR(DRV,
885 : : "Failed to delete flow filter, ret: %d:%s",
886 : : ret, sxe2_flow_convert_ret_to_flow_msg(ret));
887 : 0 : rte_flow_error_set(error, EIO,
888 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
889 : : "Failed to delete flow filter");
890 : 0 : ret1 = ret;
891 : : }
892 : :
893 [ # # ]: 0 : if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, hw_flow->action.act_types)) {
894 : 0 : ret = sxe2_flow_free_mgr(adapter, hw_flow,
895 : : &mgr, error);
896 [ # # ]: 0 : if (ret)
897 : 0 : ret1 = ret;
898 : : }
899 : : }
900 : :
901 [ # # ]: 0 : TAILQ_REMOVE(&flow->sxe2_flow_list, hw_flow, next);
902 : 0 : rte_free(hw_flow);
903 : : }
904 : 0 : rte_free(flow);
905 : 0 : *flow_ptr = NULL;
906 : 0 : rte_spinlock_unlock(&adapter->flow_ctxt.flow_list_lock);
907 : :
908 : 0 : return ret1;
909 : : }
910 : :
911 : 0 : static int32_t sxe2_flow_validate(struct rte_eth_dev *dev,
912 : : const struct rte_flow_attr *attr,
913 : : const struct rte_flow_item pattern[],
914 : : const struct rte_flow_action actions[],
915 : : struct rte_flow_error *error)
916 : : {
917 : 0 : int32_t ret = 0;
918 : 0 : struct rte_flow *flow_list = NULL;
919 : 0 : struct sxe2_flow *hw_flow = NULL;
920 : 0 : struct sxe2_flow *hw_flow_temp = NULL;
921 : 0 : flow_list = rte_zmalloc("rte_flow_va", sizeof(*flow_list), 0);
922 [ # # ]: 0 : if (!flow_list) {
923 : 0 : rte_flow_error_set(error, ENOMEM,
924 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
925 : : "Failed to alloc memory for flow rule");
926 : 0 : PMD_LOG_ERR(DRV, "Failed to alloc memory for flow rule.");
927 : 0 : ret = -ENOMEM;
928 : 0 : goto l_end;
929 : : }
930 : 0 : TAILQ_INIT(&flow_list->sxe2_flow_list);
931 : :
932 : 0 : ret = sxe2_flow_validate_with_flow(dev, flow_list, attr, pattern, actions, error);
933 : 0 : if (ret != 0)
934 : : goto l_free;
935 : 0 : l_free:
936 : :
937 [ # # ]: 0 : TAILQ_FOREACH_SAFE(hw_flow, &flow_list->sxe2_flow_list, next, hw_flow_temp) {
938 [ # # ]: 0 : TAILQ_REMOVE(&flow_list->sxe2_flow_list, hw_flow, next);
939 : 0 : rte_free(hw_flow);
940 : : }
941 : 0 : rte_free(flow_list);
942 : 0 : l_end:
943 : 0 : return ret;
944 : : }
945 : :
946 : 0 : static int32_t sxe2_flow_isolate(struct rte_eth_dev *dev,
947 : : int32_t enable,
948 : : struct rte_flow_error *error)
949 : : {
950 : 0 : int32_t ret = 0;
951 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
952 : :
953 [ # # ]: 0 : if (dev->data->dev_started) {
954 : 0 : rte_flow_error_set(error, EBUSY,
955 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
956 : : NULL,
957 : : "port must be stopped first");
958 : 0 : ret = -EBUSY;
959 : 0 : goto l_end;
960 : : }
961 : :
962 [ # # ]: 0 : if (adapter->is_dev_repr) {
963 : 0 : rte_flow_error_set(error, ENOTSUP,
964 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
965 : : "representor dev cannot change isolated mode ");
966 : 0 : ret = -EINVAL;
967 : 0 : goto l_end;
968 : : }
969 : :
970 [ # # ]: 0 : if (enable == adapter->flow_isolated)
971 : 0 : goto l_end;
972 : :
973 [ # # ]: 0 : if (adapter->dev_type == SXE2_DEV_T_VF &&
974 [ # # ]: 0 : adapter->switchdev_info.is_switchdev) {
975 : 0 : rte_flow_error_set(error, ENOTSUP,
976 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
977 : : "isolated mode cannot be change when port in switch dev mode");
978 : 0 : ret = -EINVAL;
979 : 0 : goto l_end;
980 : : }
981 : :
982 : 0 : rte_spinlock_lock(&adapter->flow_ctxt.flow_list_lock);
983 [ # # ]: 0 : if (!TAILQ_EMPTY(&adapter->flow_ctxt.rte_flow_list))
984 : 0 : PMD_DEV_LOG_WARN(adapter, DRV,
985 : : "The configured flow item may not take effect.");
986 : 0 : rte_spinlock_unlock(&adapter->flow_ctxt.flow_list_lock);
987 : :
988 : 0 : adapter->flow_isolated = !!enable;
989 : :
990 : 0 : ret = sxe2_l2_rule_update(adapter);
991 [ # # ]: 0 : if (ret != 0)
992 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "Failed to update l2 rule");
993 : :
994 : 0 : ret = sxe2_switchdev_rule_update(adapter);
995 [ # # ]: 0 : if (ret != 0)
996 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "Failed to update switchdev rule");
997 : :
998 : 0 : l_end:
999 [ # # ]: 0 : if (ret == 0)
1000 : 0 : adapter->flow_isolate_cfg = !!enable;
1001 : 0 : return ret;
1002 : : }
1003 : :
1004 : 0 : static struct rte_flow *sxe2_flow_create(struct rte_eth_dev *dev,
1005 : : const struct rte_flow_attr *attr,
1006 : : const struct rte_flow_item pattern[],
1007 : : const struct rte_flow_action action[],
1008 : : struct rte_flow_error *error)
1009 : : {
1010 : 0 : int32_t ret = 0;
1011 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1012 : 0 : struct rte_flow *flow_list = NULL;
1013 : 0 : struct sxe2_flow *flow = NULL;
1014 : :
1015 : 0 : flow_list = rte_zmalloc("sxe2_flow_create", sizeof(*flow_list), 0);
1016 [ # # ]: 0 : if (!flow_list) {
1017 : 0 : rte_flow_error_set(error, ENOMEM,
1018 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1019 : : "Failed to alloc memory for flow rule");
1020 : 0 : PMD_LOG_ERR(DRV, "Failed to alloc memory for flow rule.");
1021 : 0 : ret = -ENOMEM;
1022 : 0 : goto l_end;
1023 : : }
1024 : 0 : TAILQ_INIT(&flow_list->sxe2_flow_list);
1025 : :
1026 : 0 : ret = sxe2_flow_validate_with_flow(dev, flow_list, attr, pattern, action, error);
1027 [ # # ]: 0 : if (ret != 0)
1028 : 0 : goto l_free_flow;
1029 : :
1030 [ # # ]: 0 : TAILQ_FOREACH(flow, &flow_list->sxe2_flow_list, next) {
1031 : 0 : ret = sxe2_fnav_get_filter_cid(adapter, flow);
1032 [ # # ]: 0 : if (ret != 0) {
1033 : 0 : PMD_LOG_ERR(DRV, "fnav get stats id failed, ret:%d", ret);
1034 : 0 : rte_flow_error_set(error, EIO,
1035 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1036 : : "Failed to add fnav rule:alloc cid failed.");
1037 : 0 : goto l_free_flow;
1038 : : }
1039 : 0 : ret = sxe2_drv_flow_filter_add(adapter, flow);
1040 [ # # ]: 0 : if (ret) {
1041 : 0 : rte_flow_error_set(error, EINVAL,
1042 : : RTE_FLOW_ERROR_TYPE_ITEM, NULL,
1043 : : "Failed to add flow filter to hw.");
1044 : 0 : PMD_LOG_ERR(DRV, "Failed to add flow filter to hw.ret:%d:%s",
1045 : : ret, sxe2_flow_convert_ret_to_flow_msg(ret));
1046 : 0 : goto l_free_flow;
1047 : : }
1048 : : }
1049 : :
1050 : 0 : TAILQ_INSERT_TAIL(&adapter->flow_ctxt.rte_flow_list, flow_list, next);
1051 : 0 : goto l_end;
1052 : 0 : l_free_flow:
1053 : 0 : (void)sxe2_flow_rte_list_free(adapter, &flow_list, error);
1054 : 0 : l_end:
1055 : 0 : return flow_list;
1056 : : }
1057 : :
1058 : 0 : static int32_t sxe2_flow_destroy(struct rte_eth_dev *dev,
1059 : : struct rte_flow *flow,
1060 : : struct rte_flow_error *error)
1061 : : {
1062 : 0 : int32_t ret = 0;
1063 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1064 : 0 : ret = sxe2_flow_rte_list_free(adapter, &flow, error);
1065 [ # # ]: 0 : if (ret)
1066 : 0 : PMD_LOG_ERR(DRV, "Failed to destroy flow.ret:%d.", ret);
1067 : 0 : return ret;
1068 : : }
1069 : :
1070 : 0 : static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
1071 : : {
1072 : 0 : int32_t ret = 0;
1073 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1074 : 0 : struct rte_flow *flow = NULL;
1075 : 0 : struct rte_flow *tmp_flow = NULL;
1076 : 0 : struct rte_flow_list_t *flow_list = &adapter->flow_ctxt.rte_flow_list;
1077 [ # # ]: 0 : TAILQ_FOREACH_SAFE(flow, flow_list, next, tmp_flow) {
1078 : 0 : ret = sxe2_flow_destroy(dev, flow, error);
1079 [ # # ]: 0 : if (ret) {
1080 : 0 : PMD_LOG_ERR(DRV, "Failed to flush flows.ret:%d.", ret);
1081 : :
1082 [ # # ]: 0 : if (ret != -EAGAIN)
1083 : 0 : ret = -EINVAL;
1084 : 0 : goto l_end;
1085 : : }
1086 : : }
1087 : 0 : l_end:
1088 : 0 : return ret;
1089 : : }
1090 : :
1091 : 0 : int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
1092 : : {
1093 : 0 : int32_t ret = 0;
1094 : 0 : struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
1095 : : &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
1096 : 0 : uint32_t stat_index;
1097 : 0 : uint32_t user_id;
1098 : 0 : uint32_t driver_id;
1099 : 0 : struct sxe2_fnav_cid_mgr *temp = NULL;
1100 : 0 : struct sxe2_fnav_cid_mgr *mgr = NULL;
1101 : :
1102 [ # # ]: 0 : if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
1103 : 0 : user_id = flow->action.count.user_id;
1104 : 0 : driver_id = flow->action.count.driver_id;
1105 : :
1106 [ # # ]: 0 : TAILQ_FOREACH(temp, cid_mgr_list, next) {
1107 [ # # ]: 0 : if (temp->user_id == user_id &&
1108 [ # # ]: 0 : temp->driver_id == driver_id) {
1109 : : mgr = temp;
1110 : : break;
1111 : : }
1112 : : }
1113 [ # # ]: 0 : if (mgr == NULL) {
1114 : 0 : mgr = rte_zmalloc("sxe2_fnav_cid_mgr",
1115 : : sizeof(struct sxe2_fnav_cid_mgr), 0);
1116 [ # # ]: 0 : if (!mgr) {
1117 : 0 : PMD_LOG_ERR(DRV,
1118 : : "Failed to alloc sxe2vf_fnav_cid_mgr memory.");
1119 : 0 : ret = -ENOMEM;
1120 : 0 : goto l_end;
1121 : : }
1122 : :
1123 : 0 : ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
1124 [ # # ]: 0 : if (ret) {
1125 : 0 : PMD_LOG_ERR(DRV, "Failed to alloc fw count id.");
1126 : 0 : rte_free(mgr);
1127 : 0 : goto l_end;
1128 : : }
1129 : :
1130 : 0 : TAILQ_INSERT_TAIL(cid_mgr_list, mgr, next);
1131 : 0 : mgr->user_id = user_id;
1132 : 0 : mgr->driver_id = driver_id;
1133 : 0 : mgr->stat_index = stat_index;
1134 : 0 : mgr->count_type = adapter->flow_ctxt.hw_res.count_type;
1135 : : }
1136 : 0 : flow->action.count.stat_index = mgr->stat_index;
1137 : 0 : flow->action.count.stat_ctrl = mgr->count_type;
1138 : : }
1139 : :
1140 : 0 : l_end:
1141 : 0 : return ret;
1142 : : }
1143 : :
1144 : 0 : int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
1145 : : struct sxe2_flow *flow,
1146 : : struct sxe2_fnav_cid_mgr **mgr_ptr,
1147 : : struct rte_flow_error *error)
1148 : : {
1149 : 0 : int32_t ret = 0;
1150 : 0 : struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
1151 : : &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
1152 : 0 : struct sxe2_fnav_cid_mgr *mgr = *mgr_ptr;
1153 : 0 : uint32_t user_id = flow->action.count.user_id;
1154 [ # # ]: 0 : if (user_id == 0) {
1155 [ # # ]: 0 : TAILQ_REMOVE(cid_mgr_list, mgr, next);
1156 : 0 : ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
1157 [ # # ]: 0 : if (ret) {
1158 : 0 : rte_flow_error_set(error, EIO,
1159 : : RTE_FLOW_ERROR_TYPE_ACTION, NULL,
1160 : : "Failed to free flow count.");
1161 : 0 : PMD_LOG_ERR(DRV,
1162 : : "Failed to free flow count, flow id: %u, ret: %d.",
1163 : : flow->flow_id, ret);
1164 : : }
1165 : 0 : rte_free(mgr);
1166 : 0 : *mgr_ptr = NULL;
1167 : : }
1168 : 0 : return ret;
1169 : : }
1170 : :
1171 : 0 : int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
1172 : : struct sxe2_flow *flow,
1173 : : struct sxe2_fnav_cid_mgr **mgr_ptr,
1174 : : struct rte_flow_error *error)
1175 : : {
1176 : 0 : int32_t ret = 0;
1177 : 0 : struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
1178 : : &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
1179 : 0 : struct sxe2_fnav_cid_mgr *temp = NULL;
1180 : 0 : struct sxe2_fnav_cid_mgr *mgr = NULL;
1181 : 0 : uint32_t user_id = flow->action.count.user_id;
1182 : 0 : uint32_t driver_id = flow->action.count.driver_id;
1183 : :
1184 [ # # ]: 0 : TAILQ_FOREACH(temp, cid_mgr_list, next) {
1185 [ # # ]: 0 : if (temp->user_id == user_id &&
1186 [ # # ]: 0 : temp->driver_id == driver_id) {
1187 : : mgr = temp;
1188 : : break;
1189 : : }
1190 : : }
1191 [ # # ]: 0 : if (!mgr) {
1192 : 0 : rte_flow_error_set(error, EINVAL,
1193 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1194 : : "fnav flow query count invalid user_id or driver_id.");
1195 : 0 : PMD_LOG_ERR(DRV,
1196 : : "fnav flow query count invalid user_id or driver_id.");
1197 : 0 : ret = -EINVAL;
1198 : 0 : goto l_end;
1199 : : }
1200 : 0 : ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
1201 [ # # ]: 0 : if (ret) {
1202 : 0 : rte_flow_error_set(error, EINVAL,
1203 : : RTE_FLOW_ERROR_TYPE_ITEM, NULL,
1204 : : "Failed to query flow count.");
1205 : 0 : PMD_LOG_ERR(DRV,
1206 : : "Failed to query flow count, flow id: %u, ret: %d.",
1207 : : flow->flow_id, ret);
1208 : 0 : goto l_end;
1209 : : }
1210 : 0 : *mgr_ptr = mgr;
1211 : 0 : l_end:
1212 : 0 : return ret;
1213 : : }
1214 : :
1215 : 0 : static int32_t sxe2_flow_query_count(struct sxe2_adapter *adapter,
1216 : : struct sxe2_flow *flow,
1217 : : struct rte_flow_query_count *count,
1218 : : struct rte_flow_error *error)
1219 : : {
1220 : 0 : int32_t ret = 0;
1221 : 0 : struct sxe2_fnav_cid_mgr *mgr = NULL;
1222 [ # # # # : 0 : switch (flow->action.count.stat_ctrl) {
# ]
1223 : 0 : case SXE2_FNAV_STAT_ENA_NONE:
1224 : 0 : count->hits_set = 0;
1225 : 0 : count->bytes_set = 0;
1226 : 0 : break;
1227 : 0 : case SXE2_FNAV_STAT_ENA_PKTS:
1228 : 0 : count->hits_set = 1;
1229 : 0 : count->bytes_set = 0;
1230 : 0 : break;
1231 : 0 : case SXE2_FNAV_STAT_ENA_BYTES:
1232 : 0 : count->hits_set = 0;
1233 : 0 : count->bytes_set = 1;
1234 : 0 : break;
1235 : 0 : case SXE2_FNAV_STAT_ENA_ALL:
1236 : 0 : count->hits_set = 1;
1237 : 0 : count->bytes_set = 1;
1238 : 0 : break;
1239 : 0 : default:
1240 : 0 : ret = -EINVAL;
1241 : 0 : goto l_end;
1242 : : }
1243 [ # # ]: 0 : if (!sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
1244 : 0 : rte_flow_error_set(error, EINVAL,
1245 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1246 : : "this flow don't have count action.");
1247 : 0 : PMD_LOG_ERR(DRV, "this flow don't have count action.");
1248 : 0 : ret = -EINVAL;
1249 : 0 : goto l_end;
1250 : : }
1251 : 0 : ret = sxe2_flow_query_mgr(adapter, flow, &mgr, error);
1252 [ # # ]: 0 : if (ret) {
1253 : 0 : PMD_LOG_ERR(DRV,
1254 : : "Failed to query flow count, flow id: %u, ret: %d.",
1255 : : flow->flow_id, ret);
1256 : 0 : goto l_end;
1257 : : }
1258 : 0 : count->hits = mgr->hits;
1259 : 0 : count->bytes = mgr->bytes;
1260 [ # # ]: 0 : if (count->reset) {
1261 : 0 : mgr->hits = 0;
1262 : 0 : mgr->bytes = 0;
1263 : : }
1264 : 0 : l_end:
1265 : 0 : return ret;
1266 : : }
1267 : :
1268 : 0 : static int32_t sxe2_flow_query(struct rte_eth_dev *dev,
1269 : : struct rte_flow *flow_list,
1270 : : const struct rte_flow_action *actions,
1271 : : void *data,
1272 : : struct rte_flow_error *error)
1273 : : {
1274 : 0 : int32_t ret = 0;
1275 : 0 : struct rte_flow_query_count *count = data;
1276 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1277 : 0 : struct sxe2_flow *flow = NULL;
1278 : :
1279 [ # # ]: 0 : if (!flow_list) {
1280 : 0 : ret = -EINVAL;
1281 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
1282 : : NULL, "Invalid flow");
1283 : 0 : PMD_LOG_ERR(DRV, "Invalid flow to query flow.");
1284 : 0 : goto l_end;
1285 : : }
1286 : :
1287 : 0 : rte_spinlock_lock(&adapter->flow_ctxt.flow_list_lock);
1288 [ # # ]: 0 : for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
1289 [ # # # ]: 0 : switch (actions->type) {
1290 : : case RTE_FLOW_ACTION_TYPE_VOID:
1291 : : break;
1292 : 0 : case RTE_FLOW_ACTION_TYPE_COUNT:
1293 : 0 : flow = TAILQ_FIRST(&flow_list->sxe2_flow_list);
1294 : 0 : ret = sxe2_flow_query_count(adapter, flow, count, error);
1295 [ # # ]: 0 : if (ret) {
1296 : 0 : PMD_LOG_ERR(DRV,
1297 : : "Failed to query flow count, flow id: %u, ret: %d.",
1298 : : flow->flow_id, ret);
1299 : 0 : goto l_end_unlock;
1300 : : }
1301 : : break;
1302 : 0 : default:
1303 : 0 : rte_flow_error_set(error, ENOTSUP,
1304 : : RTE_FLOW_ERROR_TYPE_ACTION,
1305 : : actions,
1306 : : "action not supported");
1307 : 0 : PMD_LOG_ERR(DRV,
1308 : : "Failed to query flow action type:%d.",
1309 : : actions->type);
1310 : 0 : ret = -ENOTSUP;
1311 : 0 : goto l_end_unlock;
1312 : : }
1313 : : }
1314 : :
1315 : 0 : l_end_unlock:
1316 : 0 : rte_spinlock_unlock(&adapter->flow_ctxt.flow_list_lock);
1317 : :
1318 : 0 : l_end:
1319 : 0 : return ret;
1320 : : }
1321 : :
1322 : : const struct rte_flow_ops sxe2_flow_ops = {
1323 : : .validate = sxe2_flow_validate,
1324 : : .create = sxe2_flow_create,
1325 : : .destroy = sxe2_flow_destroy,
1326 : : .flush = sxe2_flow_flush,
1327 : : .query = sxe2_flow_query,
1328 : : .isolate = sxe2_flow_isolate,
1329 : : };
1330 : :
1331 : 0 : int32_t sxe2_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops)
1332 : : {
1333 : 0 : int32_t ret = 0;
1334 : :
1335 [ # # ]: 0 : if (dev == NULL) {
1336 : 0 : ret = -EINVAL;
1337 : 0 : goto l_end;
1338 : : }
1339 : :
1340 : 0 : *ops = &sxe2_flow_ops;
1341 : :
1342 : 0 : l_end:
1343 : 0 : return ret;
1344 : : }
1345 : :
1346 : 0 : int32_t sxe2_flow_init(struct rte_eth_dev *dev)
1347 : : {
1348 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1349 : 0 : int32_t ret = 0;
1350 : 0 : TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
1351 : 0 : TAILQ_INIT(&adapter->flow_ctxt.hw_res.fnav_cid_mgr_list);
1352 [ # # ]: 0 : if (adapter->devargs.fnav_stat_type)
1353 : 0 : adapter->flow_ctxt.hw_res.count_type =
1354 : 0 : adapter->devargs.fnav_stat_type;
1355 : : else
1356 : 0 : adapter->flow_ctxt.hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
1357 : :
1358 : 0 : adapter->flow_ctxt.fnav_inited = 1;
1359 : 0 : rte_spinlock_init(&adapter->flow_ctxt.flow_list_lock);
1360 : :
1361 : 0 : ret = sxe2_flow_init_udp_tunnel_port(dev);
1362 [ # # ]: 0 : if (ret)
1363 : 0 : PMD_LOG_ERR(DRV, "Failed to init udp tunnel port, ret: %d.", ret);
1364 : :
1365 : 0 : return ret;
1366 : : }
1367 : :
1368 : 0 : int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
1369 : : {
1370 : 0 : int32_t ret = 0;
1371 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1372 : 0 : struct rte_flow_error error;
1373 : 0 : struct sxe2_fnav_cid_mgr *mgr = NULL;
1374 : 0 : struct sxe2_fnav_cid_mgr *temp = NULL;
1375 : 0 : struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
1376 : : &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
1377 : :
1378 : 0 : ret = sxe2_flow_flush(dev, &error);
1379 [ # # ]: 0 : if (ret)
1380 : 0 : PMD_LOG_ERR(DRV, "Failed to flush flow, ret: %d.", ret);
1381 : :
1382 [ # # ]: 0 : TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
1383 [ # # ]: 0 : TAILQ_REMOVE(cid_mgr_list, mgr, next);
1384 : 0 : ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
1385 [ # # ]: 0 : if (ret)
1386 : 0 : PMD_LOG_ERR(DRV,
1387 : : "Failed to free fnav stat id, ret: %d.", ret);
1388 : 0 : rte_free(mgr);
1389 : : }
1390 : 0 : return ret;
1391 : : }
|