drivers/octeontx2: fix Coverity warnings
[dpdk.git] / drivers / net / octeontx2 / otx2_vlan.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <rte_malloc.h>
6 #include <rte_tailq.h>
7
8 #include "otx2_ethdev.h"
9 #include "otx2_flow.h"
10
11
12 #define VLAN_ID_MATCH   0x1
13 #define VTAG_F_MATCH    0x2
14 #define MAC_ADDR_MATCH  0x4
15 #define QINQ_F_MATCH    0x8
16 #define VLAN_DROP       0x10
17 #define DEF_F_ENTRY     0x20
18
19 enum vtag_cfg_dir {
20         VTAG_TX,
21         VTAG_RX
22 };
23
24 static int
25 nix_vlan_mcam_enb_dis(struct otx2_eth_dev *dev,
26                       uint32_t entry, const int enable)
27 {
28         struct npc_mcam_ena_dis_entry_req *req;
29         struct otx2_mbox *mbox = dev->mbox;
30         int rc = -EINVAL;
31
32         if (enable)
33                 req = otx2_mbox_alloc_msg_npc_mcam_ena_entry(mbox);
34         else
35                 req = otx2_mbox_alloc_msg_npc_mcam_dis_entry(mbox);
36
37         req->entry = entry;
38
39         rc = otx2_mbox_process_msg(mbox, NULL);
40         return rc;
41 }
42
43 static void
44 nix_set_rx_vlan_action(struct rte_eth_dev *eth_dev,
45                     struct mcam_entry *entry, bool qinq, bool drop)
46 {
47         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
48         int pcifunc = otx2_pfvf_func(dev->pf, dev->vf);
49         uint64_t action = 0, vtag_action = 0;
50
51         action = NIX_RX_ACTIONOP_UCAST;
52
53         if (eth_dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) {
54                 action = NIX_RX_ACTIONOP_RSS;
55                 action |= (uint64_t)(dev->rss_info.alg_idx) << 56;
56         }
57
58         action |= (uint64_t)pcifunc << 4;
59         entry->action = action;
60
61         if (drop) {
62                 entry->action &= ~((uint64_t)0xF);
63                 entry->action |= NIX_RX_ACTIONOP_DROP;
64                 return;
65         }
66
67         if (!qinq) {
68                 /* VTAG0 fields denote CTAG in single vlan case */
69                 vtag_action |= (NIX_RX_VTAGACTION_VTAG_VALID << 15);
70                 vtag_action |= (NPC_LID_LB << 8);
71                 vtag_action |= NIX_RX_VTAGACTION_VTAG0_RELPTR;
72         } else {
73                 /* VTAG0 & VTAG1 fields denote CTAG & STAG respectively */
74                 vtag_action |= (NIX_RX_VTAGACTION_VTAG_VALID << 15);
75                 vtag_action |= (NPC_LID_LB << 8);
76                 vtag_action |= NIX_RX_VTAGACTION_VTAG1_RELPTR;
77                 vtag_action |= (NIX_RX_VTAGACTION_VTAG_VALID << 47);
78                 vtag_action |= ((uint64_t)(NPC_LID_LB) << 40);
79                 vtag_action |= (NIX_RX_VTAGACTION_VTAG0_RELPTR << 32);
80         }
81
82         entry->vtag_action = vtag_action;
83 }
84
85 static void
86 nix_set_tx_vlan_action(struct mcam_entry *entry, enum rte_vlan_type type,
87                        int vtag_index)
88 {
89         union {
90                 uint64_t reg;
91                 struct nix_tx_vtag_action_s act;
92         } vtag_action;
93
94         uint64_t action;
95
96         action = NIX_TX_ACTIONOP_UCAST_DEFAULT;
97
98         /*
99          * Take offset from LA since in case of untagged packet,
100          * lbptr is zero.
101          */
102         if (type == ETH_VLAN_TYPE_OUTER) {
103                 vtag_action.act.vtag0_def = vtag_index;
104                 vtag_action.act.vtag0_lid = NPC_LID_LA;
105                 vtag_action.act.vtag0_op = NIX_TX_VTAGOP_INSERT;
106                 vtag_action.act.vtag0_relptr = NIX_TX_VTAGACTION_VTAG0_RELPTR;
107         } else {
108                 vtag_action.act.vtag1_def = vtag_index;
109                 vtag_action.act.vtag1_lid = NPC_LID_LA;
110                 vtag_action.act.vtag1_op = NIX_TX_VTAGOP_INSERT;
111                 vtag_action.act.vtag1_relptr = NIX_TX_VTAGACTION_VTAG1_RELPTR;
112         }
113
114         entry->action = action;
115         entry->vtag_action = vtag_action.reg;
116 }
117
118 static int
119 nix_vlan_mcam_free(struct otx2_eth_dev *dev, uint32_t entry)
120 {
121         struct npc_mcam_free_entry_req *req;
122         struct otx2_mbox *mbox = dev->mbox;
123         int rc = -EINVAL;
124
125         req = otx2_mbox_alloc_msg_npc_mcam_free_entry(mbox);
126         req->entry = entry;
127
128         rc = otx2_mbox_process_msg(mbox, NULL);
129         return rc;
130 }
131
132 static int
133 nix_vlan_mcam_write(struct rte_eth_dev *eth_dev, uint16_t ent_idx,
134                     struct mcam_entry *entry, uint8_t intf, uint8_t ena)
135 {
136         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
137         struct npc_mcam_write_entry_req *req;
138         struct otx2_mbox *mbox = dev->mbox;
139         struct msghdr *rsp;
140         int rc = -EINVAL;
141
142         req = otx2_mbox_alloc_msg_npc_mcam_write_entry(mbox);
143
144         req->entry = ent_idx;
145         req->intf = intf;
146         req->enable_entry = ena;
147         memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
148
149         rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
150         return rc;
151 }
152
153 static int
154 nix_vlan_mcam_alloc_and_write(struct rte_eth_dev *eth_dev,
155                               struct mcam_entry *entry,
156                               uint8_t intf, bool drop)
157 {
158         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
159         struct npc_mcam_alloc_and_write_entry_req *req;
160         struct npc_mcam_alloc_and_write_entry_rsp *rsp;
161         struct otx2_mbox *mbox = dev->mbox;
162         int rc = -EINVAL;
163
164         req = otx2_mbox_alloc_msg_npc_mcam_alloc_and_write_entry(mbox);
165
166         if (intf == NPC_MCAM_RX) {
167                 if (!drop && dev->vlan_info.def_rx_mcam_idx) {
168                         req->priority = NPC_MCAM_HIGHER_PRIO;
169                         req->ref_entry = dev->vlan_info.def_rx_mcam_idx;
170                 } else if (drop && dev->vlan_info.qinq_mcam_idx) {
171                         req->priority = NPC_MCAM_LOWER_PRIO;
172                         req->ref_entry = dev->vlan_info.qinq_mcam_idx;
173                 } else {
174                         req->priority = NPC_MCAM_ANY_PRIO;
175                         req->ref_entry = 0;
176                 }
177         } else {
178                 req->priority = NPC_MCAM_ANY_PRIO;
179                 req->ref_entry = 0;
180         }
181
182         req->intf = intf;
183         req->enable_entry = 1;
184         memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
185
186         rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
187         if (rc)
188                 return rc;
189
190         return rsp->entry;
191 }
192
193 static void
194 nix_vlan_update_mac(struct rte_eth_dev *eth_dev, int mcam_index,
195                            int enable)
196 {
197         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
198         struct vlan_mkex_info *mkex = &dev->vlan_info.mkex;
199         volatile uint8_t *key_data, *key_mask;
200         struct npc_mcam_read_entry_req *req;
201         struct npc_mcam_read_entry_rsp *rsp;
202         struct otx2_mbox *mbox = dev->mbox;
203         uint64_t mcam_data, mcam_mask;
204         struct mcam_entry entry;
205         uint8_t intf, mcam_ena;
206         int idx, rc = -EINVAL;
207         uint8_t *mac_addr;
208
209         memset(&entry, 0, sizeof(struct mcam_entry));
210
211         /* Read entry first */
212         req = otx2_mbox_alloc_msg_npc_mcam_read_entry(mbox);
213
214         req->entry = mcam_index;
215
216         rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
217         if (rc) {
218                 otx2_err("Failed to read entry %d", mcam_index);
219                 return;
220         }
221
222         entry = rsp->entry_data;
223         intf = rsp->intf;
224         mcam_ena = rsp->enable;
225
226         /* Update mcam address */
227         key_data = (volatile uint8_t *)entry.kw;
228         key_mask = (volatile uint8_t *)entry.kw_mask;
229
230         if (enable) {
231                 mcam_mask = 0;
232                 otx2_mbox_memcpy(key_mask + mkex->la_xtract.key_off,
233                                  &mcam_mask, mkex->la_xtract.len + 1);
234
235         } else {
236                 mcam_data = 0ULL;
237                 mac_addr = dev->mac_addr;
238                 for (idx = RTE_ETHER_ADDR_LEN - 1; idx >= 0; idx--)
239                         mcam_data |= ((uint64_t)*mac_addr++) << (8 * idx);
240
241                 mcam_mask = BIT_ULL(48) - 1;
242
243                 otx2_mbox_memcpy(key_data + mkex->la_xtract.key_off,
244                                  &mcam_data, mkex->la_xtract.len + 1);
245                 otx2_mbox_memcpy(key_mask + mkex->la_xtract.key_off,
246                                  &mcam_mask, mkex->la_xtract.len + 1);
247         }
248
249         /* Write back the mcam entry */
250         rc = nix_vlan_mcam_write(eth_dev, mcam_index,
251                                  &entry, intf, mcam_ena);
252         if (rc) {
253                 otx2_err("Failed to write entry %d", mcam_index);
254                 return;
255         }
256 }
257
258 void
259 otx2_nix_vlan_update_promisc(struct rte_eth_dev *eth_dev, int enable)
260 {
261         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
262         struct otx2_vlan_info *vlan = &dev->vlan_info;
263         struct vlan_entry *entry;
264
265         /* Already in required mode */
266         if (enable == vlan->promisc_on)
267                 return;
268
269         /* Update default rx entry */
270         if (vlan->def_rx_mcam_idx)
271                 nix_vlan_update_mac(eth_dev, vlan->def_rx_mcam_idx, enable);
272
273         /* Update all other rx filter entries */
274         TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
275                 nix_vlan_update_mac(eth_dev, entry->mcam_idx, enable);
276
277         vlan->promisc_on = enable;
278 }
279
280 /* Configure mcam entry with required MCAM search rules */
281 static int
282 nix_vlan_mcam_config(struct rte_eth_dev *eth_dev,
283                      uint16_t vlan_id, uint16_t flags)
284 {
285         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
286         struct vlan_mkex_info *mkex = &dev->vlan_info.mkex;
287         volatile uint8_t *key_data, *key_mask;
288         uint64_t mcam_data, mcam_mask;
289         struct mcam_entry entry;
290         uint8_t *mac_addr;
291         int idx, kwi = 0;
292
293         memset(&entry, 0, sizeof(struct mcam_entry));
294         key_data = (volatile uint8_t *)entry.kw;
295         key_mask = (volatile uint8_t *)entry.kw_mask;
296
297         /* Channel base extracted to KW0[11:0] */
298         entry.kw[kwi] = dev->rx_chan_base;
299         entry.kw_mask[kwi] = BIT_ULL(12) - 1;
300
301         /* Adds vlan_id & LB CTAG flag to MCAM KW */
302         if (flags & VLAN_ID_MATCH) {
303                 entry.kw[kwi] |= NPC_LT_LB_CTAG << mkex->lb_lt_offset;
304                 entry.kw_mask[kwi] |= 0xFULL << mkex->lb_lt_offset;
305
306                 mcam_data = ((uint32_t)vlan_id << 16);
307                 mcam_mask = (BIT_ULL(16) - 1) << 16;
308                 otx2_mbox_memcpy(key_data + mkex->lb_xtract.key_off,
309                                      &mcam_data, mkex->lb_xtract.len + 1);
310                 otx2_mbox_memcpy(key_mask + mkex->lb_xtract.key_off,
311                                      &mcam_mask, mkex->lb_xtract.len + 1);
312         }
313
314         /* Adds LB STAG flag to MCAM KW */
315         if (flags & QINQ_F_MATCH) {
316                 entry.kw[kwi] |= NPC_LT_LB_STAG << mkex->lb_lt_offset;
317                 entry.kw_mask[kwi] |= 0xFULL << mkex->lb_lt_offset;
318         }
319
320         /* Adds LB CTAG & LB STAG flags to MCAM KW */
321         if (flags & VTAG_F_MATCH) {
322                 entry.kw[kwi] |= (NPC_LT_LB_CTAG | NPC_LT_LB_STAG)
323                                                         << mkex->lb_lt_offset;
324                 entry.kw_mask[kwi] |= (NPC_LT_LB_CTAG & NPC_LT_LB_STAG)
325                                                         << mkex->lb_lt_offset;
326         }
327
328         /* Adds port MAC address to MCAM KW */
329         if (flags & MAC_ADDR_MATCH) {
330                 mcam_data = 0ULL;
331                 mac_addr = dev->mac_addr;
332                 for (idx = RTE_ETHER_ADDR_LEN - 1; idx >= 0; idx--)
333                         mcam_data |= ((uint64_t)*mac_addr++) << (8 * idx);
334
335                 mcam_mask = BIT_ULL(48) - 1;
336                 otx2_mbox_memcpy(key_data + mkex->la_xtract.key_off,
337                                      &mcam_data, mkex->la_xtract.len + 1);
338                 otx2_mbox_memcpy(key_mask + mkex->la_xtract.key_off,
339                                      &mcam_mask, mkex->la_xtract.len + 1);
340         }
341
342         /* VLAN_DROP: for drop action for all vlan packets when filter is on.
343          * For QinQ, enable vtag action for both outer & inner tags
344          */
345         if (flags & VLAN_DROP)
346                 nix_set_rx_vlan_action(eth_dev, &entry, false, true);
347         else if (flags & QINQ_F_MATCH)
348                 nix_set_rx_vlan_action(eth_dev, &entry, true, false);
349         else
350                 nix_set_rx_vlan_action(eth_dev, &entry, false, false);
351
352         if (flags & DEF_F_ENTRY)
353                 dev->vlan_info.def_rx_mcam_ent = entry;
354
355         return nix_vlan_mcam_alloc_and_write(eth_dev, &entry, NIX_INTF_RX,
356                                              flags & VLAN_DROP);
357 }
358
359 /* Installs/Removes/Modifies default rx entry */
360 static int
361 nix_vlan_handle_default_rx_entry(struct rte_eth_dev *eth_dev, bool strip,
362                                  bool filter, bool enable)
363 {
364         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
365         struct otx2_vlan_info *vlan = &dev->vlan_info;
366         uint16_t flags = 0;
367         int mcam_idx, rc;
368
369         /* Use default mcam entry to either drop vlan traffic when
370          * vlan filter is on or strip vtag when strip is enabled.
371          * Allocate default entry which matches port mac address
372          * and vtag(ctag/stag) flags with drop action.
373          */
374         if (!vlan->def_rx_mcam_idx) {
375                 if (!eth_dev->data->promiscuous)
376                         flags = MAC_ADDR_MATCH;
377
378                 if (filter && enable)
379                         flags |= VTAG_F_MATCH | VLAN_DROP;
380                 else if (strip && enable)
381                         flags |= VTAG_F_MATCH;
382                 else
383                         return 0;
384
385                 flags |= DEF_F_ENTRY;
386
387                 mcam_idx = nix_vlan_mcam_config(eth_dev, 0, flags);
388                 if (mcam_idx < 0) {
389                         otx2_err("Failed to config vlan mcam");
390                         return -mcam_idx;
391                 }
392
393                 vlan->def_rx_mcam_idx = mcam_idx;
394                 return 0;
395         }
396
397         /* Filter is already enabled, so packets would be dropped anyways. No
398          * processing needed for enabling strip wrt mcam entry.
399          */
400
401         /* Filter disable request */
402         if (vlan->filter_on && filter && !enable) {
403                 vlan->def_rx_mcam_ent.action &= ~((uint64_t)0xF);
404
405                 /* Free default rx entry only when
406                  * 1. strip is not on and
407                  * 2. qinq entry is allocated before default entry.
408                  */
409                 if (vlan->strip_on ||
410                     (vlan->qinq_on && !vlan->qinq_before_def)) {
411                         if (eth_dev->data->dev_conf.rxmode.mq_mode ==
412                                                                 ETH_MQ_RX_RSS)
413                                 vlan->def_rx_mcam_ent.action |=
414                                                         NIX_RX_ACTIONOP_RSS;
415                         else
416                                 vlan->def_rx_mcam_ent.action |=
417                                                         NIX_RX_ACTIONOP_UCAST;
418                         return nix_vlan_mcam_write(eth_dev,
419                                                    vlan->def_rx_mcam_idx,
420                                                    &vlan->def_rx_mcam_ent,
421                                                    NIX_INTF_RX, 1);
422                 } else {
423                         rc = nix_vlan_mcam_free(dev, vlan->def_rx_mcam_idx);
424                         if (rc)
425                                 return rc;
426                         vlan->def_rx_mcam_idx = 0;
427                 }
428         }
429
430         /* Filter enable request */
431         if (!vlan->filter_on && filter && enable) {
432                 vlan->def_rx_mcam_ent.action &= ~((uint64_t)0xF);
433                 vlan->def_rx_mcam_ent.action |= NIX_RX_ACTIONOP_DROP;
434                 return nix_vlan_mcam_write(eth_dev, vlan->def_rx_mcam_idx,
435                                    &vlan->def_rx_mcam_ent, NIX_INTF_RX, 1);
436         }
437
438         /* Strip disable request */
439         if (vlan->strip_on && strip && !enable) {
440                 if (!vlan->filter_on &&
441                     !(vlan->qinq_on && !vlan->qinq_before_def)) {
442                         rc = nix_vlan_mcam_free(dev, vlan->def_rx_mcam_idx);
443                         if (rc)
444                                 return rc;
445                         vlan->def_rx_mcam_idx = 0;
446                 }
447         }
448
449         return 0;
450 }
451
452 /* Installs/Removes default tx entry */
453 static int
454 nix_vlan_handle_default_tx_entry(struct rte_eth_dev *eth_dev,
455                                  enum rte_vlan_type type, int vtag_index,
456                                  int enable)
457 {
458         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
459         struct otx2_vlan_info *vlan = &dev->vlan_info;
460         struct mcam_entry entry;
461         uint16_t pf_func;
462         int rc;
463
464         if (!vlan->def_tx_mcam_idx && enable) {
465                 memset(&entry, 0, sizeof(struct mcam_entry));
466
467                 /* Only pf_func is matched, swap it's bytes */
468                 pf_func = (dev->pf_func & 0xff) << 8;
469                 pf_func |= (dev->pf_func >> 8) & 0xff;
470
471                 /* PF Func extracted to KW1[63:48] */
472                 entry.kw[1] = (uint64_t)pf_func << 48;
473                 entry.kw_mask[1] = (BIT_ULL(16) - 1) << 48;
474
475                 nix_set_tx_vlan_action(&entry, type, vtag_index);
476                 vlan->def_tx_mcam_ent = entry;
477
478                 return nix_vlan_mcam_alloc_and_write(eth_dev, &entry,
479                                                      NIX_INTF_TX, 0);
480         }
481
482         if (vlan->def_tx_mcam_idx && !enable) {
483                 rc = nix_vlan_mcam_free(dev, vlan->def_tx_mcam_idx);
484                 if (rc)
485                         return rc;
486                 vlan->def_rx_mcam_idx = 0;
487         }
488
489         return 0;
490 }
491
492 /* Configure vlan stripping on or off */
493 static int
494 nix_vlan_hw_strip(struct rte_eth_dev *eth_dev, const uint8_t enable)
495 {
496         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
497         struct otx2_mbox *mbox = dev->mbox;
498         struct nix_vtag_config *vtag_cfg;
499         int rc = -EINVAL;
500
501         rc = nix_vlan_handle_default_rx_entry(eth_dev, true, false, enable);
502         if (rc) {
503                 otx2_err("Failed to config default rx entry");
504                 return rc;
505         }
506
507         vtag_cfg = otx2_mbox_alloc_msg_nix_vtag_cfg(mbox);
508         /* cfg_type = 1 for rx vlan cfg */
509         vtag_cfg->cfg_type = VTAG_RX;
510
511         if (enable)
512                 vtag_cfg->rx.strip_vtag = 1;
513         else
514                 vtag_cfg->rx.strip_vtag = 0;
515
516         /* Always capture */
517         vtag_cfg->rx.capture_vtag = 1;
518         vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
519         /* Use rx vtag type index[0] for now */
520         vtag_cfg->rx.vtag_type = 0;
521
522         rc = otx2_mbox_process(mbox);
523         if (rc)
524                 return rc;
525
526         dev->vlan_info.strip_on = enable;
527         return rc;
528 }
529
530 /* Configure vlan filtering on or off for all vlans if vlan_id == 0 */
531 static int
532 nix_vlan_hw_filter(struct rte_eth_dev *eth_dev, const uint8_t enable,
533                    uint16_t vlan_id)
534 {
535         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
536         struct otx2_vlan_info *vlan = &dev->vlan_info;
537         struct vlan_entry *entry;
538         int rc = -EINVAL;
539
540         if (!vlan_id && enable) {
541                 rc = nix_vlan_handle_default_rx_entry(eth_dev, false, true,
542                                                       enable);
543                 if (rc) {
544                         otx2_err("Failed to config vlan mcam");
545                         return rc;
546                 }
547                 dev->vlan_info.filter_on = enable;
548                 return 0;
549         }
550
551         /* Enable/disable existing vlan filter entries */
552         TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
553                 if (vlan_id) {
554                         if (entry->vlan_id == vlan_id) {
555                                 rc = nix_vlan_mcam_enb_dis(dev,
556                                                            entry->mcam_idx,
557                                                            enable);
558                                 if (rc)
559                                         return rc;
560                         }
561                 } else {
562                         rc = nix_vlan_mcam_enb_dis(dev, entry->mcam_idx,
563                                                    enable);
564                         if (rc)
565                                 return rc;
566                 }
567         }
568
569         if (!vlan_id && !enable) {
570                 rc = nix_vlan_handle_default_rx_entry(eth_dev, false, true,
571                                                       enable);
572                 if (rc) {
573                         otx2_err("Failed to config vlan mcam");
574                         return rc;
575                 }
576                 dev->vlan_info.filter_on = enable;
577                 return 0;
578         }
579
580         return 0;
581 }
582
583 /* Enable/disable vlan filtering for the given vlan_id */
584 int
585 otx2_nix_vlan_filter_set(struct rte_eth_dev *eth_dev, uint16_t vlan_id,
586                          int on)
587 {
588         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
589         struct otx2_vlan_info *vlan = &dev->vlan_info;
590         struct vlan_entry *entry;
591         int entry_exists = 0;
592         int rc = -EINVAL;
593         int mcam_idx;
594
595         if (!vlan_id) {
596                 otx2_err("Vlan Id can't be zero");
597                 return rc;
598         }
599
600         if (!vlan->def_rx_mcam_idx) {
601                 otx2_err("Vlan Filtering is disabled, enable it first");
602                 return rc;
603         }
604
605         if (on) {
606                 TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
607                         if (entry->vlan_id == vlan_id) {
608                                 /* Vlan entry already exists */
609                                 entry_exists = 1;
610                                 /* Mcam entry already allocated */
611                                 if (entry->mcam_idx) {
612                                         rc = nix_vlan_hw_filter(eth_dev, on,
613                                                                 vlan_id);
614                                         return rc;
615                                 }
616                                 break;
617                         }
618                 }
619
620                 if (!entry_exists) {
621                         entry = rte_zmalloc("otx2_nix_vlan_entry",
622                                             sizeof(struct vlan_entry), 0);
623                         if (!entry) {
624                                 otx2_err("Failed to allocate memory");
625                                 return -ENOMEM;
626                         }
627                 }
628
629                 /* Enables vlan_id & mac address based filtering */
630                 if (eth_dev->data->promiscuous)
631                         mcam_idx = nix_vlan_mcam_config(eth_dev, vlan_id,
632                                                         VLAN_ID_MATCH);
633                 else
634                         mcam_idx = nix_vlan_mcam_config(eth_dev, vlan_id,
635                                                         VLAN_ID_MATCH |
636                                                         MAC_ADDR_MATCH);
637                 if (mcam_idx < 0) {
638                         otx2_err("Failed to config vlan mcam");
639                         TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
640                         rte_free(entry);
641                         return mcam_idx;
642                 }
643
644                 entry->mcam_idx = mcam_idx;
645                 if (!entry_exists) {
646                         entry->vlan_id  = vlan_id;
647                         TAILQ_INSERT_HEAD(&vlan->fltr_tbl, entry, next);
648                 }
649         } else {
650                 TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
651                         if (entry->vlan_id == vlan_id) {
652                                 rc = nix_vlan_mcam_free(dev, entry->mcam_idx);
653                                 if (rc)
654                                         return rc;
655                                 TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
656                                 rte_free(entry);
657                                 break;
658                         }
659                 }
660         }
661         return 0;
662 }
663
664 /* Configure double vlan(qinq) on or off */
665 static int
666 otx2_nix_config_double_vlan(struct rte_eth_dev *eth_dev,
667                             const uint8_t enable)
668 {
669         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
670         struct otx2_vlan_info *vlan_info;
671         int mcam_idx;
672         int rc;
673
674         vlan_info = &dev->vlan_info;
675
676         if (!enable) {
677                 if (!vlan_info->qinq_mcam_idx)
678                         return 0;
679
680                 rc = nix_vlan_mcam_free(dev, vlan_info->qinq_mcam_idx);
681                 if (rc)
682                         return rc;
683
684                 vlan_info->qinq_mcam_idx = 0;
685                 dev->vlan_info.qinq_on = 0;
686                 vlan_info->qinq_before_def = 0;
687                 return 0;
688         }
689
690         if (eth_dev->data->promiscuous)
691                 mcam_idx = nix_vlan_mcam_config(eth_dev, 0, QINQ_F_MATCH);
692         else
693                 mcam_idx = nix_vlan_mcam_config(eth_dev, 0,
694                                                 QINQ_F_MATCH | MAC_ADDR_MATCH);
695         if (mcam_idx < 0)
696                 return mcam_idx;
697
698         if (!vlan_info->def_rx_mcam_idx)
699                 vlan_info->qinq_before_def = 1;
700
701         vlan_info->qinq_mcam_idx = mcam_idx;
702         dev->vlan_info.qinq_on = 1;
703         return 0;
704 }
705
706 int
707 otx2_nix_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
708 {
709         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
710         uint64_t offloads = dev->rx_offloads;
711         struct rte_eth_rxmode *rxmode;
712         int rc = 0;
713
714         rxmode = &eth_dev->data->dev_conf.rxmode;
715
716         if (mask & ETH_VLAN_EXTEND_MASK) {
717                 otx2_err("Extend offload not supported");
718                 return -ENOTSUP;
719         }
720
721         if (mask & ETH_VLAN_STRIP_MASK) {
722                 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
723                         offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
724                         rc = nix_vlan_hw_strip(eth_dev, true);
725                 } else {
726                         offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
727                         rc = nix_vlan_hw_strip(eth_dev, false);
728                 }
729                 if (rc)
730                         goto done;
731         }
732
733         if (mask & ETH_VLAN_FILTER_MASK) {
734                 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
735                         offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
736                         rc = nix_vlan_hw_filter(eth_dev, true, 0);
737                 } else {
738                         offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
739                         rc = nix_vlan_hw_filter(eth_dev, false, 0);
740                 }
741                 if (rc)
742                         goto done;
743         }
744
745         if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) {
746                 if (!dev->vlan_info.qinq_on) {
747                         offloads |= DEV_RX_OFFLOAD_QINQ_STRIP;
748                         rc = otx2_nix_config_double_vlan(eth_dev, true);
749                         if (rc)
750                                 goto done;
751                 }
752         } else {
753                 if (dev->vlan_info.qinq_on) {
754                         offloads &= ~DEV_RX_OFFLOAD_QINQ_STRIP;
755                         rc = otx2_nix_config_double_vlan(eth_dev, false);
756                         if (rc)
757                                 goto done;
758                 }
759         }
760
761         if (offloads & (DEV_RX_OFFLOAD_VLAN_STRIP |
762                         DEV_RX_OFFLOAD_QINQ_STRIP)) {
763                 dev->rx_offloads |= offloads;
764                 dev->rx_offload_flags |= NIX_RX_OFFLOAD_VLAN_STRIP_F;
765                 otx2_eth_set_rx_function(eth_dev);
766         }
767
768 done:
769         return rc;
770 }
771
772 int
773 otx2_nix_vlan_tpid_set(struct rte_eth_dev *eth_dev,
774                        enum rte_vlan_type type, uint16_t tpid)
775 {
776         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
777         struct nix_set_vlan_tpid *tpid_cfg;
778         struct otx2_mbox *mbox = dev->mbox;
779         int rc;
780
781         tpid_cfg = otx2_mbox_alloc_msg_nix_set_vlan_tpid(mbox);
782
783         tpid_cfg->tpid = tpid;
784         if (type == ETH_VLAN_TYPE_OUTER)
785                 tpid_cfg->vlan_type = NIX_VLAN_TYPE_OUTER;
786         else
787                 tpid_cfg->vlan_type = NIX_VLAN_TYPE_INNER;
788
789         rc = otx2_mbox_process(mbox);
790         if (rc)
791                 return rc;
792
793         if (type == ETH_VLAN_TYPE_OUTER)
794                 dev->vlan_info.outer_vlan_tpid = tpid;
795         else
796                 dev->vlan_info.inner_vlan_tpid = tpid;
797         return 0;
798 }
799
800 int
801 otx2_nix_vlan_pvid_set(struct rte_eth_dev *dev,       uint16_t vlan_id, int on)
802 {
803         struct otx2_eth_dev *otx2_dev = otx2_eth_pmd_priv(dev);
804         struct otx2_mbox *mbox = otx2_dev->mbox;
805         struct nix_vtag_config *vtag_cfg;
806         struct nix_vtag_config_rsp *rsp;
807         struct otx2_vlan_info *vlan;
808         int rc, rc1, vtag_index = 0;
809
810         if (vlan_id == 0) {
811                 otx2_err("vlan id can't be zero");
812                 return -EINVAL;
813         }
814
815         vlan = &otx2_dev->vlan_info;
816
817         if (on && vlan->pvid_insert_on && vlan->pvid == vlan_id) {
818                 otx2_err("pvid %d is already enabled", vlan_id);
819                 return -EINVAL;
820         }
821
822         if (on && vlan->pvid_insert_on && vlan->pvid != vlan_id) {
823                 otx2_err("another pvid is enabled, disable that first");
824                 return -EINVAL;
825         }
826
827         /* No pvid active */
828         if (!on && !vlan->pvid_insert_on)
829                 return 0;
830
831         /* Given pvid already disabled */
832         if (!on && vlan->pvid != vlan_id)
833                 return 0;
834
835         vtag_cfg = otx2_mbox_alloc_msg_nix_vtag_cfg(mbox);
836
837         if (on) {
838                 vtag_cfg->cfg_type = VTAG_TX;
839                 vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
840
841                 if (vlan->outer_vlan_tpid)
842                         vtag_cfg->tx.vtag0 = ((uint32_t)vlan->outer_vlan_tpid
843                                               << 16) | vlan_id;
844                 else
845                         vtag_cfg->tx.vtag0 =
846                                 ((RTE_ETHER_TYPE_VLAN << 16) | vlan_id);
847                 vtag_cfg->tx.cfg_vtag0 = 1;
848         } else {
849                 vtag_cfg->cfg_type = VTAG_TX;
850                 vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
851
852                 vtag_cfg->tx.vtag0_idx = vlan->outer_vlan_idx;
853                 vtag_cfg->tx.free_vtag0 = 1;
854         }
855
856         rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
857         if (rc)
858                 return rc;
859
860         if (on) {
861                 vtag_index = rsp->vtag0_idx;
862         } else {
863                 vlan->pvid = 0;
864                 vlan->pvid_insert_on = 0;
865                 vlan->outer_vlan_idx = 0;
866         }
867
868         rc = nix_vlan_handle_default_tx_entry(dev, ETH_VLAN_TYPE_OUTER,
869                                               vtag_index, on);
870         if (rc < 0) {
871                 printf("Default tx entry failed with rc %d\n", rc);
872                 vtag_cfg->tx.vtag0_idx = vtag_index;
873                 vtag_cfg->tx.free_vtag0 = 1;
874                 vtag_cfg->tx.cfg_vtag0 = 0;
875
876                 rc1 = otx2_mbox_process_msg(mbox, (void *)&rsp);
877                 if (rc1)
878                         otx2_err("Vtag free failed");
879
880                 return rc;
881         }
882
883         if (on) {
884                 vlan->pvid = vlan_id;
885                 vlan->pvid_insert_on = 1;
886                 vlan->outer_vlan_idx = vtag_index;
887         }
888
889         return 0;
890 }
891
892 void otx2_nix_vlan_strip_queue_set(__rte_unused struct rte_eth_dev *dev,
893                                    __rte_unused uint16_t queue,
894                                    __rte_unused int on)
895 {
896         otx2_err("Not Supported");
897 }
898
899 static int
900 nix_vlan_rx_mkex_offset(uint64_t mask)
901 {
902         int nib_count = 0;
903
904         while (mask) {
905                 nib_count += mask & 1;
906                 mask >>= 1;
907         }
908
909         return nib_count * 4;
910 }
911
912 static int
913 nix_vlan_get_mkex_info(struct otx2_eth_dev *dev)
914 {
915         struct vlan_mkex_info *mkex = &dev->vlan_info.mkex;
916         struct otx2_npc_flow_info *npc = &dev->npc_flow;
917         struct npc_xtract_info *x_info = NULL;
918         uint64_t rx_keyx;
919         otx2_dxcfg_t *p;
920         int rc = -EINVAL;
921
922         if (npc == NULL) {
923                 otx2_err("Missing npc mkex configuration");
924                 return rc;
925         }
926
927 #define NPC_KEX_CHAN_NIBBLE_ENA                 0x7ULL
928 #define NPC_KEX_LB_LTYPE_NIBBLE_ENA             0x1000ULL
929 #define NPC_KEX_LB_LTYPE_NIBBLE_MASK            0xFFFULL
930
931         rx_keyx = npc->keyx_supp_nmask[NPC_MCAM_RX];
932         if ((rx_keyx & NPC_KEX_CHAN_NIBBLE_ENA) != NPC_KEX_CHAN_NIBBLE_ENA)
933                 return rc;
934
935         if ((rx_keyx & NPC_KEX_LB_LTYPE_NIBBLE_ENA) !=
936             NPC_KEX_LB_LTYPE_NIBBLE_ENA)
937                 return rc;
938
939         mkex->lb_lt_offset =
940             nix_vlan_rx_mkex_offset(rx_keyx & NPC_KEX_LB_LTYPE_NIBBLE_MASK);
941
942         p = &npc->prx_dxcfg;
943         x_info = &(*p)[NPC_MCAM_RX][NPC_LID_LA][NPC_LT_LA_ETHER].xtract[0];
944         memcpy(&mkex->la_xtract, x_info, sizeof(struct npc_xtract_info));
945         x_info = &(*p)[NPC_MCAM_RX][NPC_LID_LB][NPC_LT_LB_CTAG].xtract[0];
946         memcpy(&mkex->lb_xtract, x_info, sizeof(struct npc_xtract_info));
947
948         return 0;
949 }
950
951 static void nix_vlan_reinstall_vlan_filters(struct rte_eth_dev *eth_dev)
952 {
953         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
954         struct vlan_entry *entry;
955         int rc;
956
957         /* VLAN filters can't be set without setting filtern on */
958         rc = nix_vlan_handle_default_rx_entry(eth_dev, false, true, true);
959         if (rc) {
960                 otx2_err("Failed to reinstall vlan filters");
961                 return;
962         }
963
964         TAILQ_FOREACH(entry, &dev->vlan_info.fltr_tbl, next) {
965                 rc = otx2_nix_vlan_filter_set(eth_dev, entry->vlan_id, true);
966                 if (rc)
967                         otx2_err("Failed to reinstall filter for vlan:%d",
968                                  entry->vlan_id);
969         }
970 }
971
972 int
973 otx2_nix_vlan_offload_init(struct rte_eth_dev *eth_dev)
974 {
975         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
976         int rc, mask;
977
978         /* Port initialized for first time or restarted */
979         if (!dev->configured) {
980                 rc = nix_vlan_get_mkex_info(dev);
981                 if (rc) {
982                         otx2_err("Failed to get vlan mkex info rc=%d", rc);
983                         return rc;
984                 }
985
986                 TAILQ_INIT(&dev->vlan_info.fltr_tbl);
987         } else {
988                 /* Reinstall all mcam entries now if filter offload is set */
989                 if (eth_dev->data->dev_conf.rxmode.offloads &
990                     DEV_RX_OFFLOAD_VLAN_FILTER)
991                         nix_vlan_reinstall_vlan_filters(eth_dev);
992         }
993
994         mask =
995             ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK;
996         rc = otx2_nix_vlan_offload_set(eth_dev, mask);
997         if (rc) {
998                 otx2_err("Failed to set vlan offload rc=%d", rc);
999                 return rc;
1000         }
1001
1002         return 0;
1003 }
1004
1005 int
1006 otx2_nix_vlan_fini(struct rte_eth_dev *eth_dev)
1007 {
1008         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
1009         struct otx2_vlan_info *vlan = &dev->vlan_info;
1010         struct vlan_entry *entry;
1011         int rc;
1012
1013         TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
1014                 if (!dev->configured) {
1015                         TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
1016                         rte_free(entry);
1017                 } else {
1018                         /* MCAM entries freed by flow_fini & lf_free on
1019                          * port stop.
1020                          */
1021                         entry->mcam_idx = 0;
1022                 }
1023         }
1024
1025         if (!dev->configured) {
1026                 if (vlan->def_rx_mcam_idx) {
1027                         rc = nix_vlan_mcam_free(dev, vlan->def_rx_mcam_idx);
1028                         if (rc)
1029                                 return rc;
1030                 }
1031         }
1032
1033         otx2_nix_config_double_vlan(eth_dev, false);
1034         vlan->def_rx_mcam_idx = 0;
1035         return 0;
1036 }