xref: /dpdk/drivers/net/dpaa2/dpaa2_mux.c (revision e6bf3256b95c77ee4d0b2874e1896d01c41c2d7c)
11def64c2SNipun Gupta /* SPDX-License-Identifier: BSD-3-Clause
200e928e9SSachin Saxena  * Copyright 2018-2021,2023 NXP
31def64c2SNipun Gupta  */
41def64c2SNipun Gupta 
51def64c2SNipun Gupta #include <sys/queue.h>
61def64c2SNipun Gupta #include <stdio.h>
71def64c2SNipun Gupta #include <errno.h>
81def64c2SNipun Gupta #include <stdint.h>
91def64c2SNipun Gupta #include <string.h>
101def64c2SNipun Gupta #include <unistd.h>
111def64c2SNipun Gupta #include <stdarg.h>
121def64c2SNipun Gupta 
131def64c2SNipun Gupta #include <rte_ethdev.h>
141def64c2SNipun Gupta #include <rte_log.h>
151def64c2SNipun Gupta #include <rte_malloc.h>
161def64c2SNipun Gupta #include <rte_flow_driver.h>
171def64c2SNipun Gupta #include <rte_tailq.h>
181def64c2SNipun Gupta 
19b4f22ca5SDavid Marchand #include <bus_fslmc_driver.h>
201def64c2SNipun Gupta #include <fsl_dpdmux.h>
211def64c2SNipun Gupta #include <fsl_dpkg.h>
221def64c2SNipun Gupta 
231def64c2SNipun Gupta #include <dpaa2_ethdev.h>
241def64c2SNipun Gupta #include <dpaa2_pmd_logs.h>
251def64c2SNipun Gupta 
261def64c2SNipun Gupta struct dpaa2_dpdmux_dev {
271def64c2SNipun Gupta 	TAILQ_ENTRY(dpaa2_dpdmux_dev) next;
281def64c2SNipun Gupta 		/**< Pointer to Next device instance */
291def64c2SNipun Gupta 	struct fsl_mc_io dpdmux;  /** handle to DPDMUX portal object */
301def64c2SNipun Gupta 	uint16_t token;
311def64c2SNipun Gupta 	uint32_t dpdmux_id; /*HW ID for DPDMUX object */
321def64c2SNipun Gupta 	uint8_t num_ifs;   /* Number of interfaces in DPDMUX */
331def64c2SNipun Gupta };
341def64c2SNipun Gupta 
35*25e5845bSJun Yang #define DPAA2_MUX_FLOW_MAX_RULE_NUM 8
36*25e5845bSJun Yang struct dpaa2_mux_flow {
37*25e5845bSJun Yang 	struct dpdmux_rule_cfg rule[DPAA2_MUX_FLOW_MAX_RULE_NUM];
381def64c2SNipun Gupta };
391def64c2SNipun Gupta 
401def64c2SNipun Gupta TAILQ_HEAD(dpdmux_dev_list, dpaa2_dpdmux_dev);
411def64c2SNipun Gupta static struct dpdmux_dev_list dpdmux_dev_list =
421def64c2SNipun Gupta 	TAILQ_HEAD_INITIALIZER(dpdmux_dev_list); /*!< DPDMUX device list */
431def64c2SNipun Gupta 
441def64c2SNipun Gupta static struct dpaa2_dpdmux_dev *get_dpdmux_from_id(uint32_t dpdmux_id)
451def64c2SNipun Gupta {
461def64c2SNipun Gupta 	struct dpaa2_dpdmux_dev *dpdmux_dev = NULL;
471def64c2SNipun Gupta 
48274fd921SRohit Raj 	/* Get DPDMUX dev handle from list using index */
491def64c2SNipun Gupta 	TAILQ_FOREACH(dpdmux_dev, &dpdmux_dev_list, next) {
501def64c2SNipun Gupta 		if (dpdmux_dev->dpdmux_id == dpdmux_id)
511def64c2SNipun Gupta 			break;
521def64c2SNipun Gupta 	}
531def64c2SNipun Gupta 
541def64c2SNipun Gupta 	return dpdmux_dev;
551def64c2SNipun Gupta }
561def64c2SNipun Gupta 
57*25e5845bSJun Yang int
581def64c2SNipun Gupta rte_pmd_dpaa2_mux_flow_create(uint32_t dpdmux_id,
59*25e5845bSJun Yang 	struct rte_flow_item pattern[],
60*25e5845bSJun Yang 	struct rte_flow_action actions[])
611def64c2SNipun Gupta {
621def64c2SNipun Gupta 	struct dpaa2_dpdmux_dev *dpdmux_dev;
63*25e5845bSJun Yang 	static struct dpkg_profile_cfg s_kg_cfg;
641def64c2SNipun Gupta 	struct dpkg_profile_cfg kg_cfg;
651def64c2SNipun Gupta 	const struct rte_flow_action_vf *vf_conf;
661def64c2SNipun Gupta 	struct dpdmux_cls_action dpdmux_action;
67*25e5845bSJun Yang 	uint8_t *key_va = NULL, *mask_va = NULL;
68*25e5845bSJun Yang 	void *key_cfg_va = NULL;
69*25e5845bSJun Yang 	uint64_t key_iova, mask_iova, key_cfg_iova;
7016035e4eSHemant Agrawal 	uint8_t key_size = 0;
71*25e5845bSJun Yang 	int ret = 0, loop = 0;
72*25e5845bSJun Yang 	static int s_i;
73*25e5845bSJun Yang 	struct dpkg_extract *extract;
74*25e5845bSJun Yang 	struct dpdmux_rule_cfg rule;
751def64c2SNipun Gupta 
76*25e5845bSJun Yang 	memset(&kg_cfg, 0, sizeof(struct dpkg_profile_cfg));
774ed8a733SVanshika Shukla 
781def64c2SNipun Gupta 	/* Find the DPDMUX from dpdmux_id in our list */
791def64c2SNipun Gupta 	dpdmux_dev = get_dpdmux_from_id(dpdmux_id);
801def64c2SNipun Gupta 	if (!dpdmux_dev) {
811def64c2SNipun Gupta 		DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id);
82*25e5845bSJun Yang 		ret = -ENODEV;
8316035e4eSHemant Agrawal 		goto creation_error;
8416035e4eSHemant Agrawal 	}
85*25e5845bSJun Yang 
86*25e5845bSJun Yang 	key_cfg_va = rte_zmalloc(NULL, DIST_PARAM_IOVA_SIZE,
87*25e5845bSJun Yang 				RTE_CACHE_LINE_SIZE);
88*25e5845bSJun Yang 	if (!key_cfg_va) {
89*25e5845bSJun Yang 		DPAA2_PMD_ERR("Unable to allocate key configure buffer");
90*25e5845bSJun Yang 		ret = -ENOMEM;
91*25e5845bSJun Yang 		goto creation_error;
92*25e5845bSJun Yang 	}
93*25e5845bSJun Yang 
94*25e5845bSJun Yang 	key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_va,
95*25e5845bSJun Yang 		DIST_PARAM_IOVA_SIZE);
96*25e5845bSJun Yang 	if (key_cfg_iova == RTE_BAD_IOVA) {
97*25e5845bSJun Yang 		DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)",
98*25e5845bSJun Yang 			__func__, key_cfg_va);
99*25e5845bSJun Yang 		ret = -ENOBUFS;
100*25e5845bSJun Yang 		goto creation_error;
101*25e5845bSJun Yang 	}
102*25e5845bSJun Yang 
103*25e5845bSJun Yang 	key_va = rte_zmalloc(NULL, (2 * DIST_PARAM_IOVA_SIZE),
104*25e5845bSJun Yang 		RTE_CACHE_LINE_SIZE);
105*25e5845bSJun Yang 	if (!key_va) {
106*25e5845bSJun Yang 		DPAA2_PMD_ERR("Unable to allocate flow dist parameter");
107*25e5845bSJun Yang 		ret = -ENOMEM;
108*25e5845bSJun Yang 		goto creation_error;
109*25e5845bSJun Yang 	}
110*25e5845bSJun Yang 
111*25e5845bSJun Yang 	key_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_va,
112*25e5845bSJun Yang 		(2 * DIST_PARAM_IOVA_SIZE));
113*25e5845bSJun Yang 	if (key_iova == RTE_BAD_IOVA) {
114*25e5845bSJun Yang 		DPAA2_PMD_ERR("%s: No IOMMU mapping for address(%p)",
115*25e5845bSJun Yang 			__func__, key_va);
116*25e5845bSJun Yang 		ret = -ENOBUFS;
117*25e5845bSJun Yang 		goto creation_error;
118*25e5845bSJun Yang 	}
119*25e5845bSJun Yang 
120*25e5845bSJun Yang 	mask_va = key_va + DIST_PARAM_IOVA_SIZE;
121*25e5845bSJun Yang 	mask_iova = key_iova + DIST_PARAM_IOVA_SIZE;
1221def64c2SNipun Gupta 
1231def64c2SNipun Gupta 	/* Currently taking only IP protocol as an extract type.
1247be78d02SJosh Soref 	 * This can be extended to other fields using pattern->type.
1251def64c2SNipun Gupta 	 */
1261def64c2SNipun Gupta 	memset(&kg_cfg, 0, sizeof(struct dpkg_profile_cfg));
12716035e4eSHemant Agrawal 
128*25e5845bSJun Yang 	while (pattern[loop].type != RTE_FLOW_ITEM_TYPE_END) {
129*25e5845bSJun Yang 		if (kg_cfg.num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
130*25e5845bSJun Yang 			DPAA2_PMD_ERR("Too many extracts(%d)",
131*25e5845bSJun Yang 				kg_cfg.num_extracts);
132*25e5845bSJun Yang 			ret = -ENOTSUP;
133*25e5845bSJun Yang 			goto creation_error;
134*25e5845bSJun Yang 		}
135*25e5845bSJun Yang 		switch (pattern[loop].type) {
13616035e4eSHemant Agrawal 		case RTE_FLOW_ITEM_TYPE_IPV4:
13716035e4eSHemant Agrawal 		{
13816035e4eSHemant Agrawal 			const struct rte_flow_item_ipv4 *spec;
139*25e5845bSJun Yang 			const struct rte_flow_item_ipv4 *mask;
1407a582318SNipun Gupta 
141*25e5845bSJun Yang 			extract = &kg_cfg.extracts[kg_cfg.num_extracts];
142*25e5845bSJun Yang 			extract->type = DPKG_EXTRACT_FROM_HDR;
143*25e5845bSJun Yang 			extract->extract.from_hdr.prot = NET_PROT_IP;
144*25e5845bSJun Yang 			extract->extract.from_hdr.field = NH_FLD_IP_PROTO;
145*25e5845bSJun Yang 			extract->extract.from_hdr.type = DPKG_FULL_FIELD;
1461def64c2SNipun Gupta 
147*25e5845bSJun Yang 			kg_cfg.num_extracts++;
148*25e5845bSJun Yang 
149*25e5845bSJun Yang 			spec = pattern[loop].spec;
150*25e5845bSJun Yang 			mask = pattern[loop].mask;
151*25e5845bSJun Yang 			rte_memcpy(&key_va[key_size],
152*25e5845bSJun Yang 				&spec->hdr.next_proto_id, sizeof(uint8_t));
153*25e5845bSJun Yang 			if (mask) {
154*25e5845bSJun Yang 				rte_memcpy(&mask_va[key_size],
155*25e5845bSJun Yang 					&mask->hdr.next_proto_id,
15616035e4eSHemant Agrawal 					sizeof(uint8_t));
157*25e5845bSJun Yang 			} else {
158*25e5845bSJun Yang 				mask_va[key_size] = 0xff;
159*25e5845bSJun Yang 			}
160*25e5845bSJun Yang 			key_size += sizeof(uint8_t);
16116035e4eSHemant Agrawal 		}
16216035e4eSHemant Agrawal 		break;
16316035e4eSHemant Agrawal 
16441603590SVanshika Shukla 		case RTE_FLOW_ITEM_TYPE_VLAN:
16541603590SVanshika Shukla 		{
16641603590SVanshika Shukla 			const struct rte_flow_item_vlan *spec;
167*25e5845bSJun Yang 			const struct rte_flow_item_vlan *mask;
16841603590SVanshika Shukla 
169*25e5845bSJun Yang 			extract = &kg_cfg.extracts[kg_cfg.num_extracts];
170*25e5845bSJun Yang 			extract->type = DPKG_EXTRACT_FROM_HDR;
171*25e5845bSJun Yang 			extract->extract.from_hdr.prot = NET_PROT_VLAN;
172*25e5845bSJun Yang 			extract->extract.from_hdr.field = NH_FLD_VLAN_TCI;
173*25e5845bSJun Yang 			extract->extract.from_hdr.type = DPKG_FULL_FIELD;
17441603590SVanshika Shukla 
175*25e5845bSJun Yang 			kg_cfg.num_extracts++;
176*25e5845bSJun Yang 
177*25e5845bSJun Yang 			spec = pattern[loop].spec;
178*25e5845bSJun Yang 			mask = pattern[loop].mask;
179*25e5845bSJun Yang 			rte_memcpy(&key_va[key_size],
180*25e5845bSJun Yang 				&spec->tci, sizeof(uint16_t));
181*25e5845bSJun Yang 			if (mask) {
182*25e5845bSJun Yang 				rte_memcpy(&mask_va[key_size],
183*25e5845bSJun Yang 					&mask->tci, sizeof(uint16_t));
184*25e5845bSJun Yang 			} else {
185*25e5845bSJun Yang 				memset(&mask_va[key_size], 0xff,
186*25e5845bSJun Yang 					sizeof(rte_be16_t));
187*25e5845bSJun Yang 			}
188*25e5845bSJun Yang 			key_size += sizeof(uint16_t);
18941603590SVanshika Shukla 		}
19041603590SVanshika Shukla 		break;
19141603590SVanshika Shukla 
1927a582318SNipun Gupta 		case RTE_FLOW_ITEM_TYPE_UDP:
1937a582318SNipun Gupta 		{
1947a582318SNipun Gupta 			const struct rte_flow_item_udp *spec;
195*25e5845bSJun Yang 			const struct rte_flow_item_udp *mask;
1967a582318SNipun Gupta 
197*25e5845bSJun Yang 			extract = &kg_cfg.extracts[kg_cfg.num_extracts];
198*25e5845bSJun Yang 			extract->type = DPKG_EXTRACT_FROM_HDR;
199*25e5845bSJun Yang 			extract->extract.from_hdr.prot = NET_PROT_UDP;
200*25e5845bSJun Yang 			extract->extract.from_hdr.type = DPKG_FULL_FIELD;
201*25e5845bSJun Yang 			extract->extract.from_hdr.field = NH_FLD_UDP_PORT_DST;
202*25e5845bSJun Yang 			kg_cfg.num_extracts++;
2037a582318SNipun Gupta 
204*25e5845bSJun Yang 			spec = pattern[loop].spec;
205*25e5845bSJun Yang 			mask = pattern[loop].mask;
206*25e5845bSJun Yang 			rte_memcpy(&key_va[key_size],
207*25e5845bSJun Yang 				&spec->hdr.dst_port, sizeof(rte_be16_t));
208*25e5845bSJun Yang 			if (mask) {
209*25e5845bSJun Yang 				rte_memcpy(&mask_va[key_size],
210*25e5845bSJun Yang 					&mask->hdr.dst_port,
2117a582318SNipun Gupta 					sizeof(rte_be16_t));
212*25e5845bSJun Yang 			} else {
213*25e5845bSJun Yang 				memset(&mask_va[key_size], 0xff,
214*25e5845bSJun Yang 					sizeof(rte_be16_t));
215*25e5845bSJun Yang 			}
216*25e5845bSJun Yang 			key_size += sizeof(rte_be16_t);
2177a582318SNipun Gupta 		}
2187a582318SNipun Gupta 		break;
2197a582318SNipun Gupta 
22016035e4eSHemant Agrawal 		case RTE_FLOW_ITEM_TYPE_ETH:
22116035e4eSHemant Agrawal 		{
22216035e4eSHemant Agrawal 			const struct rte_flow_item_eth *spec;
223*25e5845bSJun Yang 			const struct rte_flow_item_eth *mask;
2247a582318SNipun Gupta 
225*25e5845bSJun Yang 			extract = &kg_cfg.extracts[kg_cfg.num_extracts];
226*25e5845bSJun Yang 			extract->type = DPKG_EXTRACT_FROM_HDR;
227*25e5845bSJun Yang 			extract->extract.from_hdr.prot = NET_PROT_ETH;
228*25e5845bSJun Yang 			extract->extract.from_hdr.type = DPKG_FULL_FIELD;
229*25e5845bSJun Yang 			extract->extract.from_hdr.field = NH_FLD_ETH_TYPE;
230*25e5845bSJun Yang 			kg_cfg.num_extracts++;
23116035e4eSHemant Agrawal 
232*25e5845bSJun Yang 			spec = pattern[loop].spec;
233*25e5845bSJun Yang 			mask = pattern[loop].mask;
234*25e5845bSJun Yang 			rte_memcpy(&key_va[key_size],
235*25e5845bSJun Yang 				&spec->type, sizeof(rte_be16_t));
236*25e5845bSJun Yang 			if (mask) {
237*25e5845bSJun Yang 				rte_memcpy(&mask_va[key_size],
238*25e5845bSJun Yang 					&mask->type, sizeof(rte_be16_t));
239*25e5845bSJun Yang 			} else {
240*25e5845bSJun Yang 				memset(&mask_va[key_size], 0xff,
24116035e4eSHemant Agrawal 					sizeof(rte_be16_t));
242*25e5845bSJun Yang 			}
243*25e5845bSJun Yang 			key_size += sizeof(rte_be16_t);
24416035e4eSHemant Agrawal 		}
24516035e4eSHemant Agrawal 		break;
24616035e4eSHemant Agrawal 
247e5e9ef72SAkhil Goyal 		case RTE_FLOW_ITEM_TYPE_RAW:
248e5e9ef72SAkhil Goyal 		{
249e5e9ef72SAkhil Goyal 			const struct rte_flow_item_raw *spec;
250*25e5845bSJun Yang 			const struct rte_flow_item_raw *mask;
251e5e9ef72SAkhil Goyal 
252*25e5845bSJun Yang 			spec = pattern[loop].spec;
253*25e5845bSJun Yang 			mask = pattern[loop].mask;
254*25e5845bSJun Yang 			extract = &kg_cfg.extracts[kg_cfg.num_extracts];
255*25e5845bSJun Yang 			extract->type = DPKG_EXTRACT_FROM_DATA;
256*25e5845bSJun Yang 			extract->extract.from_data.offset = spec->offset;
257*25e5845bSJun Yang 			extract->extract.from_data.size = spec->length;
258*25e5845bSJun Yang 			kg_cfg.num_extracts++;
259e5e9ef72SAkhil Goyal 
260*25e5845bSJun Yang 			rte_memcpy(&key_va[key_size],
261*25e5845bSJun Yang 				spec->pattern, spec->length);
262*25e5845bSJun Yang 			if (mask && mask->pattern) {
263*25e5845bSJun Yang 				rte_memcpy(&mask_va[key_size],
264*25e5845bSJun Yang 					mask->pattern, spec->length);
265*25e5845bSJun Yang 			} else {
266*25e5845bSJun Yang 				memset(&mask_va[key_size], 0xff, spec->length);
267*25e5845bSJun Yang 			}
268*25e5845bSJun Yang 
269*25e5845bSJun Yang 			key_size += spec->length;
270e5e9ef72SAkhil Goyal 		}
271e5e9ef72SAkhil Goyal 		break;
272e5e9ef72SAkhil Goyal 
27316035e4eSHemant Agrawal 		default:
274*25e5845bSJun Yang 			DPAA2_PMD_ERR("Not supported pattern[%d] type: %d",
275*25e5845bSJun Yang 				loop, pattern[loop].type);
276*25e5845bSJun Yang 			ret = -ENOTSUP;
27716035e4eSHemant Agrawal 			goto creation_error;
27816035e4eSHemant Agrawal 		}
279*25e5845bSJun Yang 		loop++;
280*25e5845bSJun Yang 	}
28116035e4eSHemant Agrawal 
282*25e5845bSJun Yang 	ret = dpkg_prepare_key_cfg(&kg_cfg, key_cfg_va);
2831def64c2SNipun Gupta 	if (ret) {
2841def64c2SNipun Gupta 		DPAA2_PMD_ERR("dpkg_prepare_key_cfg failed: err(%d)", ret);
2851def64c2SNipun Gupta 		goto creation_error;
2861def64c2SNipun Gupta 	}
2871def64c2SNipun Gupta 
288*25e5845bSJun Yang 	if (!s_i) {
289*25e5845bSJun Yang 		ret = dpdmux_set_custom_key(&dpdmux_dev->dpdmux,
290*25e5845bSJun Yang 				CMD_PRI_LOW, dpdmux_dev->token, key_cfg_iova);
2911def64c2SNipun Gupta 		if (ret) {
292e5e9ef72SAkhil Goyal 			DPAA2_PMD_ERR("dpdmux_set_custom_key failed: err(%d)",
293e5e9ef72SAkhil Goyal 				ret);
2941def64c2SNipun Gupta 			goto creation_error;
2951def64c2SNipun Gupta 		}
296*25e5845bSJun Yang 		rte_memcpy(&s_kg_cfg, &kg_cfg, sizeof(struct dpkg_profile_cfg));
297*25e5845bSJun Yang 	} else {
298*25e5845bSJun Yang 		if (memcmp(&s_kg_cfg, &kg_cfg,
299*25e5845bSJun Yang 			sizeof(struct dpkg_profile_cfg))) {
300*25e5845bSJun Yang 			DPAA2_PMD_ERR("%s: Single flow support only.",
301*25e5845bSJun Yang 				__func__);
302*25e5845bSJun Yang 			ret = -ENOTSUP;
303*25e5845bSJun Yang 			goto creation_error;
304e5e9ef72SAkhil Goyal 		}
305*25e5845bSJun Yang 	}
3061def64c2SNipun Gupta 
307*25e5845bSJun Yang 	vf_conf = actions[0].conf;
3081def64c2SNipun Gupta 	if (vf_conf->id == 0 || vf_conf->id > dpdmux_dev->num_ifs) {
309*25e5845bSJun Yang 		DPAA2_PMD_ERR("Invalid destination id(%d)", vf_conf->id);
3101def64c2SNipun Gupta 		goto creation_error;
3111def64c2SNipun Gupta 	}
3121def64c2SNipun Gupta 	dpdmux_action.dest_if = vf_conf->id;
3131def64c2SNipun Gupta 
314*25e5845bSJun Yang 	rule.key_iova = key_iova;
315*25e5845bSJun Yang 	rule.mask_iova = mask_iova;
316*25e5845bSJun Yang 	rule.key_size = key_size;
317*25e5845bSJun Yang 	rule.entry_index = s_i;
318*25e5845bSJun Yang 	s_i++;
319*25e5845bSJun Yang 
320*25e5845bSJun Yang 	/* As now our key extract parameters are set, let us configure
321*25e5845bSJun Yang 	 * the rule.
322*25e5845bSJun Yang 	 */
323*25e5845bSJun Yang 	ret = dpdmux_add_custom_cls_entry(&dpdmux_dev->dpdmux,
324*25e5845bSJun Yang 			CMD_PRI_LOW, dpdmux_dev->token,
325*25e5845bSJun Yang 			&rule, &dpdmux_action);
3261def64c2SNipun Gupta 	if (ret) {
327*25e5845bSJun Yang 		DPAA2_PMD_ERR("Add classification entry failed:err(%d)", ret);
3281def64c2SNipun Gupta 		goto creation_error;
3291def64c2SNipun Gupta 	}
3301def64c2SNipun Gupta 
3311def64c2SNipun Gupta creation_error:
332*25e5845bSJun Yang 	rte_free(key_cfg_va);
333*25e5845bSJun Yang 	rte_free(key_va);
334*25e5845bSJun Yang 
335*25e5845bSJun Yang 	return ret;
3361def64c2SNipun Gupta }
3371def64c2SNipun Gupta 
33866c64eb2SHemant Agrawal int
339cfe96771SVanshika Shukla rte_pmd_dpaa2_mux_flow_l2(uint32_t dpdmux_id,
340cfe96771SVanshika Shukla 	uint8_t mac_addr[6], uint16_t vlan_id, int dest_if)
341cfe96771SVanshika Shukla {
342cfe96771SVanshika Shukla 	struct dpaa2_dpdmux_dev *dpdmux_dev;
343cfe96771SVanshika Shukla 	struct dpdmux_l2_rule rule;
344cfe96771SVanshika Shukla 	int ret, i;
345cfe96771SVanshika Shukla 
346cfe96771SVanshika Shukla 	/* Find the DPDMUX from dpdmux_id in our list */
347cfe96771SVanshika Shukla 	dpdmux_dev = get_dpdmux_from_id(dpdmux_id);
348cfe96771SVanshika Shukla 	if (!dpdmux_dev) {
349cfe96771SVanshika Shukla 		DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id);
350cfe96771SVanshika Shukla 		return -ENODEV;
351cfe96771SVanshika Shukla 	}
352cfe96771SVanshika Shukla 
353cfe96771SVanshika Shukla 	for (i = 0; i < 6; i++)
354cfe96771SVanshika Shukla 		rule.mac_addr[i] = mac_addr[i];
355cfe96771SVanshika Shukla 	rule.vlan_id = vlan_id;
356cfe96771SVanshika Shukla 
357cfe96771SVanshika Shukla 	ret = dpdmux_if_add_l2_rule(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
358cfe96771SVanshika Shukla 			dpdmux_dev->token, dest_if, &rule);
359cfe96771SVanshika Shukla 	if (ret) {
360cfe96771SVanshika Shukla 		DPAA2_PMD_ERR("dpdmux_if_add_l2_rule failed:err(%d)", ret);
361cfe96771SVanshika Shukla 		return ret;
362cfe96771SVanshika Shukla 	}
363cfe96771SVanshika Shukla 
364cfe96771SVanshika Shukla 	return 0;
365cfe96771SVanshika Shukla }
366cfe96771SVanshika Shukla 
367cfe96771SVanshika Shukla int
36866c64eb2SHemant Agrawal rte_pmd_dpaa2_mux_rx_frame_len(uint32_t dpdmux_id, uint16_t max_rx_frame_len)
36966c64eb2SHemant Agrawal {
37066c64eb2SHemant Agrawal 	struct dpaa2_dpdmux_dev *dpdmux_dev;
37166c64eb2SHemant Agrawal 	int ret;
37266c64eb2SHemant Agrawal 
37366c64eb2SHemant Agrawal 	/* Find the DPDMUX from dpdmux_id in our list */
37466c64eb2SHemant Agrawal 	dpdmux_dev = get_dpdmux_from_id(dpdmux_id);
37566c64eb2SHemant Agrawal 	if (!dpdmux_dev) {
37666c64eb2SHemant Agrawal 		DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id);
37766c64eb2SHemant Agrawal 		return -1;
37866c64eb2SHemant Agrawal 	}
37966c64eb2SHemant Agrawal 
38066c64eb2SHemant Agrawal 	ret = dpdmux_set_max_frame_length(&dpdmux_dev->dpdmux,
38166c64eb2SHemant Agrawal 			CMD_PRI_LOW, dpdmux_dev->token, max_rx_frame_len);
38266c64eb2SHemant Agrawal 	if (ret) {
38366c64eb2SHemant Agrawal 		DPAA2_PMD_ERR("DPDMUX:Unable to set mtu. check config %d", ret);
38466c64eb2SHemant Agrawal 		return ret;
38566c64eb2SHemant Agrawal 	}
38666c64eb2SHemant Agrawal 
38766c64eb2SHemant Agrawal 	DPAA2_PMD_INFO("dpdmux mtu set as %u",
38866c64eb2SHemant Agrawal 			DPAA2_MAX_RX_PKT_LEN - RTE_ETHER_CRC_LEN);
38966c64eb2SHemant Agrawal 
39066c64eb2SHemant Agrawal 	return ret;
39166c64eb2SHemant Agrawal }
39266c64eb2SHemant Agrawal 
39317eda10dSHemant Agrawal /* dump the status of the dpaa2_mux counters on the console */
39417eda10dSHemant Agrawal void
39517eda10dSHemant Agrawal rte_pmd_dpaa2_mux_dump_counter(FILE *f, uint32_t dpdmux_id, int num_if)
39617eda10dSHemant Agrawal {
39717eda10dSHemant Agrawal 	struct dpaa2_dpdmux_dev *dpdmux;
39817eda10dSHemant Agrawal 	uint64_t counter;
39917eda10dSHemant Agrawal 	int ret;
40017eda10dSHemant Agrawal 	int if_id;
40117eda10dSHemant Agrawal 
40217eda10dSHemant Agrawal 	/* Find the DPDMUX from dpdmux_id in our list */
40317eda10dSHemant Agrawal 	dpdmux = get_dpdmux_from_id(dpdmux_id);
40417eda10dSHemant Agrawal 	if (!dpdmux) {
40517eda10dSHemant Agrawal 		DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id);
40617eda10dSHemant Agrawal 		return;
40717eda10dSHemant Agrawal 	}
40817eda10dSHemant Agrawal 
40917eda10dSHemant Agrawal 	for (if_id = 0; if_id < num_if; if_id++) {
41017eda10dSHemant Agrawal 		fprintf(f, "dpdmux.%d\n", if_id);
41117eda10dSHemant Agrawal 
41217eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
41317eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_ING_FRAME, &counter);
41417eda10dSHemant Agrawal 		if (!ret)
41517eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_ING_FRAME %" PRIu64 "\n",
41617eda10dSHemant Agrawal 				counter);
41717eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
41817eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_ING_BYTE, &counter);
41917eda10dSHemant Agrawal 		if (!ret)
42017eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_ING_BYTE %" PRIu64 "\n",
42117eda10dSHemant Agrawal 				counter);
42217eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
42317eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_ING_FLTR_FRAME,
42417eda10dSHemant Agrawal 			&counter);
42517eda10dSHemant Agrawal 		if (!ret)
42617eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_ING_FLTR_FRAME %" PRIu64 "\n",
42717eda10dSHemant Agrawal 				counter);
42817eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
42917eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_ING_FRAME_DISCARD,
43017eda10dSHemant Agrawal 			&counter);
43117eda10dSHemant Agrawal 		if (!ret)
43217eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_ING_FRAME_DISCARD %" PRIu64 "\n",
43317eda10dSHemant Agrawal 				counter);
43417eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
43517eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_ING_MCAST_FRAME,
43617eda10dSHemant Agrawal 			&counter);
43717eda10dSHemant Agrawal 		if (!ret)
43817eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_ING_MCAST_FRAME %" PRIu64 "\n",
43917eda10dSHemant Agrawal 				counter);
44017eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
44117eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_ING_MCAST_BYTE,
44217eda10dSHemant Agrawal 			&counter);
44317eda10dSHemant Agrawal 		if (!ret)
44417eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_ING_MCAST_BYTE %" PRIu64 "\n",
44517eda10dSHemant Agrawal 				counter);
44617eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
44717eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_ING_BCAST_FRAME,
44817eda10dSHemant Agrawal 			&counter);
44917eda10dSHemant Agrawal 		if (!ret)
45017eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_ING_BCAST_FRAME %" PRIu64 "\n",
45117eda10dSHemant Agrawal 				counter);
45217eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
45317eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_ING_BCAST_BYTES,
45417eda10dSHemant Agrawal 			&counter);
45517eda10dSHemant Agrawal 		if (!ret)
45617eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_ING_BCAST_BYTES %" PRIu64 "\n",
45717eda10dSHemant Agrawal 				counter);
45817eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
45917eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_EGR_FRAME, &counter);
46017eda10dSHemant Agrawal 		if (!ret)
46117eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_EGR_FRAME %" PRIu64 "\n",
46217eda10dSHemant Agrawal 				counter);
46317eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
46417eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_EGR_BYTE, &counter);
46517eda10dSHemant Agrawal 		if (!ret)
46617eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_EGR_BYTE %" PRIu64 "\n",
46717eda10dSHemant Agrawal 				counter);
46817eda10dSHemant Agrawal 		ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
46917eda10dSHemant Agrawal 			dpdmux->token, if_id, DPDMUX_CNT_EGR_FRAME_DISCARD,
47017eda10dSHemant Agrawal 			&counter);
47117eda10dSHemant Agrawal 		if (!ret)
47217eda10dSHemant Agrawal 			fprintf(f, "DPDMUX_CNT_EGR_FRAME_DISCARD %" PRIu64 "\n",
47317eda10dSHemant Agrawal 				counter);
47417eda10dSHemant Agrawal 	}
47517eda10dSHemant Agrawal }
47617eda10dSHemant Agrawal 
4771def64c2SNipun Gupta static int
4781def64c2SNipun Gupta dpaa2_create_dpdmux_device(int vdev_fd __rte_unused,
4791def64c2SNipun Gupta 	struct vfio_device_info *obj_info __rte_unused,
4804d4399aeSJun Yang 	struct rte_dpaa2_device *obj)
4811def64c2SNipun Gupta {
4821def64c2SNipun Gupta 	struct dpaa2_dpdmux_dev *dpdmux_dev;
4831def64c2SNipun Gupta 	struct dpdmux_attr attr;
4844d4399aeSJun Yang 	int ret, dpdmux_id = obj->object_id;
485914450baSApeksha Gupta 	uint16_t maj_ver;
486914450baSApeksha Gupta 	uint16_t min_ver;
487cfe96771SVanshika Shukla 	uint8_t skip_reset_flags;
4881def64c2SNipun Gupta 
4891def64c2SNipun Gupta 	PMD_INIT_FUNC_TRACE();
4901def64c2SNipun Gupta 
4911def64c2SNipun Gupta 	/* Allocate DPAA2 dpdmux handle */
492*25e5845bSJun Yang 	dpdmux_dev = rte_zmalloc(NULL,
493*25e5845bSJun Yang 		sizeof(struct dpaa2_dpdmux_dev), RTE_CACHE_LINE_SIZE);
4941def64c2SNipun Gupta 	if (!dpdmux_dev) {
4951def64c2SNipun Gupta 		DPAA2_PMD_ERR("Memory allocation failed for DPDMUX Device");
496*25e5845bSJun Yang 		return -ENOMEM;
4971def64c2SNipun Gupta 	}
4981def64c2SNipun Gupta 
4991def64c2SNipun Gupta 	/* Open the dpdmux object */
500a6a5f4b4SHemant Agrawal 	dpdmux_dev->dpdmux.regs = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX);
5011def64c2SNipun Gupta 	ret = dpdmux_open(&dpdmux_dev->dpdmux, CMD_PRI_LOW, dpdmux_id,
5021def64c2SNipun Gupta 			  &dpdmux_dev->token);
5031def64c2SNipun Gupta 	if (ret) {
5041def64c2SNipun Gupta 		DPAA2_PMD_ERR("Unable to open dpdmux object: err(%d)", ret);
5051def64c2SNipun Gupta 		goto init_err;
5061def64c2SNipun Gupta 	}
5071def64c2SNipun Gupta 
5081def64c2SNipun Gupta 	ret = dpdmux_get_attributes(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
5091def64c2SNipun Gupta 				    dpdmux_dev->token, &attr);
5101def64c2SNipun Gupta 	if (ret) {
5111def64c2SNipun Gupta 		DPAA2_PMD_ERR("Unable to get dpdmux attr: err(%d)", ret);
5121def64c2SNipun Gupta 		goto init_err;
5131def64c2SNipun Gupta 	}
5141def64c2SNipun Gupta 
515cfe96771SVanshika Shukla 	if (attr.method != DPDMUX_METHOD_C_VLAN_MAC) {
5161def64c2SNipun Gupta 		ret = dpdmux_if_set_default(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
5170b5da8ccSTianli Lai 				dpdmux_dev->token, attr.default_if);
5181def64c2SNipun Gupta 		if (ret) {
5191def64c2SNipun Gupta 			DPAA2_PMD_ERR("setting default interface failed in %s",
5201def64c2SNipun Gupta 				      __func__);
5211def64c2SNipun Gupta 			goto init_err;
5221def64c2SNipun Gupta 		}
523cfe96771SVanshika Shukla 		skip_reset_flags = DPDMUX_SKIP_DEFAULT_INTERFACE
524cfe96771SVanshika Shukla 			| DPDMUX_SKIP_UNICAST_RULES | DPDMUX_SKIP_MULTICAST_RULES;
525cfe96771SVanshika Shukla 	} else {
526cfe96771SVanshika Shukla 		skip_reset_flags = DPDMUX_SKIP_DEFAULT_INTERFACE;
527cfe96771SVanshika Shukla 	}
5281def64c2SNipun Gupta 
529914450baSApeksha Gupta 	ret = dpdmux_get_api_version(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
530914450baSApeksha Gupta 					&maj_ver, &min_ver);
531914450baSApeksha Gupta 	if (ret) {
532914450baSApeksha Gupta 		DPAA2_PMD_ERR("setting version failed in %s",
533914450baSApeksha Gupta 				__func__);
534914450baSApeksha Gupta 		goto init_err;
535914450baSApeksha Gupta 	}
536914450baSApeksha Gupta 
537914450baSApeksha Gupta 	/* The new dpdmux_set/get_resetable() API are available starting with
538914450baSApeksha Gupta 	 * DPDMUX_VER_MAJOR==6 and DPDMUX_VER_MINOR==6
539914450baSApeksha Gupta 	 */
540914450baSApeksha Gupta 	if (maj_ver >= 6 && min_ver >= 6) {
541914450baSApeksha Gupta 		ret = dpdmux_set_resetable(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
542cfe96771SVanshika Shukla 				dpdmux_dev->token, skip_reset_flags);
543914450baSApeksha Gupta 		if (ret) {
544914450baSApeksha Gupta 			DPAA2_PMD_ERR("setting default interface failed in %s",
545914450baSApeksha Gupta 				      __func__);
546914450baSApeksha Gupta 			goto init_err;
547914450baSApeksha Gupta 		}
548914450baSApeksha Gupta 	}
549914450baSApeksha Gupta 
5503d43972bSHemant Agrawal 	if (maj_ver >= 6 && min_ver >= 9) {
5513d43972bSHemant Agrawal 		struct dpdmux_error_cfg mux_err_cfg;
5523d43972bSHemant Agrawal 
5533d43972bSHemant Agrawal 		memset(&mux_err_cfg, 0, sizeof(mux_err_cfg));
55400e928e9SSachin Saxena 		/* Note: Discarded flag(DPDMUX_ERROR_DISC) has effect only when
55500e928e9SSachin Saxena 		 * ERROR_ACTION is set to DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE.
55600e928e9SSachin Saxena 		 */
557cfe96771SVanshika Shukla 		mux_err_cfg.errors = DPDMUX_ALL_ERRORS;
55800e928e9SSachin Saxena 		mux_err_cfg.error_action = DPDMUX_ERROR_ACTION_CONTINUE;
5593d43972bSHemant Agrawal 
5603d43972bSHemant Agrawal 		ret = dpdmux_if_set_errors_behavior(&dpdmux_dev->dpdmux,
5613d43972bSHemant Agrawal 				CMD_PRI_LOW,
562e45956ceSVanshika Shukla 				dpdmux_dev->token, DPAA2_DPDMUX_DPMAC_IDX,
5633d43972bSHemant Agrawal 				&mux_err_cfg);
5643d43972bSHemant Agrawal 		if (ret) {
5653d43972bSHemant Agrawal 			DPAA2_PMD_ERR("dpdmux_if_set_errors_behavior %s err %d",
5663d43972bSHemant Agrawal 				      __func__, ret);
5673d43972bSHemant Agrawal 			goto init_err;
5683d43972bSHemant Agrawal 		}
5693d43972bSHemant Agrawal 	}
5703d43972bSHemant Agrawal 
5711def64c2SNipun Gupta 	dpdmux_dev->dpdmux_id = dpdmux_id;
5721def64c2SNipun Gupta 	dpdmux_dev->num_ifs = attr.num_ifs;
5731def64c2SNipun Gupta 
5741def64c2SNipun Gupta 	TAILQ_INSERT_TAIL(&dpdmux_dev_list, dpdmux_dev, next);
5751def64c2SNipun Gupta 
5761def64c2SNipun Gupta 	return 0;
5771def64c2SNipun Gupta 
5781def64c2SNipun Gupta init_err:
5791def64c2SNipun Gupta 	rte_free(dpdmux_dev);
5801def64c2SNipun Gupta 
5811def64c2SNipun Gupta 	return -1;
5821def64c2SNipun Gupta }
5831def64c2SNipun Gupta 
584274fd921SRohit Raj static void
585274fd921SRohit Raj dpaa2_close_dpdmux_device(int object_id)
586274fd921SRohit Raj {
587274fd921SRohit Raj 	struct dpaa2_dpdmux_dev *dpdmux_dev;
588274fd921SRohit Raj 
589274fd921SRohit Raj 	dpdmux_dev = get_dpdmux_from_id((uint32_t)object_id);
590274fd921SRohit Raj 
591274fd921SRohit Raj 	if (dpdmux_dev) {
592274fd921SRohit Raj 		dpdmux_close(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
593274fd921SRohit Raj 			     dpdmux_dev->token);
594274fd921SRohit Raj 		TAILQ_REMOVE(&dpdmux_dev_list, dpdmux_dev, next);
595274fd921SRohit Raj 		rte_free(dpdmux_dev);
596274fd921SRohit Raj 	}
597274fd921SRohit Raj }
598274fd921SRohit Raj 
5991def64c2SNipun Gupta static struct rte_dpaa2_object rte_dpaa2_dpdmux_obj = {
6001def64c2SNipun Gupta 	.dev_type = DPAA2_MUX,
6011def64c2SNipun Gupta 	.create = dpaa2_create_dpdmux_device,
602274fd921SRohit Raj 	.close = dpaa2_close_dpdmux_device,
6031def64c2SNipun Gupta };
6041def64c2SNipun Gupta 
6051def64c2SNipun Gupta RTE_PMD_REGISTER_DPAA2_OBJECT(dpdmux, rte_dpaa2_dpdmux_obj);
606