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