Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2020 Intel Corporation
3 : : */
4 : :
5 : : #include <sys/queue.h>
6 : : #include <stdio.h>
7 : : #include <errno.h>
8 : : #include <stdint.h>
9 : : #include <string.h>
10 : : #include <unistd.h>
11 : : #include <stdarg.h>
12 : : #include <rte_debug.h>
13 : : #include <rte_ether.h>
14 : : #include <ethdev_driver.h>
15 : : #include <rte_log.h>
16 : : #include <rte_malloc.h>
17 : : #include <rte_eth_ctrl.h>
18 : : #include <rte_tailq.h>
19 : : #include <rte_flow_driver.h>
20 : : #include <rte_flow.h>
21 : : #include <rte_bitmap.h>
22 : : #include "base/ice_type.h"
23 : : #include "base/ice_acl.h"
24 : : #include "ice_logs.h"
25 : : #include "ice_ethdev.h"
26 : : #include "ice_generic_flow.h"
27 : : #include "base/ice_flow.h"
28 : :
29 : : #define MAX_ACL_SLOTS_ID 2048
30 : :
31 : : #define ICE_ACL_INSET_ETH_IPV4 ( \
32 : : ICE_INSET_SMAC | ICE_INSET_DMAC | \
33 : : ICE_INSET_IPV4_SRC | ICE_INSET_IPV4_DST)
34 : : #define ICE_ACL_INSET_ETH_IPV4_UDP ( \
35 : : ICE_ACL_INSET_ETH_IPV4 | \
36 : : ICE_INSET_UDP_SRC_PORT | ICE_INSET_UDP_DST_PORT)
37 : : #define ICE_ACL_INSET_ETH_IPV4_TCP ( \
38 : : ICE_ACL_INSET_ETH_IPV4 | \
39 : : ICE_INSET_TCP_SRC_PORT | ICE_INSET_TCP_DST_PORT)
40 : : #define ICE_ACL_INSET_ETH_IPV4_SCTP ( \
41 : : ICE_ACL_INSET_ETH_IPV4 | \
42 : : ICE_INSET_SCTP_SRC_PORT | ICE_INSET_SCTP_DST_PORT)
43 : :
44 : : struct acl_rule {
45 : : enum ice_fltr_ptype flow_type;
46 : : uint64_t entry_id[4];
47 : : };
48 : :
49 : : static struct
50 : : ice_pattern_match_item ice_acl_supported_pattern[] = {
51 : : {pattern_eth_ipv4, ICE_ACL_INSET_ETH_IPV4, ICE_INSET_NONE, ICE_INSET_NONE},
52 : : {pattern_eth_ipv4_udp, ICE_ACL_INSET_ETH_IPV4_UDP, ICE_INSET_NONE, ICE_INSET_NONE},
53 : : {pattern_eth_ipv4_tcp, ICE_ACL_INSET_ETH_IPV4_TCP, ICE_INSET_NONE, ICE_INSET_NONE},
54 : : {pattern_eth_ipv4_sctp, ICE_ACL_INSET_ETH_IPV4_SCTP, ICE_INSET_NONE, ICE_INSET_NONE},
55 : : };
56 : :
57 : : static int
58 : 0 : ice_acl_prof_alloc(struct ice_hw *hw)
59 : : {
60 : : enum ice_fltr_ptype ptype, fltr_ptype;
61 : :
62 [ # # ]: 0 : if (!hw->acl_prof) {
63 : 0 : hw->acl_prof = (struct ice_fd_hw_prof **)
64 : 0 : ice_malloc(hw, ICE_FLTR_PTYPE_MAX *
65 : : sizeof(*hw->acl_prof));
66 [ # # ]: 0 : if (!hw->acl_prof)
67 : : return -ENOMEM;
68 : : }
69 : :
70 : : for (ptype = ICE_FLTR_PTYPE_NONF_NONE + 1;
71 [ # # ]: 0 : ptype < ICE_FLTR_PTYPE_MAX; ptype++) {
72 [ # # ]: 0 : if (!hw->acl_prof[ptype]) {
73 : 0 : hw->acl_prof[ptype] = (struct ice_fd_hw_prof *)
74 : 0 : ice_malloc(hw, sizeof(**hw->acl_prof));
75 [ # # ]: 0 : if (!hw->acl_prof[ptype])
76 : 0 : goto fail_mem;
77 : : }
78 : : }
79 : :
80 : : return 0;
81 : :
82 : : fail_mem:
83 : 0 : for (fltr_ptype = ICE_FLTR_PTYPE_NONF_NONE + 1;
84 [ # # ]: 0 : fltr_ptype < ptype; fltr_ptype++) {
85 : 0 : rte_free(hw->acl_prof[fltr_ptype]);
86 : 0 : hw->acl_prof[fltr_ptype] = NULL;
87 : : }
88 : :
89 : 0 : rte_free(hw->acl_prof);
90 : 0 : hw->acl_prof = NULL;
91 : :
92 : 0 : return -ENOMEM;
93 : : }
94 : :
95 : : /**
96 : : * ice_acl_setup - Reserve and initialize the ACL resources
97 : : * @pf: board private structure
98 : : */
99 : : static int
100 : 0 : ice_acl_setup(struct ice_pf *pf)
101 : : {
102 : 0 : struct ice_hw *hw = ICE_PF_TO_HW(pf);
103 [ # # ]: 0 : uint32_t pf_num = hw->dev_caps.num_funcs;
104 : : struct ice_acl_tbl_params params;
105 : : uint16_t scen_id;
106 : : int err = 0;
107 : :
108 : : memset(¶ms, 0, sizeof(params));
109 : :
110 : : /* create for IPV4 table */
111 [ # # ]: 0 : if (pf_num < 4)
112 : 0 : params.width = ICE_AQC_ACL_KEY_WIDTH_BYTES * 6;
113 : : else
114 : 0 : params.width = ICE_AQC_ACL_KEY_WIDTH_BYTES * 3;
115 : :
116 : 0 : params.depth = ICE_AQC_ACL_TCAM_DEPTH;
117 : 0 : params.entry_act_pairs = 1;
118 : : params.concurr = false;
119 : :
120 : 0 : err = ice_acl_create_tbl(hw, ¶ms);
121 [ # # ]: 0 : if (err)
122 : : return err;
123 : :
124 : 0 : err = ice_acl_create_scen(hw, params.width, params.depth,
125 : : &scen_id);
126 [ # # ]: 0 : if (err)
127 : 0 : return err;
128 : :
129 : : return 0;
130 : : }
131 : :
132 : : /**
133 : : * ice_deinit_acl - Unroll the initialization of the ACL block
134 : : * @pf: ptr to PF device
135 : : *
136 : : * returns 0 on success, negative on error
137 : : */
138 : 0 : static void ice_deinit_acl(struct ice_pf *pf)
139 : : {
140 : 0 : struct ice_hw *hw = ICE_PF_TO_HW(pf);
141 : :
142 : 0 : ice_acl_destroy_tbl(hw);
143 : :
144 : 0 : rte_free(hw->acl_tbl);
145 : 0 : hw->acl_tbl = NULL;
146 : :
147 [ # # ]: 0 : if (pf->acl.slots) {
148 : 0 : rte_free(pf->acl.slots);
149 : 0 : pf->acl.slots = NULL;
150 : : }
151 : 0 : }
152 : :
153 : : static void
154 : 0 : acl_add_prof_prepare(struct ice_hw *hw, struct ice_flow_seg_info *seg,
155 : : bool is_l4, uint16_t src_port, uint16_t dst_port)
156 : : {
157 : : uint16_t val_loc, mask_loc;
158 : :
159 [ # # ]: 0 : if (hw->dev_caps.num_funcs < 4) {
160 : : /* mac source address */
161 : : val_loc = offsetof(struct ice_fdir_fltr,
162 : : ext_data.src_mac);
163 : : mask_loc = offsetof(struct ice_fdir_fltr,
164 : : ext_mask.src_mac);
165 : 0 : ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_ETH_SA,
166 : : val_loc, mask_loc,
167 : : ICE_FLOW_FLD_OFF_INVAL, false);
168 : :
169 : : /* mac destination address */
170 : : val_loc = offsetof(struct ice_fdir_fltr,
171 : : ext_data.dst_mac);
172 : : mask_loc = offsetof(struct ice_fdir_fltr,
173 : : ext_mask.dst_mac);
174 : 0 : ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_ETH_DA,
175 : : val_loc, mask_loc,
176 : : ICE_FLOW_FLD_OFF_INVAL, false);
177 : : }
178 : :
179 : : /* IP source address */
180 : : val_loc = offsetof(struct ice_fdir_fltr, ip.v4.src_ip);
181 : : mask_loc = offsetof(struct ice_fdir_fltr, mask.v4.src_ip);
182 : 0 : ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV4_SA, val_loc,
183 : : mask_loc, ICE_FLOW_FLD_OFF_INVAL, false);
184 : :
185 : : /* IP destination address */
186 : : val_loc = offsetof(struct ice_fdir_fltr, ip.v4.dst_ip);
187 : : mask_loc = offsetof(struct ice_fdir_fltr, mask.v4.dst_ip);
188 : 0 : ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV4_DA, val_loc,
189 : : mask_loc, ICE_FLOW_FLD_OFF_INVAL, false);
190 : :
191 [ # # ]: 0 : if (is_l4) {
192 : : /* Layer 4 source port */
193 : : val_loc = offsetof(struct ice_fdir_fltr, ip.v4.src_port);
194 : : mask_loc = offsetof(struct ice_fdir_fltr, mask.v4.src_port);
195 : 0 : ice_flow_set_fld(seg, src_port, val_loc,
196 : : mask_loc, ICE_FLOW_FLD_OFF_INVAL, false);
197 : :
198 : : /* Layer 4 destination port */
199 : : val_loc = offsetof(struct ice_fdir_fltr, ip.v4.dst_port);
200 : : mask_loc = offsetof(struct ice_fdir_fltr, mask.v4.dst_port);
201 : 0 : ice_flow_set_fld(seg, dst_port, val_loc,
202 : : mask_loc, ICE_FLOW_FLD_OFF_INVAL, false);
203 : : }
204 : 0 : }
205 : :
206 : : /**
207 : : * ice_acl_prof_init - Initialize ACL profile
208 : : * @pf: ice PF structure
209 : : *
210 : : * Returns 0 on success.
211 : : */
212 : : static int
213 : 0 : ice_acl_prof_init(struct ice_pf *pf)
214 : : {
215 : 0 : struct ice_hw *hw = ICE_PF_TO_HW(pf);
216 : 0 : struct ice_flow_prof *prof_ipv4 = NULL;
217 : 0 : struct ice_flow_prof *prof_ipv4_udp = NULL;
218 : 0 : struct ice_flow_prof *prof_ipv4_tcp = NULL;
219 : 0 : struct ice_flow_prof *prof_ipv4_sctp = NULL;
220 : : struct ice_flow_seg_info *seg;
221 : : int i;
222 : : int ret;
223 : :
224 : : seg = (struct ice_flow_seg_info *)
225 : 0 : ice_malloc(hw, sizeof(*seg));
226 [ # # ]: 0 : if (!seg)
227 : : return -ENOMEM;
228 : :
229 : 0 : ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV4);
230 : 0 : acl_add_prof_prepare(hw, seg, false, 0, 0);
231 : 0 : ret = ice_flow_add_prof(hw, ICE_BLK_ACL, ICE_FLOW_RX,
232 : : ICE_FLTR_PTYPE_NONF_IPV4_OTHER,
233 : : seg, 1, NULL, 0, &prof_ipv4);
234 [ # # ]: 0 : if (ret)
235 : 0 : goto err_add_prof;
236 : :
237 : : ice_memset(seg, 0, sizeof(*seg), ICE_NONDMA_MEM);
238 : 0 : ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV4);
239 : 0 : acl_add_prof_prepare(hw, seg, true,
240 : : ICE_FLOW_FIELD_IDX_UDP_SRC_PORT,
241 : : ICE_FLOW_FIELD_IDX_UDP_DST_PORT);
242 : 0 : ret = ice_flow_add_prof(hw, ICE_BLK_ACL, ICE_FLOW_RX,
243 : : ICE_FLTR_PTYPE_NONF_IPV4_UDP,
244 : : seg, 1, NULL, 0, &prof_ipv4_udp);
245 [ # # ]: 0 : if (ret)
246 : 0 : goto err_add_prof_ipv4_udp;
247 : :
248 : : ice_memset(seg, 0, sizeof(*seg), ICE_NONDMA_MEM);
249 : 0 : ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV4);
250 : 0 : acl_add_prof_prepare(hw, seg, true,
251 : : ICE_FLOW_FIELD_IDX_TCP_SRC_PORT,
252 : : ICE_FLOW_FIELD_IDX_TCP_DST_PORT);
253 : 0 : ret = ice_flow_add_prof(hw, ICE_BLK_ACL, ICE_FLOW_RX,
254 : : ICE_FLTR_PTYPE_NONF_IPV4_TCP,
255 : : seg, 1, NULL, 0, &prof_ipv4_tcp);
256 [ # # ]: 0 : if (ret)
257 : 0 : goto err_add_prof_ipv4_tcp;
258 : :
259 : : ice_memset(seg, 0, sizeof(*seg), ICE_NONDMA_MEM);
260 : 0 : ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV4);
261 : 0 : acl_add_prof_prepare(hw, seg, true,
262 : : ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT,
263 : : ICE_FLOW_FIELD_IDX_SCTP_DST_PORT);
264 : 0 : ret = ice_flow_add_prof(hw, ICE_BLK_ACL, ICE_FLOW_RX,
265 : : ICE_FLTR_PTYPE_NONF_IPV4_SCTP,
266 : : seg, 1, NULL, 0, &prof_ipv4_sctp);
267 [ # # ]: 0 : if (ret)
268 : 0 : goto err_add_prof_ipv4_sctp;
269 : :
270 [ # # ]: 0 : for (i = 0; i < pf->main_vsi->idx; i++) {
271 : 0 : ret = ice_flow_assoc_prof(hw, ICE_BLK_ACL, prof_ipv4, i);
272 [ # # ]: 0 : if (ret)
273 : 0 : goto err_assoc_prof;
274 : :
275 : 0 : ret = ice_flow_assoc_prof(hw, ICE_BLK_ACL, prof_ipv4_udp, i);
276 [ # # ]: 0 : if (ret)
277 : 0 : goto err_assoc_prof;
278 : :
279 : 0 : ret = ice_flow_assoc_prof(hw, ICE_BLK_ACL, prof_ipv4_tcp, i);
280 [ # # ]: 0 : if (ret)
281 : 0 : goto err_assoc_prof;
282 : :
283 : 0 : ret = ice_flow_assoc_prof(hw, ICE_BLK_ACL, prof_ipv4_sctp, i);
284 [ # # ]: 0 : if (ret)
285 : 0 : goto err_assoc_prof;
286 : : }
287 : : return 0;
288 : :
289 : 0 : err_assoc_prof:
290 : 0 : ice_flow_rem_prof(hw, ICE_BLK_ACL, ICE_FLTR_PTYPE_NONF_IPV4_SCTP);
291 : 0 : err_add_prof_ipv4_sctp:
292 : 0 : ice_flow_rem_prof(hw, ICE_BLK_ACL, ICE_FLTR_PTYPE_NONF_IPV4_TCP);
293 : 0 : err_add_prof_ipv4_tcp:
294 : 0 : ice_flow_rem_prof(hw, ICE_BLK_ACL, ICE_FLTR_PTYPE_NONF_IPV4_UDP);
295 : 0 : err_add_prof_ipv4_udp:
296 : 0 : ice_flow_rem_prof(hw, ICE_BLK_ACL, ICE_FLTR_PTYPE_NONF_IPV4_OTHER);
297 : 0 : err_add_prof:
298 : 0 : ice_free(hw, seg);
299 : 0 : return ret;
300 : : }
301 : :
302 : : /**
303 : : * ice_acl_set_input_set - Helper function to set the input set for ACL
304 : : * @hw: pointer to HW instance
305 : : * @filter: pointer to ACL info
306 : : * @input: filter structure
307 : : *
308 : : * Return error value or 0 on success.
309 : : */
310 : : static int
311 : 0 : ice_acl_set_input_set(struct ice_acl_conf *filter, struct ice_fdir_fltr *input)
312 : : {
313 [ # # ]: 0 : if (!input)
314 : : return ICE_ERR_BAD_PTR;
315 : :
316 : 0 : input->q_index = filter->input.q_index;
317 : 0 : input->dest_vsi = filter->input.dest_vsi;
318 : 0 : input->dest_ctl = filter->input.dest_ctl;
319 : 0 : input->fltr_status = ICE_FLTR_PRGM_DESC_FD_STATUS_FD_ID;
320 : 0 : input->flow_type = filter->input.flow_type;
321 : :
322 [ # # # ]: 0 : switch (input->flow_type) {
323 : 0 : case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
324 : : case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
325 : : case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
326 : 0 : input->ip.v4.dst_port = filter->input.ip.v4.dst_port;
327 : 0 : input->ip.v4.src_port = filter->input.ip.v4.src_port;
328 : 0 : input->ip.v4.dst_ip = filter->input.ip.v4.dst_ip;
329 : 0 : input->ip.v4.src_ip = filter->input.ip.v4.src_ip;
330 : :
331 : 0 : input->mask.v4.dst_port = filter->input.mask.v4.dst_port;
332 : 0 : input->mask.v4.src_port = filter->input.mask.v4.src_port;
333 : 0 : input->mask.v4.dst_ip = filter->input.mask.v4.dst_ip;
334 : 0 : input->mask.v4.src_ip = filter->input.mask.v4.src_ip;
335 : :
336 [ # # ]: 0 : ice_memcpy(&input->ext_data.src_mac,
337 : : &filter->input.ext_data.src_mac,
338 : : RTE_ETHER_ADDR_LEN,
339 : : ICE_NONDMA_TO_NONDMA);
340 : :
341 [ # # ]: 0 : ice_memcpy(&input->ext_mask.src_mac,
342 : : &filter->input.ext_mask.src_mac,
343 : : RTE_ETHER_ADDR_LEN,
344 : : ICE_NONDMA_TO_NONDMA);
345 : :
346 [ # # ]: 0 : ice_memcpy(&input->ext_data.dst_mac,
347 : : &filter->input.ext_data.dst_mac,
348 : : RTE_ETHER_ADDR_LEN,
349 : : ICE_NONDMA_TO_NONDMA);
350 [ # # ]: 0 : ice_memcpy(&input->ext_mask.dst_mac,
351 : : &filter->input.ext_mask.dst_mac,
352 : : RTE_ETHER_ADDR_LEN,
353 : : ICE_NONDMA_TO_NONDMA);
354 : :
355 : : break;
356 : 0 : case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
357 [ # # ]: 0 : ice_memcpy(&input->ip.v4, &filter->input.ip.v4,
358 : : sizeof(struct ice_fdir_v4),
359 : : ICE_NONDMA_TO_NONDMA);
360 [ # # ]: 0 : ice_memcpy(&input->mask.v4, &filter->input.mask.v4,
361 : : sizeof(struct ice_fdir_v4),
362 : : ICE_NONDMA_TO_NONDMA);
363 : :
364 [ # # ]: 0 : ice_memcpy(&input->ext_data.src_mac,
365 : : &filter->input.ext_data.src_mac,
366 : : RTE_ETHER_ADDR_LEN,
367 : : ICE_NONDMA_TO_NONDMA);
368 [ # # ]: 0 : ice_memcpy(&input->ext_mask.src_mac,
369 : : &filter->input.ext_mask.src_mac,
370 : : RTE_ETHER_ADDR_LEN,
371 : : ICE_NONDMA_TO_NONDMA);
372 : :
373 [ # # ]: 0 : ice_memcpy(&input->ext_data.dst_mac,
374 : : &filter->input.ext_data.dst_mac,
375 : : RTE_ETHER_ADDR_LEN,
376 : : ICE_NONDMA_TO_NONDMA);
377 [ # # ]: 0 : ice_memcpy(&input->ext_mask.dst_mac,
378 : : &filter->input.ext_mask.dst_mac,
379 : : RTE_ETHER_ADDR_LEN,
380 : : ICE_NONDMA_TO_NONDMA);
381 : :
382 : : break;
383 : : default:
384 : : return -EINVAL;
385 : : }
386 : :
387 : : return 0;
388 : : }
389 : :
390 : : static inline int
391 : 0 : ice_acl_alloc_slot_id(struct rte_bitmap *slots, uint32_t *slot_id)
392 : : {
393 : 0 : uint32_t pos = 0;
394 : 0 : uint64_t slab = 0;
395 : : uint32_t i = 0;
396 : :
397 : : __rte_bitmap_scan_init(slots);
398 [ # # ]: 0 : if (!rte_bitmap_scan(slots, &pos, &slab))
399 : 0 : return -rte_errno;
400 : :
401 : 0 : i = rte_bsf64(slab);
402 : 0 : pos += i;
403 : 0 : rte_bitmap_clear(slots, pos);
404 : :
405 : 0 : *slot_id = pos;
406 : 0 : return 0;
407 : : }
408 : :
409 : : static inline int
410 : 0 : ice_acl_hw_set_conf(struct ice_pf *pf, struct ice_fdir_fltr *input,
411 : : struct ice_flow_action *acts, struct acl_rule *rule,
412 : : enum ice_fltr_ptype flow_type, int32_t entry_idx)
413 : : {
414 : 0 : struct ice_hw *hw = ICE_PF_TO_HW(pf);
415 : : enum ice_block blk = ICE_BLK_ACL;
416 : : uint64_t entry_id, hw_entry;
417 : 0 : uint32_t slot_id = 0;
418 : : int act_cnt = 1;
419 : : int ret = 0;
420 : :
421 : : /* Allocate slot_id from bitmap table. */
422 : 0 : ret = ice_acl_alloc_slot_id(pf->acl.slots, &slot_id);
423 [ # # ]: 0 : if (ret) {
424 : 0 : PMD_DRV_LOG(ERR, "fail to alloc slot id.");
425 : 0 : return ret;
426 : : }
427 : :
428 : : /* For IPV4_OTHER type, should add entry for all types.
429 : : * For IPV4_UDP/TCP/SCTP type, only add entry for each.
430 : : */
431 [ # # ]: 0 : if (slot_id < MAX_ACL_NORMAL_ENTRIES) {
432 : 0 : entry_id = ((uint64_t)flow_type << 32) | slot_id;
433 : 0 : ret = ice_flow_add_entry(hw, blk, flow_type,
434 : 0 : entry_id, pf->main_vsi->idx,
435 : : ICE_FLOW_PRIO_NORMAL, input,
436 : : acts, act_cnt, &hw_entry);
437 [ # # ]: 0 : if (ret) {
438 : 0 : PMD_DRV_LOG(ERR, "Fail to add entry.");
439 : 0 : return ret;
440 : : }
441 : 0 : rule->entry_id[entry_idx] = entry_id;
442 : 0 : pf->acl.hw_entry_id[slot_id] = hw_entry;
443 : : } else {
444 : 0 : PMD_DRV_LOG(ERR, "Exceed the maximum entry number(%d)"
445 : : " HW supported!", MAX_ACL_NORMAL_ENTRIES);
446 : 0 : return -1;
447 : : }
448 : :
449 : 0 : return 0;
450 : : }
451 : :
452 : : static inline void
453 : 0 : ice_acl_del_entry(struct ice_hw *hw, uint64_t entry_id)
454 : : {
455 : : uint64_t hw_entry;
456 : :
457 : 0 : hw_entry = ice_flow_find_entry(hw, ICE_BLK_ACL, entry_id);
458 : 0 : ice_flow_rem_entry(hw, ICE_BLK_ACL, hw_entry);
459 : 0 : }
460 : :
461 : : static inline void
462 : 0 : ice_acl_hw_rem_conf(struct ice_pf *pf, struct acl_rule *rule, int32_t entry_idx)
463 : : {
464 : : uint32_t slot_id;
465 : : int32_t i;
466 : : uint64_t entry_id;
467 : 0 : struct ice_hw *hw = ICE_PF_TO_HW(pf);
468 : :
469 [ # # ]: 0 : for (i = 0; i < entry_idx; i++) {
470 : 0 : entry_id = rule->entry_id[i];
471 : 0 : slot_id = ICE_LO_DWORD(entry_id);
472 : 0 : rte_bitmap_set(pf->acl.slots, slot_id);
473 : 0 : ice_acl_del_entry(hw, entry_id);
474 : : }
475 : 0 : }
476 : :
477 : : static int
478 : 0 : ice_acl_create_filter(struct ice_adapter *ad,
479 : : struct rte_flow *flow,
480 : : void *meta,
481 : : struct rte_flow_error *error)
482 : : {
483 : : struct ice_acl_conf *filter = meta;
484 : 0 : enum ice_fltr_ptype flow_type = filter->input.flow_type;
485 : : struct ice_flow_action acts[1];
486 : 0 : struct ice_pf *pf = &ad->pf;
487 : : struct ice_fdir_fltr *input;
488 : : struct acl_rule *rule;
489 : : int ret;
490 : :
491 : 0 : rule = rte_zmalloc("acl_rule", sizeof(*rule), 0);
492 [ # # ]: 0 : if (!rule) {
493 : 0 : rte_flow_error_set(error, ENOMEM,
494 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
495 : : "Failed to allocate memory for acl rule");
496 : 0 : return -rte_errno;
497 : : }
498 : :
499 : 0 : input = rte_zmalloc("acl_entry", sizeof(*input), 0);
500 [ # # ]: 0 : if (!input) {
501 : 0 : rte_flow_error_set(error, ENOMEM,
502 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
503 : : "Failed to allocate memory for acl input");
504 : 0 : ret = -rte_errno;
505 : 0 : goto err_acl_input_alloc;
506 : : }
507 : :
508 : 0 : ret = ice_acl_set_input_set(filter, input);
509 [ # # ]: 0 : if (ret) {
510 : 0 : rte_flow_error_set(error, -ret,
511 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
512 : : "failed to set input set.");
513 : 0 : ret = -rte_errno;
514 : 0 : goto err_acl_set_input;
515 : : }
516 : :
517 [ # # ]: 0 : if (filter->input.dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) {
518 : 0 : acts[0].type = ICE_FLOW_ACT_DROP;
519 : 0 : acts[0].data.acl_act.mdid = ICE_MDID_RX_PKT_DROP;
520 : 0 : acts[0].data.acl_act.prio = 0x3;
521 : 0 : acts[0].data.acl_act.value = CPU_TO_LE16(0x1);
522 : : }
523 : :
524 : 0 : input->acl_fltr = true;
525 : 0 : ret = ice_acl_hw_set_conf(pf, input, acts, rule, flow_type, 0);
526 [ # # ]: 0 : if (ret) {
527 : 0 : rte_flow_error_set(error, -ret,
528 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
529 : : "failed to set hw configure.");
530 : 0 : ret = -rte_errno;
531 : 0 : return ret;
532 : : }
533 : :
534 [ # # ]: 0 : if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
535 : 0 : ret = ice_acl_hw_set_conf(pf, input, acts, rule,
536 : : ICE_FLTR_PTYPE_NONF_IPV4_UDP, 1);
537 [ # # ]: 0 : if (ret)
538 : 0 : goto err_acl_hw_set_conf_udp;
539 : 0 : ret = ice_acl_hw_set_conf(pf, input, acts, rule,
540 : : ICE_FLTR_PTYPE_NONF_IPV4_TCP, 2);
541 [ # # ]: 0 : if (ret)
542 : 0 : goto err_acl_hw_set_conf_tcp;
543 : 0 : ret = ice_acl_hw_set_conf(pf, input, acts, rule,
544 : : ICE_FLTR_PTYPE_NONF_IPV4_SCTP, 3);
545 [ # # ]: 0 : if (ret)
546 : 0 : goto err_acl_hw_set_conf_sctp;
547 : : }
548 : :
549 : 0 : rule->flow_type = flow_type;
550 : 0 : flow->rule = rule;
551 : 0 : return 0;
552 : :
553 : : err_acl_hw_set_conf_sctp:
554 : 0 : ice_acl_hw_rem_conf(pf, rule, 3);
555 : 0 : err_acl_hw_set_conf_tcp:
556 : 0 : ice_acl_hw_rem_conf(pf, rule, 2);
557 : 0 : err_acl_hw_set_conf_udp:
558 : 0 : ice_acl_hw_rem_conf(pf, rule, 1);
559 : 0 : err_acl_set_input:
560 : 0 : rte_free(input);
561 : 0 : err_acl_input_alloc:
562 : 0 : rte_free(rule);
563 : 0 : return ret;
564 : : }
565 : :
566 : : static int
567 : 0 : ice_acl_destroy_filter(struct ice_adapter *ad,
568 : : struct rte_flow *flow,
569 : : struct rte_flow_error *error __rte_unused)
570 : : {
571 : 0 : struct acl_rule *rule = (struct acl_rule *)flow->rule;
572 : : uint32_t slot_id, i;
573 : : uint64_t entry_id;
574 : : struct ice_pf *pf = &ad->pf;
575 : 0 : struct ice_hw *hw = ICE_PF_TO_HW(pf);
576 : : int ret = 0;
577 : :
578 [ # # # ]: 0 : switch (rule->flow_type) {
579 : : case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
580 [ # # ]: 0 : for (i = 0; i < 4; i++) {
581 : 0 : entry_id = rule->entry_id[i];
582 : 0 : slot_id = ICE_LO_DWORD(entry_id);
583 : 0 : rte_bitmap_set(pf->acl.slots, slot_id);
584 : 0 : ice_acl_del_entry(hw, entry_id);
585 : : }
586 : : break;
587 : 0 : case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
588 : : case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
589 : : case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
590 : 0 : entry_id = rule->entry_id[0];
591 : 0 : slot_id = ICE_LO_DWORD(entry_id);
592 : 0 : rte_bitmap_set(pf->acl.slots, slot_id);
593 : 0 : ice_acl_del_entry(hw, entry_id);
594 : 0 : break;
595 : 0 : default:
596 : 0 : rte_flow_error_set(error, EINVAL,
597 : : RTE_FLOW_ERROR_TYPE_ITEM,
598 : : NULL, "Unsupported flow type.");
599 : 0 : break;
600 : : }
601 : :
602 : 0 : flow->rule = NULL;
603 : 0 : rte_free(rule);
604 : 0 : return ret;
605 : : }
606 : :
607 : : static void
608 : 0 : ice_acl_filter_free(struct rte_flow *flow)
609 : : {
610 : 0 : rte_free(flow->rule);
611 : 0 : flow->rule = NULL;
612 : 0 : }
613 : :
614 : : static int
615 : 0 : ice_acl_parse_action(__rte_unused struct ice_adapter *ad,
616 : : const struct rte_flow_action actions[],
617 : : struct rte_flow_error *error,
618 : : struct ice_acl_conf *filter)
619 : : {
620 : : uint32_t dest_num = 0;
621 : :
622 [ # # ]: 0 : for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
623 [ # # # ]: 0 : switch (actions->type) {
624 : : case RTE_FLOW_ACTION_TYPE_VOID:
625 : : break;
626 : 0 : case RTE_FLOW_ACTION_TYPE_DROP:
627 : 0 : dest_num++;
628 : :
629 : 0 : filter->input.dest_ctl =
630 : : ICE_FLTR_PRGM_DESC_DEST_DROP_PKT;
631 : 0 : break;
632 : 0 : default:
633 : 0 : rte_flow_error_set(error, EINVAL,
634 : : RTE_FLOW_ERROR_TYPE_ACTION, actions,
635 : : "Invalid action.");
636 : 0 : return -rte_errno;
637 : : }
638 : : }
639 : :
640 [ # # ]: 0 : if (dest_num == 0 || dest_num >= 2) {
641 : 0 : rte_flow_error_set(error, EINVAL,
642 : : RTE_FLOW_ERROR_TYPE_ACTION, actions,
643 : : "Unsupported action combination");
644 : 0 : return -rte_errno;
645 : : }
646 : :
647 : : return 0;
648 : : }
649 : :
650 : : static int
651 : 0 : ice_acl_parse_pattern(__rte_unused struct ice_adapter *ad,
652 : : const struct rte_flow_item pattern[],
653 : : struct rte_flow_error *error,
654 : : struct ice_acl_conf *filter)
655 : : {
656 : : const struct rte_flow_item *item = pattern;
657 : : enum rte_flow_item_type item_type;
658 : : enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
659 : : const struct rte_flow_item_eth *eth_spec, *eth_mask;
660 : : const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_mask;
661 : : const struct rte_flow_item_tcp *tcp_spec, *tcp_mask;
662 : : const struct rte_flow_item_udp *udp_spec, *udp_mask;
663 : : const struct rte_flow_item_sctp *sctp_spec, *sctp_mask;
664 : : uint64_t input_set = ICE_INSET_NONE;
665 : : uint8_t flow_type = ICE_FLTR_PTYPE_NONF_NONE;
666 : :
667 [ # # ]: 0 : for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
668 : : item_type = item->type;
669 : :
670 [ # # # # : 0 : switch (item_type) {
# # # ]
671 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
672 : 0 : eth_spec = item->spec;
673 : 0 : eth_mask = item->mask;
674 : :
675 [ # # ]: 0 : if (eth_spec && eth_mask) {
676 [ # # # # ]: 0 : if (rte_is_broadcast_ether_addr(ð_mask->hdr.src_addr) ||
677 : : rte_is_broadcast_ether_addr(ð_mask->hdr.dst_addr)) {
678 : 0 : rte_flow_error_set(error, EINVAL,
679 : : RTE_FLOW_ERROR_TYPE_ITEM,
680 : : item, "Invalid mac addr mask");
681 : 0 : return -rte_errno;
682 : : }
683 : :
684 [ # # # # ]: 0 : if (!rte_is_zero_ether_addr(ð_spec->hdr.src_addr) &&
685 : : !rte_is_zero_ether_addr(ð_mask->hdr.src_addr)) {
686 : 0 : input_set |= ICE_INSET_SMAC;
687 [ # # ]: 0 : ice_memcpy(&filter->input.ext_data.src_mac,
688 : : ð_spec->hdr.src_addr,
689 : : RTE_ETHER_ADDR_LEN,
690 : : ICE_NONDMA_TO_NONDMA);
691 [ # # ]: 0 : ice_memcpy(&filter->input.ext_mask.src_mac,
692 : : ð_mask->hdr.src_addr,
693 : : RTE_ETHER_ADDR_LEN,
694 : : ICE_NONDMA_TO_NONDMA);
695 : : }
696 : :
697 [ # # # # ]: 0 : if (!rte_is_zero_ether_addr(ð_spec->hdr.dst_addr) &&
698 : : !rte_is_zero_ether_addr(ð_mask->hdr.dst_addr)) {
699 : 0 : input_set |= ICE_INSET_DMAC;
700 [ # # ]: 0 : ice_memcpy(&filter->input.ext_data.dst_mac,
701 : : ð_spec->hdr.dst_addr,
702 : : RTE_ETHER_ADDR_LEN,
703 : : ICE_NONDMA_TO_NONDMA);
704 [ # # ]: 0 : ice_memcpy(&filter->input.ext_mask.dst_mac,
705 : : ð_mask->hdr.dst_addr,
706 : : RTE_ETHER_ADDR_LEN,
707 : : ICE_NONDMA_TO_NONDMA);
708 : : }
709 : : }
710 : : break;
711 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
712 : : l3 = RTE_FLOW_ITEM_TYPE_IPV4;
713 : 0 : ipv4_spec = item->spec;
714 : 0 : ipv4_mask = item->mask;
715 : :
716 [ # # ]: 0 : if (ipv4_spec && ipv4_mask) {
717 : : /* Check IPv4 mask and update input set */
718 [ # # ]: 0 : if (ipv4_mask->hdr.version_ihl ||
719 [ # # ]: 0 : ipv4_mask->hdr.total_length ||
720 [ # # ]: 0 : ipv4_mask->hdr.packet_id ||
721 [ # # ]: 0 : ipv4_mask->hdr.fragment_offset ||
722 [ # # ]: 0 : ipv4_mask->hdr.hdr_checksum) {
723 : 0 : rte_flow_error_set(error, EINVAL,
724 : : RTE_FLOW_ERROR_TYPE_ITEM,
725 : : item,
726 : : "Invalid IPv4 mask.");
727 : 0 : return -rte_errno;
728 : : }
729 : :
730 [ # # ]: 0 : if (ipv4_mask->hdr.src_addr == UINT32_MAX ||
731 [ # # ]: 0 : ipv4_mask->hdr.dst_addr == UINT32_MAX) {
732 : 0 : rte_flow_error_set(error, EINVAL,
733 : : RTE_FLOW_ERROR_TYPE_ITEM,
734 : : item,
735 : : "Invalid IPv4 mask.");
736 : 0 : return -rte_errno;
737 : : }
738 : :
739 [ # # ]: 0 : if (ipv4_mask->hdr.src_addr) {
740 : 0 : filter->input.ip.v4.src_ip =
741 : 0 : ipv4_spec->hdr.src_addr;
742 : 0 : filter->input.mask.v4.src_ip =
743 : : ipv4_mask->hdr.src_addr;
744 : :
745 : 0 : input_set |= ICE_INSET_IPV4_SRC;
746 : : }
747 : :
748 [ # # ]: 0 : if (ipv4_mask->hdr.dst_addr) {
749 : 0 : filter->input.ip.v4.dst_ip =
750 : 0 : ipv4_spec->hdr.dst_addr;
751 : 0 : filter->input.mask.v4.dst_ip =
752 : : ipv4_mask->hdr.dst_addr;
753 : :
754 : 0 : input_set |= ICE_INSET_IPV4_DST;
755 : : }
756 : : }
757 : :
758 : : flow_type = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
759 : : break;
760 : 0 : case RTE_FLOW_ITEM_TYPE_TCP:
761 : 0 : tcp_spec = item->spec;
762 : 0 : tcp_mask = item->mask;
763 : :
764 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
765 : : flow_type = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
766 : :
767 [ # # ]: 0 : if (tcp_spec && tcp_mask) {
768 : : /* Check TCP mask and update input set */
769 [ # # ]: 0 : if (tcp_mask->hdr.sent_seq ||
770 [ # # ]: 0 : tcp_mask->hdr.recv_ack ||
771 [ # # ]: 0 : tcp_mask->hdr.data_off ||
772 [ # # ]: 0 : tcp_mask->hdr.tcp_flags ||
773 [ # # ]: 0 : tcp_mask->hdr.rx_win ||
774 [ # # ]: 0 : tcp_mask->hdr.cksum ||
775 [ # # ]: 0 : tcp_mask->hdr.tcp_urp) {
776 : 0 : rte_flow_error_set(error, EINVAL,
777 : : RTE_FLOW_ERROR_TYPE_ITEM,
778 : : item,
779 : : "Invalid TCP mask");
780 : 0 : return -rte_errno;
781 : : }
782 : :
783 [ # # ]: 0 : if (tcp_mask->hdr.src_port == UINT16_MAX ||
784 [ # # ]: 0 : tcp_mask->hdr.dst_port == UINT16_MAX) {
785 : 0 : rte_flow_error_set(error, EINVAL,
786 : : RTE_FLOW_ERROR_TYPE_ITEM,
787 : : item,
788 : : "Invalid TCP mask");
789 : 0 : return -rte_errno;
790 : : }
791 : :
792 [ # # # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4 &&
793 : : tcp_mask->hdr.src_port) {
794 : 0 : input_set |= ICE_INSET_TCP_SRC_PORT;
795 : 0 : filter->input.ip.v4.src_port =
796 : 0 : tcp_spec->hdr.src_port;
797 : 0 : filter->input.mask.v4.src_port =
798 : : tcp_mask->hdr.src_port;
799 : : }
800 : :
801 [ # # # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4 &&
802 : : tcp_mask->hdr.dst_port) {
803 : 0 : input_set |= ICE_INSET_TCP_DST_PORT;
804 : 0 : filter->input.ip.v4.dst_port =
805 : 0 : tcp_spec->hdr.dst_port;
806 : 0 : filter->input.mask.v4.dst_port =
807 : : tcp_mask->hdr.dst_port;
808 : : }
809 : : }
810 : : break;
811 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
812 : 0 : udp_spec = item->spec;
813 : 0 : udp_mask = item->mask;
814 : :
815 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
816 : : flow_type = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
817 : :
818 [ # # ]: 0 : if (udp_spec && udp_mask) {
819 : : /* Check UDP mask and update input set*/
820 [ # # ]: 0 : if (udp_mask->hdr.dgram_len ||
821 [ # # ]: 0 : udp_mask->hdr.dgram_cksum) {
822 : 0 : rte_flow_error_set(error, EINVAL,
823 : : RTE_FLOW_ERROR_TYPE_ITEM,
824 : : item,
825 : : "Invalid UDP mask");
826 : 0 : return -rte_errno;
827 : : }
828 : :
829 [ # # ]: 0 : if (udp_mask->hdr.src_port == UINT16_MAX ||
830 [ # # ]: 0 : udp_mask->hdr.dst_port == UINT16_MAX) {
831 : 0 : rte_flow_error_set(error, EINVAL,
832 : : RTE_FLOW_ERROR_TYPE_ITEM,
833 : : item,
834 : : "Invalid UDP mask");
835 : 0 : return -rte_errno;
836 : : }
837 : :
838 [ # # # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4 &&
839 : : udp_mask->hdr.src_port) {
840 : 0 : input_set |= ICE_INSET_UDP_SRC_PORT;
841 : 0 : filter->input.ip.v4.src_port =
842 : 0 : udp_spec->hdr.src_port;
843 : 0 : filter->input.mask.v4.src_port =
844 : : udp_mask->hdr.src_port;
845 : : }
846 : :
847 [ # # # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4 &&
848 : : udp_mask->hdr.dst_port) {
849 : 0 : input_set |= ICE_INSET_UDP_DST_PORT;
850 : 0 : filter->input.ip.v4.dst_port =
851 : 0 : udp_spec->hdr.dst_port;
852 : 0 : filter->input.mask.v4.dst_port =
853 : : udp_mask->hdr.dst_port;
854 : : }
855 : : }
856 : : break;
857 : 0 : case RTE_FLOW_ITEM_TYPE_SCTP:
858 : 0 : sctp_spec = item->spec;
859 : 0 : sctp_mask = item->mask;
860 : :
861 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
862 : : flow_type = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
863 : :
864 [ # # ]: 0 : if (sctp_spec && sctp_mask) {
865 [ # # ]: 0 : if (sctp_mask->hdr.src_port == UINT16_MAX ||
866 [ # # ]: 0 : sctp_mask->hdr.dst_port == UINT16_MAX) {
867 : 0 : rte_flow_error_set(error, EINVAL,
868 : : RTE_FLOW_ERROR_TYPE_ITEM,
869 : : item,
870 : : "Invalid SCTP mask");
871 : 0 : return -rte_errno;
872 : : }
873 : :
874 [ # # # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4 &&
875 : : sctp_mask->hdr.src_port) {
876 : 0 : input_set |= ICE_INSET_SCTP_SRC_PORT;
877 : 0 : filter->input.ip.v4.src_port =
878 : 0 : sctp_spec->hdr.src_port;
879 : 0 : filter->input.mask.v4.src_port =
880 : : sctp_mask->hdr.src_port;
881 : : }
882 : :
883 [ # # # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4 &&
884 : : sctp_mask->hdr.dst_port) {
885 : 0 : input_set |= ICE_INSET_SCTP_DST_PORT;
886 : 0 : filter->input.ip.v4.dst_port =
887 : 0 : sctp_spec->hdr.dst_port;
888 : 0 : filter->input.mask.v4.dst_port =
889 : : sctp_mask->hdr.dst_port;
890 : : }
891 : : }
892 : : break;
893 : : case RTE_FLOW_ITEM_TYPE_VOID:
894 : : break;
895 : 0 : default:
896 : 0 : rte_flow_error_set(error, EINVAL,
897 : : RTE_FLOW_ERROR_TYPE_ITEM,
898 : : item,
899 : : "Invalid pattern item.");
900 : 0 : return -rte_errno;
901 : : }
902 : : }
903 : :
904 : 0 : filter->input.flow_type = flow_type;
905 : 0 : filter->input_set = input_set;
906 : :
907 : 0 : return 0;
908 : : }
909 : :
910 : : static int
911 : 0 : ice_acl_parse(struct ice_adapter *ad,
912 : : struct ice_pattern_match_item *array,
913 : : uint32_t array_len,
914 : : const struct rte_flow_item pattern[],
915 : : const struct rte_flow_action actions[],
916 : : uint32_t priority,
917 : : void **meta,
918 : : struct rte_flow_error *error)
919 : : {
920 : : struct ice_pf *pf = &ad->pf;
921 : 0 : struct ice_acl_conf *filter = &pf->acl.conf;
922 : : struct ice_pattern_match_item *item = NULL;
923 : : uint64_t input_set;
924 : : int ret;
925 : :
926 [ # # ]: 0 : if (priority >= 1)
927 : 0 : return -rte_errno;
928 : :
929 : : memset(filter, 0, sizeof(*filter));
930 : 0 : item = ice_search_pattern_match_item(ad, pattern, array, array_len,
931 : : error);
932 [ # # ]: 0 : if (!item)
933 : 0 : return -rte_errno;
934 : :
935 : 0 : ret = ice_acl_parse_pattern(ad, pattern, error, filter);
936 [ # # ]: 0 : if (ret)
937 : 0 : goto error;
938 : 0 : input_set = filter->input_set;
939 [ # # # # ]: 0 : if (!input_set || input_set & ~item->input_set_mask_o) {
940 : 0 : rte_flow_error_set(error, EINVAL,
941 : : RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
942 : : pattern,
943 : : "Invalid input set");
944 : 0 : ret = -rte_errno;
945 : 0 : goto error;
946 : : }
947 : :
948 : 0 : ret = ice_acl_parse_action(ad, actions, error, filter);
949 [ # # ]: 0 : if (ret)
950 : 0 : goto error;
951 : :
952 [ # # ]: 0 : if (meta)
953 : 0 : *meta = filter;
954 : :
955 : 0 : error:
956 : 0 : rte_free(item);
957 : 0 : return ret;
958 : : }
959 : :
960 : : static int
961 : 0 : ice_acl_bitmap_init(struct ice_pf *pf)
962 : : {
963 : : uint32_t bmp_size;
964 : : void *mem = NULL;
965 : : struct rte_bitmap *slots;
966 : : int ret = 0;
967 : : bmp_size = rte_bitmap_get_memory_footprint(MAX_ACL_SLOTS_ID);
968 : 0 : mem = rte_zmalloc("create_acl_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
969 [ # # ]: 0 : if (mem == NULL) {
970 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory for acl bitmap.");
971 : 0 : return -rte_errno;
972 : : }
973 : :
974 : 0 : slots = rte_bitmap_init_with_all_set(MAX_ACL_SLOTS_ID, mem, bmp_size);
975 [ # # ]: 0 : if (slots == NULL) {
976 : 0 : PMD_DRV_LOG(ERR, "Failed to initialize acl bitmap.");
977 : 0 : ret = -rte_errno;
978 : 0 : goto err_acl_mem_alloc;
979 : : }
980 : 0 : pf->acl.slots = slots;
981 : 0 : return 0;
982 : :
983 : : err_acl_mem_alloc:
984 : 0 : rte_free(mem);
985 : 0 : return ret;
986 : : }
987 : :
988 : : static int
989 : 0 : ice_acl_init(struct ice_adapter *ad)
990 : : {
991 : : int ret = 0;
992 : 0 : struct ice_pf *pf = &ad->pf;
993 : 0 : struct ice_hw *hw = ICE_PF_TO_HW(pf);
994 : :
995 : 0 : ret = ice_acl_prof_alloc(hw);
996 [ # # ]: 0 : if (ret) {
997 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate memory for "
998 : : "ACL profile.");
999 : 0 : return -ENOMEM;
1000 : : }
1001 : :
1002 : 0 : ret = ice_acl_setup(pf);
1003 [ # # ]: 0 : if (ret)
1004 : : return ret;
1005 : :
1006 : 0 : ret = ice_acl_bitmap_init(pf);
1007 [ # # ]: 0 : if (ret)
1008 : : return ret;
1009 : :
1010 : 0 : return ice_acl_prof_init(pf);
1011 : : }
1012 : :
1013 : : static void
1014 : 0 : ice_acl_prof_free(struct ice_hw *hw)
1015 : : {
1016 : : enum ice_fltr_ptype ptype;
1017 : :
1018 : 0 : for (ptype = ICE_FLTR_PTYPE_NONF_NONE + 1;
1019 [ # # ]: 0 : ptype < ICE_FLTR_PTYPE_MAX; ptype++) {
1020 : 0 : rte_free(hw->acl_prof[ptype]);
1021 : 0 : hw->acl_prof[ptype] = NULL;
1022 : : }
1023 : :
1024 : 0 : rte_free(hw->acl_prof);
1025 : 0 : hw->acl_prof = NULL;
1026 : 0 : }
1027 : :
1028 : : static void
1029 : 0 : ice_acl_uninit(struct ice_adapter *ad)
1030 : : {
1031 : 0 : struct ice_pf *pf = &ad->pf;
1032 : 0 : struct ice_hw *hw = ICE_PF_TO_HW(pf);
1033 : :
1034 [ # # ]: 0 : if (ad->hw.dcf_enabled) {
1035 : 0 : ice_deinit_acl(pf);
1036 : 0 : ice_acl_prof_free(hw);
1037 : : }
1038 : 0 : }
1039 : :
1040 : : static struct
1041 : : ice_flow_engine ice_acl_engine = {
1042 : : .init = ice_acl_init,
1043 : : .uninit = ice_acl_uninit,
1044 : : .create = ice_acl_create_filter,
1045 : : .destroy = ice_acl_destroy_filter,
1046 : : .free = ice_acl_filter_free,
1047 : : .type = ICE_FLOW_ENGINE_ACL,
1048 : : };
1049 : :
1050 : : struct
1051 : : ice_flow_parser ice_acl_parser = {
1052 : : .engine = &ice_acl_engine,
1053 : : .array = ice_acl_supported_pattern,
1054 : : .array_len = RTE_DIM(ice_acl_supported_pattern),
1055 : : .parse_pattern_action = ice_acl_parse,
1056 : : .stage = ICE_FLOW_STAGE_DISTRIBUTOR,
1057 : : };
1058 : :
1059 : 235 : RTE_INIT(ice_acl_engine_init)
1060 : : {
1061 : : struct ice_flow_engine *engine = &ice_acl_engine;
1062 : 235 : ice_register_flow_engine(engine);
1063 : 235 : }
|