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