Merge tag 'cgroup-for-6.4-rc7-fixes' of git://git.kernel.org/pub/scm/linux/kernel...
[platform/kernel/linux-rpi.git] / drivers / net / ethernet / sfc / efx_devlink.c
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 }