06301b9ecb073b305699c86b9dd7f3f224ba0ebe
[dpdk.git] / drivers / net / cnxk / cnxk_flow.c
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
63 static int
64 npc_rss_action_validate(struct rte_eth_dev *eth_dev,
65                         const struct rte_flow_attr *attr,
66                         const struct rte_flow_action *act)
67 {
68         const struct rte_flow_action_rss *rss;
69
70         rss = (const struct rte_flow_action_rss *)act->conf;
71
72         if (attr->egress) {
73                 plt_err("No support of RSS in egress");
74                 return -EINVAL;
75         }
76
77         if (eth_dev->data->dev_conf.rxmode.mq_mode != RTE_ETH_MQ_RX_RSS) {
78                 plt_err("multi-queue mode is disabled");
79                 return -ENOTSUP;
80         }
81
82         if (!rss || !rss->queue_num) {
83                 plt_err("no valid queues");
84                 return -EINVAL;
85         }
86
87         if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
88                 plt_err("non-default RSS hash functions are not supported");
89                 return -ENOTSUP;
90         }
91
92         if (rss->key_len && rss->key_len > ROC_NIX_RSS_KEY_LEN) {
93                 plt_err("RSS hash key too large");
94                 return -ENOTSUP;
95         }
96
97         return 0;
98 }
99
100 static void
101 npc_rss_flowkey_get(struct cnxk_eth_dev *eth_dev,
102                     const struct roc_npc_action *rss_action,
103                     uint32_t *flowkey_cfg)
104 {
105         const struct roc_npc_action_rss *rss;
106
107         rss = (const struct roc_npc_action_rss *)rss_action->conf;
108
109         *flowkey_cfg = cnxk_rss_ethdev_to_nix(eth_dev, rss->types, rss->level);
110 }
111
112 static int
113 cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
114                  const struct rte_flow_action actions[],
115                  struct roc_npc_action in_actions[], uint32_t *flowkey_cfg)
116 {
117         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
118         const struct rte_flow_action_port_id *port_act;
119         const struct rte_flow_action_queue *act_q;
120         struct roc_npc *roc_npc_src = &dev->npc;
121         struct rte_eth_dev *portid_eth_dev;
122         char if_name[RTE_ETH_NAME_MAX_LEN];
123         struct cnxk_eth_dev *hw_dst;
124         struct roc_npc *roc_npc_dst;
125         int i = 0, rc = 0;
126         int rq;
127
128         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
129                 switch (actions->type) {
130                 case RTE_FLOW_ACTION_TYPE_VOID:
131                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VOID;
132                         break;
133
134                 case RTE_FLOW_ACTION_TYPE_MARK:
135                         in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK;
136                         in_actions[i].conf = actions->conf;
137                         break;
138
139                 case RTE_FLOW_ACTION_TYPE_FLAG:
140                         in_actions[i].type = ROC_NPC_ACTION_TYPE_FLAG;
141                         break;
142
143                 case RTE_FLOW_ACTION_TYPE_COUNT:
144                         in_actions[i].type = ROC_NPC_ACTION_TYPE_COUNT;
145                         break;
146
147                 case RTE_FLOW_ACTION_TYPE_DROP:
148                         in_actions[i].type = ROC_NPC_ACTION_TYPE_DROP;
149                         break;
150
151                 case RTE_FLOW_ACTION_TYPE_PF:
152                         in_actions[i].type = ROC_NPC_ACTION_TYPE_PF;
153                         break;
154
155                 case RTE_FLOW_ACTION_TYPE_VF:
156                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VF;
157                         in_actions[i].conf = actions->conf;
158                         break;
159
160                 case RTE_FLOW_ACTION_TYPE_PORT_ID:
161                         in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID;
162                         in_actions[i].conf = actions->conf;
163                         port_act = (const struct rte_flow_action_port_id *)
164                                            actions->conf;
165                         if (rte_eth_dev_get_name_by_port(port_act->id,
166                                                          if_name)) {
167                                 plt_err("Name not found for output port id");
168                                 goto err_exit;
169                         }
170                         portid_eth_dev = rte_eth_dev_allocated(if_name);
171                         if (!portid_eth_dev) {
172                                 plt_err("eth_dev not found for output port id");
173                                 goto err_exit;
174                         }
175                         if (strcmp(portid_eth_dev->device->driver->name,
176                                    eth_dev->device->driver->name) != 0) {
177                                 plt_err("Output port not under same driver");
178                                 goto err_exit;
179                         }
180                         hw_dst = portid_eth_dev->data->dev_private;
181                         roc_npc_dst = &hw_dst->npc;
182
183                         rc = roc_npc_validate_portid_action(roc_npc_src,
184                                                             roc_npc_dst);
185
186                         if (rc)
187                                 goto err_exit;
188                         break;
189
190                 case RTE_FLOW_ACTION_TYPE_QUEUE:
191                         act_q = (const struct rte_flow_action_queue *)
192                                         actions->conf;
193                         rq = act_q->index;
194                         if (rq >= eth_dev->data->nb_rx_queues) {
195                                 plt_npc_dbg("Invalid queue index");
196                                 goto err_exit;
197                         }
198                         in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE;
199                         in_actions[i].conf = actions->conf;
200                         break;
201
202                 case RTE_FLOW_ACTION_TYPE_RSS:
203                         rc = npc_rss_action_validate(eth_dev, attr, actions);
204                         if (rc)
205                                 goto err_exit;
206                         in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS;
207                         in_actions[i].conf = actions->conf;
208                         npc_rss_flowkey_get(dev, &in_actions[i], flowkey_cfg);
209                         break;
210
211                 case RTE_FLOW_ACTION_TYPE_SECURITY:
212                         in_actions[i].type = ROC_NPC_ACTION_TYPE_SEC;
213                         in_actions[i].conf = actions->conf;
214                         break;
215                 case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
216                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_STRIP;
217                         break;
218                 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
219                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_INSERT;
220                         in_actions[i].conf = actions->conf;
221                         break;
222                 case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
223                         in_actions[i].type =
224                                 ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT;
225                         in_actions[i].conf = actions->conf;
226                         break;
227                 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
228                         in_actions[i].type =
229                                 ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT;
230                         in_actions[i].conf = actions->conf;
231                         break;
232                 case RTE_FLOW_ACTION_TYPE_METER:
233                         in_actions[i].type = ROC_NPC_ACTION_TYPE_METER;
234                         in_actions[i].conf = actions->conf;
235                         break;
236                 default:
237                         plt_npc_dbg("Action is not supported = %d",
238                                     actions->type);
239                         goto err_exit;
240                 }
241                 i++;
242         }
243         in_actions[i].type = ROC_NPC_ACTION_TYPE_END;
244         return 0;
245
246 err_exit:
247         return -EINVAL;
248 }
249
250 static int
251 cnxk_map_flow_data(struct rte_eth_dev *eth_dev,
252                    const struct rte_flow_attr *attr,
253                    const struct rte_flow_item pattern[],
254                    const struct rte_flow_action actions[],
255                    struct roc_npc_attr *in_attr,
256                    struct roc_npc_item_info in_pattern[],
257                    struct roc_npc_action in_actions[], uint32_t *flowkey_cfg)
258 {
259         int i = 0;
260
261         in_attr->priority = attr->priority;
262         in_attr->ingress = attr->ingress;
263         in_attr->egress = attr->egress;
264
265         while (pattern->type != RTE_FLOW_ITEM_TYPE_END) {
266                 in_pattern[i].spec = pattern->spec;
267                 in_pattern[i].last = pattern->last;
268                 in_pattern[i].mask = pattern->mask;
269                 in_pattern[i].type = term[pattern->type].item_type;
270                 in_pattern[i].size = term[pattern->type].item_size;
271                 pattern++;
272                 i++;
273         }
274         in_pattern[i].type = ROC_NPC_ITEM_TYPE_END;
275
276         return cnxk_map_actions(eth_dev, attr, actions, in_actions,
277                                 flowkey_cfg);
278 }
279
280 static int
281 cnxk_flow_validate(struct rte_eth_dev *eth_dev,
282                    const struct rte_flow_attr *attr,
283                    const struct rte_flow_item pattern[],
284                    const struct rte_flow_action actions[],
285                    struct rte_flow_error *error)
286 {
287         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
288         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
289         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
290         struct roc_npc *npc = &dev->npc;
291         struct roc_npc_attr in_attr;
292         struct roc_npc_flow flow;
293         uint32_t flowkey_cfg = 0;
294         int rc;
295
296         memset(&flow, 0, sizeof(flow));
297
298         rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,
299                                 in_pattern, in_actions, &flowkey_cfg);
300         if (rc) {
301                 rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
302                                    NULL, "Failed to map flow data");
303                 return rc;
304         }
305
306         rc = roc_npc_flow_parse(npc, &in_attr, in_pattern, in_actions, &flow);
307
308         if (rc) {
309                 rte_flow_error_set(error, 0, rc, NULL,
310                                    "Flow validation failed");
311                 return rc;
312         }
313         return 0;
314 }
315
316 struct roc_npc_flow *
317 cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
318                  const struct rte_flow_item pattern[],
319                  const struct rte_flow_action actions[],
320                  struct rte_flow_error *error)
321 {
322         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
323         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
324         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
325         struct roc_npc *npc = &dev->npc;
326         struct roc_npc_attr in_attr;
327         struct roc_npc_flow *flow;
328         int errcode = 0;
329         int rc;
330
331         rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,
332                                 in_pattern, in_actions,
333                                 &npc->flowkey_cfg_state);
334         if (rc) {
335                 rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
336                                    NULL, "Failed to map flow data");
337                 return NULL;
338         }
339
340         flow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions,
341                                    &errcode);
342         if (errcode != 0) {
343                 rte_flow_error_set(error, errcode, errcode, NULL,
344                                    roc_error_msg_get(errcode));
345                 return NULL;
346         }
347
348         return flow;
349 }
350
351 int
352 cnxk_flow_destroy(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
353                   struct rte_flow_error *error)
354 {
355         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
356         struct roc_npc *npc = &dev->npc;
357         int rc;
358
359         rc = roc_npc_flow_destroy(npc, flow);
360         if (rc)
361                 rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
362                                    NULL, "Flow Destroy failed");
363         return rc;
364 }
365
366 static int
367 cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
368 {
369         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
370         struct roc_npc *npc = &dev->npc;
371         int rc;
372
373         rc = roc_npc_mcam_free_all_resources(npc);
374         if (rc) {
375                 rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
376                                    NULL, "Failed to flush filter");
377                 return -rte_errno;
378         }
379
380         return 0;
381 }
382
383 static int
384 cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
385                 const struct rte_flow_action *action, void *data,
386                 struct rte_flow_error *error)
387 {
388         struct roc_npc_flow *in_flow = (struct roc_npc_flow *)flow;
389         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
390         struct roc_npc *npc = &dev->npc;
391         struct rte_flow_query_count *query = data;
392         const char *errmsg = NULL;
393         int errcode = ENOTSUP;
394         int rc;
395
396         if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) {
397                 errmsg = "Only COUNT is supported in query";
398                 goto err_exit;
399         }
400
401         if (in_flow->ctr_id == NPC_COUNTER_NONE) {
402                 errmsg = "Counter is not available";
403                 goto err_exit;
404         }
405
406         rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
407         if (rc != 0) {
408                 errcode = EIO;
409                 errmsg = "Error reading flow counter";
410                 goto err_exit;
411         }
412         query->hits_set = 1;
413         query->bytes_set = 0;
414
415         if (query->reset)
416                 rc = roc_npc_mcam_clear_counter(npc, in_flow->ctr_id);
417         if (rc != 0) {
418                 errcode = EIO;
419                 errmsg = "Error clearing flow counter";
420                 goto err_exit;
421         }
422
423         return 0;
424
425 err_exit:
426         rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
427                            NULL, errmsg);
428         return -rte_errno;
429 }
430
431 static int
432 cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused,
433                   int enable __rte_unused, struct rte_flow_error *error)
434 {
435         /* If we support, we need to un-install the default mcam
436          * entry for this port.
437          */
438
439         rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
440                            NULL, "Flow isolation not supported");
441
442         return -rte_errno;
443 }
444
445 static int
446 cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
447                    FILE *file, struct rte_flow_error *error)
448 {
449         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
450         struct roc_npc *npc = &dev->npc;
451
452         if (file == NULL) {
453                 rte_flow_error_set(error, EINVAL,
454                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
455                                    "Invalid file");
456                 return -rte_errno;
457         }
458
459         if (flow != NULL) {
460                 rte_flow_error_set(error, EINVAL,
461                                    RTE_FLOW_ERROR_TYPE_HANDLE,
462                                    NULL,
463                                    "Invalid argument");
464                 return -EINVAL;
465         }
466
467         roc_npc_flow_dump(file, npc);
468
469         return 0;
470 }
471
472 struct rte_flow_ops cnxk_flow_ops = {
473         .validate = cnxk_flow_validate,
474         .flush = cnxk_flow_flush,
475         .query = cnxk_flow_query,
476         .isolate = cnxk_flow_isolate,
477         .dev_dump = cnxk_flow_dev_dump,
478 };