xref: /linux/drivers/net/ethernet/sfc/efx_devlink.c (revision 84b9b44b)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /****************************************************************************
3  * Driver for AMD network controllers and boards
4  * Copyright (C) 2023, Advanced Micro Devices, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published
8  * by the Free Software Foundation, incorporated herein by reference.
9  */
10 
11 #include "net_driver.h"
12 #include "ef100_nic.h"
13 #include "efx_devlink.h"
14 #include <linux/rtc.h>
15 #include "mcdi.h"
16 #include "mcdi_functions.h"
17 #include "mcdi_pcol.h"
18 #ifdef CONFIG_SFC_SRIOV
19 #include "mae.h"
20 #include "ef100_rep.h"
21 #endif
22 
23 struct efx_devlink {
24 	struct efx_nic *efx;
25 };
26 
27 #ifdef CONFIG_SFC_SRIOV
28 static void efx_devlink_del_port(struct devlink_port *dl_port)
29 {
30 	if (!dl_port)
31 		return;
32 	devl_port_unregister(dl_port);
33 }
34 
35 static int efx_devlink_add_port(struct efx_nic *efx,
36 				struct mae_mport_desc *mport)
37 {
38 	bool external = false;
39 
40 	if (!ef100_mport_on_local_intf(efx, mport))
41 		external = true;
42 
43 	switch (mport->mport_type) {
44 	case MAE_MPORT_DESC_MPORT_TYPE_VNIC:
45 		if (mport->vf_idx != MAE_MPORT_DESC_VF_IDX_NULL)
46 			devlink_port_attrs_pci_vf_set(&mport->dl_port, 0, mport->pf_idx,
47 						      mport->vf_idx,
48 						      external);
49 		else
50 			devlink_port_attrs_pci_pf_set(&mport->dl_port, 0, mport->pf_idx,
51 						      external);
52 		break;
53 	default:
54 		/* MAE_MPORT_DESC_MPORT_ALIAS and UNDEFINED */
55 		return 0;
56 	}
57 
58 	mport->dl_port.index = mport->mport_id;
59 
60 	return devl_port_register(efx->devlink, &mport->dl_port, mport->mport_id);
61 }
62 
63 static int efx_devlink_port_addr_get(struct devlink_port *port, u8 *hw_addr,
64 				     int *hw_addr_len,
65 				     struct netlink_ext_ack *extack)
66 {
67 	struct efx_devlink *devlink = devlink_priv(port->devlink);
68 	struct mae_mport_desc *mport_desc;
69 	efx_qword_t pciefn;
70 	u32 client_id;
71 	int rc = 0;
72 
73 	mport_desc = container_of(port, struct mae_mport_desc, dl_port);
74 
75 	if (!ef100_mport_on_local_intf(devlink->efx, mport_desc)) {
76 		rc = -EINVAL;
77 		NL_SET_ERR_MSG_FMT(extack,
78 				   "Port not on local interface (mport: %u)",
79 				   mport_desc->mport_id);
80 		goto out;
81 	}
82 
83 	if (ef100_mport_is_vf(mport_desc))
84 		EFX_POPULATE_QWORD_3(pciefn,
85 				     PCIE_FUNCTION_PF, PCIE_FUNCTION_PF_NULL,
86 				     PCIE_FUNCTION_VF, mport_desc->vf_idx,
87 				     PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);
88 	else
89 		EFX_POPULATE_QWORD_3(pciefn,
90 				     PCIE_FUNCTION_PF, mport_desc->pf_idx,
91 				     PCIE_FUNCTION_VF, PCIE_FUNCTION_VF_NULL,
92 				     PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);
93 
94 	rc = efx_ef100_lookup_client_id(devlink->efx, pciefn, &client_id);
95 	if (rc) {
96 		NL_SET_ERR_MSG_FMT(extack,
97 				   "No internal client_ID for port (mport: %u)",
98 				   mport_desc->mport_id);
99 		goto out;
100 	}
101 
102 	rc = ef100_get_mac_address(devlink->efx, hw_addr, client_id, true);
103 	if (rc != 0)
104 		NL_SET_ERR_MSG_FMT(extack,
105 				   "No available MAC for port (mport: %u)",
106 				   mport_desc->mport_id);
107 out:
108 	*hw_addr_len = ETH_ALEN;
109 	return rc;
110 }
111 
112 static int efx_devlink_port_addr_set(struct devlink_port *port,
113 				     const u8 *hw_addr, int hw_addr_len,
114 				     struct netlink_ext_ack *extack)
115 {
116 	MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_CLIENT_MAC_ADDRESSES_IN_LEN(1));
117 	struct efx_devlink *devlink = devlink_priv(port->devlink);
118 	struct mae_mport_desc *mport_desc;
119 	efx_qword_t pciefn;
120 	u32 client_id;
121 	int rc;
122 
123 	mport_desc = container_of(port, struct mae_mport_desc, dl_port);
124 
125 	if (!ef100_mport_is_vf(mport_desc)) {
126 		NL_SET_ERR_MSG_FMT(extack,
127 				   "port mac change not allowed (mport: %u)",
128 				   mport_desc->mport_id);
129 		return -EPERM;
130 	}
131 
132 	EFX_POPULATE_QWORD_3(pciefn,
133 			     PCIE_FUNCTION_PF, PCIE_FUNCTION_PF_NULL,
134 			     PCIE_FUNCTION_VF, mport_desc->vf_idx,
135 			     PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);
136 
137 	rc = efx_ef100_lookup_client_id(devlink->efx, pciefn, &client_id);
138 	if (rc) {
139 		NL_SET_ERR_MSG_FMT(extack,
140 				   "No internal client_ID for port (mport: %u)",
141 				   mport_desc->mport_id);
142 		return rc;
143 	}
144 
145 	MCDI_SET_DWORD(inbuf, SET_CLIENT_MAC_ADDRESSES_IN_CLIENT_HANDLE,
146 		       client_id);
147 
148 	ether_addr_copy(MCDI_PTR(inbuf, SET_CLIENT_MAC_ADDRESSES_IN_MAC_ADDRS),
149 			hw_addr);
150 
151 	rc = efx_mcdi_rpc(devlink->efx, MC_CMD_SET_CLIENT_MAC_ADDRESSES, inbuf,
152 			  sizeof(inbuf), NULL, 0, NULL);
153 	if (rc)
154 		NL_SET_ERR_MSG_FMT(extack,
155 				   "sfc MC_CMD_SET_CLIENT_MAC_ADDRESSES mcdi error (mport: %u)",
156 				   mport_desc->mport_id);
157 
158 	return rc;
159 }
160 
161 #endif
162 
163 static int efx_devlink_info_nvram_partition(struct efx_nic *efx,
164 					    struct devlink_info_req *req,
165 					    unsigned int partition_type,
166 					    const char *version_name)
167 {
168 	char buf[EFX_MAX_VERSION_INFO_LEN];
169 	u16 version[4];
170 	int rc;
171 
172 	rc = efx_mcdi_nvram_metadata(efx, partition_type, NULL, version, NULL,
173 				     0);
174 
175 	/* If the partition does not exist, that is not an error. */
176 	if (rc == -ENOENT)
177 		return 0;
178 
179 	if (rc) {
180 		netif_err(efx, drv, efx->net_dev, "mcdi nvram %s: failed (rc=%d)\n",
181 			  version_name, rc);
182 		return rc;
183 	}
184 
185 	snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", version[0],
186 		 version[1], version[2], version[3]);
187 	devlink_info_version_stored_put(req, version_name, buf);
188 
189 	return 0;
190 }
191 
192 static int efx_devlink_info_stored_versions(struct efx_nic *efx,
193 					    struct devlink_info_req *req)
194 {
195 	int err;
196 
197 	/* We do not care here about the specific error but just if an error
198 	 * happened. The specific error will be reported inside the call
199 	 * through system messages, and if any error happened in any call
200 	 * below, we report it through extack.
201 	 */
202 	err = efx_devlink_info_nvram_partition(efx, req,
203 					       NVRAM_PARTITION_TYPE_BUNDLE,
204 					       DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID);
205 
206 	err |= efx_devlink_info_nvram_partition(efx, req,
207 						NVRAM_PARTITION_TYPE_MC_FIRMWARE,
208 						DEVLINK_INFO_VERSION_GENERIC_FW_MGMT);
209 
210 	err |= efx_devlink_info_nvram_partition(efx, req,
211 						NVRAM_PARTITION_TYPE_SUC_FIRMWARE,
212 						EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC);
213 
214 	err |= efx_devlink_info_nvram_partition(efx, req,
215 						NVRAM_PARTITION_TYPE_EXPANSION_ROM,
216 						EFX_DEVLINK_INFO_VERSION_FW_EXPROM);
217 
218 	err |= efx_devlink_info_nvram_partition(efx, req,
219 						NVRAM_PARTITION_TYPE_EXPANSION_UEFI,
220 						EFX_DEVLINK_INFO_VERSION_FW_UEFI);
221 	return err;
222 }
223 
224 #define EFX_VER_FLAG(_f)	\
225 	(MC_CMD_GET_VERSION_V5_OUT_ ## _f ## _PRESENT_LBN)
226 
227 static void efx_devlink_info_running_v2(struct efx_nic *efx,
228 					struct devlink_info_req *req,
229 					unsigned int flags, efx_dword_t *outbuf)
230 {
231 	char buf[EFX_MAX_VERSION_INFO_LEN];
232 	union {
233 		const __le32 *dwords;
234 		const __le16 *words;
235 		const char *str;
236 	} ver;
237 	struct rtc_time build_date;
238 	unsigned int build_id;
239 	size_t offset;
240 	__maybe_unused u64 tstamp;
241 
242 	if (flags & BIT(EFX_VER_FLAG(BOARD_EXT_INFO))) {
243 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%s",
244 			 MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_NAME));
245 		devlink_info_version_fixed_put(req,
246 					       DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
247 					       buf);
248 
249 		/* Favour full board version if present (in V5 or later) */
250 		if (~flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) {
251 			snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u",
252 				 MCDI_DWORD(outbuf,
253 					    GET_VERSION_V2_OUT_BOARD_REVISION));
254 			devlink_info_version_fixed_put(req,
255 						       DEVLINK_INFO_VERSION_GENERIC_BOARD_REV,
256 						       buf);
257 		}
258 
259 		ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_SERIAL);
260 		if (ver.str[0])
261 			devlink_info_board_serial_number_put(req, ver.str);
262 	}
263 
264 	if (flags & BIT(EFX_VER_FLAG(FPGA_EXT_INFO))) {
265 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
266 						GET_VERSION_V2_OUT_FPGA_VERSION);
267 		offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u_%c%u",
268 				  le32_to_cpu(ver.dwords[0]),
269 				  'A' + le32_to_cpu(ver.dwords[1]),
270 				  le32_to_cpu(ver.dwords[2]));
271 
272 		ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_FPGA_EXTRA);
273 		if (ver.str[0])
274 			snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
275 				 " (%s)", ver.str);
276 
277 		devlink_info_version_running_put(req,
278 						 EFX_DEVLINK_INFO_VERSION_FPGA_REV,
279 						 buf);
280 	}
281 
282 	if (flags & BIT(EFX_VER_FLAG(CMC_EXT_INFO))) {
283 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
284 						GET_VERSION_V2_OUT_CMCFW_VERSION);
285 		offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
286 				  le32_to_cpu(ver.dwords[0]),
287 				  le32_to_cpu(ver.dwords[1]),
288 				  le32_to_cpu(ver.dwords[2]),
289 				  le32_to_cpu(ver.dwords[3]));
290 
291 #ifdef CONFIG_RTC_LIB
292 		tstamp = MCDI_QWORD(outbuf,
293 				    GET_VERSION_V2_OUT_CMCFW_BUILD_DATE);
294 		if (tstamp) {
295 			rtc_time64_to_tm(tstamp, &build_date);
296 			snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
297 				 " (%ptRd)", &build_date);
298 		}
299 #endif
300 
301 		devlink_info_version_running_put(req,
302 						 EFX_DEVLINK_INFO_VERSION_FW_MGMT_CMC,
303 						 buf);
304 	}
305 
306 	ver.words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_V2_OUT_VERSION);
307 	offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
308 			  le16_to_cpu(ver.words[0]), le16_to_cpu(ver.words[1]),
309 			  le16_to_cpu(ver.words[2]), le16_to_cpu(ver.words[3]));
310 	if (flags & BIT(EFX_VER_FLAG(MCFW_EXT_INFO))) {
311 		build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_ID);
312 		snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
313 			 " (%x) %s", build_id,
314 			 MCDI_PTR(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_NAME));
315 	}
316 	devlink_info_version_running_put(req,
317 					 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT,
318 					 buf);
319 
320 	if (flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) {
321 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
322 						GET_VERSION_V2_OUT_SUCFW_VERSION);
323 #ifdef CONFIG_RTC_LIB
324 		tstamp = MCDI_QWORD(outbuf,
325 				    GET_VERSION_V2_OUT_SUCFW_BUILD_DATE);
326 		rtc_time64_to_tm(tstamp, &build_date);
327 #else
328 		memset(&build_date, 0, sizeof(build_date));
329 #endif
330 		build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_SUCFW_CHIP_ID);
331 
332 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN,
333 			 "%u.%u.%u.%u type %x (%ptRd)",
334 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
335 			 le32_to_cpu(ver.dwords[2]), le32_to_cpu(ver.dwords[3]),
336 			 build_id, &build_date);
337 
338 		devlink_info_version_running_put(req,
339 						 EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC,
340 						 buf);
341 	}
342 }
343 
344 static void efx_devlink_info_running_v3(struct efx_nic *efx,
345 					struct devlink_info_req *req,
346 					unsigned int flags, efx_dword_t *outbuf)
347 {
348 	char buf[EFX_MAX_VERSION_INFO_LEN];
349 	union {
350 		const __le32 *dwords;
351 		const __le16 *words;
352 		const char *str;
353 	} ver;
354 
355 	if (flags & BIT(EFX_VER_FLAG(DATAPATH_HW_VERSION))) {
356 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
357 						GET_VERSION_V3_OUT_DATAPATH_HW_VERSION);
358 
359 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u",
360 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
361 			 le32_to_cpu(ver.dwords[2]));
362 
363 		devlink_info_version_running_put(req,
364 						 EFX_DEVLINK_INFO_VERSION_DATAPATH_HW,
365 						 buf);
366 	}
367 
368 	if (flags & BIT(EFX_VER_FLAG(DATAPATH_FW_VERSION))) {
369 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
370 						GET_VERSION_V3_OUT_DATAPATH_FW_VERSION);
371 
372 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u",
373 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
374 			 le32_to_cpu(ver.dwords[2]));
375 
376 		devlink_info_version_running_put(req,
377 						 EFX_DEVLINK_INFO_VERSION_DATAPATH_FW,
378 						 buf);
379 	}
380 }
381 
382 static void efx_devlink_info_running_v4(struct efx_nic *efx,
383 					struct devlink_info_req *req,
384 					unsigned int flags, efx_dword_t *outbuf)
385 {
386 	char buf[EFX_MAX_VERSION_INFO_LEN];
387 	union {
388 		const __le32 *dwords;
389 		const __le16 *words;
390 		const char *str;
391 	} ver;
392 
393 	if (flags & BIT(EFX_VER_FLAG(SOC_BOOT_VERSION))) {
394 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
395 						GET_VERSION_V4_OUT_SOC_BOOT_VERSION);
396 
397 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
398 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
399 			 le32_to_cpu(ver.dwords[2]),
400 			 le32_to_cpu(ver.dwords[3]));
401 
402 		devlink_info_version_running_put(req,
403 						 EFX_DEVLINK_INFO_VERSION_SOC_BOOT,
404 						 buf);
405 	}
406 
407 	if (flags & BIT(EFX_VER_FLAG(SOC_UBOOT_VERSION))) {
408 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
409 						GET_VERSION_V4_OUT_SOC_UBOOT_VERSION);
410 
411 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
412 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
413 			 le32_to_cpu(ver.dwords[2]),
414 			 le32_to_cpu(ver.dwords[3]));
415 
416 		devlink_info_version_running_put(req,
417 						 EFX_DEVLINK_INFO_VERSION_SOC_UBOOT,
418 						 buf);
419 	}
420 
421 	if (flags & BIT(EFX_VER_FLAG(SOC_MAIN_ROOTFS_VERSION))) {
422 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
423 					GET_VERSION_V4_OUT_SOC_MAIN_ROOTFS_VERSION);
424 
425 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
426 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
427 			 le32_to_cpu(ver.dwords[2]),
428 			 le32_to_cpu(ver.dwords[3]));
429 
430 		devlink_info_version_running_put(req,
431 						 EFX_DEVLINK_INFO_VERSION_SOC_MAIN,
432 						 buf);
433 	}
434 
435 	if (flags & BIT(EFX_VER_FLAG(SOC_RECOVERY_BUILDROOT_VERSION))) {
436 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
437 						GET_VERSION_V4_OUT_SOC_RECOVERY_BUILDROOT_VERSION);
438 
439 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
440 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
441 			 le32_to_cpu(ver.dwords[2]),
442 			 le32_to_cpu(ver.dwords[3]));
443 
444 		devlink_info_version_running_put(req,
445 						 EFX_DEVLINK_INFO_VERSION_SOC_RECOVERY,
446 						 buf);
447 	}
448 
449 	if (flags & BIT(EFX_VER_FLAG(SUCFW_VERSION)) &&
450 	    ~flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) {
451 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
452 						GET_VERSION_V4_OUT_SUCFW_VERSION);
453 
454 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
455 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
456 			 le32_to_cpu(ver.dwords[2]),
457 			 le32_to_cpu(ver.dwords[3]));
458 
459 		devlink_info_version_running_put(req,
460 						 EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC,
461 						 buf);
462 	}
463 }
464 
465 static void efx_devlink_info_running_v5(struct efx_nic *efx,
466 					struct devlink_info_req *req,
467 					unsigned int flags, efx_dword_t *outbuf)
468 {
469 	char buf[EFX_MAX_VERSION_INFO_LEN];
470 	union {
471 		const __le32 *dwords;
472 		const __le16 *words;
473 		const char *str;
474 	} ver;
475 
476 	if (flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) {
477 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
478 						GET_VERSION_V5_OUT_BOARD_VERSION);
479 
480 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
481 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
482 			 le32_to_cpu(ver.dwords[2]),
483 			 le32_to_cpu(ver.dwords[3]));
484 
485 		devlink_info_version_running_put(req,
486 						 DEVLINK_INFO_VERSION_GENERIC_BOARD_REV,
487 						 buf);
488 	}
489 
490 	if (flags & BIT(EFX_VER_FLAG(BUNDLE_VERSION))) {
491 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
492 						GET_VERSION_V5_OUT_BUNDLE_VERSION);
493 
494 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
495 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
496 			 le32_to_cpu(ver.dwords[2]),
497 			 le32_to_cpu(ver.dwords[3]));
498 
499 		devlink_info_version_running_put(req,
500 						 DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
501 						 buf);
502 	}
503 }
504 
505 static int efx_devlink_info_running_versions(struct efx_nic *efx,
506 					     struct devlink_info_req *req)
507 {
508 	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_VERSION_V5_OUT_LEN);
509 	MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_VERSION_EXT_IN_LEN);
510 	char buf[EFX_MAX_VERSION_INFO_LEN];
511 	union {
512 		const __le32 *dwords;
513 		const __le16 *words;
514 		const char *str;
515 	} ver;
516 	size_t outlength;
517 	unsigned int flags;
518 	int rc;
519 
520 	rc = efx_mcdi_rpc(efx, MC_CMD_GET_VERSION, inbuf, sizeof(inbuf),
521 			  outbuf, sizeof(outbuf), &outlength);
522 	if (rc || outlength < MC_CMD_GET_VERSION_OUT_LEN) {
523 		netif_err(efx, drv, efx->net_dev,
524 			  "mcdi MC_CMD_GET_VERSION failed\n");
525 		return rc;
526 	}
527 
528 	/* Handle previous output */
529 	if (outlength < MC_CMD_GET_VERSION_V2_OUT_LEN) {
530 		ver.words = (__le16 *)MCDI_PTR(outbuf,
531 					       GET_VERSION_EXT_OUT_VERSION);
532 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
533 			 le16_to_cpu(ver.words[0]),
534 			 le16_to_cpu(ver.words[1]),
535 			 le16_to_cpu(ver.words[2]),
536 			 le16_to_cpu(ver.words[3]));
537 
538 		devlink_info_version_running_put(req,
539 						 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT,
540 						 buf);
541 		return 0;
542 	}
543 
544 	/* Handle V2 additions */
545 	flags = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_FLAGS);
546 	efx_devlink_info_running_v2(efx, req, flags, outbuf);
547 
548 	if (outlength < MC_CMD_GET_VERSION_V3_OUT_LEN)
549 		return 0;
550 
551 	/* Handle V3 additions */
552 	efx_devlink_info_running_v3(efx, req, flags, outbuf);
553 
554 	if (outlength < MC_CMD_GET_VERSION_V4_OUT_LEN)
555 		return 0;
556 
557 	/* Handle V4 additions */
558 	efx_devlink_info_running_v4(efx, req, flags, outbuf);
559 
560 	if (outlength < MC_CMD_GET_VERSION_V5_OUT_LEN)
561 		return 0;
562 
563 	/* Handle V5 additions */
564 	efx_devlink_info_running_v5(efx, req, flags, outbuf);
565 
566 	return 0;
567 }
568 
569 #define EFX_MAX_SERIALNUM_LEN	(ETH_ALEN * 2 + 1)
570 
571 static int efx_devlink_info_board_cfg(struct efx_nic *efx,
572 				      struct devlink_info_req *req)
573 {
574 	char sn[EFX_MAX_SERIALNUM_LEN];
575 	u8 mac_address[ETH_ALEN];
576 	int rc;
577 
578 	rc = efx_mcdi_get_board_cfg(efx, (u8 *)mac_address, NULL, NULL);
579 	if (!rc) {
580 		snprintf(sn, EFX_MAX_SERIALNUM_LEN, "%pm", mac_address);
581 		devlink_info_serial_number_put(req, sn);
582 	}
583 	return rc;
584 }
585 
586 static int efx_devlink_info_get(struct devlink *devlink,
587 				struct devlink_info_req *req,
588 				struct netlink_ext_ack *extack)
589 {
590 	struct efx_devlink *devlink_private = devlink_priv(devlink);
591 	struct efx_nic *efx = devlink_private->efx;
592 	int err;
593 
594 	/* Several different MCDI commands are used. We report if errors
595 	 * happened through extack. Specific error information via system
596 	 * messages inside the calls.
597 	 */
598 	err = efx_devlink_info_board_cfg(efx, req);
599 
600 	err |= efx_devlink_info_stored_versions(efx, req);
601 
602 	err |= efx_devlink_info_running_versions(efx, req);
603 
604 	if (err)
605 		NL_SET_ERR_MSG_MOD(extack, "Errors when getting device info. Check system messages");
606 
607 	return 0;
608 }
609 
610 static const struct devlink_ops sfc_devlink_ops = {
611 	.info_get			= efx_devlink_info_get,
612 #ifdef CONFIG_SFC_SRIOV
613 	.port_function_hw_addr_get	= efx_devlink_port_addr_get,
614 	.port_function_hw_addr_set	= efx_devlink_port_addr_set,
615 #endif
616 };
617 
618 #ifdef CONFIG_SFC_SRIOV
619 static struct devlink_port *ef100_set_devlink_port(struct efx_nic *efx, u32 idx)
620 {
621 	struct mae_mport_desc *mport;
622 	u32 id;
623 	int rc;
624 
625 	if (efx_mae_lookup_mport(efx, idx, &id)) {
626 		/* This should not happen. */
627 		if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
628 			pci_warn_once(efx->pci_dev, "No mport ID found for PF.\n");
629 		else
630 			pci_warn_once(efx->pci_dev, "No mport ID found for VF %u.\n",
631 				      idx);
632 		return NULL;
633 	}
634 
635 	mport = efx_mae_get_mport(efx, id);
636 	if (!mport) {
637 		/* This should not happen. */
638 		if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
639 			pci_warn_once(efx->pci_dev, "No mport found for PF.\n");
640 		else
641 			pci_warn_once(efx->pci_dev, "No mport found for VF %u.\n",
642 				      idx);
643 		return NULL;
644 	}
645 
646 	rc = efx_devlink_add_port(efx, mport);
647 	if (rc) {
648 		if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
649 			pci_warn(efx->pci_dev,
650 				 "devlink port creation for PF failed.\n");
651 		else
652 			pci_warn(efx->pci_dev,
653 				 "devlink_port creation for VF %u failed.\n",
654 				 idx);
655 		return NULL;
656 	}
657 
658 	return &mport->dl_port;
659 }
660 
661 void ef100_rep_set_devlink_port(struct efx_rep *efv)
662 {
663 	efv->dl_port = ef100_set_devlink_port(efv->parent, efv->idx);
664 }
665 
666 void ef100_pf_set_devlink_port(struct efx_nic *efx)
667 {
668 	efx->dl_port = ef100_set_devlink_port(efx, MAE_MPORT_DESC_VF_IDX_NULL);
669 }
670 
671 void ef100_rep_unset_devlink_port(struct efx_rep *efv)
672 {
673 	efx_devlink_del_port(efv->dl_port);
674 }
675 
676 void ef100_pf_unset_devlink_port(struct efx_nic *efx)
677 {
678 	efx_devlink_del_port(efx->dl_port);
679 }
680 #endif
681 
682 void efx_fini_devlink_lock(struct efx_nic *efx)
683 {
684 	if (efx->devlink)
685 		devl_lock(efx->devlink);
686 }
687 
688 void efx_fini_devlink_and_unlock(struct efx_nic *efx)
689 {
690 	if (efx->devlink) {
691 		devl_unregister(efx->devlink);
692 		devl_unlock(efx->devlink);
693 		devlink_free(efx->devlink);
694 		efx->devlink = NULL;
695 	}
696 }
697 
698 int efx_probe_devlink_and_lock(struct efx_nic *efx)
699 {
700 	struct efx_devlink *devlink_private;
701 
702 	if (efx->type->is_vf)
703 		return 0;
704 
705 	efx->devlink = devlink_alloc(&sfc_devlink_ops,
706 				     sizeof(struct efx_devlink),
707 				     &efx->pci_dev->dev);
708 	if (!efx->devlink)
709 		return -ENOMEM;
710 
711 	devl_lock(efx->devlink);
712 	devlink_private = devlink_priv(efx->devlink);
713 	devlink_private->efx = efx;
714 
715 	devl_register(efx->devlink);
716 
717 	return 0;
718 }
719 
720 void efx_probe_devlink_unlock(struct efx_nic *efx)
721 {
722 	if (!efx->devlink)
723 		return;
724 
725 	devl_unlock(efx->devlink);
726 }
727