xref: /dpdk/drivers/net/cnxk/cnxk_eswitch_devargs.c (revision f665790a5dbad7b645ff46f31d65e977324e7bfc)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2024 Marvell.
3  */
4 
5 #include <cnxk_eswitch.h>
6 
7 #define PF_SHIFT 10
8 static inline int
9 get_hw_func(uint16_t pf, uint16_t vf)
10 {
11 	return (pf << PF_SHIFT) | vf;
12 }
13 
14 static int
15 populate_repr_hw_info(struct cnxk_eswitch_dev *eswitch_dev, struct rte_eth_devargs *eth_da,
16 		      uint16_t idx)
17 {
18 	struct cnxk_eswitch_devargs *esw_da = &eswitch_dev->esw_da[idx];
19 	uint16_t nb_repr_ports, hw_func;
20 	int rc, i, j;
21 
22 	if (eth_da->type == RTE_ETH_REPRESENTOR_NONE) {
23 		plt_err("No representor type found");
24 		return -EINVAL;
25 	}
26 
27 	if (eth_da->type != RTE_ETH_REPRESENTOR_VF && eth_da->type != RTE_ETH_REPRESENTOR_PF &&
28 	    eth_da->type != RTE_ETH_REPRESENTOR_SF) {
29 		plt_err("unsupported representor type %d", eth_da->type);
30 		return -ENOTSUP;
31 	}
32 
33 	nb_repr_ports = (eth_da->type == RTE_ETH_REPRESENTOR_PF) ? eth_da->nb_ports :
34 								   eth_da->nb_representor_ports;
35 	esw_da->nb_repr_ports = nb_repr_ports;
36 	/* If plain list is provided as representor pattern */
37 	if (eth_da->nb_ports == 0)
38 		return 0;
39 
40 	esw_da->repr_hw_info = plt_zmalloc(nb_repr_ports * sizeof(struct cnxk_esw_repr_hw_info), 0);
41 	if (!esw_da->repr_hw_info) {
42 		plt_err("Failed to allocate memory");
43 		rc = -ENOMEM;
44 		goto fail;
45 	}
46 
47 	plt_esw_dbg("Representor param %d has %d pfvf", idx, nb_repr_ports);
48 	/* Check if representor can be created for PFVF and populating HW func list */
49 	for (i = 0; i < nb_repr_ports; i++) {
50 		if (eth_da->type == RTE_ETH_REPRESENTOR_PF)
51 			hw_func = get_hw_func(eth_da->ports[i], 0);
52 		else
53 			hw_func = get_hw_func(eth_da->ports[0], eth_da->representor_ports[i] + 1);
54 
55 		for (j = 0; j < eswitch_dev->repr_cnt.max_repr; j++) {
56 			if (eswitch_dev->nix.rep_pfvf_map[j] == hw_func)
57 				break;
58 		}
59 
60 		/* HW func which doesn not match the map table received from AF, no
61 		 * representor port is assigned.
62 		 */
63 		if (j == eswitch_dev->repr_cnt.max_repr) {
64 			plt_err("Representor port can't be created for PF%dVF%d", eth_da->ports[0],
65 				eth_da->representor_ports[i]);
66 			rc = -EINVAL;
67 			goto fail;
68 		}
69 
70 		esw_da->repr_hw_info[i].hw_func = hw_func;
71 		esw_da->repr_hw_info[i].rep_id = j;
72 		esw_da->repr_hw_info[i].pfvf = (eth_da->type == RTE_ETH_REPRESENTOR_PF) ?
73 						       eth_da->ports[0] :
74 						       eth_da->representor_ports[i];
75 		TAILQ_INIT(&esw_da->repr_hw_info[i].repr_flow_list);
76 		plt_esw_dbg("	HW func %x index %d type %d", hw_func, j, eth_da->type);
77 	}
78 
79 	esw_da->type = CNXK_ESW_DA_TYPE_PFVF;
80 
81 	return 0;
82 fail:
83 	return rc;
84 }
85 
86 int
87 cnxk_eswitch_repr_devargs(struct rte_pci_device *pci_dev, struct cnxk_eswitch_dev *eswitch_dev)
88 {
89 	struct rte_devargs *devargs = pci_dev->device.devargs;
90 	struct rte_eth_devargs eth_da[RTE_MAX_ETHPORTS];
91 	int rc, i, j, count;
92 
93 	if (devargs == NULL) {
94 		plt_err("No devargs passed");
95 		rc = -EINVAL;
96 		goto fail;
97 	}
98 
99 	/* Parse devargs passed to ESW device */
100 	rc = rte_eth_devargs_parse(devargs->args, eth_da, RTE_MAX_ETHPORTS);
101 	if (rc < 0) {
102 		plt_err("Failed to parse devargs, err %d", rc);
103 		goto fail;
104 	}
105 
106 	count = rc;
107 	j = eswitch_dev->nb_esw_da;
108 	for (i = 0; i < count; i++) {
109 		rc = populate_repr_hw_info(eswitch_dev, &eth_da[i], j);
110 		if (rc) {
111 			plt_err("Failed to populate representer hw funcs, err %d", rc);
112 			goto fail;
113 		}
114 
115 		rte_memcpy(&eswitch_dev->esw_da[j].da, &eth_da[i], sizeof(struct rte_eth_devargs));
116 		/* No of representor ports to be created */
117 		eswitch_dev->repr_cnt.nb_repr_created += eswitch_dev->esw_da[j].nb_repr_ports;
118 		j++;
119 	}
120 	eswitch_dev->nb_esw_da += count;
121 
122 	return 0;
123 fail:
124 	return rc;
125 }
126