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 if (rc) { 175 netif_err(efx, drv, efx->net_dev, "mcdi nvram %s: failed\n", 176 version_name); 177 return rc; 178 } 179 180 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", version[0], 181 version[1], version[2], version[3]); 182 devlink_info_version_stored_put(req, version_name, buf); 183 184 return 0; 185 } 186 187 static int efx_devlink_info_stored_versions(struct efx_nic *efx, 188 struct devlink_info_req *req) 189 { 190 int rc; 191 192 rc = efx_devlink_info_nvram_partition(efx, req, 193 NVRAM_PARTITION_TYPE_BUNDLE, 194 DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID); 195 if (rc) 196 return rc; 197 198 rc = efx_devlink_info_nvram_partition(efx, req, 199 NVRAM_PARTITION_TYPE_MC_FIRMWARE, 200 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT); 201 if (rc) 202 return rc; 203 204 rc = efx_devlink_info_nvram_partition(efx, req, 205 NVRAM_PARTITION_TYPE_SUC_FIRMWARE, 206 EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC); 207 if (rc) 208 return rc; 209 210 rc = efx_devlink_info_nvram_partition(efx, req, 211 NVRAM_PARTITION_TYPE_EXPANSION_ROM, 212 EFX_DEVLINK_INFO_VERSION_FW_EXPROM); 213 if (rc) 214 return rc; 215 216 rc = efx_devlink_info_nvram_partition(efx, req, 217 NVRAM_PARTITION_TYPE_EXPANSION_UEFI, 218 EFX_DEVLINK_INFO_VERSION_FW_UEFI); 219 return rc; 220 } 221 222 #define EFX_VER_FLAG(_f) \ 223 (MC_CMD_GET_VERSION_V5_OUT_ ## _f ## _PRESENT_LBN) 224 225 static void efx_devlink_info_running_v2(struct efx_nic *efx, 226 struct devlink_info_req *req, 227 unsigned int flags, efx_dword_t *outbuf) 228 { 229 char buf[EFX_MAX_VERSION_INFO_LEN]; 230 union { 231 const __le32 *dwords; 232 const __le16 *words; 233 const char *str; 234 } ver; 235 struct rtc_time build_date; 236 unsigned int build_id; 237 size_t offset; 238 __maybe_unused u64 tstamp; 239 240 if (flags & BIT(EFX_VER_FLAG(BOARD_EXT_INFO))) { 241 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%s", 242 MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_NAME)); 243 devlink_info_version_fixed_put(req, 244 DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, 245 buf); 246 247 /* Favour full board version if present (in V5 or later) */ 248 if (~flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) { 249 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u", 250 MCDI_DWORD(outbuf, 251 GET_VERSION_V2_OUT_BOARD_REVISION)); 252 devlink_info_version_fixed_put(req, 253 DEVLINK_INFO_VERSION_GENERIC_BOARD_REV, 254 buf); 255 } 256 257 ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_SERIAL); 258 if (ver.str[0]) 259 devlink_info_board_serial_number_put(req, ver.str); 260 } 261 262 if (flags & BIT(EFX_VER_FLAG(FPGA_EXT_INFO))) { 263 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 264 GET_VERSION_V2_OUT_FPGA_VERSION); 265 offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u_%c%u", 266 le32_to_cpu(ver.dwords[0]), 267 'A' + le32_to_cpu(ver.dwords[1]), 268 le32_to_cpu(ver.dwords[2])); 269 270 ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_FPGA_EXTRA); 271 if (ver.str[0]) 272 snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset, 273 " (%s)", ver.str); 274 275 devlink_info_version_running_put(req, 276 EFX_DEVLINK_INFO_VERSION_FPGA_REV, 277 buf); 278 } 279 280 if (flags & BIT(EFX_VER_FLAG(CMC_EXT_INFO))) { 281 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 282 GET_VERSION_V2_OUT_CMCFW_VERSION); 283 offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 284 le32_to_cpu(ver.dwords[0]), 285 le32_to_cpu(ver.dwords[1]), 286 le32_to_cpu(ver.dwords[2]), 287 le32_to_cpu(ver.dwords[3])); 288 289 #ifdef CONFIG_RTC_LIB 290 tstamp = MCDI_QWORD(outbuf, 291 GET_VERSION_V2_OUT_CMCFW_BUILD_DATE); 292 if (tstamp) { 293 rtc_time64_to_tm(tstamp, &build_date); 294 snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset, 295 " (%ptRd)", &build_date); 296 } 297 #endif 298 299 devlink_info_version_running_put(req, 300 EFX_DEVLINK_INFO_VERSION_FW_MGMT_CMC, 301 buf); 302 } 303 304 ver.words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_V2_OUT_VERSION); 305 offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 306 le16_to_cpu(ver.words[0]), le16_to_cpu(ver.words[1]), 307 le16_to_cpu(ver.words[2]), le16_to_cpu(ver.words[3])); 308 if (flags & BIT(EFX_VER_FLAG(MCFW_EXT_INFO))) { 309 build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_ID); 310 snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset, 311 " (%x) %s", build_id, 312 MCDI_PTR(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_NAME)); 313 } 314 devlink_info_version_running_put(req, 315 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, 316 buf); 317 318 if (flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) { 319 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 320 GET_VERSION_V2_OUT_SUCFW_VERSION); 321 #ifdef CONFIG_RTC_LIB 322 tstamp = MCDI_QWORD(outbuf, 323 GET_VERSION_V2_OUT_SUCFW_BUILD_DATE); 324 rtc_time64_to_tm(tstamp, &build_date); 325 #else 326 memset(&build_date, 0, sizeof(build_date)); 327 #endif 328 build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_SUCFW_CHIP_ID); 329 330 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, 331 "%u.%u.%u.%u type %x (%ptRd)", 332 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 333 le32_to_cpu(ver.dwords[2]), le32_to_cpu(ver.dwords[3]), 334 build_id, &build_date); 335 336 devlink_info_version_running_put(req, 337 EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC, 338 buf); 339 } 340 } 341 342 static void efx_devlink_info_running_v3(struct efx_nic *efx, 343 struct devlink_info_req *req, 344 unsigned int flags, efx_dword_t *outbuf) 345 { 346 char buf[EFX_MAX_VERSION_INFO_LEN]; 347 union { 348 const __le32 *dwords; 349 const __le16 *words; 350 const char *str; 351 } ver; 352 353 if (flags & BIT(EFX_VER_FLAG(DATAPATH_HW_VERSION))) { 354 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 355 GET_VERSION_V3_OUT_DATAPATH_HW_VERSION); 356 357 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u", 358 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 359 le32_to_cpu(ver.dwords[2])); 360 361 devlink_info_version_running_put(req, 362 EFX_DEVLINK_INFO_VERSION_DATAPATH_HW, 363 buf); 364 } 365 366 if (flags & BIT(EFX_VER_FLAG(DATAPATH_FW_VERSION))) { 367 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 368 GET_VERSION_V3_OUT_DATAPATH_FW_VERSION); 369 370 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u", 371 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 372 le32_to_cpu(ver.dwords[2])); 373 374 devlink_info_version_running_put(req, 375 EFX_DEVLINK_INFO_VERSION_DATAPATH_FW, 376 buf); 377 } 378 } 379 380 static void efx_devlink_info_running_v4(struct efx_nic *efx, 381 struct devlink_info_req *req, 382 unsigned int flags, efx_dword_t *outbuf) 383 { 384 char buf[EFX_MAX_VERSION_INFO_LEN]; 385 union { 386 const __le32 *dwords; 387 const __le16 *words; 388 const char *str; 389 } ver; 390 391 if (flags & BIT(EFX_VER_FLAG(SOC_BOOT_VERSION))) { 392 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 393 GET_VERSION_V4_OUT_SOC_BOOT_VERSION); 394 395 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 396 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 397 le32_to_cpu(ver.dwords[2]), 398 le32_to_cpu(ver.dwords[3])); 399 400 devlink_info_version_running_put(req, 401 EFX_DEVLINK_INFO_VERSION_SOC_BOOT, 402 buf); 403 } 404 405 if (flags & BIT(EFX_VER_FLAG(SOC_UBOOT_VERSION))) { 406 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 407 GET_VERSION_V4_OUT_SOC_UBOOT_VERSION); 408 409 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 410 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 411 le32_to_cpu(ver.dwords[2]), 412 le32_to_cpu(ver.dwords[3])); 413 414 devlink_info_version_running_put(req, 415 EFX_DEVLINK_INFO_VERSION_SOC_UBOOT, 416 buf); 417 } 418 419 if (flags & BIT(EFX_VER_FLAG(SOC_MAIN_ROOTFS_VERSION))) { 420 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 421 GET_VERSION_V4_OUT_SOC_MAIN_ROOTFS_VERSION); 422 423 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 424 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 425 le32_to_cpu(ver.dwords[2]), 426 le32_to_cpu(ver.dwords[3])); 427 428 devlink_info_version_running_put(req, 429 EFX_DEVLINK_INFO_VERSION_SOC_MAIN, 430 buf); 431 } 432 433 if (flags & BIT(EFX_VER_FLAG(SOC_RECOVERY_BUILDROOT_VERSION))) { 434 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 435 GET_VERSION_V4_OUT_SOC_RECOVERY_BUILDROOT_VERSION); 436 437 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 438 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 439 le32_to_cpu(ver.dwords[2]), 440 le32_to_cpu(ver.dwords[3])); 441 442 devlink_info_version_running_put(req, 443 EFX_DEVLINK_INFO_VERSION_SOC_RECOVERY, 444 buf); 445 } 446 447 if (flags & BIT(EFX_VER_FLAG(SUCFW_VERSION)) && 448 ~flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) { 449 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 450 GET_VERSION_V4_OUT_SUCFW_VERSION); 451 452 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 453 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 454 le32_to_cpu(ver.dwords[2]), 455 le32_to_cpu(ver.dwords[3])); 456 457 devlink_info_version_running_put(req, 458 EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC, 459 buf); 460 } 461 } 462 463 static void efx_devlink_info_running_v5(struct efx_nic *efx, 464 struct devlink_info_req *req, 465 unsigned int flags, efx_dword_t *outbuf) 466 { 467 char buf[EFX_MAX_VERSION_INFO_LEN]; 468 union { 469 const __le32 *dwords; 470 const __le16 *words; 471 const char *str; 472 } ver; 473 474 if (flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) { 475 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 476 GET_VERSION_V5_OUT_BOARD_VERSION); 477 478 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 479 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 480 le32_to_cpu(ver.dwords[2]), 481 le32_to_cpu(ver.dwords[3])); 482 483 devlink_info_version_running_put(req, 484 DEVLINK_INFO_VERSION_GENERIC_BOARD_REV, 485 buf); 486 } 487 488 if (flags & BIT(EFX_VER_FLAG(BUNDLE_VERSION))) { 489 ver.dwords = (__le32 *)MCDI_PTR(outbuf, 490 GET_VERSION_V5_OUT_BUNDLE_VERSION); 491 492 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 493 le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]), 494 le32_to_cpu(ver.dwords[2]), 495 le32_to_cpu(ver.dwords[3])); 496 497 devlink_info_version_running_put(req, 498 DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, 499 buf); 500 } 501 } 502 503 static int efx_devlink_info_running_versions(struct efx_nic *efx, 504 struct devlink_info_req *req) 505 { 506 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_VERSION_V5_OUT_LEN); 507 MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_VERSION_EXT_IN_LEN); 508 char buf[EFX_MAX_VERSION_INFO_LEN]; 509 union { 510 const __le32 *dwords; 511 const __le16 *words; 512 const char *str; 513 } ver; 514 size_t outlength; 515 unsigned int flags; 516 int rc; 517 518 rc = efx_mcdi_rpc(efx, MC_CMD_GET_VERSION, inbuf, sizeof(inbuf), 519 outbuf, sizeof(outbuf), &outlength); 520 if (rc || outlength < MC_CMD_GET_VERSION_OUT_LEN) { 521 netif_err(efx, drv, efx->net_dev, 522 "mcdi MC_CMD_GET_VERSION failed\n"); 523 return rc; 524 } 525 526 /* Handle previous output */ 527 if (outlength < MC_CMD_GET_VERSION_V2_OUT_LEN) { 528 ver.words = (__le16 *)MCDI_PTR(outbuf, 529 GET_VERSION_EXT_OUT_VERSION); 530 snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", 531 le16_to_cpu(ver.words[0]), 532 le16_to_cpu(ver.words[1]), 533 le16_to_cpu(ver.words[2]), 534 le16_to_cpu(ver.words[3])); 535 536 devlink_info_version_running_put(req, 537 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, 538 buf); 539 return 0; 540 } 541 542 /* Handle V2 additions */ 543 flags = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_FLAGS); 544 efx_devlink_info_running_v2(efx, req, flags, outbuf); 545 546 if (outlength < MC_CMD_GET_VERSION_V3_OUT_LEN) 547 return 0; 548 549 /* Handle V3 additions */ 550 efx_devlink_info_running_v3(efx, req, flags, outbuf); 551 552 if (outlength < MC_CMD_GET_VERSION_V4_OUT_LEN) 553 return 0; 554 555 /* Handle V4 additions */ 556 efx_devlink_info_running_v4(efx, req, flags, outbuf); 557 558 if (outlength < MC_CMD_GET_VERSION_V5_OUT_LEN) 559 return 0; 560 561 /* Handle V5 additions */ 562 efx_devlink_info_running_v5(efx, req, flags, outbuf); 563 564 return 0; 565 } 566 567 #define EFX_MAX_SERIALNUM_LEN (ETH_ALEN * 2 + 1) 568 569 static int efx_devlink_info_board_cfg(struct efx_nic *efx, 570 struct devlink_info_req *req) 571 { 572 char sn[EFX_MAX_SERIALNUM_LEN]; 573 u8 mac_address[ETH_ALEN]; 574 int rc; 575 576 rc = efx_mcdi_get_board_cfg(efx, (u8 *)mac_address, NULL, NULL); 577 if (!rc) { 578 snprintf(sn, EFX_MAX_SERIALNUM_LEN, "%pm", mac_address); 579 devlink_info_serial_number_put(req, sn); 580 } 581 return rc; 582 } 583 584 static int efx_devlink_info_get(struct devlink *devlink, 585 struct devlink_info_req *req, 586 struct netlink_ext_ack *extack) 587 { 588 struct efx_devlink *devlink_private = devlink_priv(devlink); 589 struct efx_nic *efx = devlink_private->efx; 590 int rc; 591 592 /* Several different MCDI commands are used. We report first error 593 * through extack returning at that point. Specific error 594 * information via system messages. 595 */ 596 rc = efx_devlink_info_board_cfg(efx, req); 597 if (rc) { 598 NL_SET_ERR_MSG_MOD(extack, "Getting board info failed"); 599 return rc; 600 } 601 rc = efx_devlink_info_stored_versions(efx, req); 602 if (rc) { 603 NL_SET_ERR_MSG_MOD(extack, "Getting stored versions failed"); 604 return rc; 605 } 606 rc = efx_devlink_info_running_versions(efx, req); 607 if (rc) { 608 NL_SET_ERR_MSG_MOD(extack, "Getting running versions failed"); 609 return rc; 610 } 611 612 return 0; 613 } 614 615 static const struct devlink_ops sfc_devlink_ops = { 616 .info_get = efx_devlink_info_get, 617 #ifdef CONFIG_SFC_SRIOV 618 .port_function_hw_addr_get = efx_devlink_port_addr_get, 619 .port_function_hw_addr_set = efx_devlink_port_addr_set, 620 #endif 621 }; 622 623 #ifdef CONFIG_SFC_SRIOV 624 static struct devlink_port *ef100_set_devlink_port(struct efx_nic *efx, u32 idx) 625 { 626 struct mae_mport_desc *mport; 627 u32 id; 628 int rc; 629 630 if (efx_mae_lookup_mport(efx, idx, &id)) { 631 /* This should not happen. */ 632 if (idx == MAE_MPORT_DESC_VF_IDX_NULL) 633 pci_warn_once(efx->pci_dev, "No mport ID found for PF.\n"); 634 else 635 pci_warn_once(efx->pci_dev, "No mport ID found for VF %u.\n", 636 idx); 637 return NULL; 638 } 639 640 mport = efx_mae_get_mport(efx, id); 641 if (!mport) { 642 /* This should not happen. */ 643 if (idx == MAE_MPORT_DESC_VF_IDX_NULL) 644 pci_warn_once(efx->pci_dev, "No mport found for PF.\n"); 645 else 646 pci_warn_once(efx->pci_dev, "No mport found for VF %u.\n", 647 idx); 648 return NULL; 649 } 650 651 rc = efx_devlink_add_port(efx, mport); 652 if (rc) { 653 if (idx == MAE_MPORT_DESC_VF_IDX_NULL) 654 pci_warn(efx->pci_dev, 655 "devlink port creation for PF failed.\n"); 656 else 657 pci_warn(efx->pci_dev, 658 "devlink_port creation for VF %u failed.\n", 659 idx); 660 return NULL; 661 } 662 663 return &mport->dl_port; 664 } 665 666 void ef100_rep_set_devlink_port(struct efx_rep *efv) 667 { 668 efv->dl_port = ef100_set_devlink_port(efv->parent, efv->idx); 669 } 670 671 void ef100_pf_set_devlink_port(struct efx_nic *efx) 672 { 673 efx->dl_port = ef100_set_devlink_port(efx, MAE_MPORT_DESC_VF_IDX_NULL); 674 } 675 676 void ef100_rep_unset_devlink_port(struct efx_rep *efv) 677 { 678 efx_devlink_del_port(efv->dl_port); 679 } 680 681 void ef100_pf_unset_devlink_port(struct efx_nic *efx) 682 { 683 efx_devlink_del_port(efx->dl_port); 684 } 685 #endif 686 687 void efx_fini_devlink_lock(struct efx_nic *efx) 688 { 689 if (efx->devlink) 690 devl_lock(efx->devlink); 691 } 692 693 void efx_fini_devlink_and_unlock(struct efx_nic *efx) 694 { 695 if (efx->devlink) { 696 devl_unregister(efx->devlink); 697 devl_unlock(efx->devlink); 698 devlink_free(efx->devlink); 699 efx->devlink = NULL; 700 } 701 } 702 703 int efx_probe_devlink_and_lock(struct efx_nic *efx) 704 { 705 struct efx_devlink *devlink_private; 706 707 if (efx->type->is_vf) 708 return 0; 709 710 efx->devlink = devlink_alloc(&sfc_devlink_ops, 711 sizeof(struct efx_devlink), 712 &efx->pci_dev->dev); 713 if (!efx->devlink) 714 return -ENOMEM; 715 716 devl_lock(efx->devlink); 717 devlink_private = devlink_priv(efx->devlink); 718 devlink_private->efx = efx; 719 720 devl_register(efx->devlink); 721 722 return 0; 723 } 724 725 void efx_probe_devlink_unlock(struct efx_nic *efx) 726 { 727 if (!efx->devlink) 728 return; 729 730 devl_unlock(efx->devlink); 731 } 732