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 } 727