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