c61618a61d5516b9e030ddad3470dcb1a1f1cb3e
[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] = {
54                 ROC_NPC_ITEM_TYPE_HIGIG2,
55                 sizeof(struct rte_flow_item_higig2_hdr)}
56 };
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_count *act_count;
114         const struct rte_flow_action_queue *act_q;
115         int i = 0, rc = 0;
116         int rq;
117
118         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
119                 switch (actions->type) {
120                 case RTE_FLOW_ACTION_TYPE_VOID:
121                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VOID;
122                         break;
123
124                 case RTE_FLOW_ACTION_TYPE_MARK:
125                         in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK;
126                         in_actions[i].conf = actions->conf;
127                         break;
128
129                 case RTE_FLOW_ACTION_TYPE_FLAG:
130                         in_actions[i].type = ROC_NPC_ACTION_TYPE_FLAG;
131                         break;
132
133                 case RTE_FLOW_ACTION_TYPE_COUNT:
134                         act_count = (const struct rte_flow_action_count *)
135                                             actions->conf;
136
137                         if (act_count->shared == 1) {
138                                 plt_npc_dbg("Shared counter is not supported");
139                                 goto err_exit;
140                         }
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_QUEUE:
158                         act_q = (const struct rte_flow_action_queue *)
159                                         actions->conf;
160                         rq = act_q->index;
161                         if (rq >= eth_dev->data->nb_rx_queues) {
162                                 plt_npc_dbg("Invalid queue index");
163                                 goto err_exit;
164                         }
165                         in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE;
166                         in_actions[i].conf = actions->conf;
167                         break;
168
169                 case RTE_FLOW_ACTION_TYPE_RSS:
170                         rc = npc_rss_action_validate(eth_dev, attr, actions);
171                         if (rc)
172                                 goto err_exit;
173                         in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS;
174                         in_actions[i].conf = actions->conf;
175                         npc_rss_flowkey_get(dev, &in_actions[i], flowkey_cfg);
176                         break;
177
178                 case RTE_FLOW_ACTION_TYPE_SECURITY:
179                         in_actions[i].type = ROC_NPC_ACTION_TYPE_SEC;
180                         break;
181                 default:
182                         plt_npc_dbg("Action is not supported = %d",
183                                     actions->type);
184                         goto err_exit;
185                 }
186                 i++;
187         }
188         in_actions[i].type = ROC_NPC_ACTION_TYPE_END;
189         return 0;
190
191 err_exit:
192         return -EINVAL;
193 }
194
195 static int
196 cnxk_map_flow_data(struct rte_eth_dev *eth_dev,
197                    const struct rte_flow_attr *attr,
198                    const struct rte_flow_item pattern[],
199                    const struct rte_flow_action actions[],
200                    struct roc_npc_attr *in_attr,
201                    struct roc_npc_item_info in_pattern[],
202                    struct roc_npc_action in_actions[], uint32_t *flowkey_cfg)
203 {
204         int i = 0;
205
206         in_attr->priority = attr->priority;
207         in_attr->ingress = attr->ingress;
208         in_attr->egress = attr->egress;
209
210         while (pattern->type != RTE_FLOW_ITEM_TYPE_END) {
211                 in_pattern[i].spec = pattern->spec;
212                 in_pattern[i].last = pattern->last;
213                 in_pattern[i].mask = pattern->mask;
214                 in_pattern[i].type = term[pattern->type].item_type;
215                 in_pattern[i].size = term[pattern->type].item_size;
216                 pattern++;
217                 i++;
218         }
219         in_pattern[i].type = ROC_NPC_ITEM_TYPE_END;
220
221         return cnxk_map_actions(eth_dev, attr, actions, in_actions,
222                                 flowkey_cfg);
223 }
224
225 static int
226 cnxk_flow_validate(struct rte_eth_dev *eth_dev,
227                    const struct rte_flow_attr *attr,
228                    const struct rte_flow_item pattern[],
229                    const struct rte_flow_action actions[],
230                    struct rte_flow_error *error)
231 {
232         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
233         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
234         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
235         struct roc_npc *npc = &dev->npc;
236         struct roc_npc_attr in_attr;
237         struct roc_npc_flow flow;
238         uint32_t flowkey_cfg = 0;
239         int rc;
240
241         memset(&flow, 0, sizeof(flow));
242
243         rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,
244                                 in_pattern, in_actions, &flowkey_cfg);
245         if (rc) {
246                 rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
247                                    NULL, "Failed to map flow data");
248                 return rc;
249         }
250
251         return roc_npc_flow_parse(npc, &in_attr, in_pattern, in_actions, &flow);
252 }
253
254 struct roc_npc_flow *
255 cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
256                  const struct rte_flow_item pattern[],
257                  const struct rte_flow_action actions[],
258                  struct rte_flow_error *error)
259 {
260         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
261         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
262         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
263         struct roc_npc *npc = &dev->npc;
264         struct roc_npc_attr in_attr;
265         struct roc_npc_flow *flow;
266         int errcode = 0;
267         int rc;
268
269         rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,
270                                 in_pattern, in_actions,
271                                 &npc->flowkey_cfg_state);
272         if (rc) {
273                 rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
274                                    NULL, "Failed to map flow data");
275                 return NULL;
276         }
277
278         flow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions,
279                                    &errcode);
280         if (errcode != 0) {
281                 rte_flow_error_set(error, errcode, errcode, NULL,
282                                    roc_error_msg_get(errcode));
283                 return NULL;
284         }
285
286         return flow;
287 }
288
289 int
290 cnxk_flow_destroy(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
291                   struct rte_flow_error *error)
292 {
293         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
294         struct roc_npc *npc = &dev->npc;
295         int rc;
296
297         rc = roc_npc_flow_destroy(npc, flow);
298         if (rc)
299                 rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
300                                    NULL, "Flow Destroy failed");
301         return rc;
302 }
303
304 static int
305 cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
306 {
307         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
308         struct roc_npc *npc = &dev->npc;
309         int rc;
310
311         rc = roc_npc_mcam_free_all_resources(npc);
312         if (rc) {
313                 rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
314                                    NULL, "Failed to flush filter");
315                 return -rte_errno;
316         }
317
318         return 0;
319 }
320
321 static int
322 cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
323                 const struct rte_flow_action *action, void *data,
324                 struct rte_flow_error *error)
325 {
326         struct roc_npc_flow *in_flow = (struct roc_npc_flow *)flow;
327         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
328         struct roc_npc *npc = &dev->npc;
329         struct rte_flow_query_count *query = data;
330         const char *errmsg = NULL;
331         int errcode = ENOTSUP;
332         int rc;
333
334         if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) {
335                 errmsg = "Only COUNT is supported in query";
336                 goto err_exit;
337         }
338
339         if (in_flow->ctr_id == NPC_COUNTER_NONE) {
340                 errmsg = "Counter is not available";
341                 goto err_exit;
342         }
343
344         rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
345         if (rc != 0) {
346                 errcode = EIO;
347                 errmsg = "Error reading flow counter";
348                 goto err_exit;
349         }
350         query->hits_set = 1;
351         query->bytes_set = 0;
352
353         if (query->reset)
354                 rc = roc_npc_mcam_clear_counter(npc, in_flow->ctr_id);
355         if (rc != 0) {
356                 errcode = EIO;
357                 errmsg = "Error clearing flow counter";
358                 goto err_exit;
359         }
360
361         return 0;
362
363 err_exit:
364         rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
365                            NULL, errmsg);
366         return -rte_errno;
367 }
368
369 static int
370 cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused,
371                   int enable __rte_unused, struct rte_flow_error *error)
372 {
373         /* If we support, we need to un-install the default mcam
374          * entry for this port.
375          */
376
377         rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
378                            NULL, "Flow isolation not supported");
379
380         return -rte_errno;
381 }
382
383 static int
384 cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
385                    FILE *file, struct rte_flow_error *error)
386 {
387         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
388         struct roc_npc *npc = &dev->npc;
389
390         if (file == NULL) {
391                 rte_flow_error_set(error, EINVAL,
392                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
393                                    "Invalid file");
394                 return -rte_errno;
395         }
396
397         if (flow != NULL) {
398                 rte_flow_error_set(error, EINVAL,
399                                    RTE_FLOW_ERROR_TYPE_HANDLE,
400                                    NULL,
401                                    "Invalid argument");
402                 return -EINVAL;
403         }
404
405         roc_npc_flow_dump(file, npc);
406
407         return 0;
408 }
409
410 struct rte_flow_ops cnxk_flow_ops = {
411         .validate = cnxk_flow_validate,
412         .flush = cnxk_flow_flush,
413         .query = cnxk_flow_query,
414         .isolate = cnxk_flow_isolate,
415         .dev_dump = cnxk_flow_dev_dump,
416 };