replace alignment attributes
[dpdk.git] / drivers / net / octeontx2 / otx2_flow.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include "otx2_ethdev.h"
6 #include "otx2_ethdev_sec.h"
7 #include "otx2_flow.h"
8
9 int
10 otx2_flow_free_all_resources(struct otx2_eth_dev *hw)
11 {
12         struct otx2_npc_flow_info *npc = &hw->npc_flow;
13         struct otx2_mbox *mbox = hw->mbox;
14         struct otx2_mcam_ents_info *info;
15         struct rte_bitmap *bmap;
16         struct rte_flow *flow;
17         int entry_count = 0;
18         int rc, idx;
19
20         for (idx = 0; idx < npc->flow_max_priority; idx++) {
21                 info = &npc->flow_entry_info[idx];
22                 entry_count += info->live_ent;
23         }
24
25         if (entry_count == 0)
26                 return 0;
27
28         /* Free all MCAM entries allocated */
29         rc = otx2_flow_mcam_free_all_entries(mbox);
30
31         /* Free any MCAM counters and delete flow list */
32         for (idx = 0; idx < npc->flow_max_priority; idx++) {
33                 while ((flow = TAILQ_FIRST(&npc->flow_list[idx])) != NULL) {
34                         if (flow->ctr_id != NPC_COUNTER_NONE)
35                                 rc |= otx2_flow_mcam_free_counter(mbox,
36                                                              flow->ctr_id);
37
38                         TAILQ_REMOVE(&npc->flow_list[idx], flow, next);
39                         rte_free(flow);
40                         bmap = npc->live_entries[flow->priority];
41                         rte_bitmap_clear(bmap, flow->mcam_id);
42                 }
43                 info = &npc->flow_entry_info[idx];
44                 info->free_ent = 0;
45                 info->live_ent = 0;
46         }
47         return rc;
48 }
49
50
51 static int
52 flow_program_npc(struct otx2_parse_state *pst, struct otx2_mbox *mbox,
53                  struct otx2_npc_flow_info *flow_info)
54 {
55         /* This is non-LDATA part in search key */
56         uint64_t key_data[2] = {0ULL, 0ULL};
57         uint64_t key_mask[2] = {0ULL, 0ULL};
58         int intf = pst->flow->nix_intf;
59         int key_len, bit = 0, index;
60         int off, idx, data_off = 0;
61         uint8_t lid, mask, data;
62         uint16_t layer_info;
63         uint64_t lt, flags;
64
65
66         /* Skip till Layer A data start */
67         while (bit < NPC_PARSE_KEX_S_LA_OFFSET) {
68                 if (flow_info->keyx_supp_nmask[intf] & (1 << bit))
69                         data_off++;
70                 bit++;
71         }
72
73         /* Each bit represents 1 nibble */
74         data_off *= 4;
75
76         index = 0;
77         for (lid = 0; lid < NPC_MAX_LID; lid++) {
78                 /* Offset in key */
79                 off = NPC_PARSE_KEX_S_LID_OFFSET(lid);
80                 lt = pst->lt[lid] & 0xf;
81                 flags = pst->flags[lid] & 0xff;
82
83                 /* NPC_LAYER_KEX_S */
84                 layer_info = ((flow_info->keyx_supp_nmask[intf] >> off) & 0x7);
85
86                 if (layer_info) {
87                         for (idx = 0; idx <= 2 ; idx++) {
88                                 if (layer_info & (1 << idx)) {
89                                         if (idx == 2)
90                                                 data = lt;
91                                         else if (idx == 1)
92                                                 data = ((flags >> 4) & 0xf);
93                                         else
94                                                 data = (flags & 0xf);
95
96                                         if (data_off >= 64) {
97                                                 data_off = 0;
98                                                 index++;
99                                         }
100                                         key_data[index] |= ((uint64_t)data <<
101                                                             data_off);
102                                         mask = 0xf;
103                                         if (lt == 0)
104                                                 mask = 0;
105                                         key_mask[index] |= ((uint64_t)mask <<
106                                                             data_off);
107                                         data_off += 4;
108                                 }
109                         }
110                 }
111         }
112
113         otx2_npc_dbg("Npc prog key data0: 0x%" PRIx64 ", data1: 0x%" PRIx64,
114                      key_data[0], key_data[1]);
115
116         /* Copy this into mcam string */
117         key_len = (pst->npc->keyx_len[intf] + 7) / 8;
118         otx2_npc_dbg("Key_len  = %d", key_len);
119         memcpy(pst->flow->mcam_data, key_data, key_len);
120         memcpy(pst->flow->mcam_mask, key_mask, key_len);
121
122         otx2_npc_dbg("Final flow data");
123         for (idx = 0; idx < OTX2_MAX_MCAM_WIDTH_DWORDS; idx++) {
124                 otx2_npc_dbg("data[%d]: 0x%" PRIx64 ", mask[%d]: 0x%" PRIx64,
125                              idx, pst->flow->mcam_data[idx],
126                              idx, pst->flow->mcam_mask[idx]);
127         }
128
129         /*
130          * Now we have mcam data and mask formatted as
131          * [Key_len/4 nibbles][0 or 1 nibble hole][data]
132          * hole is present if key_len is odd number of nibbles.
133          * mcam data must be split into 64 bits + 48 bits segments
134          * for each back W0, W1.
135          */
136
137         return otx2_flow_mcam_alloc_and_write(pst->flow, mbox, pst, flow_info);
138 }
139
140 static int
141 flow_parse_attr(struct rte_eth_dev *eth_dev,
142                 const struct rte_flow_attr *attr,
143                 struct rte_flow_error *error,
144                 struct rte_flow *flow)
145 {
146         struct otx2_eth_dev *dev = eth_dev->data->dev_private;
147         const char *errmsg = NULL;
148
149         if (attr == NULL)
150                 errmsg = "Attribute can't be empty";
151         else if (attr->group)
152                 errmsg = "Groups are not supported";
153         else if (attr->priority >= dev->npc_flow.flow_max_priority)
154                 errmsg = "Priority should be with in specified range";
155         else if ((!attr->egress && !attr->ingress) ||
156                  (attr->egress && attr->ingress))
157                 errmsg = "Exactly one of ingress or egress must be set";
158
159         if (errmsg != NULL) {
160                 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR,
161                                    attr, errmsg);
162                 return -ENOTSUP;
163         }
164
165         if (attr->ingress)
166                 flow->nix_intf = OTX2_INTF_RX;
167         else
168                 flow->nix_intf = OTX2_INTF_TX;
169
170         flow->priority = attr->priority;
171         return 0;
172 }
173
174 static inline int
175 flow_get_free_rss_grp(struct rte_bitmap *bmap,
176                       uint32_t size, uint32_t *pos)
177 {
178         for (*pos = 0; *pos < size; ++*pos) {
179                 if (!rte_bitmap_get(bmap, *pos))
180                         break;
181         }
182
183         return *pos < size ? 0 : -1;
184 }
185
186 static int
187 flow_configure_rss_action(struct otx2_eth_dev *dev,
188                           const struct rte_flow_action_rss *rss,
189                           uint8_t *alg_idx, uint32_t *rss_grp,
190                           int mcam_index)
191 {
192         struct otx2_npc_flow_info *flow_info = &dev->npc_flow;
193         uint16_t reta[NIX_RSS_RETA_SIZE_MAX];
194         uint32_t flowkey_cfg, grp_aval, i;
195         uint16_t *ind_tbl = NULL;
196         uint8_t flowkey_algx;
197         int rc;
198
199         rc = flow_get_free_rss_grp(flow_info->rss_grp_entries,
200                                    flow_info->rss_grps, &grp_aval);
201         /* RSS group :0 is not usable for flow rss action */
202         if (rc < 0 || grp_aval == 0)
203                 return -ENOSPC;
204
205         *rss_grp = grp_aval;
206
207         otx2_nix_rss_set_key(dev, (uint8_t *)(uintptr_t)rss->key,
208                              rss->key_len);
209
210         /* If queue count passed in the rss action is less than
211          * HW configured reta size, replicate rss action reta
212          * across HW reta table.
213          */
214         if (dev->rss_info.rss_size > rss->queue_num) {
215                 ind_tbl = reta;
216
217                 for (i = 0; i < (dev->rss_info.rss_size / rss->queue_num); i++)
218                         memcpy(reta + i * rss->queue_num, rss->queue,
219                                sizeof(uint16_t) * rss->queue_num);
220
221                 i = dev->rss_info.rss_size % rss->queue_num;
222                 if (i)
223                         memcpy(&reta[dev->rss_info.rss_size] - i,
224                                rss->queue, i * sizeof(uint16_t));
225         } else {
226                 ind_tbl = (uint16_t *)(uintptr_t)rss->queue;
227         }
228
229         rc = otx2_nix_rss_tbl_init(dev, *rss_grp, ind_tbl);
230         if (rc) {
231                 otx2_err("Failed to init rss table rc = %d", rc);
232                 return rc;
233         }
234
235         flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss->types, rss->level);
236
237         rc = otx2_rss_set_hf(dev, flowkey_cfg, &flowkey_algx,
238                              *rss_grp, mcam_index);
239         if (rc) {
240                 otx2_err("Failed to set rss hash function rc = %d", rc);
241                 return rc;
242         }
243
244         *alg_idx = flowkey_algx;
245
246         rte_bitmap_set(flow_info->rss_grp_entries, *rss_grp);
247
248         return 0;
249 }
250
251
252 static int
253 flow_program_rss_action(struct rte_eth_dev *eth_dev,
254                         const struct rte_flow_action actions[],
255                         struct rte_flow *flow)
256 {
257         struct otx2_eth_dev *dev = eth_dev->data->dev_private;
258         const struct rte_flow_action_rss *rss;
259         uint32_t rss_grp;
260         uint8_t alg_idx;
261         int rc;
262
263         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
264                 if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
265                         rss = (const struct rte_flow_action_rss *)actions->conf;
266
267                         rc = flow_configure_rss_action(dev,
268                                                        rss, &alg_idx, &rss_grp,
269                                                        flow->mcam_id);
270                         if (rc)
271                                 return rc;
272
273                         flow->npc_action |=
274                                 ((uint64_t)(alg_idx & NIX_RSS_ACT_ALG_MASK) <<
275                                  NIX_RSS_ACT_ALG_OFFSET) |
276                                 ((uint64_t)(rss_grp & NIX_RSS_ACT_GRP_MASK) <<
277                                  NIX_RSS_ACT_GRP_OFFSET);
278                 }
279         }
280         return 0;
281 }
282
283 static int
284 flow_free_rss_action(struct rte_eth_dev *eth_dev,
285                      struct rte_flow *flow)
286 {
287         struct otx2_eth_dev *dev = eth_dev->data->dev_private;
288         struct otx2_npc_flow_info *npc = &dev->npc_flow;
289         uint32_t rss_grp;
290
291         if (flow->npc_action & NIX_RX_ACTIONOP_RSS) {
292                 rss_grp = (flow->npc_action >> NIX_RSS_ACT_GRP_OFFSET) &
293                         NIX_RSS_ACT_GRP_MASK;
294                 if (rss_grp == 0 || rss_grp >= npc->rss_grps)
295                         return -EINVAL;
296
297                 rte_bitmap_clear(npc->rss_grp_entries, rss_grp);
298         }
299
300         return 0;
301 }
302
303 static int
304 flow_update_sec_tt(struct rte_eth_dev *eth_dev,
305                    const struct rte_flow_action actions[])
306 {
307         int rc = 0;
308
309         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
310                 if (actions->type == RTE_FLOW_ACTION_TYPE_SECURITY) {
311                         rc = otx2_eth_sec_update_tag_type(eth_dev);
312                         break;
313                 }
314         }
315
316         return rc;
317 }
318
319 static int
320 flow_parse_meta_items(__rte_unused struct otx2_parse_state *pst)
321 {
322         otx2_npc_dbg("Meta Item");
323         return 0;
324 }
325
326 /*
327  * Parse function of each layer:
328  *  - Consume one or more patterns that are relevant.
329  *  - Update parse_state
330  *  - Set parse_state.pattern = last item consumed
331  *  - Set appropriate error code/message when returning error.
332  */
333 typedef int (*flow_parse_stage_func_t)(struct otx2_parse_state *pst);
334
335 static int
336 flow_parse_pattern(struct rte_eth_dev *dev,
337                    const struct rte_flow_item pattern[],
338                    struct rte_flow_error *error,
339                    struct rte_flow *flow,
340                    struct otx2_parse_state *pst)
341 {
342         flow_parse_stage_func_t parse_stage_funcs[] = {
343                 flow_parse_meta_items,
344                 otx2_flow_parse_higig2_hdr,
345                 otx2_flow_parse_la,
346                 otx2_flow_parse_lb,
347                 otx2_flow_parse_lc,
348                 otx2_flow_parse_ld,
349                 otx2_flow_parse_le,
350                 otx2_flow_parse_lf,
351                 otx2_flow_parse_lg,
352                 otx2_flow_parse_lh,
353         };
354         struct otx2_eth_dev *hw = dev->data->dev_private;
355         uint8_t layer = 0;
356         int key_offset;
357         int rc;
358
359         if (pattern == NULL) {
360                 rte_flow_error_set(error, EINVAL,
361                                    RTE_FLOW_ERROR_TYPE_ITEM_NUM, NULL,
362                                    "pattern is NULL");
363                 return -EINVAL;
364         }
365
366         memset(pst, 0, sizeof(*pst));
367         pst->npc = &hw->npc_flow;
368         pst->error = error;
369         pst->flow = flow;
370
371         /* Use integral byte offset */
372         key_offset = pst->npc->keyx_len[flow->nix_intf];
373         key_offset = (key_offset + 7) / 8;
374
375         /* Location where LDATA would begin */
376         pst->mcam_data = (uint8_t *)flow->mcam_data;
377         pst->mcam_mask = (uint8_t *)flow->mcam_mask;
378
379         while (pattern->type != RTE_FLOW_ITEM_TYPE_END &&
380                layer < RTE_DIM(parse_stage_funcs)) {
381                 otx2_npc_dbg("Pattern type = %d", pattern->type);
382
383                 /* Skip place-holders */
384                 pattern = otx2_flow_skip_void_and_any_items(pattern);
385
386                 pst->pattern = pattern;
387                 otx2_npc_dbg("Is tunnel = %d, layer = %d", pst->tunnel, layer);
388                 rc = parse_stage_funcs[layer](pst);
389                 if (rc != 0)
390                         return -rte_errno;
391
392                 layer++;
393
394                 /*
395                  * Parse stage function sets pst->pattern to
396                  * 1 past the last item it consumed.
397                  */
398                 pattern = pst->pattern;
399
400                 if (pst->terminate)
401                         break;
402         }
403
404         /* Skip trailing place-holders */
405         pattern = otx2_flow_skip_void_and_any_items(pattern);
406
407         /* Are there more items than what we can handle? */
408         if (pattern->type != RTE_FLOW_ITEM_TYPE_END) {
409                 rte_flow_error_set(error, ENOTSUP,
410                                    RTE_FLOW_ERROR_TYPE_ITEM, pattern,
411                                    "unsupported item in the sequence");
412                 return -ENOTSUP;
413         }
414
415         return 0;
416 }
417
418 static int
419 flow_parse_rule(struct rte_eth_dev *dev,
420                 const struct rte_flow_attr *attr,
421                 const struct rte_flow_item pattern[],
422                 const struct rte_flow_action actions[],
423                 struct rte_flow_error *error,
424                 struct rte_flow *flow,
425                 struct otx2_parse_state *pst)
426 {
427         int err;
428
429         /* Check attributes */
430         err = flow_parse_attr(dev, attr, error, flow);
431         if (err)
432                 return err;
433
434         /* Check actions */
435         err = otx2_flow_parse_actions(dev, attr, actions, error, flow);
436         if (err)
437                 return err;
438
439         /* Check pattern */
440         err = flow_parse_pattern(dev, pattern, error, flow, pst);
441         if (err)
442                 return err;
443
444         /* Check for overlaps? */
445         return 0;
446 }
447
448 static int
449 otx2_flow_validate(struct rte_eth_dev *dev,
450                    const struct rte_flow_attr *attr,
451                    const struct rte_flow_item pattern[],
452                    const struct rte_flow_action actions[],
453                    struct rte_flow_error *error)
454 {
455         struct otx2_parse_state parse_state;
456         struct rte_flow flow;
457
458         memset(&flow, 0, sizeof(flow));
459         return flow_parse_rule(dev, attr, pattern, actions, error, &flow,
460                                &parse_state);
461 }
462
463 static struct rte_flow *
464 otx2_flow_create(struct rte_eth_dev *dev,
465                  const struct rte_flow_attr *attr,
466                  const struct rte_flow_item pattern[],
467                  const struct rte_flow_action actions[],
468                  struct rte_flow_error *error)
469 {
470         struct otx2_eth_dev *hw = dev->data->dev_private;
471         struct otx2_parse_state parse_state;
472         struct otx2_mbox *mbox = hw->mbox;
473         struct rte_flow *flow, *flow_iter;
474         struct otx2_flow_list *list;
475         int rc;
476
477         flow = rte_zmalloc("otx2_rte_flow", sizeof(*flow), 0);
478         if (flow == NULL) {
479                 rte_flow_error_set(error, ENOMEM,
480                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
481                                    NULL,
482                                    "Memory allocation failed");
483                 return NULL;
484         }
485         memset(flow, 0, sizeof(*flow));
486
487         rc = flow_parse_rule(dev, attr, pattern, actions, error, flow,
488                              &parse_state);
489         if (rc != 0)
490                 goto err_exit;
491
492         rc = flow_program_npc(&parse_state, mbox, &hw->npc_flow);
493         if (rc != 0) {
494                 rte_flow_error_set(error, EIO,
495                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
496                                    NULL,
497                                    "Failed to insert filter");
498                 goto err_exit;
499         }
500
501         rc = flow_program_rss_action(dev, actions, flow);
502         if (rc != 0) {
503                 rte_flow_error_set(error, EIO,
504                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
505                                    NULL,
506                                    "Failed to program rss action");
507                 goto err_exit;
508         }
509
510         if (hw->rx_offloads & DEV_RX_OFFLOAD_SECURITY) {
511                 rc = flow_update_sec_tt(dev, actions);
512                 if (rc != 0) {
513                         rte_flow_error_set(error, EIO,
514                                            RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
515                                            NULL,
516                                            "Failed to update tt with sec act");
517                         goto err_exit;
518                 }
519         }
520
521         list = &hw->npc_flow.flow_list[flow->priority];
522         /* List in ascending order of mcam entries */
523         TAILQ_FOREACH(flow_iter, list, next) {
524                 if (flow_iter->mcam_id > flow->mcam_id) {
525                         TAILQ_INSERT_BEFORE(flow_iter, flow, next);
526                         return flow;
527                 }
528         }
529
530         TAILQ_INSERT_TAIL(list, flow, next);
531         return flow;
532
533 err_exit:
534         rte_free(flow);
535         return NULL;
536 }
537
538 static int
539 otx2_flow_destroy(struct rte_eth_dev *dev,
540                   struct rte_flow *flow,
541                   struct rte_flow_error *error)
542 {
543         struct otx2_eth_dev *hw = dev->data->dev_private;
544         struct otx2_npc_flow_info *npc = &hw->npc_flow;
545         struct otx2_mbox *mbox = hw->mbox;
546         struct rte_bitmap *bmap;
547         uint16_t match_id;
548         int rc;
549
550         match_id = (flow->npc_action >> NIX_RX_ACT_MATCH_OFFSET) &
551                 NIX_RX_ACT_MATCH_MASK;
552
553         if (match_id && match_id < OTX2_FLOW_ACTION_FLAG_DEFAULT) {
554                 if (rte_atomic32_read(&npc->mark_actions) == 0)
555                         return -EINVAL;
556
557                 /* Clear mark offload flag if there are no more mark actions */
558                 if (rte_atomic32_sub_return(&npc->mark_actions, 1) == 0) {
559                         hw->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F;
560                         otx2_eth_set_rx_function(dev);
561                 }
562         }
563
564         rc = flow_free_rss_action(dev, flow);
565         if (rc != 0) {
566                 rte_flow_error_set(error, EIO,
567                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
568                                    NULL,
569                                    "Failed to free rss action");
570         }
571
572         rc = otx2_flow_mcam_free_entry(mbox, flow->mcam_id);
573         if (rc != 0) {
574                 rte_flow_error_set(error, EIO,
575                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
576                                    NULL,
577                                    "Failed to destroy filter");
578         }
579
580         TAILQ_REMOVE(&npc->flow_list[flow->priority], flow, next);
581
582         bmap = npc->live_entries[flow->priority];
583         rte_bitmap_clear(bmap, flow->mcam_id);
584
585         rte_free(flow);
586         return 0;
587 }
588
589 static int
590 otx2_flow_flush(struct rte_eth_dev *dev,
591                 struct rte_flow_error *error)
592 {
593         struct otx2_eth_dev *hw = dev->data->dev_private;
594         int rc;
595
596         rc = otx2_flow_free_all_resources(hw);
597         if (rc) {
598                 otx2_err("Error when deleting NPC MCAM entries "
599                                 ", counters");
600                 rte_flow_error_set(error, EIO,
601                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
602                                    NULL,
603                                    "Failed to flush filter");
604                 return -rte_errno;
605         }
606
607         return 0;
608 }
609
610 static int
611 otx2_flow_isolate(struct rte_eth_dev *dev __rte_unused,
612                   int enable __rte_unused,
613                   struct rte_flow_error *error)
614 {
615         /*
616          * If we support, we need to un-install the default mcam
617          * entry for this port.
618          */
619
620         rte_flow_error_set(error, ENOTSUP,
621                            RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
622                            NULL,
623                            "Flow isolation not supported");
624
625         return -rte_errno;
626 }
627
628 static int
629 otx2_flow_query(struct rte_eth_dev *dev,
630                 struct rte_flow *flow,
631                 const struct rte_flow_action *action,
632                 void *data,
633                 struct rte_flow_error *error)
634 {
635         struct otx2_eth_dev *hw = dev->data->dev_private;
636         struct rte_flow_query_count *query = data;
637         struct otx2_mbox *mbox = hw->mbox;
638         const char *errmsg = NULL;
639         int errcode = ENOTSUP;
640         int rc;
641
642         if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) {
643                 errmsg = "Only COUNT is supported in query";
644                 goto err_exit;
645         }
646
647         if (flow->ctr_id == NPC_COUNTER_NONE) {
648                 errmsg = "Counter is not available";
649                 goto err_exit;
650         }
651
652         rc = otx2_flow_mcam_read_counter(mbox, flow->ctr_id, &query->hits);
653         if (rc != 0) {
654                 errcode = EIO;
655                 errmsg = "Error reading flow counter";
656                 goto err_exit;
657         }
658         query->hits_set = 1;
659         query->bytes_set = 0;
660
661         if (query->reset)
662                 rc = otx2_flow_mcam_clear_counter(mbox, flow->ctr_id);
663         if (rc != 0) {
664                 errcode = EIO;
665                 errmsg = "Error clearing flow counter";
666                 goto err_exit;
667         }
668
669         return 0;
670
671 err_exit:
672         rte_flow_error_set(error, errcode,
673                            RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
674                            NULL,
675                            errmsg);
676         return -rte_errno;
677 }
678
679 const struct rte_flow_ops otx2_flow_ops = {
680         .validate = otx2_flow_validate,
681         .create = otx2_flow_create,
682         .destroy = otx2_flow_destroy,
683         .flush = otx2_flow_flush,
684         .query = otx2_flow_query,
685         .isolate = otx2_flow_isolate,
686 };
687
688 static int
689 flow_supp_key_len(uint32_t supp_mask)
690 {
691         int nib_count = 0;
692         while (supp_mask) {
693                 nib_count++;
694                 supp_mask &= (supp_mask - 1);
695         }
696         return nib_count * 4;
697 }
698
699 /* Refer HRM register:
700  * NPC_AF_INTF(0..1)_LID(0..7)_LT(0..15)_LD(0..1)_CFG
701  * and
702  * NPC_AF_INTF(0..1)_LDATA(0..1)_FLAGS(0..15)_CFG
703  **/
704 #define BYTESM1_SHIFT   16
705 #define HDR_OFF_SHIFT   8
706 static void
707 flow_update_kex_info(struct npc_xtract_info *xtract_info,
708                      uint64_t val)
709 {
710         xtract_info->len = ((val >> BYTESM1_SHIFT) & 0xf) + 1;
711         xtract_info->hdr_off = (val >> HDR_OFF_SHIFT) & 0xff;
712         xtract_info->key_off = val & 0x3f;
713         xtract_info->enable = ((val >> 7) & 0x1);
714         xtract_info->flags_enable = ((val >> 6) & 0x1);
715 }
716
717 static void
718 flow_process_mkex_cfg(struct otx2_npc_flow_info *npc,
719                       struct npc_get_kex_cfg_rsp *kex_rsp)
720 {
721         volatile uint64_t (*q)[NPC_MAX_INTF][NPC_MAX_LID][NPC_MAX_LT]
722                 [NPC_MAX_LD];
723         struct npc_xtract_info *x_info = NULL;
724         int lid, lt, ld, fl, ix;
725         otx2_dxcfg_t *p;
726         uint64_t keyw;
727         uint64_t val;
728
729         npc->keyx_supp_nmask[NPC_MCAM_RX] =
730                 kex_rsp->rx_keyx_cfg & 0x7fffffffULL;
731         npc->keyx_supp_nmask[NPC_MCAM_TX] =
732                 kex_rsp->tx_keyx_cfg & 0x7fffffffULL;
733         npc->keyx_len[NPC_MCAM_RX] =
734                 flow_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_RX]);
735         npc->keyx_len[NPC_MCAM_TX] =
736                 flow_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_TX]);
737
738         keyw = (kex_rsp->rx_keyx_cfg >> 32) & 0x7ULL;
739         npc->keyw[NPC_MCAM_RX] = keyw;
740         keyw = (kex_rsp->tx_keyx_cfg >> 32) & 0x7ULL;
741         npc->keyw[NPC_MCAM_TX] = keyw;
742
743         /* Update KEX_LD_FLAG */
744         for (ix = 0; ix < NPC_MAX_INTF; ix++) {
745                 for (ld = 0; ld < NPC_MAX_LD; ld++) {
746                         for (fl = 0; fl < NPC_MAX_LFL; fl++) {
747                                 x_info =
748                                     &npc->prx_fxcfg[ix][ld][fl].xtract[0];
749                                 val = kex_rsp->intf_ld_flags[ix][ld][fl];
750                                 flow_update_kex_info(x_info, val);
751                         }
752                 }
753         }
754
755         /* Update LID, LT and LDATA cfg */
756         p = &npc->prx_dxcfg;
757         q = (volatile uint64_t (*)[][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD])
758                         (&kex_rsp->intf_lid_lt_ld);
759         for (ix = 0; ix < NPC_MAX_INTF; ix++) {
760                 for (lid = 0; lid < NPC_MAX_LID; lid++) {
761                         for (lt = 0; lt < NPC_MAX_LT; lt++) {
762                                 for (ld = 0; ld < NPC_MAX_LD; ld++) {
763                                         x_info = &(*p)[ix][lid][lt].xtract[ld];
764                                         val = (*q)[ix][lid][lt][ld];
765                                         flow_update_kex_info(x_info, val);
766                                 }
767                         }
768                 }
769         }
770         /* Update LDATA Flags cfg */
771         npc->prx_lfcfg[0].i = kex_rsp->kex_ld_flags[0];
772         npc->prx_lfcfg[1].i = kex_rsp->kex_ld_flags[1];
773 }
774
775 static struct otx2_idev_kex_cfg *
776 flow_intra_dev_kex_cfg(void)
777 {
778         static const char name[] = "octeontx2_intra_device_kex_conf";
779         struct otx2_idev_kex_cfg *idev;
780         const struct rte_memzone *mz;
781
782         mz = rte_memzone_lookup(name);
783         if (mz)
784                 return mz->addr;
785
786         /* Request for the first time */
787         mz = rte_memzone_reserve_aligned(name, sizeof(struct otx2_idev_kex_cfg),
788                                          SOCKET_ID_ANY, 0, OTX2_ALIGN);
789         if (mz) {
790                 idev = mz->addr;
791                 rte_atomic16_set(&idev->kex_refcnt, 0);
792                 return idev;
793         }
794         return NULL;
795 }
796
797 static int
798 flow_fetch_kex_cfg(struct otx2_eth_dev *dev)
799 {
800         struct otx2_npc_flow_info *npc = &dev->npc_flow;
801         struct npc_get_kex_cfg_rsp *kex_rsp;
802         struct otx2_mbox *mbox = dev->mbox;
803         char mkex_pfl_name[MKEX_NAME_LEN];
804         struct otx2_idev_kex_cfg *idev;
805         int rc = 0;
806
807         idev = flow_intra_dev_kex_cfg();
808         if (!idev)
809                 return -ENOMEM;
810
811         /* Is kex_cfg read by any another driver? */
812         if (rte_atomic16_add_return(&idev->kex_refcnt, 1) == 1) {
813                 /* Call mailbox to get key & data size */
814                 (void)otx2_mbox_alloc_msg_npc_get_kex_cfg(mbox);
815                 otx2_mbox_msg_send(mbox, 0);
816                 rc = otx2_mbox_get_rsp(mbox, 0, (void *)&kex_rsp);
817                 if (rc) {
818                         otx2_err("Failed to fetch NPC keyx config");
819                         goto done;
820                 }
821                 memcpy(&idev->kex_cfg, kex_rsp,
822                        sizeof(struct npc_get_kex_cfg_rsp));
823         }
824
825         otx2_mbox_memcpy(mkex_pfl_name,
826                          idev->kex_cfg.mkex_pfl_name, MKEX_NAME_LEN);
827
828         strlcpy((char *)dev->mkex_pfl_name,
829                 mkex_pfl_name, sizeof(dev->mkex_pfl_name));
830
831         flow_process_mkex_cfg(npc, &idev->kex_cfg);
832
833 done:
834         return rc;
835 }
836
837 int
838 otx2_flow_init(struct otx2_eth_dev *hw)
839 {
840         uint8_t *mem = NULL, *nix_mem = NULL, *npc_mem = NULL;
841         struct otx2_npc_flow_info *npc = &hw->npc_flow;
842         uint32_t bmap_sz;
843         int rc = 0, idx;
844
845         rc = flow_fetch_kex_cfg(hw);
846         if (rc) {
847                 otx2_err("Failed to fetch NPC keyx config from idev");
848                 return rc;
849         }
850
851         rte_atomic32_init(&npc->mark_actions);
852
853         npc->mcam_entries = NPC_MCAM_TOT_ENTRIES >> npc->keyw[NPC_MCAM_RX];
854         /* Free, free_rev, live and live_rev entries */
855         bmap_sz = rte_bitmap_get_memory_footprint(npc->mcam_entries);
856         mem = rte_zmalloc(NULL, 4 * bmap_sz * npc->flow_max_priority,
857                           RTE_CACHE_LINE_SIZE);
858         if (mem == NULL) {
859                 otx2_err("Bmap alloc failed");
860                 rc = -ENOMEM;
861                 return rc;
862         }
863
864         npc->flow_entry_info = rte_zmalloc(NULL, npc->flow_max_priority
865                                            * sizeof(struct otx2_mcam_ents_info),
866                                            0);
867         if (npc->flow_entry_info == NULL) {
868                 otx2_err("flow_entry_info alloc failed");
869                 rc = -ENOMEM;
870                 goto err;
871         }
872
873         npc->free_entries = rte_zmalloc(NULL, npc->flow_max_priority
874                                         * sizeof(struct rte_bitmap *),
875                                         0);
876         if (npc->free_entries == NULL) {
877                 otx2_err("free_entries alloc failed");
878                 rc = -ENOMEM;
879                 goto err;
880         }
881
882         npc->free_entries_rev = rte_zmalloc(NULL, npc->flow_max_priority
883                                         * sizeof(struct rte_bitmap *),
884                                         0);
885         if (npc->free_entries_rev == NULL) {
886                 otx2_err("free_entries_rev alloc failed");
887                 rc = -ENOMEM;
888                 goto err;
889         }
890
891         npc->live_entries = rte_zmalloc(NULL, npc->flow_max_priority
892                                         * sizeof(struct rte_bitmap *),
893                                         0);
894         if (npc->live_entries == NULL) {
895                 otx2_err("live_entries alloc failed");
896                 rc = -ENOMEM;
897                 goto err;
898         }
899
900         npc->live_entries_rev = rte_zmalloc(NULL, npc->flow_max_priority
901                                         * sizeof(struct rte_bitmap *),
902                                         0);
903         if (npc->live_entries_rev == NULL) {
904                 otx2_err("live_entries_rev alloc failed");
905                 rc = -ENOMEM;
906                 goto err;
907         }
908
909         npc->flow_list = rte_zmalloc(NULL, npc->flow_max_priority
910                                         * sizeof(struct otx2_flow_list),
911                                         0);
912         if (npc->flow_list == NULL) {
913                 otx2_err("flow_list alloc failed");
914                 rc = -ENOMEM;
915                 goto err;
916         }
917
918         npc_mem = mem;
919         for (idx = 0; idx < npc->flow_max_priority; idx++) {
920                 TAILQ_INIT(&npc->flow_list[idx]);
921
922                 npc->free_entries[idx] =
923                         rte_bitmap_init(npc->mcam_entries, mem, bmap_sz);
924                 mem += bmap_sz;
925
926                 npc->free_entries_rev[idx] =
927                         rte_bitmap_init(npc->mcam_entries, mem, bmap_sz);
928                 mem += bmap_sz;
929
930                 npc->live_entries[idx] =
931                         rte_bitmap_init(npc->mcam_entries, mem, bmap_sz);
932                 mem += bmap_sz;
933
934                 npc->live_entries_rev[idx] =
935                         rte_bitmap_init(npc->mcam_entries, mem, bmap_sz);
936                 mem += bmap_sz;
937
938                 npc->flow_entry_info[idx].free_ent = 0;
939                 npc->flow_entry_info[idx].live_ent = 0;
940                 npc->flow_entry_info[idx].max_id = 0;
941                 npc->flow_entry_info[idx].min_id = ~(0);
942         }
943
944         npc->rss_grps = NIX_RSS_GRPS;
945
946         bmap_sz = rte_bitmap_get_memory_footprint(npc->rss_grps);
947         nix_mem = rte_zmalloc(NULL, bmap_sz,  RTE_CACHE_LINE_SIZE);
948         if (nix_mem == NULL) {
949                 otx2_err("Bmap alloc failed");
950                 rc = -ENOMEM;
951                 goto err;
952         }
953
954         npc->rss_grp_entries = rte_bitmap_init(npc->rss_grps, nix_mem, bmap_sz);
955
956         /* Group 0 will be used for RSS,
957          * 1 -7 will be used for rte_flow RSS action
958          */
959         rte_bitmap_set(npc->rss_grp_entries, 0);
960
961         return 0;
962
963 err:
964         if (npc->flow_list)
965                 rte_free(npc->flow_list);
966         if (npc->live_entries_rev)
967                 rte_free(npc->live_entries_rev);
968         if (npc->live_entries)
969                 rte_free(npc->live_entries);
970         if (npc->free_entries_rev)
971                 rte_free(npc->free_entries_rev);
972         if (npc->free_entries)
973                 rte_free(npc->free_entries);
974         if (npc->flow_entry_info)
975                 rte_free(npc->flow_entry_info);
976         if (npc_mem)
977                 rte_free(npc_mem);
978         return rc;
979 }
980
981 int
982 otx2_flow_fini(struct otx2_eth_dev *hw)
983 {
984         struct otx2_npc_flow_info *npc = &hw->npc_flow;
985         int rc;
986
987         rc = otx2_flow_free_all_resources(hw);
988         if (rc) {
989                 otx2_err("Error when deleting NPC MCAM entries, counters");
990                 return rc;
991         }
992
993         if (npc->flow_list)
994                 rte_free(npc->flow_list);
995         if (npc->live_entries_rev)
996                 rte_free(npc->live_entries_rev);
997         if (npc->live_entries)
998                 rte_free(npc->live_entries);
999         if (npc->free_entries_rev)
1000                 rte_free(npc->free_entries_rev);
1001         if (npc->free_entries)
1002                 rte_free(npc->free_entries);
1003         if (npc->flow_entry_info)
1004                 rte_free(npc->flow_entry_info);
1005
1006         return 0;
1007 }