xref: /f-stack/dpdk/drivers/net/octeontx2/otx2_vlan.c (revision 0c6bd470)
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
nix_vlan_mcam_enb_dis(struct otx2_eth_dev * dev,uint32_t entry,const int enable)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
nix_set_rx_vlan_action(struct rte_eth_dev * eth_dev,struct mcam_entry * entry,bool qinq,bool drop)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
nix_set_tx_vlan_action(struct mcam_entry * entry,enum rte_vlan_type type,int vtag_index)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
nix_vlan_mcam_free(struct otx2_eth_dev * dev,uint32_t entry)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
nix_vlan_mcam_write(struct rte_eth_dev * eth_dev,uint16_t ent_idx,struct mcam_entry * entry,uint8_t intf,uint8_t ena)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
nix_vlan_mcam_alloc_and_write(struct rte_eth_dev * eth_dev,struct mcam_entry * entry,uint8_t intf,bool drop)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
nix_vlan_update_mac(struct rte_eth_dev * eth_dev,int mcam_index,int enable)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
otx2_nix_vlan_update_promisc(struct rte_eth_dev * eth_dev,int enable)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
nix_vlan_mcam_config(struct rte_eth_dev * eth_dev,uint16_t vlan_id,uint16_t flags)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
nix_vlan_handle_default_rx_entry(struct rte_eth_dev * eth_dev,bool strip,bool filter,bool enable)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
nix_vlan_handle_default_tx_entry(struct rte_eth_dev * eth_dev,enum rte_vlan_type type,int vtag_index,int enable)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
nix_vlan_hw_strip(struct rte_eth_dev * eth_dev,const uint8_t enable)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
nix_vlan_hw_filter(struct rte_eth_dev * eth_dev,const uint8_t enable,uint16_t vlan_id)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
otx2_nix_vlan_filter_set(struct rte_eth_dev * eth_dev,uint16_t vlan_id,int on)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
otx2_nix_config_double_vlan(struct rte_eth_dev * eth_dev,const uint8_t enable)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
otx2_nix_vlan_offload_set(struct rte_eth_dev * eth_dev,int mask)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
otx2_nix_vlan_tpid_set(struct rte_eth_dev * eth_dev,enum rte_vlan_type type,uint16_t tpid)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
otx2_nix_vlan_pvid_set(struct rte_eth_dev * dev,uint16_t vlan_id,int on)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 
otx2_nix_vlan_strip_queue_set(__rte_unused struct rte_eth_dev * dev,__rte_unused uint16_t queue,__rte_unused int on)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
nix_vlan_rx_mkex_offset(uint64_t mask)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
nix_vlan_get_mkex_info(struct otx2_eth_dev * dev)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 
nix_vlan_reinstall_vlan_filters(struct rte_eth_dev * eth_dev)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
otx2_nix_vlan_offload_init(struct rte_eth_dev * eth_dev)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
otx2_nix_vlan_fini(struct rte_eth_dev * eth_dev)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 }
1036