Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : : #include <cnxk_flow.h>
5 : :
6 : : const struct cnxk_rte_flow_term_info term[] = {
7 : : [RTE_FLOW_ITEM_TYPE_ETH] = {ROC_NPC_ITEM_TYPE_ETH,
8 : : sizeof(struct rte_flow_item_eth)},
9 : : [RTE_FLOW_ITEM_TYPE_VLAN] = {ROC_NPC_ITEM_TYPE_VLAN,
10 : : sizeof(struct rte_flow_item_vlan)},
11 : : [RTE_FLOW_ITEM_TYPE_E_TAG] = {ROC_NPC_ITEM_TYPE_E_TAG,
12 : : sizeof(struct rte_flow_item_e_tag)},
13 : : [RTE_FLOW_ITEM_TYPE_IPV4] = {ROC_NPC_ITEM_TYPE_IPV4,
14 : : sizeof(struct rte_flow_item_ipv4)},
15 : : [RTE_FLOW_ITEM_TYPE_IPV6] = {ROC_NPC_ITEM_TYPE_IPV6,
16 : : sizeof(struct rte_flow_item_ipv6)},
17 : : [RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT] = {
18 : : ROC_NPC_ITEM_TYPE_IPV6_FRAG_EXT,
19 : : sizeof(struct rte_flow_item_ipv6_frag_ext)},
20 : : [RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4] = {
21 : : ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4,
22 : : sizeof(struct rte_flow_item_arp_eth_ipv4)},
23 : : [RTE_FLOW_ITEM_TYPE_MPLS] = {ROC_NPC_ITEM_TYPE_MPLS,
24 : : sizeof(struct rte_flow_item_mpls)},
25 : : [RTE_FLOW_ITEM_TYPE_ICMP] = {ROC_NPC_ITEM_TYPE_ICMP,
26 : : sizeof(struct rte_flow_item_icmp)},
27 : : [RTE_FLOW_ITEM_TYPE_UDP] = {ROC_NPC_ITEM_TYPE_UDP,
28 : : sizeof(struct rte_flow_item_udp)},
29 : : [RTE_FLOW_ITEM_TYPE_TCP] = {ROC_NPC_ITEM_TYPE_TCP,
30 : : sizeof(struct rte_flow_item_tcp)},
31 : : [RTE_FLOW_ITEM_TYPE_SCTP] = {ROC_NPC_ITEM_TYPE_SCTP,
32 : : sizeof(struct rte_flow_item_sctp)},
33 : : [RTE_FLOW_ITEM_TYPE_ESP] = {ROC_NPC_ITEM_TYPE_ESP,
34 : : sizeof(struct rte_flow_item_esp)},
35 : : [RTE_FLOW_ITEM_TYPE_GRE] = {ROC_NPC_ITEM_TYPE_GRE,
36 : : sizeof(struct rte_flow_item_gre)},
37 : : [RTE_FLOW_ITEM_TYPE_NVGRE] = {ROC_NPC_ITEM_TYPE_NVGRE,
38 : : sizeof(struct rte_flow_item_nvgre)},
39 : : [RTE_FLOW_ITEM_TYPE_VXLAN] = {ROC_NPC_ITEM_TYPE_VXLAN,
40 : : sizeof(struct rte_flow_item_vxlan)},
41 : : [RTE_FLOW_ITEM_TYPE_GTPC] = {ROC_NPC_ITEM_TYPE_GTPC,
42 : : sizeof(struct rte_flow_item_gtp)},
43 : : [RTE_FLOW_ITEM_TYPE_GTPU] = {ROC_NPC_ITEM_TYPE_GTPU,
44 : : sizeof(struct rte_flow_item_gtp)},
45 : : [RTE_FLOW_ITEM_TYPE_GENEVE] = {ROC_NPC_ITEM_TYPE_GENEVE,
46 : : sizeof(struct rte_flow_item_geneve)},
47 : : [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = {
48 : : ROC_NPC_ITEM_TYPE_VXLAN_GPE,
49 : : sizeof(struct rte_flow_item_vxlan_gpe)},
50 : : [RTE_FLOW_ITEM_TYPE_IPV6_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_EXT,
51 : : sizeof(struct rte_flow_item_ipv6_ext)},
52 : : [RTE_FLOW_ITEM_TYPE_VOID] = {ROC_NPC_ITEM_TYPE_VOID, 0},
53 : : [RTE_FLOW_ITEM_TYPE_ANY] = {ROC_NPC_ITEM_TYPE_ANY, 0},
54 : : [RTE_FLOW_ITEM_TYPE_GRE_KEY] = {ROC_NPC_ITEM_TYPE_GRE_KEY,
55 : : sizeof(uint32_t)},
56 : : [RTE_FLOW_ITEM_TYPE_HIGIG2] = {ROC_NPC_ITEM_TYPE_HIGIG2,
57 : : sizeof(struct rte_flow_item_higig2_hdr)},
58 : : [RTE_FLOW_ITEM_TYPE_RAW] = {ROC_NPC_ITEM_TYPE_RAW,
59 : : sizeof(struct rte_flow_item_raw)},
60 : : [RTE_FLOW_ITEM_TYPE_MARK] = {ROC_NPC_ITEM_TYPE_MARK,
61 : : sizeof(struct rte_flow_item_mark)},
62 : : [RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_ROUTING_EXT,
63 : : sizeof(struct rte_flow_item_ipv6_routing_ext)},
64 : : [RTE_FLOW_ITEM_TYPE_TX_QUEUE] = {ROC_NPC_ITEM_TYPE_TX_QUEUE,
65 : : sizeof(struct rte_flow_item_tx_queue)}};
66 : :
67 : : static int
68 : 0 : npc_rss_action_validate(struct rte_eth_dev *eth_dev,
69 : : const struct rte_flow_attr *attr,
70 : : const struct rte_flow_action *act)
71 : : {
72 : : const struct rte_flow_action_rss *rss;
73 : :
74 : 0 : rss = (const struct rte_flow_action_rss *)act->conf;
75 : :
76 [ # # ]: 0 : if (attr->egress) {
77 : 0 : plt_err("No support of RSS in egress");
78 : 0 : return -EINVAL;
79 : : }
80 : :
81 [ # # ]: 0 : if (eth_dev->data->dev_conf.rxmode.mq_mode != RTE_ETH_MQ_RX_RSS) {
82 : 0 : plt_err("multi-queue mode is disabled");
83 : 0 : return -ENOTSUP;
84 : : }
85 : :
86 [ # # # # ]: 0 : if (!rss || !rss->queue_num) {
87 : 0 : plt_err("no valid queues");
88 : 0 : return -EINVAL;
89 : : }
90 : :
91 [ # # ]: 0 : if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
92 : 0 : plt_err("non-default RSS hash functions are not supported");
93 : 0 : return -ENOTSUP;
94 : : }
95 : :
96 [ # # ]: 0 : if (rss->key_len && rss->key_len > ROC_NIX_RSS_KEY_LEN) {
97 : 0 : plt_err("RSS hash key too large");
98 : 0 : return -ENOTSUP;
99 : : }
100 : :
101 : : return 0;
102 : : }
103 : :
104 : : static void
105 : : npc_rss_flowkey_get(struct cnxk_eth_dev *eth_dev,
106 : : const struct roc_npc_action *rss_action,
107 : : uint32_t *flowkey_cfg)
108 : : {
109 : : const struct roc_npc_action_rss *rss;
110 : :
111 : : rss = (const struct roc_npc_action_rss *)rss_action->conf;
112 : :
113 : 0 : *flowkey_cfg = cnxk_rss_ethdev_to_nix(eth_dev, rss->types, rss->level);
114 : 0 : }
115 : :
116 : : static int
117 : 0 : cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
118 : : const struct rte_flow_action actions[], struct roc_npc_action in_actions[],
119 : : uint32_t *flowkey_cfg, uint16_t *dst_pf_func)
120 : : {
121 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
122 : : const struct rte_flow_action_queue *act_q = NULL;
123 : : const struct rte_flow_action_ethdev *act_ethdev;
124 : : const struct rte_flow_action_port_id *port_act;
125 : : struct rte_eth_dev *portid_eth_dev;
126 : : char if_name[RTE_ETH_NAME_MAX_LEN];
127 : : struct cnxk_eth_dev *hw_dst;
128 : : struct roc_npc *roc_npc_dst;
129 : : bool is_vf_action = false;
130 : : int i = 0, rc = 0;
131 : : int rq;
132 : :
133 [ # # ]: 0 : for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
134 [ # # # # : 0 : switch (actions->type) {
# # # # #
# # # # #
# # # # ]
135 : 0 : case RTE_FLOW_ACTION_TYPE_VOID:
136 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_VOID;
137 : 0 : break;
138 : :
139 : 0 : case RTE_FLOW_ACTION_TYPE_MARK:
140 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK;
141 : 0 : in_actions[i].conf = actions->conf;
142 : 0 : break;
143 : :
144 : 0 : case RTE_FLOW_ACTION_TYPE_FLAG:
145 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_FLAG;
146 : 0 : break;
147 : :
148 : 0 : case RTE_FLOW_ACTION_TYPE_COUNT:
149 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_COUNT;
150 : 0 : break;
151 : :
152 : 0 : case RTE_FLOW_ACTION_TYPE_DROP:
153 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_DROP;
154 : 0 : break;
155 : :
156 : 0 : case RTE_FLOW_ACTION_TYPE_PF:
157 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_PF;
158 : 0 : break;
159 : :
160 : 0 : case RTE_FLOW_ACTION_TYPE_VF:
161 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_VF;
162 : 0 : in_actions[i].conf = actions->conf;
163 : : is_vf_action = true;
164 : 0 : break;
165 : :
166 : 0 : case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
167 : : case RTE_FLOW_ACTION_TYPE_PORT_ID:
168 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID;
169 : 0 : in_actions[i].conf = actions->conf;
170 : : act_ethdev = (const struct rte_flow_action_ethdev *)
171 : : actions->conf;
172 : : port_act = (const struct rte_flow_action_port_id *)
173 : : actions->conf;
174 [ # # # # ]: 0 : if (rte_eth_dev_get_name_by_port(
175 : : actions->type != RTE_FLOW_ACTION_TYPE_PORT_ID ?
176 : 0 : act_ethdev->port_id : port_act->id, if_name)) {
177 : 0 : plt_err("Name not found for output port id");
178 : 0 : goto err_exit;
179 : : }
180 : 0 : portid_eth_dev = rte_eth_dev_allocated(if_name);
181 [ # # ]: 0 : if (!portid_eth_dev) {
182 : 0 : plt_err("eth_dev not found for output port id");
183 : 0 : goto err_exit;
184 : : }
185 : 0 : if (strcmp(portid_eth_dev->device->driver->name,
186 [ # # ]: 0 : eth_dev->device->driver->name) != 0) {
187 : 0 : plt_err("Output port not under same driver");
188 : 0 : goto err_exit;
189 : : }
190 : 0 : hw_dst = portid_eth_dev->data->dev_private;
191 : : roc_npc_dst = &hw_dst->npc;
192 : 0 : *dst_pf_func = roc_npc_dst->pf_func;
193 : 0 : break;
194 : :
195 : 0 : case RTE_FLOW_ACTION_TYPE_QUEUE:
196 : 0 : act_q = (const struct rte_flow_action_queue *)actions->conf;
197 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE;
198 : 0 : in_actions[i].conf = actions->conf;
199 : 0 : break;
200 : :
201 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
202 : 0 : rc = npc_rss_action_validate(eth_dev, attr, actions);
203 [ # # ]: 0 : if (rc)
204 : 0 : goto err_exit;
205 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS;
206 : 0 : in_actions[i].conf = actions->conf;
207 : : npc_rss_flowkey_get(dev, &in_actions[i], flowkey_cfg);
208 : : break;
209 : :
210 : 0 : case RTE_FLOW_ACTION_TYPE_SECURITY:
211 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_SEC;
212 : 0 : in_actions[i].conf = actions->conf;
213 : 0 : break;
214 : 0 : case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
215 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_STRIP;
216 : 0 : break;
217 : 0 : case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
218 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_INSERT;
219 : 0 : in_actions[i].conf = actions->conf;
220 : 0 : break;
221 : 0 : case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
222 : 0 : in_actions[i].type =
223 : : ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT;
224 : 0 : in_actions[i].conf = actions->conf;
225 : 0 : break;
226 : 0 : case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
227 : 0 : in_actions[i].type =
228 : : ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT;
229 : 0 : in_actions[i].conf = actions->conf;
230 : 0 : break;
231 : 0 : case RTE_FLOW_ACTION_TYPE_METER:
232 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_METER;
233 : 0 : in_actions[i].conf = actions->conf;
234 : 0 : break;
235 : 0 : case RTE_FLOW_ACTION_TYPE_AGE:
236 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_AGE;
237 : 0 : in_actions[i].conf = actions->conf;
238 : 0 : break;
239 : 0 : default:
240 : 0 : plt_npc_dbg("Action is not supported = %d",
241 : : actions->type);
242 : 0 : goto err_exit;
243 : : }
244 : 0 : i++;
245 : : }
246 : :
247 [ # # ]: 0 : if (!is_vf_action && act_q) {
248 : 0 : rq = act_q->index;
249 [ # # ]: 0 : if (rq >= eth_dev->data->nb_rx_queues) {
250 : 0 : plt_npc_dbg("Invalid queue index");
251 : 0 : goto err_exit;
252 : : }
253 : : }
254 : 0 : in_actions[i].type = ROC_NPC_ACTION_TYPE_END;
255 : 0 : return 0;
256 : :
257 : : err_exit:
258 : : return -EINVAL;
259 : : }
260 : :
261 : : static int
262 : 0 : cnxk_map_flow_data(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
263 : : const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
264 : : struct roc_npc_attr *in_attr, struct roc_npc_item_info in_pattern[],
265 : : struct roc_npc_action in_actions[], uint32_t *flowkey_cfg, uint16_t *dst_pf_func)
266 : : {
267 : : int i = 0;
268 : :
269 : 0 : in_attr->priority = attr->priority;
270 : 0 : in_attr->ingress = attr->ingress;
271 : 0 : in_attr->egress = attr->egress;
272 : :
273 [ # # ]: 0 : while (pattern->type != RTE_FLOW_ITEM_TYPE_END) {
274 : 0 : in_pattern[i].spec = pattern->spec;
275 : 0 : in_pattern[i].last = pattern->last;
276 : 0 : in_pattern[i].mask = pattern->mask;
277 : 0 : in_pattern[i].type = term[pattern->type].item_type;
278 : 0 : in_pattern[i].size = term[pattern->type].item_size;
279 : 0 : pattern++;
280 : 0 : i++;
281 : : }
282 : 0 : in_pattern[i].type = ROC_NPC_ITEM_TYPE_END;
283 : :
284 : 0 : return cnxk_map_actions(eth_dev, attr, actions, in_actions, flowkey_cfg, dst_pf_func);
285 : : }
286 : :
287 : : static int
288 [ # # ]: 0 : cnxk_flow_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
289 : : const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
290 : : struct rte_flow_error *error)
291 : : {
292 : : struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
293 : : struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
294 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
295 : 0 : struct roc_npc *npc = &dev->npc;
296 : : struct roc_npc_attr in_attr;
297 : : struct roc_npc_flow flow;
298 : 0 : uint32_t flowkey_cfg = 0;
299 : 0 : uint16_t dst_pf_func = 0;
300 : : int rc;
301 : :
302 : : /* Skip flow validation for MACsec. */
303 [ # # # # ]: 0 : if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
304 : 0 : cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL)
305 : : return 0;
306 : :
307 : : memset(&flow, 0, sizeof(flow));
308 : 0 : flow.is_validate = true;
309 : :
310 : 0 : rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions,
311 : : &flowkey_cfg, &dst_pf_func);
312 [ # # ]: 0 : if (rc) {
313 : 0 : rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
314 : : "Failed to map flow data");
315 : 0 : return rc;
316 : : }
317 : :
318 : 0 : rc = roc_npc_flow_parse(npc, &in_attr, in_pattern, in_actions, &flow);
319 : :
320 [ # # ]: 0 : if (rc) {
321 : 0 : rte_flow_error_set(error, 0, rc, NULL,
322 : : "Flow validation failed");
323 : 0 : return rc;
324 : : }
325 : : return 0;
326 : : }
327 : :
328 : : struct roc_npc_flow *
329 : 0 : cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
330 : : const struct rte_flow_item pattern[],
331 : : const struct rte_flow_action actions[],
332 : : struct rte_flow_error *error)
333 : : {
334 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
335 : : struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
336 : : struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
337 : 0 : struct roc_npc *npc = &dev->npc;
338 : : struct roc_npc_attr in_attr;
339 : : struct roc_npc_flow *flow;
340 : 0 : uint16_t dst_pf_func = 0;
341 : 0 : int errcode = 0;
342 : : int rc;
343 : :
344 : 0 : rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions,
345 : : &npc->flowkey_cfg_state, &dst_pf_func);
346 [ # # ]: 0 : if (rc) {
347 : 0 : rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
348 : : "Failed to map flow data");
349 : 0 : return NULL;
350 : : }
351 : :
352 : 0 : flow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions, dst_pf_func, &errcode);
353 [ # # ]: 0 : if (errcode != 0) {
354 : 0 : rte_flow_error_set(error, errcode, errcode, NULL, roc_error_msg_get(errcode));
355 : 0 : return NULL;
356 : : }
357 : :
358 : : return flow;
359 : : }
360 : :
361 : : int
362 : 0 : cnxk_flow_destroy(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
363 : : struct rte_flow_error *error)
364 : : {
365 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
366 : 0 : struct roc_npc *npc = &dev->npc;
367 : : int rc;
368 : :
369 : 0 : rc = roc_npc_flow_destroy(npc, flow);
370 [ # # ]: 0 : if (rc)
371 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
372 : : NULL, "Flow Destroy failed");
373 : 0 : return rc;
374 : : }
375 : :
376 : : static int
377 : 0 : cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
378 : : {
379 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
380 : 0 : struct roc_npc *npc = &dev->npc;
381 : : int rc;
382 : :
383 : 0 : rc = roc_npc_mcam_free_all_resources(npc);
384 [ # # ]: 0 : if (rc) {
385 : 0 : rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
386 : : NULL, "Failed to flush filter");
387 : 0 : return -rte_errno;
388 : : }
389 : :
390 : : return 0;
391 : : }
392 : :
393 : : static int
394 [ # # ]: 0 : cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
395 : : const struct rte_flow_action *action, void *data,
396 : : struct rte_flow_error *error)
397 : : {
398 : : struct roc_npc_flow *in_flow = (struct roc_npc_flow *)flow;
399 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
400 : 0 : struct roc_npc *npc = &dev->npc;
401 : : struct rte_flow_query_count *query = data;
402 : : const char *errmsg = NULL;
403 : : int errcode = ENOTSUP;
404 : : int rc;
405 : :
406 [ # # ]: 0 : if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) {
407 : : errmsg = "Only COUNT is supported in query";
408 : 0 : goto err_exit;
409 : : }
410 : :
411 [ # # ]: 0 : if (in_flow->ctr_id == NPC_COUNTER_NONE) {
412 : : errmsg = "Counter is not available";
413 : 0 : goto err_exit;
414 : : }
415 : :
416 [ # # ]: 0 : if (in_flow->use_pre_alloc)
417 : 0 : rc = roc_npc_inl_mcam_read_counter(in_flow->ctr_id, &query->hits);
418 : : else
419 : 0 : rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
420 [ # # ]: 0 : if (rc != 0) {
421 : : errcode = EIO;
422 : : errmsg = "Error reading flow counter";
423 : 0 : goto err_exit;
424 : : }
425 : 0 : query->hits_set = 1;
426 : 0 : query->bytes_set = 0;
427 : :
428 [ # # ]: 0 : if (query->reset) {
429 [ # # ]: 0 : if (in_flow->use_pre_alloc)
430 : 0 : rc = roc_npc_inl_mcam_clear_counter(in_flow->ctr_id);
431 : : else
432 : 0 : rc = roc_npc_mcam_clear_counter(npc, in_flow->ctr_id);
433 : : }
434 [ # # ]: 0 : if (rc != 0) {
435 : : errcode = EIO;
436 : : errmsg = "Error clearing flow counter";
437 : 0 : goto err_exit;
438 : : }
439 : :
440 : : return 0;
441 : :
442 : 0 : err_exit:
443 : 0 : rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
444 : : NULL, errmsg);
445 : 0 : return -rte_errno;
446 : : }
447 : :
448 : : static int
449 : 0 : cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused,
450 : : int enable __rte_unused, struct rte_flow_error *error)
451 : : {
452 : : /* If we support, we need to un-install the default mcam
453 : : * entry for this port.
454 : : */
455 : :
456 : 0 : rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
457 : : NULL, "Flow isolation not supported");
458 : :
459 : 0 : return -rte_errno;
460 : : }
461 : :
462 : : static int
463 [ # # ]: 0 : cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
464 : : FILE *file, struct rte_flow_error *error)
465 : : {
466 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
467 : 0 : struct roc_npc *npc = &dev->npc;
468 : :
469 [ # # ]: 0 : if (file == NULL) {
470 : 0 : rte_flow_error_set(error, EINVAL,
471 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
472 : : "Invalid file");
473 : 0 : return -rte_errno;
474 : : }
475 : :
476 [ # # ]: 0 : if (flow != NULL) {
477 : 0 : rte_flow_error_set(error, EINVAL,
478 : : RTE_FLOW_ERROR_TYPE_HANDLE,
479 : : NULL,
480 : : "Invalid argument");
481 : 0 : return -EINVAL;
482 : : }
483 : :
484 : 0 : roc_npc_flow_dump(file, npc);
485 : :
486 : 0 : return 0;
487 : : }
488 : :
489 : : static int
490 : 0 : cnxk_flow_get_aged_flows(struct rte_eth_dev *eth_dev, void **context,
491 : : uint32_t nb_contexts, struct rte_flow_error *err)
492 : : {
493 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
494 : 0 : struct roc_npc *roc_npc = &dev->npc;
495 : : struct roc_npc_flow_age *flow_age;
496 : : uint32_t start_id;
497 : : uint32_t end_id;
498 : : int cnt = 0;
499 : : uint32_t sn;
500 : : uint32_t i;
501 : :
502 : : RTE_SET_USED(err);
503 : :
504 : : flow_age = &roc_npc->flow_age;
505 : :
506 : : do {
507 : : sn = plt_seqcount_read_begin(&flow_age->seq_cnt);
508 : :
509 [ # # ]: 0 : if (nb_contexts == 0) {
510 : 0 : cnt = flow_age->aged_flows_cnt;
511 : : } else {
512 : 0 : start_id = flow_age->start_id;
513 : 0 : end_id = flow_age->end_id;
514 [ # # ]: 0 : for (i = start_id; i <= end_id; i++) {
515 [ # # ]: 0 : if ((int)nb_contexts == cnt)
516 : : break;
517 [ # # ]: 0 : if (plt_bitmap_get(flow_age->aged_flows, i)) {
518 : 0 : context[cnt] =
519 : 0 : roc_npc_aged_flow_ctx_get(roc_npc, i);
520 : 0 : cnt++;
521 : : }
522 : : }
523 : : }
524 [ # # ]: 0 : } while (plt_seqcount_read_retry(&flow_age->seq_cnt, sn));
525 : :
526 : 0 : return cnt;
527 : : }
528 : :
529 : : struct rte_flow_ops cnxk_flow_ops = {
530 : : .validate = cnxk_flow_validate,
531 : : .flush = cnxk_flow_flush,
532 : : .query = cnxk_flow_query,
533 : : .isolate = cnxk_flow_isolate,
534 : : .dev_dump = cnxk_flow_dev_dump,
535 : : .get_aged_flows = cnxk_flow_get_aged_flows,
536 : : };
|