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