xref: /openbmc/linux/drivers/net/ethernet/sfc/efx_devlink.c (revision fa78b01718d2f1cc95ce052fad3aa49c46d024eb)
1fa34a514SAlejandro Lucero // SPDX-License-Identifier: GPL-2.0-only
2fa34a514SAlejandro Lucero /****************************************************************************
3fa34a514SAlejandro Lucero  * Driver for AMD network controllers and boards
4fa34a514SAlejandro Lucero  * Copyright (C) 2023, Advanced Micro Devices, Inc.
5fa34a514SAlejandro Lucero  *
6fa34a514SAlejandro Lucero  * This program is free software; you can redistribute it and/or modify it
7fa34a514SAlejandro Lucero  * under the terms of the GNU General Public License version 2 as published
8fa34a514SAlejandro Lucero  * by the Free Software Foundation, incorporated herein by reference.
9fa34a514SAlejandro Lucero  */
10fa34a514SAlejandro Lucero 
11fa34a514SAlejandro Lucero #include "net_driver.h"
12*fa78b017SAlejandro Lucero #include "ef100_nic.h"
13fa34a514SAlejandro Lucero #include "efx_devlink.h"
1414743dddSAlejandro Lucero #include <linux/rtc.h>
1514743dddSAlejandro Lucero #include "mcdi.h"
1614743dddSAlejandro Lucero #include "mcdi_functions.h"
1714743dddSAlejandro Lucero #include "mcdi_pcol.h"
1825414b2aSAlejandro Lucero #ifdef CONFIG_SFC_SRIOV
1925414b2aSAlejandro Lucero #include "mae.h"
2025414b2aSAlejandro Lucero #include "ef100_rep.h"
2125414b2aSAlejandro Lucero #endif
22fa34a514SAlejandro Lucero 
23fa34a514SAlejandro Lucero struct efx_devlink {
24fa34a514SAlejandro Lucero 	struct efx_nic *efx;
25fa34a514SAlejandro Lucero };
26fa34a514SAlejandro Lucero 
2725414b2aSAlejandro Lucero #ifdef CONFIG_SFC_SRIOV
2825414b2aSAlejandro Lucero static void efx_devlink_del_port(struct devlink_port *dl_port)
2925414b2aSAlejandro Lucero {
3025414b2aSAlejandro Lucero 	if (!dl_port)
3125414b2aSAlejandro Lucero 		return;
3225414b2aSAlejandro Lucero 	devl_port_unregister(dl_port);
3325414b2aSAlejandro Lucero }
3425414b2aSAlejandro Lucero 
3525414b2aSAlejandro Lucero static int efx_devlink_add_port(struct efx_nic *efx,
3625414b2aSAlejandro Lucero 				struct mae_mport_desc *mport)
3725414b2aSAlejandro Lucero {
3825414b2aSAlejandro Lucero 	bool external = false;
3925414b2aSAlejandro Lucero 
4025414b2aSAlejandro Lucero 	if (!ef100_mport_on_local_intf(efx, mport))
4125414b2aSAlejandro Lucero 		external = true;
4225414b2aSAlejandro Lucero 
4325414b2aSAlejandro Lucero 	switch (mport->mport_type) {
4425414b2aSAlejandro Lucero 	case MAE_MPORT_DESC_MPORT_TYPE_VNIC:
4525414b2aSAlejandro Lucero 		if (mport->vf_idx != MAE_MPORT_DESC_VF_IDX_NULL)
4625414b2aSAlejandro Lucero 			devlink_port_attrs_pci_vf_set(&mport->dl_port, 0, mport->pf_idx,
4725414b2aSAlejandro Lucero 						      mport->vf_idx,
4825414b2aSAlejandro Lucero 						      external);
4925414b2aSAlejandro Lucero 		else
5025414b2aSAlejandro Lucero 			devlink_port_attrs_pci_pf_set(&mport->dl_port, 0, mport->pf_idx,
5125414b2aSAlejandro Lucero 						      external);
5225414b2aSAlejandro Lucero 		break;
5325414b2aSAlejandro Lucero 	default:
5425414b2aSAlejandro Lucero 		/* MAE_MPORT_DESC_MPORT_ALIAS and UNDEFINED */
5525414b2aSAlejandro Lucero 		return 0;
5625414b2aSAlejandro Lucero 	}
5725414b2aSAlejandro Lucero 
5825414b2aSAlejandro Lucero 	mport->dl_port.index = mport->mport_id;
5925414b2aSAlejandro Lucero 
6025414b2aSAlejandro Lucero 	return devl_port_register(efx->devlink, &mport->dl_port, mport->mport_id);
6125414b2aSAlejandro Lucero }
62*fa78b017SAlejandro Lucero 
63*fa78b017SAlejandro Lucero static int efx_devlink_port_addr_get(struct devlink_port *port, u8 *hw_addr,
64*fa78b017SAlejandro Lucero 				     int *hw_addr_len,
65*fa78b017SAlejandro Lucero 				     struct netlink_ext_ack *extack)
66*fa78b017SAlejandro Lucero {
67*fa78b017SAlejandro Lucero 	struct efx_devlink *devlink = devlink_priv(port->devlink);
68*fa78b017SAlejandro Lucero 	struct mae_mport_desc *mport_desc;
69*fa78b017SAlejandro Lucero 	efx_qword_t pciefn;
70*fa78b017SAlejandro Lucero 	u32 client_id;
71*fa78b017SAlejandro Lucero 	int rc = 0;
72*fa78b017SAlejandro Lucero 
73*fa78b017SAlejandro Lucero 	mport_desc = container_of(port, struct mae_mport_desc, dl_port);
74*fa78b017SAlejandro Lucero 
75*fa78b017SAlejandro Lucero 	if (!ef100_mport_on_local_intf(devlink->efx, mport_desc)) {
76*fa78b017SAlejandro Lucero 		rc = -EINVAL;
77*fa78b017SAlejandro Lucero 		NL_SET_ERR_MSG_FMT(extack,
78*fa78b017SAlejandro Lucero 				   "Port not on local interface (mport: %u)",
79*fa78b017SAlejandro Lucero 				   mport_desc->mport_id);
80*fa78b017SAlejandro Lucero 		goto out;
81*fa78b017SAlejandro Lucero 	}
82*fa78b017SAlejandro Lucero 
83*fa78b017SAlejandro Lucero 	if (ef100_mport_is_vf(mport_desc))
84*fa78b017SAlejandro Lucero 		EFX_POPULATE_QWORD_3(pciefn,
85*fa78b017SAlejandro Lucero 				     PCIE_FUNCTION_PF, PCIE_FUNCTION_PF_NULL,
86*fa78b017SAlejandro Lucero 				     PCIE_FUNCTION_VF, mport_desc->vf_idx,
87*fa78b017SAlejandro Lucero 				     PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);
88*fa78b017SAlejandro Lucero 	else
89*fa78b017SAlejandro Lucero 		EFX_POPULATE_QWORD_3(pciefn,
90*fa78b017SAlejandro Lucero 				     PCIE_FUNCTION_PF, mport_desc->pf_idx,
91*fa78b017SAlejandro Lucero 				     PCIE_FUNCTION_VF, PCIE_FUNCTION_VF_NULL,
92*fa78b017SAlejandro Lucero 				     PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);
93*fa78b017SAlejandro Lucero 
94*fa78b017SAlejandro Lucero 	rc = efx_ef100_lookup_client_id(devlink->efx, pciefn, &client_id);
95*fa78b017SAlejandro Lucero 	if (rc) {
96*fa78b017SAlejandro Lucero 		NL_SET_ERR_MSG_FMT(extack,
97*fa78b017SAlejandro Lucero 				   "No internal client_ID for port (mport: %u)",
98*fa78b017SAlejandro Lucero 				   mport_desc->mport_id);
99*fa78b017SAlejandro Lucero 		goto out;
100*fa78b017SAlejandro Lucero 	}
101*fa78b017SAlejandro Lucero 
102*fa78b017SAlejandro Lucero 	rc = ef100_get_mac_address(devlink->efx, hw_addr, client_id, true);
103*fa78b017SAlejandro Lucero 	if (rc != 0)
104*fa78b017SAlejandro Lucero 		NL_SET_ERR_MSG_FMT(extack,
105*fa78b017SAlejandro Lucero 				   "No available MAC for port (mport: %u)",
106*fa78b017SAlejandro Lucero 				   mport_desc->mport_id);
107*fa78b017SAlejandro Lucero out:
108*fa78b017SAlejandro Lucero 	*hw_addr_len = ETH_ALEN;
109*fa78b017SAlejandro Lucero 	return rc;
110*fa78b017SAlejandro Lucero }
111*fa78b017SAlejandro Lucero 
11225414b2aSAlejandro Lucero #endif
11325414b2aSAlejandro Lucero 
11414743dddSAlejandro Lucero static int efx_devlink_info_nvram_partition(struct efx_nic *efx,
11514743dddSAlejandro Lucero 					    struct devlink_info_req *req,
11614743dddSAlejandro Lucero 					    unsigned int partition_type,
11714743dddSAlejandro Lucero 					    const char *version_name)
11814743dddSAlejandro Lucero {
11914743dddSAlejandro Lucero 	char buf[EFX_MAX_VERSION_INFO_LEN];
12014743dddSAlejandro Lucero 	u16 version[4];
12114743dddSAlejandro Lucero 	int rc;
12214743dddSAlejandro Lucero 
12314743dddSAlejandro Lucero 	rc = efx_mcdi_nvram_metadata(efx, partition_type, NULL, version, NULL,
12414743dddSAlejandro Lucero 				     0);
12514743dddSAlejandro Lucero 	if (rc) {
12614743dddSAlejandro Lucero 		netif_err(efx, drv, efx->net_dev, "mcdi nvram %s: failed\n",
12714743dddSAlejandro Lucero 			  version_name);
12814743dddSAlejandro Lucero 		return rc;
12914743dddSAlejandro Lucero 	}
13014743dddSAlejandro Lucero 
13114743dddSAlejandro Lucero 	snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", version[0],
13214743dddSAlejandro Lucero 		 version[1], version[2], version[3]);
13314743dddSAlejandro Lucero 	devlink_info_version_stored_put(req, version_name, buf);
13414743dddSAlejandro Lucero 
13514743dddSAlejandro Lucero 	return 0;
13614743dddSAlejandro Lucero }
13714743dddSAlejandro Lucero 
13814743dddSAlejandro Lucero static int efx_devlink_info_stored_versions(struct efx_nic *efx,
13914743dddSAlejandro Lucero 					    struct devlink_info_req *req)
14014743dddSAlejandro Lucero {
14114743dddSAlejandro Lucero 	int rc;
14214743dddSAlejandro Lucero 
14314743dddSAlejandro Lucero 	rc = efx_devlink_info_nvram_partition(efx, req,
14414743dddSAlejandro Lucero 					      NVRAM_PARTITION_TYPE_BUNDLE,
14514743dddSAlejandro Lucero 					      DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID);
14614743dddSAlejandro Lucero 	if (rc)
14714743dddSAlejandro Lucero 		return rc;
14814743dddSAlejandro Lucero 
14914743dddSAlejandro Lucero 	rc = efx_devlink_info_nvram_partition(efx, req,
15014743dddSAlejandro Lucero 					      NVRAM_PARTITION_TYPE_MC_FIRMWARE,
15114743dddSAlejandro Lucero 					      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT);
15214743dddSAlejandro Lucero 	if (rc)
15314743dddSAlejandro Lucero 		return rc;
15414743dddSAlejandro Lucero 
15514743dddSAlejandro Lucero 	rc = efx_devlink_info_nvram_partition(efx, req,
15614743dddSAlejandro Lucero 					      NVRAM_PARTITION_TYPE_SUC_FIRMWARE,
15714743dddSAlejandro Lucero 					      EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC);
15814743dddSAlejandro Lucero 	if (rc)
15914743dddSAlejandro Lucero 		return rc;
16014743dddSAlejandro Lucero 
16114743dddSAlejandro Lucero 	rc = efx_devlink_info_nvram_partition(efx, req,
16214743dddSAlejandro Lucero 					      NVRAM_PARTITION_TYPE_EXPANSION_ROM,
16314743dddSAlejandro Lucero 					      EFX_DEVLINK_INFO_VERSION_FW_EXPROM);
16414743dddSAlejandro Lucero 	if (rc)
16514743dddSAlejandro Lucero 		return rc;
16614743dddSAlejandro Lucero 
16714743dddSAlejandro Lucero 	rc = efx_devlink_info_nvram_partition(efx, req,
16814743dddSAlejandro Lucero 					      NVRAM_PARTITION_TYPE_EXPANSION_UEFI,
16914743dddSAlejandro Lucero 					      EFX_DEVLINK_INFO_VERSION_FW_UEFI);
17014743dddSAlejandro Lucero 	return rc;
17114743dddSAlejandro Lucero }
17214743dddSAlejandro Lucero 
17314743dddSAlejandro Lucero #define EFX_VER_FLAG(_f)	\
17414743dddSAlejandro Lucero 	(MC_CMD_GET_VERSION_V5_OUT_ ## _f ## _PRESENT_LBN)
17514743dddSAlejandro Lucero 
17614743dddSAlejandro Lucero static void efx_devlink_info_running_v2(struct efx_nic *efx,
17714743dddSAlejandro Lucero 					struct devlink_info_req *req,
17814743dddSAlejandro Lucero 					unsigned int flags, efx_dword_t *outbuf)
17914743dddSAlejandro Lucero {
18014743dddSAlejandro Lucero 	char buf[EFX_MAX_VERSION_INFO_LEN];
18114743dddSAlejandro Lucero 	union {
18214743dddSAlejandro Lucero 		const __le32 *dwords;
18314743dddSAlejandro Lucero 		const __le16 *words;
18414743dddSAlejandro Lucero 		const char *str;
18514743dddSAlejandro Lucero 	} ver;
18614743dddSAlejandro Lucero 	struct rtc_time build_date;
18714743dddSAlejandro Lucero 	unsigned int build_id;
18814743dddSAlejandro Lucero 	size_t offset;
18914743dddSAlejandro Lucero 	__maybe_unused u64 tstamp;
19014743dddSAlejandro Lucero 
19114743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(BOARD_EXT_INFO))) {
19214743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%s",
19314743dddSAlejandro Lucero 			 MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_NAME));
19414743dddSAlejandro Lucero 		devlink_info_version_fixed_put(req,
19514743dddSAlejandro Lucero 					       DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
19614743dddSAlejandro Lucero 					       buf);
19714743dddSAlejandro Lucero 
19814743dddSAlejandro Lucero 		/* Favour full board version if present (in V5 or later) */
19914743dddSAlejandro Lucero 		if (~flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) {
20014743dddSAlejandro Lucero 			snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u",
20114743dddSAlejandro Lucero 				 MCDI_DWORD(outbuf,
20214743dddSAlejandro Lucero 					    GET_VERSION_V2_OUT_BOARD_REVISION));
20314743dddSAlejandro Lucero 			devlink_info_version_fixed_put(req,
20414743dddSAlejandro Lucero 						       DEVLINK_INFO_VERSION_GENERIC_BOARD_REV,
20514743dddSAlejandro Lucero 						       buf);
20614743dddSAlejandro Lucero 		}
20714743dddSAlejandro Lucero 
20814743dddSAlejandro Lucero 		ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_SERIAL);
20914743dddSAlejandro Lucero 		if (ver.str[0])
21014743dddSAlejandro Lucero 			devlink_info_board_serial_number_put(req, ver.str);
21114743dddSAlejandro Lucero 	}
21214743dddSAlejandro Lucero 
21314743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(FPGA_EXT_INFO))) {
21414743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
21514743dddSAlejandro Lucero 						GET_VERSION_V2_OUT_FPGA_VERSION);
21614743dddSAlejandro Lucero 		offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u_%c%u",
21714743dddSAlejandro Lucero 				  le32_to_cpu(ver.dwords[0]),
21814743dddSAlejandro Lucero 				  'A' + le32_to_cpu(ver.dwords[1]),
21914743dddSAlejandro Lucero 				  le32_to_cpu(ver.dwords[2]));
22014743dddSAlejandro Lucero 
22114743dddSAlejandro Lucero 		ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_FPGA_EXTRA);
22214743dddSAlejandro Lucero 		if (ver.str[0])
22314743dddSAlejandro Lucero 			snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
22414743dddSAlejandro Lucero 				 " (%s)", ver.str);
22514743dddSAlejandro Lucero 
22614743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
22714743dddSAlejandro Lucero 						 EFX_DEVLINK_INFO_VERSION_FPGA_REV,
22814743dddSAlejandro Lucero 						 buf);
22914743dddSAlejandro Lucero 	}
23014743dddSAlejandro Lucero 
23114743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(CMC_EXT_INFO))) {
23214743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
23314743dddSAlejandro Lucero 						GET_VERSION_V2_OUT_CMCFW_VERSION);
23414743dddSAlejandro Lucero 		offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
23514743dddSAlejandro Lucero 				  le32_to_cpu(ver.dwords[0]),
23614743dddSAlejandro Lucero 				  le32_to_cpu(ver.dwords[1]),
23714743dddSAlejandro Lucero 				  le32_to_cpu(ver.dwords[2]),
23814743dddSAlejandro Lucero 				  le32_to_cpu(ver.dwords[3]));
23914743dddSAlejandro Lucero 
24014743dddSAlejandro Lucero #ifdef CONFIG_RTC_LIB
24114743dddSAlejandro Lucero 		tstamp = MCDI_QWORD(outbuf,
24214743dddSAlejandro Lucero 				    GET_VERSION_V2_OUT_CMCFW_BUILD_DATE);
24314743dddSAlejandro Lucero 		if (tstamp) {
24414743dddSAlejandro Lucero 			rtc_time64_to_tm(tstamp, &build_date);
24514743dddSAlejandro Lucero 			snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
24614743dddSAlejandro Lucero 				 " (%ptRd)", &build_date);
24714743dddSAlejandro Lucero 		}
24814743dddSAlejandro Lucero #endif
24914743dddSAlejandro Lucero 
25014743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
25114743dddSAlejandro Lucero 						 EFX_DEVLINK_INFO_VERSION_FW_MGMT_CMC,
25214743dddSAlejandro Lucero 						 buf);
25314743dddSAlejandro Lucero 	}
25414743dddSAlejandro Lucero 
25514743dddSAlejandro Lucero 	ver.words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_V2_OUT_VERSION);
25614743dddSAlejandro Lucero 	offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
25714743dddSAlejandro Lucero 			  le16_to_cpu(ver.words[0]), le16_to_cpu(ver.words[1]),
25814743dddSAlejandro Lucero 			  le16_to_cpu(ver.words[2]), le16_to_cpu(ver.words[3]));
25914743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(MCFW_EXT_INFO))) {
26014743dddSAlejandro Lucero 		build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_ID);
26114743dddSAlejandro Lucero 		snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
26214743dddSAlejandro Lucero 			 " (%x) %s", build_id,
26314743dddSAlejandro Lucero 			 MCDI_PTR(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_NAME));
26414743dddSAlejandro Lucero 	}
26514743dddSAlejandro Lucero 	devlink_info_version_running_put(req,
26614743dddSAlejandro Lucero 					 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT,
26714743dddSAlejandro Lucero 					 buf);
26814743dddSAlejandro Lucero 
26914743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) {
27014743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
27114743dddSAlejandro Lucero 						GET_VERSION_V2_OUT_SUCFW_VERSION);
27214743dddSAlejandro Lucero #ifdef CONFIG_RTC_LIB
27314743dddSAlejandro Lucero 		tstamp = MCDI_QWORD(outbuf,
27414743dddSAlejandro Lucero 				    GET_VERSION_V2_OUT_SUCFW_BUILD_DATE);
27514743dddSAlejandro Lucero 		rtc_time64_to_tm(tstamp, &build_date);
27614743dddSAlejandro Lucero #else
27714743dddSAlejandro Lucero 		memset(&build_date, 0, sizeof(build_date)
27814743dddSAlejandro Lucero #endif
27914743dddSAlejandro Lucero 		build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_SUCFW_CHIP_ID);
28014743dddSAlejandro Lucero 
28114743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN,
28214743dddSAlejandro Lucero 			 "%u.%u.%u.%u type %x (%ptRd)",
28314743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
28414743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[2]), le32_to_cpu(ver.dwords[3]),
28514743dddSAlejandro Lucero 			 build_id, &build_date);
28614743dddSAlejandro Lucero 
28714743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
28814743dddSAlejandro Lucero 						 EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC,
28914743dddSAlejandro Lucero 						 buf);
29014743dddSAlejandro Lucero 	}
29114743dddSAlejandro Lucero }
29214743dddSAlejandro Lucero 
29314743dddSAlejandro Lucero static void efx_devlink_info_running_v3(struct efx_nic *efx,
29414743dddSAlejandro Lucero 					struct devlink_info_req *req,
29514743dddSAlejandro Lucero 					unsigned int flags, efx_dword_t *outbuf)
29614743dddSAlejandro Lucero {
29714743dddSAlejandro Lucero 	char buf[EFX_MAX_VERSION_INFO_LEN];
29814743dddSAlejandro Lucero 	union {
29914743dddSAlejandro Lucero 		const __le32 *dwords;
30014743dddSAlejandro Lucero 		const __le16 *words;
30114743dddSAlejandro Lucero 		const char *str;
30214743dddSAlejandro Lucero 	} ver;
30314743dddSAlejandro Lucero 
30414743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(DATAPATH_HW_VERSION))) {
30514743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
30614743dddSAlejandro Lucero 						GET_VERSION_V3_OUT_DATAPATH_HW_VERSION);
30714743dddSAlejandro Lucero 
30814743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u",
30914743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
31014743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[2]));
31114743dddSAlejandro Lucero 
31214743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
31314743dddSAlejandro Lucero 						 EFX_DEVLINK_INFO_VERSION_DATAPATH_HW,
31414743dddSAlejandro Lucero 						 buf);
31514743dddSAlejandro Lucero 	}
31614743dddSAlejandro Lucero 
31714743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(DATAPATH_FW_VERSION))) {
31814743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
31914743dddSAlejandro Lucero 						GET_VERSION_V3_OUT_DATAPATH_FW_VERSION);
32014743dddSAlejandro Lucero 
32114743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u",
32214743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
32314743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[2]));
32414743dddSAlejandro Lucero 
32514743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
32614743dddSAlejandro Lucero 						 EFX_DEVLINK_INFO_VERSION_DATAPATH_FW,
32714743dddSAlejandro Lucero 						 buf);
32814743dddSAlejandro Lucero 	}
32914743dddSAlejandro Lucero }
33014743dddSAlejandro Lucero 
33114743dddSAlejandro Lucero static void efx_devlink_info_running_v4(struct efx_nic *efx,
33214743dddSAlejandro Lucero 					struct devlink_info_req *req,
33314743dddSAlejandro Lucero 					unsigned int flags, efx_dword_t *outbuf)
33414743dddSAlejandro Lucero {
33514743dddSAlejandro Lucero 	char buf[EFX_MAX_VERSION_INFO_LEN];
33614743dddSAlejandro Lucero 	union {
33714743dddSAlejandro Lucero 		const __le32 *dwords;
33814743dddSAlejandro Lucero 		const __le16 *words;
33914743dddSAlejandro Lucero 		const char *str;
34014743dddSAlejandro Lucero 	} ver;
34114743dddSAlejandro Lucero 
34214743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(SOC_BOOT_VERSION))) {
34314743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
34414743dddSAlejandro Lucero 						GET_VERSION_V4_OUT_SOC_BOOT_VERSION);
34514743dddSAlejandro Lucero 
34614743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
34714743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
34814743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[2]),
34914743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[3]));
35014743dddSAlejandro Lucero 
35114743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
35214743dddSAlejandro Lucero 						 EFX_DEVLINK_INFO_VERSION_SOC_BOOT,
35314743dddSAlejandro Lucero 						 buf);
35414743dddSAlejandro Lucero 	}
35514743dddSAlejandro Lucero 
35614743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(SOC_UBOOT_VERSION))) {
35714743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
35814743dddSAlejandro Lucero 						GET_VERSION_V4_OUT_SOC_UBOOT_VERSION);
35914743dddSAlejandro Lucero 
36014743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
36114743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
36214743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[2]),
36314743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[3]));
36414743dddSAlejandro Lucero 
36514743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
36614743dddSAlejandro Lucero 						 EFX_DEVLINK_INFO_VERSION_SOC_UBOOT,
36714743dddSAlejandro Lucero 						 buf);
36814743dddSAlejandro Lucero 	}
36914743dddSAlejandro Lucero 
37014743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(SOC_MAIN_ROOTFS_VERSION))) {
37114743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
37214743dddSAlejandro Lucero 					GET_VERSION_V4_OUT_SOC_MAIN_ROOTFS_VERSION);
37314743dddSAlejandro Lucero 
37414743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
37514743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
37614743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[2]),
37714743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[3]));
37814743dddSAlejandro Lucero 
37914743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
38014743dddSAlejandro Lucero 						 EFX_DEVLINK_INFO_VERSION_SOC_MAIN,
38114743dddSAlejandro Lucero 						 buf);
38214743dddSAlejandro Lucero 	}
38314743dddSAlejandro Lucero 
38414743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(SOC_RECOVERY_BUILDROOT_VERSION))) {
38514743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
38614743dddSAlejandro Lucero 						GET_VERSION_V4_OUT_SOC_RECOVERY_BUILDROOT_VERSION);
38714743dddSAlejandro Lucero 
38814743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
38914743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
39014743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[2]),
39114743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[3]));
39214743dddSAlejandro Lucero 
39314743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
39414743dddSAlejandro Lucero 						 EFX_DEVLINK_INFO_VERSION_SOC_RECOVERY,
39514743dddSAlejandro Lucero 						 buf);
39614743dddSAlejandro Lucero 	}
39714743dddSAlejandro Lucero 
39814743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(SUCFW_VERSION)) &&
39914743dddSAlejandro Lucero 	    ~flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) {
40014743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
40114743dddSAlejandro Lucero 						GET_VERSION_V4_OUT_SUCFW_VERSION);
40214743dddSAlejandro Lucero 
40314743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
40414743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
40514743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[2]),
40614743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[3]));
40714743dddSAlejandro Lucero 
40814743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
40914743dddSAlejandro Lucero 						 EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC,
41014743dddSAlejandro Lucero 						 buf);
41114743dddSAlejandro Lucero 	}
41214743dddSAlejandro Lucero }
41314743dddSAlejandro Lucero 
41414743dddSAlejandro Lucero static void efx_devlink_info_running_v5(struct efx_nic *efx,
41514743dddSAlejandro Lucero 					struct devlink_info_req *req,
41614743dddSAlejandro Lucero 					unsigned int flags, efx_dword_t *outbuf)
41714743dddSAlejandro Lucero {
41814743dddSAlejandro Lucero 	char buf[EFX_MAX_VERSION_INFO_LEN];
41914743dddSAlejandro Lucero 	union {
42014743dddSAlejandro Lucero 		const __le32 *dwords;
42114743dddSAlejandro Lucero 		const __le16 *words;
42214743dddSAlejandro Lucero 		const char *str;
42314743dddSAlejandro Lucero 	} ver;
42414743dddSAlejandro Lucero 
42514743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) {
42614743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
42714743dddSAlejandro Lucero 						GET_VERSION_V5_OUT_BOARD_VERSION);
42814743dddSAlejandro Lucero 
42914743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
43014743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
43114743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[2]),
43214743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[3]));
43314743dddSAlejandro Lucero 
43414743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
43514743dddSAlejandro Lucero 						 DEVLINK_INFO_VERSION_GENERIC_BOARD_REV,
43614743dddSAlejandro Lucero 						 buf);
43714743dddSAlejandro Lucero 	}
43814743dddSAlejandro Lucero 
43914743dddSAlejandro Lucero 	if (flags & BIT(EFX_VER_FLAG(BUNDLE_VERSION))) {
44014743dddSAlejandro Lucero 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
44114743dddSAlejandro Lucero 						GET_VERSION_V5_OUT_BUNDLE_VERSION);
44214743dddSAlejandro Lucero 
44314743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
44414743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
44514743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[2]),
44614743dddSAlejandro Lucero 			 le32_to_cpu(ver.dwords[3]));
44714743dddSAlejandro Lucero 
44814743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
44914743dddSAlejandro Lucero 						 DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
45014743dddSAlejandro Lucero 						 buf);
45114743dddSAlejandro Lucero 	}
45214743dddSAlejandro Lucero }
45314743dddSAlejandro Lucero 
45414743dddSAlejandro Lucero static int efx_devlink_info_running_versions(struct efx_nic *efx,
45514743dddSAlejandro Lucero 					     struct devlink_info_req *req)
45614743dddSAlejandro Lucero {
45714743dddSAlejandro Lucero 	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_VERSION_V5_OUT_LEN);
45814743dddSAlejandro Lucero 	MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_VERSION_EXT_IN_LEN);
45914743dddSAlejandro Lucero 	char buf[EFX_MAX_VERSION_INFO_LEN];
46014743dddSAlejandro Lucero 	union {
46114743dddSAlejandro Lucero 		const __le32 *dwords;
46214743dddSAlejandro Lucero 		const __le16 *words;
46314743dddSAlejandro Lucero 		const char *str;
46414743dddSAlejandro Lucero 	} ver;
46514743dddSAlejandro Lucero 	size_t outlength;
46614743dddSAlejandro Lucero 	unsigned int flags;
46714743dddSAlejandro Lucero 	int rc;
46814743dddSAlejandro Lucero 
46914743dddSAlejandro Lucero 	rc = efx_mcdi_rpc(efx, MC_CMD_GET_VERSION, inbuf, sizeof(inbuf),
47014743dddSAlejandro Lucero 			  outbuf, sizeof(outbuf), &outlength);
47114743dddSAlejandro Lucero 	if (rc || outlength < MC_CMD_GET_VERSION_OUT_LEN) {
47214743dddSAlejandro Lucero 		netif_err(efx, drv, efx->net_dev,
47314743dddSAlejandro Lucero 			  "mcdi MC_CMD_GET_VERSION failed\n");
47414743dddSAlejandro Lucero 		return rc;
47514743dddSAlejandro Lucero 	}
47614743dddSAlejandro Lucero 
47714743dddSAlejandro Lucero 	/* Handle previous output */
47814743dddSAlejandro Lucero 	if (outlength < MC_CMD_GET_VERSION_V2_OUT_LEN) {
47914743dddSAlejandro Lucero 		ver.words = (__le16 *)MCDI_PTR(outbuf,
48014743dddSAlejandro Lucero 					       GET_VERSION_EXT_OUT_VERSION);
48114743dddSAlejandro Lucero 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
48214743dddSAlejandro Lucero 			 le16_to_cpu(ver.words[0]),
48314743dddSAlejandro Lucero 			 le16_to_cpu(ver.words[1]),
48414743dddSAlejandro Lucero 			 le16_to_cpu(ver.words[2]),
48514743dddSAlejandro Lucero 			 le16_to_cpu(ver.words[3]));
48614743dddSAlejandro Lucero 
48714743dddSAlejandro Lucero 		devlink_info_version_running_put(req,
48814743dddSAlejandro Lucero 						 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT,
48914743dddSAlejandro Lucero 						 buf);
49014743dddSAlejandro Lucero 		return 0;
49114743dddSAlejandro Lucero 	}
49214743dddSAlejandro Lucero 
49314743dddSAlejandro Lucero 	/* Handle V2 additions */
49414743dddSAlejandro Lucero 	flags = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_FLAGS);
49514743dddSAlejandro Lucero 	efx_devlink_info_running_v2(efx, req, flags, outbuf);
49614743dddSAlejandro Lucero 
49714743dddSAlejandro Lucero 	if (outlength < MC_CMD_GET_VERSION_V3_OUT_LEN)
49814743dddSAlejandro Lucero 		return 0;
49914743dddSAlejandro Lucero 
50014743dddSAlejandro Lucero 	/* Handle V3 additions */
50114743dddSAlejandro Lucero 	efx_devlink_info_running_v3(efx, req, flags, outbuf);
50214743dddSAlejandro Lucero 
50314743dddSAlejandro Lucero 	if (outlength < MC_CMD_GET_VERSION_V4_OUT_LEN)
50414743dddSAlejandro Lucero 		return 0;
50514743dddSAlejandro Lucero 
50614743dddSAlejandro Lucero 	/* Handle V4 additions */
50714743dddSAlejandro Lucero 	efx_devlink_info_running_v4(efx, req, flags, outbuf);
50814743dddSAlejandro Lucero 
50914743dddSAlejandro Lucero 	if (outlength < MC_CMD_GET_VERSION_V5_OUT_LEN)
51014743dddSAlejandro Lucero 		return 0;
51114743dddSAlejandro Lucero 
51214743dddSAlejandro Lucero 	/* Handle V5 additions */
51314743dddSAlejandro Lucero 	efx_devlink_info_running_v5(efx, req, flags, outbuf);
51414743dddSAlejandro Lucero 
51514743dddSAlejandro Lucero 	return 0;
51614743dddSAlejandro Lucero }
51714743dddSAlejandro Lucero 
51814743dddSAlejandro Lucero #define EFX_MAX_SERIALNUM_LEN	(ETH_ALEN * 2 + 1)
51914743dddSAlejandro Lucero 
52014743dddSAlejandro Lucero static int efx_devlink_info_board_cfg(struct efx_nic *efx,
52114743dddSAlejandro Lucero 				      struct devlink_info_req *req)
52214743dddSAlejandro Lucero {
52314743dddSAlejandro Lucero 	char sn[EFX_MAX_SERIALNUM_LEN];
52414743dddSAlejandro Lucero 	u8 mac_address[ETH_ALEN];
52514743dddSAlejandro Lucero 	int rc;
52614743dddSAlejandro Lucero 
52714743dddSAlejandro Lucero 	rc = efx_mcdi_get_board_cfg(efx, (u8 *)mac_address, NULL, NULL);
52814743dddSAlejandro Lucero 	if (!rc) {
52914743dddSAlejandro Lucero 		snprintf(sn, EFX_MAX_SERIALNUM_LEN, "%pm", mac_address);
53014743dddSAlejandro Lucero 		devlink_info_serial_number_put(req, sn);
53114743dddSAlejandro Lucero 	}
53214743dddSAlejandro Lucero 	return rc;
53314743dddSAlejandro Lucero }
53414743dddSAlejandro Lucero 
53514743dddSAlejandro Lucero static int efx_devlink_info_get(struct devlink *devlink,
53614743dddSAlejandro Lucero 				struct devlink_info_req *req,
53714743dddSAlejandro Lucero 				struct netlink_ext_ack *extack)
53814743dddSAlejandro Lucero {
53914743dddSAlejandro Lucero 	struct efx_devlink *devlink_private = devlink_priv(devlink);
54014743dddSAlejandro Lucero 	struct efx_nic *efx = devlink_private->efx;
54114743dddSAlejandro Lucero 	int rc;
54214743dddSAlejandro Lucero 
54314743dddSAlejandro Lucero 	/* Several different MCDI commands are used. We report first error
54414743dddSAlejandro Lucero 	 * through extack returning at that point. Specific error
54514743dddSAlejandro Lucero 	 * information via system messages.
54614743dddSAlejandro Lucero 	 */
54714743dddSAlejandro Lucero 	rc = efx_devlink_info_board_cfg(efx, req);
54814743dddSAlejandro Lucero 	if (rc) {
54914743dddSAlejandro Lucero 		NL_SET_ERR_MSG_MOD(extack, "Getting board info failed");
55014743dddSAlejandro Lucero 		return rc;
55114743dddSAlejandro Lucero 	}
55214743dddSAlejandro Lucero 	rc = efx_devlink_info_stored_versions(efx, req);
55314743dddSAlejandro Lucero 	if (rc) {
55414743dddSAlejandro Lucero 		NL_SET_ERR_MSG_MOD(extack, "Getting stored versions failed");
55514743dddSAlejandro Lucero 		return rc;
55614743dddSAlejandro Lucero 	}
55714743dddSAlejandro Lucero 	rc = efx_devlink_info_running_versions(efx, req);
55814743dddSAlejandro Lucero 	if (rc) {
55914743dddSAlejandro Lucero 		NL_SET_ERR_MSG_MOD(extack, "Getting running versions failed");
56014743dddSAlejandro Lucero 		return rc;
56114743dddSAlejandro Lucero 	}
56214743dddSAlejandro Lucero 
56314743dddSAlejandro Lucero 	return 0;
56414743dddSAlejandro Lucero }
56514743dddSAlejandro Lucero 
566fa34a514SAlejandro Lucero static const struct devlink_ops sfc_devlink_ops = {
56714743dddSAlejandro Lucero 	.info_get			= efx_devlink_info_get,
568*fa78b017SAlejandro Lucero #ifdef CONFIG_SFC_SRIOV
569*fa78b017SAlejandro Lucero 	.port_function_hw_addr_get	= efx_devlink_port_addr_get,
570*fa78b017SAlejandro Lucero #endif
571fa34a514SAlejandro Lucero };
572fa34a514SAlejandro Lucero 
57325414b2aSAlejandro Lucero #ifdef CONFIG_SFC_SRIOV
57425414b2aSAlejandro Lucero static struct devlink_port *ef100_set_devlink_port(struct efx_nic *efx, u32 idx)
57525414b2aSAlejandro Lucero {
57625414b2aSAlejandro Lucero 	struct mae_mport_desc *mport;
57725414b2aSAlejandro Lucero 	u32 id;
57825414b2aSAlejandro Lucero 	int rc;
57925414b2aSAlejandro Lucero 
58025414b2aSAlejandro Lucero 	if (efx_mae_lookup_mport(efx, idx, &id)) {
58125414b2aSAlejandro Lucero 		/* This should not happen. */
58225414b2aSAlejandro Lucero 		if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
58325414b2aSAlejandro Lucero 			pci_warn_once(efx->pci_dev, "No mport ID found for PF.\n");
58425414b2aSAlejandro Lucero 		else
58525414b2aSAlejandro Lucero 			pci_warn_once(efx->pci_dev, "No mport ID found for VF %u.\n",
58625414b2aSAlejandro Lucero 				      idx);
58725414b2aSAlejandro Lucero 		return NULL;
58825414b2aSAlejandro Lucero 	}
58925414b2aSAlejandro Lucero 
59025414b2aSAlejandro Lucero 	mport = efx_mae_get_mport(efx, id);
59125414b2aSAlejandro Lucero 	if (!mport) {
59225414b2aSAlejandro Lucero 		/* This should not happen. */
59325414b2aSAlejandro Lucero 		if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
59425414b2aSAlejandro Lucero 			pci_warn_once(efx->pci_dev, "No mport found for PF.\n");
59525414b2aSAlejandro Lucero 		else
59625414b2aSAlejandro Lucero 			pci_warn_once(efx->pci_dev, "No mport found for VF %u.\n",
59725414b2aSAlejandro Lucero 				      idx);
59825414b2aSAlejandro Lucero 		return NULL;
59925414b2aSAlejandro Lucero 	}
60025414b2aSAlejandro Lucero 
60125414b2aSAlejandro Lucero 	rc = efx_devlink_add_port(efx, mport);
60225414b2aSAlejandro Lucero 	if (rc) {
60325414b2aSAlejandro Lucero 		if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
60425414b2aSAlejandro Lucero 			pci_warn(efx->pci_dev,
60525414b2aSAlejandro Lucero 				 "devlink port creation for PF failed.\n");
60625414b2aSAlejandro Lucero 		else
60725414b2aSAlejandro Lucero 			pci_warn(efx->pci_dev,
60825414b2aSAlejandro Lucero 				 "devlink_port creationg for VF %u failed.\n",
60925414b2aSAlejandro Lucero 				 idx);
61025414b2aSAlejandro Lucero 		return NULL;
61125414b2aSAlejandro Lucero 	}
61225414b2aSAlejandro Lucero 
61325414b2aSAlejandro Lucero 	return &mport->dl_port;
61425414b2aSAlejandro Lucero }
61525414b2aSAlejandro Lucero 
61625414b2aSAlejandro Lucero void ef100_rep_set_devlink_port(struct efx_rep *efv)
61725414b2aSAlejandro Lucero {
61825414b2aSAlejandro Lucero 	efv->dl_port = ef100_set_devlink_port(efv->parent, efv->idx);
61925414b2aSAlejandro Lucero }
62025414b2aSAlejandro Lucero 
62125414b2aSAlejandro Lucero void ef100_pf_set_devlink_port(struct efx_nic *efx)
62225414b2aSAlejandro Lucero {
62325414b2aSAlejandro Lucero 	efx->dl_port = ef100_set_devlink_port(efx, MAE_MPORT_DESC_VF_IDX_NULL);
62425414b2aSAlejandro Lucero }
62525414b2aSAlejandro Lucero 
62625414b2aSAlejandro Lucero void ef100_rep_unset_devlink_port(struct efx_rep *efv)
62725414b2aSAlejandro Lucero {
62825414b2aSAlejandro Lucero 	efx_devlink_del_port(efv->dl_port);
62925414b2aSAlejandro Lucero }
63025414b2aSAlejandro Lucero 
63125414b2aSAlejandro Lucero void ef100_pf_unset_devlink_port(struct efx_nic *efx)
63225414b2aSAlejandro Lucero {
63325414b2aSAlejandro Lucero 	efx_devlink_del_port(efx->dl_port);
63425414b2aSAlejandro Lucero }
63525414b2aSAlejandro Lucero #endif
63625414b2aSAlejandro Lucero 
637fa34a514SAlejandro Lucero void efx_fini_devlink_lock(struct efx_nic *efx)
638fa34a514SAlejandro Lucero {
639fa34a514SAlejandro Lucero 	if (efx->devlink)
640fa34a514SAlejandro Lucero 		devl_lock(efx->devlink);
641fa34a514SAlejandro Lucero }
642fa34a514SAlejandro Lucero 
643fa34a514SAlejandro Lucero void efx_fini_devlink_and_unlock(struct efx_nic *efx)
644fa34a514SAlejandro Lucero {
645fa34a514SAlejandro Lucero 	if (efx->devlink) {
646fa34a514SAlejandro Lucero 		devl_unregister(efx->devlink);
647fa34a514SAlejandro Lucero 		devl_unlock(efx->devlink);
648fa34a514SAlejandro Lucero 		devlink_free(efx->devlink);
649fa34a514SAlejandro Lucero 		efx->devlink = NULL;
650fa34a514SAlejandro Lucero 	}
651fa34a514SAlejandro Lucero }
652fa34a514SAlejandro Lucero 
653fa34a514SAlejandro Lucero int efx_probe_devlink_and_lock(struct efx_nic *efx)
654fa34a514SAlejandro Lucero {
655fa34a514SAlejandro Lucero 	struct efx_devlink *devlink_private;
656fa34a514SAlejandro Lucero 
657fa34a514SAlejandro Lucero 	if (efx->type->is_vf)
658fa34a514SAlejandro Lucero 		return 0;
659fa34a514SAlejandro Lucero 
660fa34a514SAlejandro Lucero 	efx->devlink = devlink_alloc(&sfc_devlink_ops,
661fa34a514SAlejandro Lucero 				     sizeof(struct efx_devlink),
662fa34a514SAlejandro Lucero 				     &efx->pci_dev->dev);
663fa34a514SAlejandro Lucero 	if (!efx->devlink)
664fa34a514SAlejandro Lucero 		return -ENOMEM;
665fa34a514SAlejandro Lucero 
666fa34a514SAlejandro Lucero 	devl_lock(efx->devlink);
667fa34a514SAlejandro Lucero 	devlink_private = devlink_priv(efx->devlink);
668fa34a514SAlejandro Lucero 	devlink_private->efx = efx;
669fa34a514SAlejandro Lucero 
670fa34a514SAlejandro Lucero 	devl_register(efx->devlink);
671fa34a514SAlejandro Lucero 
672fa34a514SAlejandro Lucero 	return 0;
673fa34a514SAlejandro Lucero }
674fa34a514SAlejandro Lucero 
675fa34a514SAlejandro Lucero void efx_probe_devlink_unlock(struct efx_nic *efx)
676fa34a514SAlejandro Lucero {
677fa34a514SAlejandro Lucero 	if (!efx->devlink)
678fa34a514SAlejandro Lucero 		return;
679fa34a514SAlejandro Lucero 
680fa34a514SAlejandro Lucero 	devl_unlock(efx->devlink);
681fa34a514SAlejandro Lucero }
682