1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2021-2021 Broadcom
3  * All rights reserved.
4  */
5 
6 #include <glob.h>
7 #include <libgen.h>
8 #include <stdio.h>
9 #include <net/if.h>
10 #include <sys/ioctl.h>
11 #include <sys/socket.h>
12 #include <unistd.h>
13 
14 #include "bnxt.h"
15 #include "bnxt_vnic.h"
16 #include "bnxt_hwrm.h"
17 #include "bnxt_tf_common.h"
18 #include "bnxt_tf_pmd_shim.h"
19 
20 struct bnxt *
bnxt_pmd_get_bp(uint16_t port)21 bnxt_pmd_get_bp(uint16_t port)
22 {
23 	struct bnxt *bp;
24 	struct rte_eth_dev *dev;
25 
26 	if (!rte_eth_dev_is_valid_port(port)) {
27 		PMD_DRV_LOG(ERR, "Invalid port %d\n", port);
28 		return NULL;
29 	}
30 
31 	dev = &rte_eth_devices[port];
32 	if (!is_bnxt_supported(dev)) {
33 		PMD_DRV_LOG(ERR, "Device %d not supported\n", port);
34 		return NULL;
35 	}
36 
37 	bp = (struct bnxt *)dev->data->dev_private;
38 	if (!BNXT_TRUFLOW_EN(bp)) {
39 		PMD_DRV_LOG(ERR, "TRUFLOW not enabled\n");
40 		return NULL;
41 	}
42 
43 	return bp;
44 }
45 
bnxt_rss_config_action_apply(struct bnxt_ulp_mapper_parms * parms)46 int32_t bnxt_rss_config_action_apply(struct bnxt_ulp_mapper_parms *parms)
47 {
48 	struct bnxt_vnic_info *vnic = NULL;
49 	struct bnxt *bp = NULL;
50 	uint64_t rss_types;
51 	uint16_t hwrm_type;
52 	uint32_t rss_level, key_len;
53 	uint8_t *rss_key;
54 	struct ulp_rte_act_prop *ap = parms->act_prop;
55 	int32_t rc = -EINVAL;
56 
57 	bp = bnxt_pmd_get_bp(parms->port_id);
58 	if (bp == NULL) {
59 		BNXT_TF_DBG(ERR, "Invalid bp for port_id %u\n", parms->port_id);
60 		return rc;
61 	}
62 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
63 	if (vnic == NULL) {
64 		BNXT_TF_DBG(ERR, "default vnic not available for %u\n",
65 			    parms->port_id);
66 		return rc;
67 	}
68 
69 	/* get the details */
70 	memcpy(&rss_types, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_TYPES],
71 	       BNXT_ULP_ACT_PROP_SZ_RSS_TYPES);
72 	memcpy(&rss_level, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_LEVEL],
73 	       BNXT_ULP_ACT_PROP_SZ_RSS_LEVEL);
74 	memcpy(&key_len, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY_LEN],
75 	       BNXT_ULP_ACT_PROP_SZ_RSS_KEY_LEN);
76 	rss_key = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY];
77 
78 	hwrm_type = bnxt_rte_to_hwrm_hash_types(rss_types);
79 	if (!hwrm_type) {
80 		BNXT_TF_DBG(ERR, "Error unsupported rss config type\n");
81 		return rc;
82 	}
83 	/* Configure RSS only if the queue count is > 1 */
84 	if (vnic->rx_queue_cnt > 1) {
85 		vnic->hash_type = hwrm_type;
86 		vnic->hash_mode =
87 			bnxt_rte_to_hwrm_hash_level(bp, rss_types, rss_level);
88 		memcpy(vnic->rss_hash_key, rss_key,
89 		       BNXT_ULP_ACT_PROP_SZ_RSS_KEY);
90 		rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
91 		if (rc) {
92 			BNXT_TF_DBG(ERR, "Error configuring vnic RSS config\n");
93 			return rc;
94 		}
95 		BNXT_TF_DBG(INFO, "Rss config successfully applied\n");
96 	}
97 	return 0;
98 }
99 
100 #define PARENT_PHY_INTF_PATH "/sys/bus/pci/devices/%s/physfn/net/*"
101 #define ULP_PRT_MAC_PATH "/sys/bus/pci/devices/%s/physfn/net/%s/address"
102 
103 #define ULP_FILE_PATH_SIZE 256
104 
glob_error_fn(const char * epath,int32_t eerrno)105 static int32_t glob_error_fn(const char *epath, int32_t eerrno)
106 {
107 	BNXT_TF_DBG(ERR, "path %s error %d\n", epath, eerrno);
108 	return 0;
109 }
110 
111 
ulp_pmd_get_mac_by_pci(const char * pci_name,uint8_t * mac)112 static int32_t ulp_pmd_get_mac_by_pci(const char *pci_name, uint8_t *mac)
113 {
114 	char path[ULP_FILE_PATH_SIZE], dev_str[ULP_FILE_PATH_SIZE];
115 	char *intf_name;
116 	glob_t gres;
117 	FILE *fp;
118 	int32_t rc = -EINVAL;
119 
120 	memset(path, 0, sizeof(path));
121 	sprintf(path, PARENT_PHY_INTF_PATH, pci_name);
122 
123 	/* There can be only one, no more, no less */
124 	if (glob(path, 0, glob_error_fn, &gres) == 0) {
125 		if (gres.gl_pathc != 1)
126 			return rc;
127 
128 		/* Replace the PCI address with interface name and get index */
129 		intf_name = basename(gres.gl_pathv[0]);
130 		sprintf(path, ULP_PRT_MAC_PATH, pci_name, intf_name);
131 
132 		fp = fopen(path, "r");
133 		if (!fp) {
134 			BNXT_TF_DBG(ERR, "Error in getting bond mac address\n");
135 			return rc;
136 		}
137 
138 		memset(dev_str, 0, sizeof(dev_str));
139 		if (fgets(dev_str, sizeof(dev_str), fp) == NULL) {
140 			BNXT_TF_DBG(ERR, "Error in reading %s\n", path);
141 			fclose(fp);
142 			return rc;
143 		}
144 
145 		if (sscanf(dev_str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n",
146 			   &mac[0], &mac[1], &mac[2],
147 			   &mac[3], &mac[4], &mac[5]) == 6)
148 			rc = 0;
149 		fclose(fp);
150 	}
151 	return rc;
152 }
153 
bnxt_pmd_get_parent_mac_addr(struct bnxt_ulp_mapper_parms * parms,uint8_t * mac)154 int32_t bnxt_pmd_get_parent_mac_addr(struct bnxt_ulp_mapper_parms *parms,
155 				     uint8_t *mac)
156 {
157 	struct bnxt *bp = NULL;
158 	int32_t rc = -EINVAL;
159 
160 	bp = bnxt_pmd_get_bp(parms->port_id);
161 	if (bp == NULL) {
162 		BNXT_TF_DBG(ERR, "Invalid bp for port_id %u\n", parms->port_id);
163 		return rc;
164 	}
165 	return ulp_pmd_get_mac_by_pci(bp->pdev->name, &mac[2]);
166 }
167 
168 uint16_t
bnxt_pmd_get_svif(uint16_t port_id,bool func_svif,enum bnxt_ulp_intf_type type)169 bnxt_pmd_get_svif(uint16_t port_id, bool func_svif,
170 	      enum bnxt_ulp_intf_type type)
171 {
172 	struct rte_eth_dev *eth_dev;
173 	struct bnxt *bp;
174 
175 	eth_dev = &rte_eth_devices[port_id];
176 	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
177 		struct bnxt_representor *vfr = eth_dev->data->dev_private;
178 		if (!vfr)
179 			return 0;
180 
181 		if (type == BNXT_ULP_INTF_TYPE_VF_REP)
182 			return vfr->svif;
183 
184 		eth_dev = vfr->parent_dev;
185 	}
186 
187 	bp = eth_dev->data->dev_private;
188 
189 	return func_svif ? bp->func_svif : bp->port_svif;
190 }
191 
192 void
bnxt_pmd_get_iface_mac(uint16_t port,enum bnxt_ulp_intf_type type,uint8_t * mac,uint8_t * parent_mac)193 bnxt_pmd_get_iface_mac(uint16_t port, enum bnxt_ulp_intf_type type,
194 		       uint8_t *mac, uint8_t *parent_mac)
195 {
196 	struct rte_eth_dev *eth_dev;
197 	struct bnxt *bp;
198 
199 	if (type != BNXT_ULP_INTF_TYPE_TRUSTED_VF &&
200 	    type != BNXT_ULP_INTF_TYPE_PF)
201 		return;
202 
203 	eth_dev = &rte_eth_devices[port];
204 	bp = eth_dev->data->dev_private;
205 	memcpy(mac, bp->mac_addr, RTE_ETHER_ADDR_LEN);
206 
207 	if (type == BNXT_ULP_INTF_TYPE_TRUSTED_VF)
208 		memcpy(parent_mac, bp->parent->mac_addr, RTE_ETHER_ADDR_LEN);
209 }
210 
211 uint16_t
bnxt_pmd_get_parent_vnic_id(uint16_t port,enum bnxt_ulp_intf_type type)212 bnxt_pmd_get_parent_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type)
213 {
214 	struct rte_eth_dev *eth_dev;
215 	struct bnxt *bp;
216 
217 	if (type != BNXT_ULP_INTF_TYPE_TRUSTED_VF)
218 		return 0;
219 
220 	eth_dev = &rte_eth_devices[port];
221 	bp = eth_dev->data->dev_private;
222 
223 	return bp->parent->vnic;
224 }
225 
226 uint16_t
bnxt_pmd_get_vnic_id(uint16_t port,enum bnxt_ulp_intf_type type)227 bnxt_pmd_get_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type)
228 {
229 	struct rte_eth_dev *eth_dev;
230 	struct bnxt_vnic_info *vnic;
231 	struct bnxt *bp;
232 
233 	eth_dev = &rte_eth_devices[port];
234 	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
235 		struct bnxt_representor *vfr = eth_dev->data->dev_private;
236 		if (!vfr)
237 			return 0;
238 
239 		if (type == BNXT_ULP_INTF_TYPE_VF_REP)
240 			return vfr->dflt_vnic_id;
241 
242 		eth_dev = vfr->parent_dev;
243 	}
244 
245 	bp = eth_dev->data->dev_private;
246 
247 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
248 
249 	return vnic->fw_vnic_id;
250 }
251 
252 uint16_t
bnxt_pmd_get_fw_func_id(uint16_t port,enum bnxt_ulp_intf_type type)253 bnxt_pmd_get_fw_func_id(uint16_t port, enum bnxt_ulp_intf_type type)
254 {
255 	struct rte_eth_dev *eth_dev;
256 	struct bnxt *bp;
257 
258 	eth_dev = &rte_eth_devices[port];
259 	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
260 		struct bnxt_representor *vfr = eth_dev->data->dev_private;
261 		if (!vfr)
262 			return 0;
263 
264 		if (type == BNXT_ULP_INTF_TYPE_VF_REP)
265 			return vfr->fw_fid;
266 
267 		eth_dev = vfr->parent_dev;
268 	}
269 
270 	bp = eth_dev->data->dev_private;
271 
272 	return bp->fw_fid;
273 }
274 
275 enum bnxt_ulp_intf_type
bnxt_pmd_get_interface_type(uint16_t port)276 bnxt_pmd_get_interface_type(uint16_t port)
277 {
278 	struct rte_eth_dev *eth_dev;
279 	struct bnxt *bp;
280 
281 	eth_dev = &rte_eth_devices[port];
282 	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev))
283 		return BNXT_ULP_INTF_TYPE_VF_REP;
284 
285 	bp = eth_dev->data->dev_private;
286 	if (BNXT_PF(bp))
287 		return BNXT_ULP_INTF_TYPE_PF;
288 	else if (BNXT_VF_IS_TRUSTED(bp))
289 		return BNXT_ULP_INTF_TYPE_TRUSTED_VF;
290 	else if (BNXT_VF(bp))
291 		return BNXT_ULP_INTF_TYPE_VF;
292 
293 	return BNXT_ULP_INTF_TYPE_INVALID;
294 }
295 
296 uint16_t
bnxt_pmd_get_phy_port_id(uint16_t port_id)297 bnxt_pmd_get_phy_port_id(uint16_t port_id)
298 {
299 	struct bnxt_representor *vfr;
300 	struct rte_eth_dev *eth_dev;
301 	struct bnxt *bp;
302 
303 	eth_dev = &rte_eth_devices[port_id];
304 	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
305 		vfr = eth_dev->data->dev_private;
306 		if (!vfr)
307 			return 0;
308 
309 		eth_dev = vfr->parent_dev;
310 	}
311 
312 	bp = eth_dev->data->dev_private;
313 
314 	return BNXT_PF(bp) ? bp->pf->port_id : bp->parent->port_id;
315 }
316 
317 uint16_t
bnxt_pmd_get_parif(uint16_t port_id,enum bnxt_ulp_intf_type type)318 bnxt_pmd_get_parif(uint16_t port_id, enum bnxt_ulp_intf_type type)
319 {
320 	struct rte_eth_dev *eth_dev;
321 	struct bnxt *bp;
322 
323 	eth_dev = &rte_eth_devices[port_id];
324 	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
325 		struct bnxt_representor *vfr = eth_dev->data->dev_private;
326 		if (!vfr)
327 			return 0;
328 
329 		if (type == BNXT_ULP_INTF_TYPE_VF_REP)
330 			return vfr->fw_fid - 1;
331 
332 		eth_dev = vfr->parent_dev;
333 	}
334 
335 	bp = eth_dev->data->dev_private;
336 
337 	return BNXT_PF(bp) ? bp->fw_fid - 1 : bp->parent->fid - 1;
338 }
339 
340 uint16_t
bnxt_pmd_get_vport(uint16_t port_id)341 bnxt_pmd_get_vport(uint16_t port_id)
342 {
343 	return (1 << bnxt_pmd_get_phy_port_id(port_id));
344 }
345 
346 
347 int32_t
bnxt_pmd_set_unicast_rxmask(struct rte_eth_dev * eth_dev)348 bnxt_pmd_set_unicast_rxmask(struct rte_eth_dev *eth_dev)
349 {
350 	struct bnxt *bp = eth_dev->data->dev_private;
351 	struct bnxt_vnic_info *vnic;
352 	uint32_t old_flags;
353 	int32_t rc;
354 
355 	rc = is_bnxt_in_error(bp);
356 	if (rc)
357 		return rc;
358 
359 	/* Filter settings will get applied when port is started */
360 	if (!eth_dev->data->dev_started)
361 		return 0;
362 
363 	if (bp->vnic_info == NULL)
364 		return 0;
365 
366 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
367 
368 	old_flags = vnic->flags;
369 	vnic->flags |= BNXT_VNIC_INFO_UCAST;
370 	vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
371 	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
372 	vnic->flags &= ~BNXT_VNIC_INFO_BCAST;
373 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
374 	if (rc != 0)
375 		vnic->flags = old_flags;
376 
377 	return rc;
378 }
379