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 	if (rc) {
175 		netif_err(efx, drv, efx->net_dev, "mcdi nvram %s: failed\n",
176 			  version_name);
177 		return rc;
178 	}
179 
180 	snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", version[0],
181 		 version[1], version[2], version[3]);
182 	devlink_info_version_stored_put(req, version_name, buf);
183 
184 	return 0;
185 }
186 
187 static int efx_devlink_info_stored_versions(struct efx_nic *efx,
188 					    struct devlink_info_req *req)
189 {
190 	int rc;
191 
192 	rc = efx_devlink_info_nvram_partition(efx, req,
193 					      NVRAM_PARTITION_TYPE_BUNDLE,
194 					      DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID);
195 	if (rc)
196 		return rc;
197 
198 	rc = efx_devlink_info_nvram_partition(efx, req,
199 					      NVRAM_PARTITION_TYPE_MC_FIRMWARE,
200 					      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT);
201 	if (rc)
202 		return rc;
203 
204 	rc = efx_devlink_info_nvram_partition(efx, req,
205 					      NVRAM_PARTITION_TYPE_SUC_FIRMWARE,
206 					      EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC);
207 	if (rc)
208 		return rc;
209 
210 	rc = efx_devlink_info_nvram_partition(efx, req,
211 					      NVRAM_PARTITION_TYPE_EXPANSION_ROM,
212 					      EFX_DEVLINK_INFO_VERSION_FW_EXPROM);
213 	if (rc)
214 		return rc;
215 
216 	rc = efx_devlink_info_nvram_partition(efx, req,
217 					      NVRAM_PARTITION_TYPE_EXPANSION_UEFI,
218 					      EFX_DEVLINK_INFO_VERSION_FW_UEFI);
219 	return rc;
220 }
221 
222 #define EFX_VER_FLAG(_f)	\
223 	(MC_CMD_GET_VERSION_V5_OUT_ ## _f ## _PRESENT_LBN)
224 
225 static void efx_devlink_info_running_v2(struct efx_nic *efx,
226 					struct devlink_info_req *req,
227 					unsigned int flags, efx_dword_t *outbuf)
228 {
229 	char buf[EFX_MAX_VERSION_INFO_LEN];
230 	union {
231 		const __le32 *dwords;
232 		const __le16 *words;
233 		const char *str;
234 	} ver;
235 	struct rtc_time build_date;
236 	unsigned int build_id;
237 	size_t offset;
238 	__maybe_unused u64 tstamp;
239 
240 	if (flags & BIT(EFX_VER_FLAG(BOARD_EXT_INFO))) {
241 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%s",
242 			 MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_NAME));
243 		devlink_info_version_fixed_put(req,
244 					       DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
245 					       buf);
246 
247 		/* Favour full board version if present (in V5 or later) */
248 		if (~flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) {
249 			snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u",
250 				 MCDI_DWORD(outbuf,
251 					    GET_VERSION_V2_OUT_BOARD_REVISION));
252 			devlink_info_version_fixed_put(req,
253 						       DEVLINK_INFO_VERSION_GENERIC_BOARD_REV,
254 						       buf);
255 		}
256 
257 		ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_SERIAL);
258 		if (ver.str[0])
259 			devlink_info_board_serial_number_put(req, ver.str);
260 	}
261 
262 	if (flags & BIT(EFX_VER_FLAG(FPGA_EXT_INFO))) {
263 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
264 						GET_VERSION_V2_OUT_FPGA_VERSION);
265 		offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u_%c%u",
266 				  le32_to_cpu(ver.dwords[0]),
267 				  'A' + le32_to_cpu(ver.dwords[1]),
268 				  le32_to_cpu(ver.dwords[2]));
269 
270 		ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_FPGA_EXTRA);
271 		if (ver.str[0])
272 			snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
273 				 " (%s)", ver.str);
274 
275 		devlink_info_version_running_put(req,
276 						 EFX_DEVLINK_INFO_VERSION_FPGA_REV,
277 						 buf);
278 	}
279 
280 	if (flags & BIT(EFX_VER_FLAG(CMC_EXT_INFO))) {
281 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
282 						GET_VERSION_V2_OUT_CMCFW_VERSION);
283 		offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
284 				  le32_to_cpu(ver.dwords[0]),
285 				  le32_to_cpu(ver.dwords[1]),
286 				  le32_to_cpu(ver.dwords[2]),
287 				  le32_to_cpu(ver.dwords[3]));
288 
289 #ifdef CONFIG_RTC_LIB
290 		tstamp = MCDI_QWORD(outbuf,
291 				    GET_VERSION_V2_OUT_CMCFW_BUILD_DATE);
292 		if (tstamp) {
293 			rtc_time64_to_tm(tstamp, &build_date);
294 			snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
295 				 " (%ptRd)", &build_date);
296 		}
297 #endif
298 
299 		devlink_info_version_running_put(req,
300 						 EFX_DEVLINK_INFO_VERSION_FW_MGMT_CMC,
301 						 buf);
302 	}
303 
304 	ver.words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_V2_OUT_VERSION);
305 	offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
306 			  le16_to_cpu(ver.words[0]), le16_to_cpu(ver.words[1]),
307 			  le16_to_cpu(ver.words[2]), le16_to_cpu(ver.words[3]));
308 	if (flags & BIT(EFX_VER_FLAG(MCFW_EXT_INFO))) {
309 		build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_ID);
310 		snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
311 			 " (%x) %s", build_id,
312 			 MCDI_PTR(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_NAME));
313 	}
314 	devlink_info_version_running_put(req,
315 					 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT,
316 					 buf);
317 
318 	if (flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) {
319 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
320 						GET_VERSION_V2_OUT_SUCFW_VERSION);
321 #ifdef CONFIG_RTC_LIB
322 		tstamp = MCDI_QWORD(outbuf,
323 				    GET_VERSION_V2_OUT_SUCFW_BUILD_DATE);
324 		rtc_time64_to_tm(tstamp, &build_date);
325 #else
326 		memset(&build_date, 0, sizeof(build_date));
327 #endif
328 		build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_SUCFW_CHIP_ID);
329 
330 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN,
331 			 "%u.%u.%u.%u type %x (%ptRd)",
332 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
333 			 le32_to_cpu(ver.dwords[2]), le32_to_cpu(ver.dwords[3]),
334 			 build_id, &build_date);
335 
336 		devlink_info_version_running_put(req,
337 						 EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC,
338 						 buf);
339 	}
340 }
341 
342 static void efx_devlink_info_running_v3(struct efx_nic *efx,
343 					struct devlink_info_req *req,
344 					unsigned int flags, efx_dword_t *outbuf)
345 {
346 	char buf[EFX_MAX_VERSION_INFO_LEN];
347 	union {
348 		const __le32 *dwords;
349 		const __le16 *words;
350 		const char *str;
351 	} ver;
352 
353 	if (flags & BIT(EFX_VER_FLAG(DATAPATH_HW_VERSION))) {
354 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
355 						GET_VERSION_V3_OUT_DATAPATH_HW_VERSION);
356 
357 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u",
358 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
359 			 le32_to_cpu(ver.dwords[2]));
360 
361 		devlink_info_version_running_put(req,
362 						 EFX_DEVLINK_INFO_VERSION_DATAPATH_HW,
363 						 buf);
364 	}
365 
366 	if (flags & BIT(EFX_VER_FLAG(DATAPATH_FW_VERSION))) {
367 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
368 						GET_VERSION_V3_OUT_DATAPATH_FW_VERSION);
369 
370 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u",
371 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
372 			 le32_to_cpu(ver.dwords[2]));
373 
374 		devlink_info_version_running_put(req,
375 						 EFX_DEVLINK_INFO_VERSION_DATAPATH_FW,
376 						 buf);
377 	}
378 }
379 
380 static void efx_devlink_info_running_v4(struct efx_nic *efx,
381 					struct devlink_info_req *req,
382 					unsigned int flags, efx_dword_t *outbuf)
383 {
384 	char buf[EFX_MAX_VERSION_INFO_LEN];
385 	union {
386 		const __le32 *dwords;
387 		const __le16 *words;
388 		const char *str;
389 	} ver;
390 
391 	if (flags & BIT(EFX_VER_FLAG(SOC_BOOT_VERSION))) {
392 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
393 						GET_VERSION_V4_OUT_SOC_BOOT_VERSION);
394 
395 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
396 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
397 			 le32_to_cpu(ver.dwords[2]),
398 			 le32_to_cpu(ver.dwords[3]));
399 
400 		devlink_info_version_running_put(req,
401 						 EFX_DEVLINK_INFO_VERSION_SOC_BOOT,
402 						 buf);
403 	}
404 
405 	if (flags & BIT(EFX_VER_FLAG(SOC_UBOOT_VERSION))) {
406 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
407 						GET_VERSION_V4_OUT_SOC_UBOOT_VERSION);
408 
409 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
410 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
411 			 le32_to_cpu(ver.dwords[2]),
412 			 le32_to_cpu(ver.dwords[3]));
413 
414 		devlink_info_version_running_put(req,
415 						 EFX_DEVLINK_INFO_VERSION_SOC_UBOOT,
416 						 buf);
417 	}
418 
419 	if (flags & BIT(EFX_VER_FLAG(SOC_MAIN_ROOTFS_VERSION))) {
420 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
421 					GET_VERSION_V4_OUT_SOC_MAIN_ROOTFS_VERSION);
422 
423 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
424 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
425 			 le32_to_cpu(ver.dwords[2]),
426 			 le32_to_cpu(ver.dwords[3]));
427 
428 		devlink_info_version_running_put(req,
429 						 EFX_DEVLINK_INFO_VERSION_SOC_MAIN,
430 						 buf);
431 	}
432 
433 	if (flags & BIT(EFX_VER_FLAG(SOC_RECOVERY_BUILDROOT_VERSION))) {
434 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
435 						GET_VERSION_V4_OUT_SOC_RECOVERY_BUILDROOT_VERSION);
436 
437 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
438 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
439 			 le32_to_cpu(ver.dwords[2]),
440 			 le32_to_cpu(ver.dwords[3]));
441 
442 		devlink_info_version_running_put(req,
443 						 EFX_DEVLINK_INFO_VERSION_SOC_RECOVERY,
444 						 buf);
445 	}
446 
447 	if (flags & BIT(EFX_VER_FLAG(SUCFW_VERSION)) &&
448 	    ~flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) {
449 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
450 						GET_VERSION_V4_OUT_SUCFW_VERSION);
451 
452 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
453 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
454 			 le32_to_cpu(ver.dwords[2]),
455 			 le32_to_cpu(ver.dwords[3]));
456 
457 		devlink_info_version_running_put(req,
458 						 EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC,
459 						 buf);
460 	}
461 }
462 
463 static void efx_devlink_info_running_v5(struct efx_nic *efx,
464 					struct devlink_info_req *req,
465 					unsigned int flags, efx_dword_t *outbuf)
466 {
467 	char buf[EFX_MAX_VERSION_INFO_LEN];
468 	union {
469 		const __le32 *dwords;
470 		const __le16 *words;
471 		const char *str;
472 	} ver;
473 
474 	if (flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) {
475 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
476 						GET_VERSION_V5_OUT_BOARD_VERSION);
477 
478 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
479 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
480 			 le32_to_cpu(ver.dwords[2]),
481 			 le32_to_cpu(ver.dwords[3]));
482 
483 		devlink_info_version_running_put(req,
484 						 DEVLINK_INFO_VERSION_GENERIC_BOARD_REV,
485 						 buf);
486 	}
487 
488 	if (flags & BIT(EFX_VER_FLAG(BUNDLE_VERSION))) {
489 		ver.dwords = (__le32 *)MCDI_PTR(outbuf,
490 						GET_VERSION_V5_OUT_BUNDLE_VERSION);
491 
492 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
493 			 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
494 			 le32_to_cpu(ver.dwords[2]),
495 			 le32_to_cpu(ver.dwords[3]));
496 
497 		devlink_info_version_running_put(req,
498 						 DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
499 						 buf);
500 	}
501 }
502 
503 static int efx_devlink_info_running_versions(struct efx_nic *efx,
504 					     struct devlink_info_req *req)
505 {
506 	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_VERSION_V5_OUT_LEN);
507 	MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_VERSION_EXT_IN_LEN);
508 	char buf[EFX_MAX_VERSION_INFO_LEN];
509 	union {
510 		const __le32 *dwords;
511 		const __le16 *words;
512 		const char *str;
513 	} ver;
514 	size_t outlength;
515 	unsigned int flags;
516 	int rc;
517 
518 	rc = efx_mcdi_rpc(efx, MC_CMD_GET_VERSION, inbuf, sizeof(inbuf),
519 			  outbuf, sizeof(outbuf), &outlength);
520 	if (rc || outlength < MC_CMD_GET_VERSION_OUT_LEN) {
521 		netif_err(efx, drv, efx->net_dev,
522 			  "mcdi MC_CMD_GET_VERSION failed\n");
523 		return rc;
524 	}
525 
526 	/* Handle previous output */
527 	if (outlength < MC_CMD_GET_VERSION_V2_OUT_LEN) {
528 		ver.words = (__le16 *)MCDI_PTR(outbuf,
529 					       GET_VERSION_EXT_OUT_VERSION);
530 		snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
531 			 le16_to_cpu(ver.words[0]),
532 			 le16_to_cpu(ver.words[1]),
533 			 le16_to_cpu(ver.words[2]),
534 			 le16_to_cpu(ver.words[3]));
535 
536 		devlink_info_version_running_put(req,
537 						 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT,
538 						 buf);
539 		return 0;
540 	}
541 
542 	/* Handle V2 additions */
543 	flags = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_FLAGS);
544 	efx_devlink_info_running_v2(efx, req, flags, outbuf);
545 
546 	if (outlength < MC_CMD_GET_VERSION_V3_OUT_LEN)
547 		return 0;
548 
549 	/* Handle V3 additions */
550 	efx_devlink_info_running_v3(efx, req, flags, outbuf);
551 
552 	if (outlength < MC_CMD_GET_VERSION_V4_OUT_LEN)
553 		return 0;
554 
555 	/* Handle V4 additions */
556 	efx_devlink_info_running_v4(efx, req, flags, outbuf);
557 
558 	if (outlength < MC_CMD_GET_VERSION_V5_OUT_LEN)
559 		return 0;
560 
561 	/* Handle V5 additions */
562 	efx_devlink_info_running_v5(efx, req, flags, outbuf);
563 
564 	return 0;
565 }
566 
567 #define EFX_MAX_SERIALNUM_LEN	(ETH_ALEN * 2 + 1)
568 
569 static int efx_devlink_info_board_cfg(struct efx_nic *efx,
570 				      struct devlink_info_req *req)
571 {
572 	char sn[EFX_MAX_SERIALNUM_LEN];
573 	u8 mac_address[ETH_ALEN];
574 	int rc;
575 
576 	rc = efx_mcdi_get_board_cfg(efx, (u8 *)mac_address, NULL, NULL);
577 	if (!rc) {
578 		snprintf(sn, EFX_MAX_SERIALNUM_LEN, "%pm", mac_address);
579 		devlink_info_serial_number_put(req, sn);
580 	}
581 	return rc;
582 }
583 
584 static int efx_devlink_info_get(struct devlink *devlink,
585 				struct devlink_info_req *req,
586 				struct netlink_ext_ack *extack)
587 {
588 	struct efx_devlink *devlink_private = devlink_priv(devlink);
589 	struct efx_nic *efx = devlink_private->efx;
590 	int rc;
591 
592 	/* Several different MCDI commands are used. We report first error
593 	 * through extack returning at that point. Specific error
594 	 * information via system messages.
595 	 */
596 	rc = efx_devlink_info_board_cfg(efx, req);
597 	if (rc) {
598 		NL_SET_ERR_MSG_MOD(extack, "Getting board info failed");
599 		return rc;
600 	}
601 	rc = efx_devlink_info_stored_versions(efx, req);
602 	if (rc) {
603 		NL_SET_ERR_MSG_MOD(extack, "Getting stored versions failed");
604 		return rc;
605 	}
606 	rc = efx_devlink_info_running_versions(efx, req);
607 	if (rc) {
608 		NL_SET_ERR_MSG_MOD(extack, "Getting running versions failed");
609 		return rc;
610 	}
611 
612 	return 0;
613 }
614 
615 static const struct devlink_ops sfc_devlink_ops = {
616 	.info_get			= efx_devlink_info_get,
617 #ifdef CONFIG_SFC_SRIOV
618 	.port_function_hw_addr_get	= efx_devlink_port_addr_get,
619 	.port_function_hw_addr_set	= efx_devlink_port_addr_set,
620 #endif
621 };
622 
623 #ifdef CONFIG_SFC_SRIOV
624 static struct devlink_port *ef100_set_devlink_port(struct efx_nic *efx, u32 idx)
625 {
626 	struct mae_mport_desc *mport;
627 	u32 id;
628 	int rc;
629 
630 	if (efx_mae_lookup_mport(efx, idx, &id)) {
631 		/* This should not happen. */
632 		if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
633 			pci_warn_once(efx->pci_dev, "No mport ID found for PF.\n");
634 		else
635 			pci_warn_once(efx->pci_dev, "No mport ID found for VF %u.\n",
636 				      idx);
637 		return NULL;
638 	}
639 
640 	mport = efx_mae_get_mport(efx, id);
641 	if (!mport) {
642 		/* This should not happen. */
643 		if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
644 			pci_warn_once(efx->pci_dev, "No mport found for PF.\n");
645 		else
646 			pci_warn_once(efx->pci_dev, "No mport found for VF %u.\n",
647 				      idx);
648 		return NULL;
649 	}
650 
651 	rc = efx_devlink_add_port(efx, mport);
652 	if (rc) {
653 		if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
654 			pci_warn(efx->pci_dev,
655 				 "devlink port creation for PF failed.\n");
656 		else
657 			pci_warn(efx->pci_dev,
658 				 "devlink_port creation for VF %u failed.\n",
659 				 idx);
660 		return NULL;
661 	}
662 
663 	return &mport->dl_port;
664 }
665 
666 void ef100_rep_set_devlink_port(struct efx_rep *efv)
667 {
668 	efv->dl_port = ef100_set_devlink_port(efv->parent, efv->idx);
669 }
670 
671 void ef100_pf_set_devlink_port(struct efx_nic *efx)
672 {
673 	efx->dl_port = ef100_set_devlink_port(efx, MAE_MPORT_DESC_VF_IDX_NULL);
674 }
675 
676 void ef100_rep_unset_devlink_port(struct efx_rep *efv)
677 {
678 	efx_devlink_del_port(efv->dl_port);
679 }
680 
681 void ef100_pf_unset_devlink_port(struct efx_nic *efx)
682 {
683 	efx_devlink_del_port(efx->dl_port);
684 }
685 #endif
686 
687 void efx_fini_devlink_lock(struct efx_nic *efx)
688 {
689 	if (efx->devlink)
690 		devl_lock(efx->devlink);
691 }
692 
693 void efx_fini_devlink_and_unlock(struct efx_nic *efx)
694 {
695 	if (efx->devlink) {
696 		devl_unregister(efx->devlink);
697 		devl_unlock(efx->devlink);
698 		devlink_free(efx->devlink);
699 		efx->devlink = NULL;
700 	}
701 }
702 
703 int efx_probe_devlink_and_lock(struct efx_nic *efx)
704 {
705 	struct efx_devlink *devlink_private;
706 
707 	if (efx->type->is_vf)
708 		return 0;
709 
710 	efx->devlink = devlink_alloc(&sfc_devlink_ops,
711 				     sizeof(struct efx_devlink),
712 				     &efx->pci_dev->dev);
713 	if (!efx->devlink)
714 		return -ENOMEM;
715 
716 	devl_lock(efx->devlink);
717 	devlink_private = devlink_priv(efx->devlink);
718 	devlink_private->efx = efx;
719 
720 	devl_register(efx->devlink);
721 
722 	return 0;
723 }
724 
725 void efx_probe_devlink_unlock(struct efx_nic *efx)
726 {
727 	if (!efx->devlink)
728 		return;
729 
730 	devl_unlock(efx->devlink);
731 }
732