replace alignment attributes
[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 | NPC_LT_LB_STAG_QINQ)
304                                                         << mkex->lb_lt_offset;
305                 entry.kw_mask[kwi] |=
306                         (0xF & ~(NPC_LT_LB_CTAG ^ NPC_LT_LB_STAG_QINQ))
307                                                         << mkex->lb_lt_offset;
308
309                 mcam_data = ((uint32_t)vlan_id << 16);
310                 mcam_mask = (BIT_ULL(16) - 1) << 16;
311                 otx2_mbox_memcpy(key_data + mkex->lb_xtract.key_off,
312                                      &mcam_data, mkex->lb_xtract.len + 1);
313                 otx2_mbox_memcpy(key_mask + mkex->lb_xtract.key_off,
314                                      &mcam_mask, mkex->lb_xtract.len + 1);
315         }
316
317         /* Adds LB STAG flag to MCAM KW */
318         if (flags & QINQ_F_MATCH) {
319                 entry.kw[kwi] |= NPC_LT_LB_STAG_QINQ << mkex->lb_lt_offset;
320                 entry.kw_mask[kwi] |= 0xFULL << mkex->lb_lt_offset;
321         }
322
323         /* Adds LB CTAG & LB STAG flags to MCAM KW */
324         if (flags & VTAG_F_MATCH) {
325                 entry.kw[kwi] |= (NPC_LT_LB_CTAG | NPC_LT_LB_STAG_QINQ)
326                                                         << mkex->lb_lt_offset;
327                 entry.kw_mask[kwi] |=
328                         (0xF & ~(NPC_LT_LB_CTAG ^ NPC_LT_LB_STAG_QINQ))
329                                                         << mkex->lb_lt_offset;
330         }
331
332         /* Adds port MAC address to MCAM KW */
333         if (flags & MAC_ADDR_MATCH) {
334                 mcam_data = 0ULL;
335                 mac_addr = dev->mac_addr;
336                 for (idx = RTE_ETHER_ADDR_LEN - 1; idx >= 0; idx--)
337                         mcam_data |= ((uint64_t)*mac_addr++) << (8 * idx);
338
339                 mcam_mask = BIT_ULL(48) - 1;
340                 otx2_mbox_memcpy(key_data + mkex->la_xtract.key_off,
341                                      &mcam_data, mkex->la_xtract.len + 1);
342                 otx2_mbox_memcpy(key_mask + mkex->la_xtract.key_off,
343                                      &mcam_mask, mkex->la_xtract.len + 1);
344         }
345
346         /* VLAN_DROP: for drop action for all vlan packets when filter is on.
347          * For QinQ, enable vtag action for both outer & inner tags
348          */
349         if (flags & VLAN_DROP)
350                 nix_set_rx_vlan_action(eth_dev, &entry, false, true);
351         else if (flags & QINQ_F_MATCH)
352                 nix_set_rx_vlan_action(eth_dev, &entry, true, false);
353         else
354                 nix_set_rx_vlan_action(eth_dev, &entry, false, false);
355
356         if (flags & DEF_F_ENTRY)
357                 dev->vlan_info.def_rx_mcam_ent = entry;
358
359         return nix_vlan_mcam_alloc_and_write(eth_dev, &entry, NIX_INTF_RX,
360                                              flags & VLAN_DROP);
361 }
362
363 /* Installs/Removes/Modifies default rx entry */
364 static int
365 nix_vlan_handle_default_rx_entry(struct rte_eth_dev *eth_dev, bool strip,
366                                  bool filter, bool enable)
367 {
368         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
369         struct otx2_vlan_info *vlan = &dev->vlan_info;
370         uint16_t flags = 0;
371         int mcam_idx, rc;
372
373         /* Use default mcam entry to either drop vlan traffic when
374          * vlan filter is on or strip vtag when strip is enabled.
375          * Allocate default entry which matches port mac address
376          * and vtag(ctag/stag) flags with drop action.
377          */
378         if (!vlan->def_rx_mcam_idx) {
379                 if (!eth_dev->data->promiscuous)
380                         flags = MAC_ADDR_MATCH;
381
382                 if (filter && enable)
383                         flags |= VTAG_F_MATCH | VLAN_DROP;
384                 else if (strip && enable)
385                         flags |= VTAG_F_MATCH;
386                 else
387                         return 0;
388
389                 flags |= DEF_F_ENTRY;
390
391                 mcam_idx = nix_vlan_mcam_config(eth_dev, 0, flags);
392                 if (mcam_idx < 0) {
393                         otx2_err("Failed to config vlan mcam");
394                         return -mcam_idx;
395                 }
396
397                 vlan->def_rx_mcam_idx = mcam_idx;
398                 return 0;
399         }
400
401         /* Filter is already enabled, so packets would be dropped anyways. No
402          * processing needed for enabling strip wrt mcam entry.
403          */
404
405         /* Filter disable request */
406         if (vlan->filter_on && filter && !enable) {
407                 vlan->def_rx_mcam_ent.action &= ~((uint64_t)0xF);
408
409                 /* Free default rx entry only when
410                  * 1. strip is not on and
411                  * 2. qinq entry is allocated before default entry.
412                  */
413                 if (vlan->strip_on ||
414                     (vlan->qinq_on && !vlan->qinq_before_def)) {
415                         if (eth_dev->data->dev_conf.rxmode.mq_mode ==
416                                                                 ETH_MQ_RX_RSS)
417                                 vlan->def_rx_mcam_ent.action |=
418                                                         NIX_RX_ACTIONOP_RSS;
419                         else
420                                 vlan->def_rx_mcam_ent.action |=
421                                                         NIX_RX_ACTIONOP_UCAST;
422                         return nix_vlan_mcam_write(eth_dev,
423                                                    vlan->def_rx_mcam_idx,
424                                                    &vlan->def_rx_mcam_ent,
425                                                    NIX_INTF_RX, 1);
426                 } else {
427                         rc = nix_vlan_mcam_free(dev, vlan->def_rx_mcam_idx);
428                         if (rc)
429                                 return rc;
430                         vlan->def_rx_mcam_idx = 0;
431                 }
432         }
433
434         /* Filter enable request */
435         if (!vlan->filter_on && filter && enable) {
436                 vlan->def_rx_mcam_ent.action &= ~((uint64_t)0xF);
437                 vlan->def_rx_mcam_ent.action |= NIX_RX_ACTIONOP_DROP;
438                 return nix_vlan_mcam_write(eth_dev, vlan->def_rx_mcam_idx,
439                                    &vlan->def_rx_mcam_ent, NIX_INTF_RX, 1);
440         }
441
442         /* Strip disable request */
443         if (vlan->strip_on && strip && !enable) {
444                 if (!vlan->filter_on &&
445                     !(vlan->qinq_on && !vlan->qinq_before_def)) {
446                         rc = nix_vlan_mcam_free(dev, vlan->def_rx_mcam_idx);
447                         if (rc)
448                                 return rc;
449                         vlan->def_rx_mcam_idx = 0;
450                 }
451         }
452
453         return 0;
454 }
455
456 /* Installs/Removes default tx entry */
457 static int
458 nix_vlan_handle_default_tx_entry(struct rte_eth_dev *eth_dev,
459                                  enum rte_vlan_type type, int vtag_index,
460                                  int enable)
461 {
462         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
463         struct otx2_vlan_info *vlan = &dev->vlan_info;
464         struct mcam_entry entry;
465         uint16_t pf_func;
466         int rc;
467
468         if (!vlan->def_tx_mcam_idx && enable) {
469                 memset(&entry, 0, sizeof(struct mcam_entry));
470
471                 /* Only pf_func is matched, swap it's bytes */
472                 pf_func = (dev->pf_func & 0xff) << 8;
473                 pf_func |= (dev->pf_func >> 8) & 0xff;
474
475                 /* PF Func extracted to KW1[47:32] */
476                 entry.kw[0] = (uint64_t)pf_func << 32;
477                 entry.kw_mask[0] = (BIT_ULL(16) - 1) << 32;
478
479                 nix_set_tx_vlan_action(&entry, type, vtag_index);
480                 vlan->def_tx_mcam_ent = entry;
481
482                 return nix_vlan_mcam_alloc_and_write(eth_dev, &entry,
483                                                      NIX_INTF_TX, 0);
484         }
485
486         if (vlan->def_tx_mcam_idx && !enable) {
487                 rc = nix_vlan_mcam_free(dev, vlan->def_tx_mcam_idx);
488                 if (rc)
489                         return rc;
490                 vlan->def_rx_mcam_idx = 0;
491         }
492
493         return 0;
494 }
495
496 /* Configure vlan stripping on or off */
497 static int
498 nix_vlan_hw_strip(struct rte_eth_dev *eth_dev, const uint8_t enable)
499 {
500         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
501         struct otx2_mbox *mbox = dev->mbox;
502         struct nix_vtag_config *vtag_cfg;
503         int rc = -EINVAL;
504
505         rc = nix_vlan_handle_default_rx_entry(eth_dev, true, false, enable);
506         if (rc) {
507                 otx2_err("Failed to config default rx entry");
508                 return rc;
509         }
510
511         vtag_cfg = otx2_mbox_alloc_msg_nix_vtag_cfg(mbox);
512         /* cfg_type = 1 for rx vlan cfg */
513         vtag_cfg->cfg_type = VTAG_RX;
514
515         if (enable)
516                 vtag_cfg->rx.strip_vtag = 1;
517         else
518                 vtag_cfg->rx.strip_vtag = 0;
519
520         /* Always capture */
521         vtag_cfg->rx.capture_vtag = 1;
522         vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
523         /* Use rx vtag type index[0] for now */
524         vtag_cfg->rx.vtag_type = 0;
525
526         rc = otx2_mbox_process(mbox);
527         if (rc)
528                 return rc;
529
530         dev->vlan_info.strip_on = enable;
531         return rc;
532 }
533
534 /* Configure vlan filtering on or off for all vlans if vlan_id == 0 */
535 static int
536 nix_vlan_hw_filter(struct rte_eth_dev *eth_dev, const uint8_t enable,
537                    uint16_t vlan_id)
538 {
539         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
540         struct otx2_vlan_info *vlan = &dev->vlan_info;
541         struct vlan_entry *entry;
542         int rc = -EINVAL;
543
544         if (!vlan_id && enable) {
545                 rc = nix_vlan_handle_default_rx_entry(eth_dev, false, true,
546                                                       enable);
547                 if (rc) {
548                         otx2_err("Failed to config vlan mcam");
549                         return rc;
550                 }
551                 dev->vlan_info.filter_on = enable;
552                 return 0;
553         }
554
555         /* Enable/disable existing vlan filter entries */
556         TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
557                 if (vlan_id) {
558                         if (entry->vlan_id == vlan_id) {
559                                 rc = nix_vlan_mcam_enb_dis(dev,
560                                                            entry->mcam_idx,
561                                                            enable);
562                                 if (rc)
563                                         return rc;
564                         }
565                 } else {
566                         rc = nix_vlan_mcam_enb_dis(dev, entry->mcam_idx,
567                                                    enable);
568                         if (rc)
569                                 return rc;
570                 }
571         }
572
573         if (!vlan_id && !enable) {
574                 rc = nix_vlan_handle_default_rx_entry(eth_dev, false, true,
575                                                       enable);
576                 if (rc) {
577                         otx2_err("Failed to config vlan mcam");
578                         return rc;
579                 }
580                 dev->vlan_info.filter_on = enable;
581                 return 0;
582         }
583
584         return 0;
585 }
586
587 /* Enable/disable vlan filtering for the given vlan_id */
588 int
589 otx2_nix_vlan_filter_set(struct rte_eth_dev *eth_dev, uint16_t vlan_id,
590                          int on)
591 {
592         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
593         struct otx2_vlan_info *vlan = &dev->vlan_info;
594         struct vlan_entry *entry;
595         int entry_exists = 0;
596         int rc = -EINVAL;
597         int mcam_idx;
598
599         if (!vlan_id) {
600                 otx2_err("Vlan Id can't be zero");
601                 return rc;
602         }
603
604         if (!vlan->def_rx_mcam_idx) {
605                 otx2_err("Vlan Filtering is disabled, enable it first");
606                 return rc;
607         }
608
609         if (on) {
610                 TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
611                         if (entry->vlan_id == vlan_id) {
612                                 /* Vlan entry already exists */
613                                 entry_exists = 1;
614                                 /* Mcam entry already allocated */
615                                 if (entry->mcam_idx) {
616                                         rc = nix_vlan_hw_filter(eth_dev, on,
617                                                                 vlan_id);
618                                         return rc;
619                                 }
620                                 break;
621                         }
622                 }
623
624                 if (!entry_exists) {
625                         entry = rte_zmalloc("otx2_nix_vlan_entry",
626                                             sizeof(struct vlan_entry), 0);
627                         if (!entry) {
628                                 otx2_err("Failed to allocate memory");
629                                 return -ENOMEM;
630                         }
631                 }
632
633                 /* Enables vlan_id & mac address based filtering */
634                 if (eth_dev->data->promiscuous)
635                         mcam_idx = nix_vlan_mcam_config(eth_dev, vlan_id,
636                                                         VLAN_ID_MATCH);
637                 else
638                         mcam_idx = nix_vlan_mcam_config(eth_dev, vlan_id,
639                                                         VLAN_ID_MATCH |
640                                                         MAC_ADDR_MATCH);
641                 if (mcam_idx < 0) {
642                         otx2_err("Failed to config vlan mcam");
643                         TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
644                         rte_free(entry);
645                         return mcam_idx;
646                 }
647
648                 entry->mcam_idx = mcam_idx;
649                 if (!entry_exists) {
650                         entry->vlan_id  = vlan_id;
651                         TAILQ_INSERT_HEAD(&vlan->fltr_tbl, entry, next);
652                 }
653         } else {
654                 TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
655                         if (entry->vlan_id == vlan_id) {
656                                 rc = nix_vlan_mcam_free(dev, entry->mcam_idx);
657                                 if (rc)
658                                         return rc;
659                                 TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
660                                 rte_free(entry);
661                                 break;
662                         }
663                 }
664         }
665         return 0;
666 }
667
668 /* Configure double vlan(qinq) on or off */
669 static int
670 otx2_nix_config_double_vlan(struct rte_eth_dev *eth_dev,
671                             const uint8_t enable)
672 {
673         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
674         struct otx2_vlan_info *vlan_info;
675         int mcam_idx;
676         int rc;
677
678         vlan_info = &dev->vlan_info;
679
680         if (!enable) {
681                 if (!vlan_info->qinq_mcam_idx)
682                         return 0;
683
684                 rc = nix_vlan_mcam_free(dev, vlan_info->qinq_mcam_idx);
685                 if (rc)
686                         return rc;
687
688                 vlan_info->qinq_mcam_idx = 0;
689                 dev->vlan_info.qinq_on = 0;
690                 vlan_info->qinq_before_def = 0;
691                 return 0;
692         }
693
694         if (eth_dev->data->promiscuous)
695                 mcam_idx = nix_vlan_mcam_config(eth_dev, 0, QINQ_F_MATCH);
696         else
697                 mcam_idx = nix_vlan_mcam_config(eth_dev, 0,
698                                                 QINQ_F_MATCH | MAC_ADDR_MATCH);
699         if (mcam_idx < 0)
700                 return mcam_idx;
701
702         if (!vlan_info->def_rx_mcam_idx)
703                 vlan_info->qinq_before_def = 1;
704
705         vlan_info->qinq_mcam_idx = mcam_idx;
706         dev->vlan_info.qinq_on = 1;
707         return 0;
708 }
709
710 int
711 otx2_nix_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
712 {
713         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
714         uint64_t offloads = dev->rx_offloads;
715         struct rte_eth_rxmode *rxmode;
716         int rc = 0;
717
718         rxmode = &eth_dev->data->dev_conf.rxmode;
719
720         if (mask & ETH_VLAN_EXTEND_MASK) {
721                 otx2_err("Extend offload not supported");
722                 return -ENOTSUP;
723         }
724
725         if (mask & ETH_VLAN_STRIP_MASK) {
726                 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
727                         offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
728                         rc = nix_vlan_hw_strip(eth_dev, true);
729                 } else {
730                         offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
731                         rc = nix_vlan_hw_strip(eth_dev, false);
732                 }
733                 if (rc)
734                         goto done;
735         }
736
737         if (mask & ETH_VLAN_FILTER_MASK) {
738                 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
739                         offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
740                         rc = nix_vlan_hw_filter(eth_dev, true, 0);
741                 } else {
742                         offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
743                         rc = nix_vlan_hw_filter(eth_dev, false, 0);
744                 }
745                 if (rc)
746                         goto done;
747         }
748
749         if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) {
750                 if (!dev->vlan_info.qinq_on) {
751                         offloads |= DEV_RX_OFFLOAD_QINQ_STRIP;
752                         rc = otx2_nix_config_double_vlan(eth_dev, true);
753                         if (rc)
754                                 goto done;
755                 }
756         } else {
757                 if (dev->vlan_info.qinq_on) {
758                         offloads &= ~DEV_RX_OFFLOAD_QINQ_STRIP;
759                         rc = otx2_nix_config_double_vlan(eth_dev, false);
760                         if (rc)
761                                 goto done;
762                 }
763         }
764
765         if (offloads & (DEV_RX_OFFLOAD_VLAN_STRIP |
766                         DEV_RX_OFFLOAD_QINQ_STRIP)) {
767                 dev->rx_offloads |= offloads;
768                 dev->rx_offload_flags |= NIX_RX_OFFLOAD_VLAN_STRIP_F;
769                 otx2_eth_set_rx_function(eth_dev);
770         }
771
772 done:
773         return rc;
774 }
775
776 int
777 otx2_nix_vlan_tpid_set(struct rte_eth_dev *eth_dev,
778                        enum rte_vlan_type type, uint16_t tpid)
779 {
780         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
781         struct nix_set_vlan_tpid *tpid_cfg;
782         struct otx2_mbox *mbox = dev->mbox;
783         int rc;
784
785         tpid_cfg = otx2_mbox_alloc_msg_nix_set_vlan_tpid(mbox);
786
787         tpid_cfg->tpid = tpid;
788         if (type == ETH_VLAN_TYPE_OUTER)
789                 tpid_cfg->vlan_type = NIX_VLAN_TYPE_OUTER;
790         else
791                 tpid_cfg->vlan_type = NIX_VLAN_TYPE_INNER;
792
793         rc = otx2_mbox_process(mbox);
794         if (rc)
795                 return rc;
796
797         if (type == ETH_VLAN_TYPE_OUTER)
798                 dev->vlan_info.outer_vlan_tpid = tpid;
799         else
800                 dev->vlan_info.inner_vlan_tpid = tpid;
801         return 0;
802 }
803
804 int
805 otx2_nix_vlan_pvid_set(struct rte_eth_dev *dev,       uint16_t vlan_id, int on)
806 {
807         struct otx2_eth_dev *otx2_dev = otx2_eth_pmd_priv(dev);
808         struct otx2_mbox *mbox = otx2_dev->mbox;
809         struct nix_vtag_config *vtag_cfg;
810         struct nix_vtag_config_rsp *rsp;
811         struct otx2_vlan_info *vlan;
812         int rc, rc1, vtag_index = 0;
813
814         if (vlan_id == 0) {
815                 otx2_err("vlan id can't be zero");
816                 return -EINVAL;
817         }
818
819         vlan = &otx2_dev->vlan_info;
820
821         if (on && vlan->pvid_insert_on && vlan->pvid == vlan_id) {
822                 otx2_err("pvid %d is already enabled", vlan_id);
823                 return -EINVAL;
824         }
825
826         if (on && vlan->pvid_insert_on && vlan->pvid != vlan_id) {
827                 otx2_err("another pvid is enabled, disable that first");
828                 return -EINVAL;
829         }
830
831         /* No pvid active */
832         if (!on && !vlan->pvid_insert_on)
833                 return 0;
834
835         /* Given pvid already disabled */
836         if (!on && vlan->pvid != vlan_id)
837                 return 0;
838
839         vtag_cfg = otx2_mbox_alloc_msg_nix_vtag_cfg(mbox);
840
841         if (on) {
842                 vtag_cfg->cfg_type = VTAG_TX;
843                 vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
844
845                 if (vlan->outer_vlan_tpid)
846                         vtag_cfg->tx.vtag0 = ((uint32_t)vlan->outer_vlan_tpid
847                                               << 16) | vlan_id;
848                 else
849                         vtag_cfg->tx.vtag0 =
850                                 ((RTE_ETHER_TYPE_VLAN << 16) | vlan_id);
851                 vtag_cfg->tx.cfg_vtag0 = 1;
852         } else {
853                 vtag_cfg->cfg_type = VTAG_TX;
854                 vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
855
856                 vtag_cfg->tx.vtag0_idx = vlan->outer_vlan_idx;
857                 vtag_cfg->tx.free_vtag0 = 1;
858         }
859
860         rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
861         if (rc)
862                 return rc;
863
864         if (on) {
865                 vtag_index = rsp->vtag0_idx;
866         } else {
867                 vlan->pvid = 0;
868                 vlan->pvid_insert_on = 0;
869                 vlan->outer_vlan_idx = 0;
870         }
871
872         rc = nix_vlan_handle_default_tx_entry(dev, ETH_VLAN_TYPE_OUTER,
873                                               vtag_index, on);
874         if (rc < 0) {
875                 printf("Default tx entry failed with rc %d\n", rc);
876                 vtag_cfg->tx.vtag0_idx = vtag_index;
877                 vtag_cfg->tx.free_vtag0 = 1;
878                 vtag_cfg->tx.cfg_vtag0 = 0;
879
880                 rc1 = otx2_mbox_process_msg(mbox, (void *)&rsp);
881                 if (rc1)
882                         otx2_err("Vtag free failed");
883
884                 return rc;
885         }
886
887         if (on) {
888                 vlan->pvid = vlan_id;
889                 vlan->pvid_insert_on = 1;
890                 vlan->outer_vlan_idx = vtag_index;
891         }
892
893         return 0;
894 }
895
896 void otx2_nix_vlan_strip_queue_set(__rte_unused struct rte_eth_dev *dev,
897                                    __rte_unused uint16_t queue,
898                                    __rte_unused int on)
899 {
900         otx2_err("Not Supported");
901 }
902
903 static int
904 nix_vlan_rx_mkex_offset(uint64_t mask)
905 {
906         int nib_count = 0;
907
908         while (mask) {
909                 nib_count += mask & 1;
910                 mask >>= 1;
911         }
912
913         return nib_count * 4;
914 }
915
916 static int
917 nix_vlan_get_mkex_info(struct otx2_eth_dev *dev)
918 {
919         struct vlan_mkex_info *mkex = &dev->vlan_info.mkex;
920         struct otx2_npc_flow_info *npc = &dev->npc_flow;
921         struct npc_xtract_info *x_info = NULL;
922         uint64_t rx_keyx;
923         otx2_dxcfg_t *p;
924         int rc = -EINVAL;
925
926         if (npc == NULL) {
927                 otx2_err("Missing npc mkex configuration");
928                 return rc;
929         }
930
931 #define NPC_KEX_CHAN_NIBBLE_ENA                 0x7ULL
932 #define NPC_KEX_LB_LTYPE_NIBBLE_ENA             0x1000ULL
933 #define NPC_KEX_LB_LTYPE_NIBBLE_MASK            0xFFFULL
934
935         rx_keyx = npc->keyx_supp_nmask[NPC_MCAM_RX];
936         if ((rx_keyx & NPC_KEX_CHAN_NIBBLE_ENA) != NPC_KEX_CHAN_NIBBLE_ENA)
937                 return rc;
938
939         if ((rx_keyx & NPC_KEX_LB_LTYPE_NIBBLE_ENA) !=
940             NPC_KEX_LB_LTYPE_NIBBLE_ENA)
941                 return rc;
942
943         mkex->lb_lt_offset =
944             nix_vlan_rx_mkex_offset(rx_keyx & NPC_KEX_LB_LTYPE_NIBBLE_MASK);
945
946         p = &npc->prx_dxcfg;
947         x_info = &(*p)[NPC_MCAM_RX][NPC_LID_LA][NPC_LT_LA_ETHER].xtract[0];
948         memcpy(&mkex->la_xtract, x_info, sizeof(struct npc_xtract_info));
949         x_info = &(*p)[NPC_MCAM_RX][NPC_LID_LB][NPC_LT_LB_CTAG].xtract[0];
950         memcpy(&mkex->lb_xtract, x_info, sizeof(struct npc_xtract_info));
951
952         return 0;
953 }
954
955 static void nix_vlan_reinstall_vlan_filters(struct rte_eth_dev *eth_dev)
956 {
957         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
958         struct vlan_entry *entry;
959         int rc;
960
961         /* VLAN filters can't be set without setting filtern on */
962         rc = nix_vlan_handle_default_rx_entry(eth_dev, false, true, true);
963         if (rc) {
964                 otx2_err("Failed to reinstall vlan filters");
965                 return;
966         }
967
968         TAILQ_FOREACH(entry, &dev->vlan_info.fltr_tbl, next) {
969                 rc = otx2_nix_vlan_filter_set(eth_dev, entry->vlan_id, true);
970                 if (rc)
971                         otx2_err("Failed to reinstall filter for vlan:%d",
972                                  entry->vlan_id);
973         }
974 }
975
976 int
977 otx2_nix_vlan_offload_init(struct rte_eth_dev *eth_dev)
978 {
979         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
980         int rc, mask;
981
982         /* Port initialized for first time or restarted */
983         if (!dev->configured) {
984                 rc = nix_vlan_get_mkex_info(dev);
985                 if (rc) {
986                         otx2_err("Failed to get vlan mkex info rc=%d", rc);
987                         return rc;
988                 }
989
990                 TAILQ_INIT(&dev->vlan_info.fltr_tbl);
991         } else {
992                 /* Reinstall all mcam entries now if filter offload is set */
993                 if (eth_dev->data->dev_conf.rxmode.offloads &
994                     DEV_RX_OFFLOAD_VLAN_FILTER)
995                         nix_vlan_reinstall_vlan_filters(eth_dev);
996         }
997
998         mask =
999             ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK;
1000         rc = otx2_nix_vlan_offload_set(eth_dev, mask);
1001         if (rc) {
1002                 otx2_err("Failed to set vlan offload rc=%d", rc);
1003                 return rc;
1004         }
1005
1006         return 0;
1007 }
1008
1009 int
1010 otx2_nix_vlan_fini(struct rte_eth_dev *eth_dev)
1011 {
1012         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
1013         struct otx2_vlan_info *vlan = &dev->vlan_info;
1014         struct vlan_entry *entry;
1015         int rc;
1016
1017         TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
1018                 if (!dev->configured) {
1019                         TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
1020                         rte_free(entry);
1021                 } else {
1022                         /* MCAM entries freed by flow_fini & lf_free on
1023                          * port stop.
1024                          */
1025                         entry->mcam_idx = 0;
1026                 }
1027         }
1028
1029         if (!dev->configured) {
1030                 if (vlan->def_rx_mcam_idx) {
1031                         rc = nix_vlan_mcam_free(dev, vlan->def_rx_mcam_idx);
1032                         if (rc)
1033                                 return rc;
1034                 }
1035         }
1036
1037         otx2_nix_config_double_vlan(eth_dev, false);
1038         vlan->def_rx_mcam_idx = 0;
1039         return 0;
1040 }