Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sfc: add devlink info support for ef100

Add devlink info support for ef100. The information reported is obtained
through the MCDI interface with the specific meaning defined in new
documentation file.

Signed-off-by: Alejandro Lucero <alejandro.lucero-palau@amd.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Acked-by: Martin Habets <habetsm.xilinx@gmail.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Alejandro Lucero and committed by
Paolo Abeni
14743ddd fa34a514

+608
+1
Documentation/networking/devlink/index.rst
··· 66 66 prestera 67 67 iosm 68 68 octeontx2 69 + sfc
+57
Documentation/networking/devlink/sfc.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + =================== 4 + sfc devlink support 5 + =================== 6 + 7 + This document describes the devlink features implemented by the ``sfc`` 8 + device driver for the ef100 device. 9 + 10 + Info versions 11 + ============= 12 + 13 + The ``sfc`` driver reports the following versions 14 + 15 + .. list-table:: devlink info versions implemented 16 + :widths: 5 5 90 17 + 18 + * - Name 19 + - Type 20 + - Description 21 + * - ``fw.mgmt.suc`` 22 + - running 23 + - For boards where the management function is split between multiple 24 + control units, this is the SUC control unit's firmware version. 25 + * - ``fw.mgmt.cmc`` 26 + - running 27 + - For boards where the management function is split between multiple 28 + control units, this is the CMC control unit's firmware version. 29 + * - ``fpga.rev`` 30 + - running 31 + - FPGA design revision. 32 + * - ``fpga.app`` 33 + - running 34 + - Datapath programmable logic version. 35 + * - ``fw.app`` 36 + - running 37 + - Datapath software/microcode/firmware version. 38 + * - ``coproc.boot`` 39 + - running 40 + - SmartNIC application co-processor (APU) first stage boot loader version. 41 + * - ``coproc.uboot`` 42 + - running 43 + - SmartNIC application co-processor (APU) co-operating system loader version. 44 + * - ``coproc.main`` 45 + - running 46 + - SmartNIC application co-processor (APU) main operating system version. 47 + * - ``coproc.recovery`` 48 + - running 49 + - SmartNIC application co-processor (APU) recovery operating system version. 50 + * - ``fw.exprom`` 51 + - running 52 + - Expansion ROM version. For boards where the expansion ROM is split between 53 + multiple images (e.g. PXE and UEFI), this is the specifically the PXE boot 54 + ROM version. 55 + * - ``fw.uefi`` 56 + - running 57 + - UEFI driver version (No UNDI support).
+1
MAINTAINERS
··· 18937 18937 M: Martin Habets <habetsm.xilinx@gmail.com> 18938 18938 L: netdev@vger.kernel.org 18939 18939 S: Supported 18940 + F: Documentation/networking/devlink/sfc.rst 18940 18941 F: drivers/net/ethernet/sfc/ 18941 18942 18942 18943 SFF/SFP/SFP+ MODULE SUPPORT
+457
drivers/net/ethernet/sfc/efx_devlink.c
··· 10 10 11 11 #include "net_driver.h" 12 12 #include "efx_devlink.h" 13 + #include <linux/rtc.h> 14 + #include "mcdi.h" 15 + #include "mcdi_functions.h" 16 + #include "mcdi_pcol.h" 13 17 14 18 struct efx_devlink { 15 19 struct efx_nic *efx; 16 20 }; 17 21 22 + static int efx_devlink_info_nvram_partition(struct efx_nic *efx, 23 + struct devlink_info_req *req, 24 + unsigned int partition_type, 25 + const char *version_name) 26 + { 27 + char buf[EFX_MAX_VERSION_INFO_LEN]; 28 + u16 version[4]; 29 + int rc; 30 + 31 + rc = efx_mcdi_nvram_metadata(efx, partition_type, NULL, version, NULL, 32 + 0); 33 + if (rc) { 34 + netif_err(efx, drv, efx->net_dev, "mcdi nvram %s: failed\n", 35 + version_name); 36 + return rc; 37 + } 38 + 39 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", version[0], 40 + version[1], version[2], version[3]); 41 + devlink_info_version_stored_put(req, version_name, buf); 42 + 43 + return 0; 44 + } 45 + 46 + static int efx_devlink_info_stored_versions(struct efx_nic *efx, 47 + struct devlink_info_req *req) 48 + { 49 + int rc; 50 + 51 + rc = efx_devlink_info_nvram_partition(efx, req, 52 + NVRAM_PARTITION_TYPE_BUNDLE, 53 + DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID); 54 + if (rc) 55 + return rc; 56 + 57 + rc = efx_devlink_info_nvram_partition(efx, req, 58 + NVRAM_PARTITION_TYPE_MC_FIRMWARE, 59 + DEVLINK_INFO_VERSION_GENERIC_FW_MGMT); 60 + if (rc) 61 + return rc; 62 + 63 + rc = efx_devlink_info_nvram_partition(efx, req, 64 + NVRAM_PARTITION_TYPE_SUC_FIRMWARE, 65 + EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC); 66 + if (rc) 67 + return rc; 68 + 69 + rc = efx_devlink_info_nvram_partition(efx, req, 70 + NVRAM_PARTITION_TYPE_EXPANSION_ROM, 71 + EFX_DEVLINK_INFO_VERSION_FW_EXPROM); 72 + if (rc) 73 + return rc; 74 + 75 + rc = efx_devlink_info_nvram_partition(efx, req, 76 + NVRAM_PARTITION_TYPE_EXPANSION_UEFI, 77 + EFX_DEVLINK_INFO_VERSION_FW_UEFI); 78 + return rc; 79 + } 80 + 81 + #define EFX_VER_FLAG(_f) \ 82 + (MC_CMD_GET_VERSION_V5_OUT_ ## _f ## _PRESENT_LBN) 83 + 84 + static void efx_devlink_info_running_v2(struct efx_nic *efx, 85 + struct devlink_info_req *req, 86 + unsigned int flags, efx_dword_t *outbuf) 87 + { 88 + char buf[EFX_MAX_VERSION_INFO_LEN]; 89 + union { 90 + const __le32 *dwords; 91 + const __le16 *words; 92 + const char *str; 93 + } ver; 94 + struct rtc_time build_date; 95 + unsigned int build_id; 96 + size_t offset; 97 + __maybe_unused u64 tstamp; 98 + 99 + if (flags & BIT(EFX_VER_FLAG(BOARD_EXT_INFO))) { 100 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%s", 101 + MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_NAME)); 102 + devlink_info_version_fixed_put(req, 103 + DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, 104 + buf); 105 + 106 + /* Favour full board version if present (in V5 or later) */ 107 + if (~flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) { 108 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u", 109 + MCDI_DWORD(outbuf, 110 + GET_VERSION_V2_OUT_BOARD_REVISION)); 111 + devlink_info_version_fixed_put(req, 112 + DEVLINK_INFO_VERSION_GENERIC_BOARD_REV, 113 + buf); 114 + } 115 + 116 + ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_SERIAL); 117 + if (ver.str[0]) 118 + devlink_info_board_serial_number_put(req, ver.str); 119 + } 120 + 121 + if (flags & BIT(EFX_VER_FLAG(FPGA_EXT_INFO))) { 122 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 123 + GET_VERSION_V2_OUT_FPGA_VERSION); 124 + offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u_%c%u", 125 + le32_to_cpu(ver.dwords[0]), 126 + 'A' + le32_to_cpu(ver.dwords[1]), 127 + le32_to_cpu(ver.dwords[2])); 128 + 129 + ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_FPGA_EXTRA); 130 + if (ver.str[0]) 131 + snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset, 132 + " (%s)", ver.str); 133 + 134 + devlink_info_version_running_put(req, 135 + EFX_DEVLINK_INFO_VERSION_FPGA_REV, 136 + buf); 137 + } 138 + 139 + if (flags & BIT(EFX_VER_FLAG(CMC_EXT_INFO))) { 140 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 141 + GET_VERSION_V2_OUT_CMCFW_VERSION); 142 + offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 143 + le32_to_cpu(ver.dwords[0]), 144 + le32_to_cpu(ver.dwords[1]), 145 + le32_to_cpu(ver.dwords[2]), 146 + le32_to_cpu(ver.dwords[3])); 147 + 148 + #ifdef CONFIG_RTC_LIB 149 + tstamp = MCDI_QWORD(outbuf, 150 + GET_VERSION_V2_OUT_CMCFW_BUILD_DATE); 151 + if (tstamp) { 152 + rtc_time64_to_tm(tstamp, &build_date); 153 + snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset, 154 + " (%ptRd)", &build_date); 155 + } 156 + #endif 157 + 158 + devlink_info_version_running_put(req, 159 + EFX_DEVLINK_INFO_VERSION_FW_MGMT_CMC, 160 + buf); 161 + } 162 + 163 + ver.words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_V2_OUT_VERSION); 164 + offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 165 + le16_to_cpu(ver.words[0]), le16_to_cpu(ver.words[1]), 166 + le16_to_cpu(ver.words[2]), le16_to_cpu(ver.words[3])); 167 + if (flags & BIT(EFX_VER_FLAG(MCFW_EXT_INFO))) { 168 + build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_ID); 169 + snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset, 170 + " (%x) %s", build_id, 171 + MCDI_PTR(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_NAME)); 172 + } 173 + devlink_info_version_running_put(req, 174 + DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, 175 + buf); 176 + 177 + if (flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) { 178 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 179 + GET_VERSION_V2_OUT_SUCFW_VERSION); 180 + #ifdef CONFIG_RTC_LIB 181 + tstamp = MCDI_QWORD(outbuf, 182 + GET_VERSION_V2_OUT_SUCFW_BUILD_DATE); 183 + rtc_time64_to_tm(tstamp, &build_date); 184 + #else 185 + memset(&build_date, 0, sizeof(build_date) 186 + #endif 187 + build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_SUCFW_CHIP_ID); 188 + 189 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, 190 + "%u.%u.%u.%u type %x (%ptRd)", 191 + le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 192 + le32_to_cpu(ver.dwords[2]), le32_to_cpu(ver.dwords[3]), 193 + build_id, &build_date); 194 + 195 + devlink_info_version_running_put(req, 196 + EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC, 197 + buf); 198 + } 199 + } 200 + 201 + static void efx_devlink_info_running_v3(struct efx_nic *efx, 202 + struct devlink_info_req *req, 203 + unsigned int flags, efx_dword_t *outbuf) 204 + { 205 + char buf[EFX_MAX_VERSION_INFO_LEN]; 206 + union { 207 + const __le32 *dwords; 208 + const __le16 *words; 209 + const char *str; 210 + } ver; 211 + 212 + if (flags & BIT(EFX_VER_FLAG(DATAPATH_HW_VERSION))) { 213 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 214 + GET_VERSION_V3_OUT_DATAPATH_HW_VERSION); 215 + 216 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u", 217 + le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 218 + le32_to_cpu(ver.dwords[2])); 219 + 220 + devlink_info_version_running_put(req, 221 + EFX_DEVLINK_INFO_VERSION_DATAPATH_HW, 222 + buf); 223 + } 224 + 225 + if (flags & BIT(EFX_VER_FLAG(DATAPATH_FW_VERSION))) { 226 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 227 + GET_VERSION_V3_OUT_DATAPATH_FW_VERSION); 228 + 229 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u", 230 + le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 231 + le32_to_cpu(ver.dwords[2])); 232 + 233 + devlink_info_version_running_put(req, 234 + EFX_DEVLINK_INFO_VERSION_DATAPATH_FW, 235 + buf); 236 + } 237 + } 238 + 239 + static void efx_devlink_info_running_v4(struct efx_nic *efx, 240 + struct devlink_info_req *req, 241 + unsigned int flags, efx_dword_t *outbuf) 242 + { 243 + char buf[EFX_MAX_VERSION_INFO_LEN]; 244 + union { 245 + const __le32 *dwords; 246 + const __le16 *words; 247 + const char *str; 248 + } ver; 249 + 250 + if (flags & BIT(EFX_VER_FLAG(SOC_BOOT_VERSION))) { 251 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 252 + GET_VERSION_V4_OUT_SOC_BOOT_VERSION); 253 + 254 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 255 + le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 256 + le32_to_cpu(ver.dwords[2]), 257 + le32_to_cpu(ver.dwords[3])); 258 + 259 + devlink_info_version_running_put(req, 260 + EFX_DEVLINK_INFO_VERSION_SOC_BOOT, 261 + buf); 262 + } 263 + 264 + if (flags & BIT(EFX_VER_FLAG(SOC_UBOOT_VERSION))) { 265 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 266 + GET_VERSION_V4_OUT_SOC_UBOOT_VERSION); 267 + 268 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 269 + le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 270 + le32_to_cpu(ver.dwords[2]), 271 + le32_to_cpu(ver.dwords[3])); 272 + 273 + devlink_info_version_running_put(req, 274 + EFX_DEVLINK_INFO_VERSION_SOC_UBOOT, 275 + buf); 276 + } 277 + 278 + if (flags & BIT(EFX_VER_FLAG(SOC_MAIN_ROOTFS_VERSION))) { 279 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 280 + GET_VERSION_V4_OUT_SOC_MAIN_ROOTFS_VERSION); 281 + 282 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 283 + le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 284 + le32_to_cpu(ver.dwords[2]), 285 + le32_to_cpu(ver.dwords[3])); 286 + 287 + devlink_info_version_running_put(req, 288 + EFX_DEVLINK_INFO_VERSION_SOC_MAIN, 289 + buf); 290 + } 291 + 292 + if (flags & BIT(EFX_VER_FLAG(SOC_RECOVERY_BUILDROOT_VERSION))) { 293 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 294 + GET_VERSION_V4_OUT_SOC_RECOVERY_BUILDROOT_VERSION); 295 + 296 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 297 + le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 298 + le32_to_cpu(ver.dwords[2]), 299 + le32_to_cpu(ver.dwords[3])); 300 + 301 + devlink_info_version_running_put(req, 302 + EFX_DEVLINK_INFO_VERSION_SOC_RECOVERY, 303 + buf); 304 + } 305 + 306 + if (flags & BIT(EFX_VER_FLAG(SUCFW_VERSION)) && 307 + ~flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) { 308 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 309 + GET_VERSION_V4_OUT_SUCFW_VERSION); 310 + 311 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 312 + le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 313 + le32_to_cpu(ver.dwords[2]), 314 + le32_to_cpu(ver.dwords[3])); 315 + 316 + devlink_info_version_running_put(req, 317 + EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC, 318 + buf); 319 + } 320 + } 321 + 322 + static void efx_devlink_info_running_v5(struct efx_nic *efx, 323 + struct devlink_info_req *req, 324 + unsigned int flags, efx_dword_t *outbuf) 325 + { 326 + char buf[EFX_MAX_VERSION_INFO_LEN]; 327 + union { 328 + const __le32 *dwords; 329 + const __le16 *words; 330 + const char *str; 331 + } ver; 332 + 333 + if (flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) { 334 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 335 + GET_VERSION_V5_OUT_BOARD_VERSION); 336 + 337 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 338 + le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 339 + le32_to_cpu(ver.dwords[2]), 340 + le32_to_cpu(ver.dwords[3])); 341 + 342 + devlink_info_version_running_put(req, 343 + DEVLINK_INFO_VERSION_GENERIC_BOARD_REV, 344 + buf); 345 + } 346 + 347 + if (flags & BIT(EFX_VER_FLAG(BUNDLE_VERSION))) { 348 + ver.dwords = (__le32 *)MCDI_PTR(outbuf, 349 + GET_VERSION_V5_OUT_BUNDLE_VERSION); 350 + 351 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 352 + le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 353 + le32_to_cpu(ver.dwords[2]), 354 + le32_to_cpu(ver.dwords[3])); 355 + 356 + devlink_info_version_running_put(req, 357 + DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, 358 + buf); 359 + } 360 + } 361 + 362 + static int efx_devlink_info_running_versions(struct efx_nic *efx, 363 + struct devlink_info_req *req) 364 + { 365 + MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_VERSION_V5_OUT_LEN); 366 + MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_VERSION_EXT_IN_LEN); 367 + char buf[EFX_MAX_VERSION_INFO_LEN]; 368 + union { 369 + const __le32 *dwords; 370 + const __le16 *words; 371 + const char *str; 372 + } ver; 373 + size_t outlength; 374 + unsigned int flags; 375 + int rc; 376 + 377 + rc = efx_mcdi_rpc(efx, MC_CMD_GET_VERSION, inbuf, sizeof(inbuf), 378 + outbuf, sizeof(outbuf), &outlength); 379 + if (rc || outlength < MC_CMD_GET_VERSION_OUT_LEN) { 380 + netif_err(efx, drv, efx->net_dev, 381 + "mcdi MC_CMD_GET_VERSION failed\n"); 382 + return rc; 383 + } 384 + 385 + /* Handle previous output */ 386 + if (outlength < MC_CMD_GET_VERSION_V2_OUT_LEN) { 387 + ver.words = (__le16 *)MCDI_PTR(outbuf, 388 + GET_VERSION_EXT_OUT_VERSION); 389 + snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 390 + le16_to_cpu(ver.words[0]), 391 + le16_to_cpu(ver.words[1]), 392 + le16_to_cpu(ver.words[2]), 393 + le16_to_cpu(ver.words[3])); 394 + 395 + devlink_info_version_running_put(req, 396 + DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, 397 + buf); 398 + return 0; 399 + } 400 + 401 + /* Handle V2 additions */ 402 + flags = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_FLAGS); 403 + efx_devlink_info_running_v2(efx, req, flags, outbuf); 404 + 405 + if (outlength < MC_CMD_GET_VERSION_V3_OUT_LEN) 406 + return 0; 407 + 408 + /* Handle V3 additions */ 409 + efx_devlink_info_running_v3(efx, req, flags, outbuf); 410 + 411 + if (outlength < MC_CMD_GET_VERSION_V4_OUT_LEN) 412 + return 0; 413 + 414 + /* Handle V4 additions */ 415 + efx_devlink_info_running_v4(efx, req, flags, outbuf); 416 + 417 + if (outlength < MC_CMD_GET_VERSION_V5_OUT_LEN) 418 + return 0; 419 + 420 + /* Handle V5 additions */ 421 + efx_devlink_info_running_v5(efx, req, flags, outbuf); 422 + 423 + return 0; 424 + } 425 + 426 + #define EFX_MAX_SERIALNUM_LEN (ETH_ALEN * 2 + 1) 427 + 428 + static int efx_devlink_info_board_cfg(struct efx_nic *efx, 429 + struct devlink_info_req *req) 430 + { 431 + char sn[EFX_MAX_SERIALNUM_LEN]; 432 + u8 mac_address[ETH_ALEN]; 433 + int rc; 434 + 435 + rc = efx_mcdi_get_board_cfg(efx, (u8 *)mac_address, NULL, NULL); 436 + if (!rc) { 437 + snprintf(sn, EFX_MAX_SERIALNUM_LEN, "%pm", mac_address); 438 + devlink_info_serial_number_put(req, sn); 439 + } 440 + return rc; 441 + } 442 + 443 + static int efx_devlink_info_get(struct devlink *devlink, 444 + struct devlink_info_req *req, 445 + struct netlink_ext_ack *extack) 446 + { 447 + struct efx_devlink *devlink_private = devlink_priv(devlink); 448 + struct efx_nic *efx = devlink_private->efx; 449 + int rc; 450 + 451 + /* Several different MCDI commands are used. We report first error 452 + * through extack returning at that point. Specific error 453 + * information via system messages. 454 + */ 455 + rc = efx_devlink_info_board_cfg(efx, req); 456 + if (rc) { 457 + NL_SET_ERR_MSG_MOD(extack, "Getting board info failed"); 458 + return rc; 459 + } 460 + rc = efx_devlink_info_stored_versions(efx, req); 461 + if (rc) { 462 + NL_SET_ERR_MSG_MOD(extack, "Getting stored versions failed"); 463 + return rc; 464 + } 465 + rc = efx_devlink_info_running_versions(efx, req); 466 + if (rc) { 467 + NL_SET_ERR_MSG_MOD(extack, "Getting running versions failed"); 468 + return rc; 469 + } 470 + 471 + return 0; 472 + } 473 + 18 474 static const struct devlink_ops sfc_devlink_ops = { 475 + .info_get = efx_devlink_info_get, 19 476 }; 20 477 21 478 void efx_fini_devlink_lock(struct efx_nic *efx)
+17
drivers/net/ethernet/sfc/efx_devlink.h
··· 14 14 #include "net_driver.h" 15 15 #include <net/devlink.h> 16 16 17 + /* Custom devlink-info version object names for details that do not map to the 18 + * generic standardized names. 19 + */ 20 + #define EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC "fw.mgmt.suc" 21 + #define EFX_DEVLINK_INFO_VERSION_FW_MGMT_CMC "fw.mgmt.cmc" 22 + #define EFX_DEVLINK_INFO_VERSION_FPGA_REV "fpga.rev" 23 + #define EFX_DEVLINK_INFO_VERSION_DATAPATH_HW "fpga.app" 24 + #define EFX_DEVLINK_INFO_VERSION_DATAPATH_FW DEVLINK_INFO_VERSION_GENERIC_FW_APP 25 + #define EFX_DEVLINK_INFO_VERSION_SOC_BOOT "coproc.boot" 26 + #define EFX_DEVLINK_INFO_VERSION_SOC_UBOOT "coproc.uboot" 27 + #define EFX_DEVLINK_INFO_VERSION_SOC_MAIN "coproc.main" 28 + #define EFX_DEVLINK_INFO_VERSION_SOC_RECOVERY "coproc.recovery" 29 + #define EFX_DEVLINK_INFO_VERSION_FW_EXPROM "fw.exprom" 30 + #define EFX_DEVLINK_INFO_VERSION_FW_UEFI "fw.uefi" 31 + 32 + #define EFX_MAX_VERSION_INFO_LEN 64 33 + 17 34 int efx_probe_devlink_and_lock(struct efx_nic *efx); 18 35 void efx_probe_devlink_unlock(struct efx_nic *efx); 19 36 void efx_fini_devlink_lock(struct efx_nic *efx);
+72
drivers/net/ethernet/sfc/mcdi.c
··· 2175 2175 return 0; 2176 2176 } 2177 2177 2178 + int efx_mcdi_nvram_metadata(struct efx_nic *efx, unsigned int type, 2179 + u32 *subtype, u16 version[4], char *desc, 2180 + size_t descsize) 2181 + { 2182 + MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_METADATA_IN_LEN); 2183 + efx_dword_t *outbuf; 2184 + size_t outlen; 2185 + u32 flags; 2186 + int rc; 2187 + 2188 + outbuf = kzalloc(MC_CMD_NVRAM_METADATA_OUT_LENMAX_MCDI2, GFP_KERNEL); 2189 + if (!outbuf) 2190 + return -ENOMEM; 2191 + 2192 + MCDI_SET_DWORD(inbuf, NVRAM_METADATA_IN_TYPE, type); 2193 + 2194 + rc = efx_mcdi_rpc_quiet(efx, MC_CMD_NVRAM_METADATA, inbuf, 2195 + sizeof(inbuf), outbuf, 2196 + MC_CMD_NVRAM_METADATA_OUT_LENMAX_MCDI2, 2197 + &outlen); 2198 + if (rc) 2199 + goto out_free; 2200 + if (outlen < MC_CMD_NVRAM_METADATA_OUT_LENMIN) { 2201 + rc = -EIO; 2202 + goto out_free; 2203 + } 2204 + 2205 + flags = MCDI_DWORD(outbuf, NVRAM_METADATA_OUT_FLAGS); 2206 + 2207 + if (desc && descsize > 0) { 2208 + if (flags & BIT(MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_VALID_LBN)) { 2209 + if (descsize <= 2210 + MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_NUM(outlen)) { 2211 + rc = -E2BIG; 2212 + goto out_free; 2213 + } 2214 + 2215 + strncpy(desc, 2216 + MCDI_PTR(outbuf, NVRAM_METADATA_OUT_DESCRIPTION), 2217 + MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_NUM(outlen)); 2218 + desc[MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_NUM(outlen)] = '\0'; 2219 + } else { 2220 + desc[0] = '\0'; 2221 + } 2222 + } 2223 + 2224 + if (subtype) { 2225 + if (flags & BIT(MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_LBN)) 2226 + *subtype = MCDI_DWORD(outbuf, NVRAM_METADATA_OUT_SUBTYPE); 2227 + else 2228 + *subtype = 0; 2229 + } 2230 + 2231 + if (version) { 2232 + if (flags & BIT(MC_CMD_NVRAM_METADATA_OUT_VERSION_VALID_LBN)) { 2233 + version[0] = MCDI_WORD(outbuf, NVRAM_METADATA_OUT_VERSION_W); 2234 + version[1] = MCDI_WORD(outbuf, NVRAM_METADATA_OUT_VERSION_X); 2235 + version[2] = MCDI_WORD(outbuf, NVRAM_METADATA_OUT_VERSION_Y); 2236 + version[3] = MCDI_WORD(outbuf, NVRAM_METADATA_OUT_VERSION_Z); 2237 + } else { 2238 + version[0] = 0; 2239 + version[1] = 0; 2240 + version[2] = 0; 2241 + version[3] = 0; 2242 + } 2243 + } 2244 + 2245 + out_free: 2246 + kfree(outbuf); 2247 + return rc; 2248 + } 2249 + 2178 2250 #ifdef CONFIG_SFC_MTD 2179 2251 2180 2252 #define EFX_MCDI_NVRAM_LEN_MAX 128
+3
drivers/net/ethernet/sfc/mcdi.h
··· 378 378 size_t *size_out, size_t *erase_size_out, 379 379 bool *protected_out); 380 380 int efx_new_mcdi_nvram_test_all(struct efx_nic *efx); 381 + int efx_mcdi_nvram_metadata(struct efx_nic *efx, unsigned int type, 382 + u32 *subtype, u16 version[4], char *desc, 383 + size_t descsize); 381 384 int efx_mcdi_nvram_test_all(struct efx_nic *efx); 382 385 int efx_mcdi_handle_assertion(struct efx_nic *efx); 383 386 int efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);