ethdev: fix VLAN offloads set if no relative capabilities
[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_STRIP_MASK) {
721                 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
722                         offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
723                         rc = nix_vlan_hw_strip(eth_dev, true);
724                 } else {
725                         offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
726                         rc = nix_vlan_hw_strip(eth_dev, false);
727                 }
728                 if (rc)
729                         goto done;
730         }
731
732         if (mask & ETH_VLAN_FILTER_MASK) {
733                 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
734                         offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
735                         rc = nix_vlan_hw_filter(eth_dev, true, 0);
736                 } else {
737                         offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
738                         rc = nix_vlan_hw_filter(eth_dev, false, 0);
739                 }
740                 if (rc)
741                         goto done;
742         }
743
744         if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) {
745                 if (!dev->vlan_info.qinq_on) {
746                         offloads |= DEV_RX_OFFLOAD_QINQ_STRIP;
747                         rc = otx2_nix_config_double_vlan(eth_dev, true);
748                         if (rc)
749                                 goto done;
750                 }
751         } else {
752                 if (dev->vlan_info.qinq_on) {
753                         offloads &= ~DEV_RX_OFFLOAD_QINQ_STRIP;
754                         rc = otx2_nix_config_double_vlan(eth_dev, false);
755                         if (rc)
756                                 goto done;
757                 }
758         }
759
760         if (offloads & (DEV_RX_OFFLOAD_VLAN_STRIP |
761                         DEV_RX_OFFLOAD_QINQ_STRIP)) {
762                 dev->rx_offloads |= offloads;
763                 dev->rx_offload_flags |= NIX_RX_OFFLOAD_VLAN_STRIP_F;
764                 otx2_eth_set_rx_function(eth_dev);
765         }
766
767 done:
768         return rc;
769 }
770
771 int
772 otx2_nix_vlan_tpid_set(struct rte_eth_dev *eth_dev,
773                        enum rte_vlan_type type, uint16_t tpid)
774 {
775         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
776         struct nix_set_vlan_tpid *tpid_cfg;
777         struct otx2_mbox *mbox = dev->mbox;
778         int rc;
779
780         tpid_cfg = otx2_mbox_alloc_msg_nix_set_vlan_tpid(mbox);
781
782         tpid_cfg->tpid = tpid;
783         if (type == ETH_VLAN_TYPE_OUTER)
784                 tpid_cfg->vlan_type = NIX_VLAN_TYPE_OUTER;
785         else
786                 tpid_cfg->vlan_type = NIX_VLAN_TYPE_INNER;
787
788         rc = otx2_mbox_process(mbox);
789         if (rc)
790                 return rc;
791
792         if (type == ETH_VLAN_TYPE_OUTER)
793                 dev->vlan_info.outer_vlan_tpid = tpid;
794         else
795                 dev->vlan_info.inner_vlan_tpid = tpid;
796         return 0;
797 }
798
799 int
800 otx2_nix_vlan_pvid_set(struct rte_eth_dev *dev,       uint16_t vlan_id, int on)
801 {
802         struct otx2_eth_dev *otx2_dev = otx2_eth_pmd_priv(dev);
803         struct otx2_mbox *mbox = otx2_dev->mbox;
804         struct nix_vtag_config *vtag_cfg;
805         struct nix_vtag_config_rsp *rsp;
806         struct otx2_vlan_info *vlan;
807         int rc, rc1, vtag_index = 0;
808
809         if (vlan_id == 0) {
810                 otx2_err("vlan id can't be zero");
811                 return -EINVAL;
812         }
813
814         vlan = &otx2_dev->vlan_info;
815
816         if (on && vlan->pvid_insert_on && vlan->pvid == vlan_id) {
817                 otx2_err("pvid %d is already enabled", vlan_id);
818                 return -EINVAL;
819         }
820
821         if (on && vlan->pvid_insert_on && vlan->pvid != vlan_id) {
822                 otx2_err("another pvid is enabled, disable that first");
823                 return -EINVAL;
824         }
825
826         /* No pvid active */
827         if (!on && !vlan->pvid_insert_on)
828                 return 0;
829
830         /* Given pvid already disabled */
831         if (!on && vlan->pvid != vlan_id)
832                 return 0;
833
834         vtag_cfg = otx2_mbox_alloc_msg_nix_vtag_cfg(mbox);
835
836         if (on) {
837                 vtag_cfg->cfg_type = VTAG_TX;
838                 vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
839
840                 if (vlan->outer_vlan_tpid)
841                         vtag_cfg->tx.vtag0 = ((uint32_t)vlan->outer_vlan_tpid
842                                               << 16) | vlan_id;
843                 else
844                         vtag_cfg->tx.vtag0 =
845                                 ((RTE_ETHER_TYPE_VLAN << 16) | vlan_id);
846                 vtag_cfg->tx.cfg_vtag0 = 1;
847         } else {
848                 vtag_cfg->cfg_type = VTAG_TX;
849                 vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
850
851                 vtag_cfg->tx.vtag0_idx = vlan->outer_vlan_idx;
852                 vtag_cfg->tx.free_vtag0 = 1;
853         }
854
855         rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
856         if (rc)
857                 return rc;
858
859         if (on) {
860                 vtag_index = rsp->vtag0_idx;
861         } else {
862                 vlan->pvid = 0;
863                 vlan->pvid_insert_on = 0;
864                 vlan->outer_vlan_idx = 0;
865         }
866
867         rc = nix_vlan_handle_default_tx_entry(dev, ETH_VLAN_TYPE_OUTER,
868                                               vtag_index, on);
869         if (rc < 0) {
870                 printf("Default tx entry failed with rc %d\n", rc);
871                 vtag_cfg->tx.vtag0_idx = vtag_index;
872                 vtag_cfg->tx.free_vtag0 = 1;
873                 vtag_cfg->tx.cfg_vtag0 = 0;
874
875                 rc1 = otx2_mbox_process_msg(mbox, (void *)&rsp);
876                 if (rc1)
877                         otx2_err("Vtag free failed");
878
879                 return rc;
880         }
881
882         if (on) {
883                 vlan->pvid = vlan_id;
884                 vlan->pvid_insert_on = 1;
885                 vlan->outer_vlan_idx = vtag_index;
886         }
887
888         return 0;
889 }
890
891 void otx2_nix_vlan_strip_queue_set(__rte_unused struct rte_eth_dev *dev,
892                                    __rte_unused uint16_t queue,
893                                    __rte_unused int on)
894 {
895         otx2_err("Not Supported");
896 }
897
898 static int
899 nix_vlan_rx_mkex_offset(uint64_t mask)
900 {
901         int nib_count = 0;
902
903         while (mask) {
904                 nib_count += mask & 1;
905                 mask >>= 1;
906         }
907
908         return nib_count * 4;
909 }
910
911 static int
912 nix_vlan_get_mkex_info(struct otx2_eth_dev *dev)
913 {
914         struct vlan_mkex_info *mkex = &dev->vlan_info.mkex;
915         struct otx2_npc_flow_info *npc = &dev->npc_flow;
916         struct npc_xtract_info *x_info = NULL;
917         uint64_t rx_keyx;
918         otx2_dxcfg_t *p;
919         int rc = -EINVAL;
920
921         if (npc == NULL) {
922                 otx2_err("Missing npc mkex configuration");
923                 return rc;
924         }
925
926 #define NPC_KEX_CHAN_NIBBLE_ENA                 0x7ULL
927 #define NPC_KEX_LB_LTYPE_NIBBLE_ENA             0x1000ULL
928 #define NPC_KEX_LB_LTYPE_NIBBLE_MASK            0xFFFULL
929
930         rx_keyx = npc->keyx_supp_nmask[NPC_MCAM_RX];
931         if ((rx_keyx & NPC_KEX_CHAN_NIBBLE_ENA) != NPC_KEX_CHAN_NIBBLE_ENA)
932                 return rc;
933
934         if ((rx_keyx & NPC_KEX_LB_LTYPE_NIBBLE_ENA) !=
935             NPC_KEX_LB_LTYPE_NIBBLE_ENA)
936                 return rc;
937
938         mkex->lb_lt_offset =
939             nix_vlan_rx_mkex_offset(rx_keyx & NPC_KEX_LB_LTYPE_NIBBLE_MASK);
940
941         p = &npc->prx_dxcfg;
942         x_info = &(*p)[NPC_MCAM_RX][NPC_LID_LA][NPC_LT_LA_ETHER].xtract[0];
943         memcpy(&mkex->la_xtract, x_info, sizeof(struct npc_xtract_info));
944         x_info = &(*p)[NPC_MCAM_RX][NPC_LID_LB][NPC_LT_LB_CTAG].xtract[0];
945         memcpy(&mkex->lb_xtract, x_info, sizeof(struct npc_xtract_info));
946
947         return 0;
948 }
949
950 static void nix_vlan_reinstall_vlan_filters(struct rte_eth_dev *eth_dev)
951 {
952         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
953         struct vlan_entry *entry;
954         int rc;
955
956         /* VLAN filters can't be set without setting filtern on */
957         rc = nix_vlan_handle_default_rx_entry(eth_dev, false, true, true);
958         if (rc) {
959                 otx2_err("Failed to reinstall vlan filters");
960                 return;
961         }
962
963         TAILQ_FOREACH(entry, &dev->vlan_info.fltr_tbl, next) {
964                 rc = otx2_nix_vlan_filter_set(eth_dev, entry->vlan_id, true);
965                 if (rc)
966                         otx2_err("Failed to reinstall filter for vlan:%d",
967                                  entry->vlan_id);
968         }
969 }
970
971 int
972 otx2_nix_vlan_offload_init(struct rte_eth_dev *eth_dev)
973 {
974         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
975         int rc, mask;
976
977         /* Port initialized for first time or restarted */
978         if (!dev->configured) {
979                 rc = nix_vlan_get_mkex_info(dev);
980                 if (rc) {
981                         otx2_err("Failed to get vlan mkex info rc=%d", rc);
982                         return rc;
983                 }
984
985                 TAILQ_INIT(&dev->vlan_info.fltr_tbl);
986         } else {
987                 /* Reinstall all mcam entries now if filter offload is set */
988                 if (eth_dev->data->dev_conf.rxmode.offloads &
989                     DEV_RX_OFFLOAD_VLAN_FILTER)
990                         nix_vlan_reinstall_vlan_filters(eth_dev);
991         }
992
993         mask =
994             ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK;
995         rc = otx2_nix_vlan_offload_set(eth_dev, mask);
996         if (rc) {
997                 otx2_err("Failed to set vlan offload rc=%d", rc);
998                 return rc;
999         }
1000
1001         return 0;
1002 }
1003
1004 int
1005 otx2_nix_vlan_fini(struct rte_eth_dev *eth_dev)
1006 {
1007         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
1008         struct otx2_vlan_info *vlan = &dev->vlan_info;
1009         struct vlan_entry *entry;
1010         int rc;
1011
1012         TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
1013                 if (!dev->configured) {
1014                         TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
1015                         rte_free(entry);
1016                 } else {
1017                         /* MCAM entries freed by flow_fini & lf_free on
1018                          * port stop.
1019                          */
1020                         entry->mcam_idx = 0;
1021                 }
1022         }
1023
1024         if (!dev->configured) {
1025                 if (vlan->def_rx_mcam_idx) {
1026                         rc = nix_vlan_mcam_free(dev, vlan->def_rx_mcam_idx);
1027                         if (rc)
1028                                 return rc;
1029                 }
1030         }
1031
1032         otx2_nix_config_double_vlan(eth_dev, false);
1033         vlan->def_rx_mcam_idx = 0;
1034         return 0;
1035 }