1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2020, Intel Corporation. */ 3 4 #include "ice.h" 5 #include "ice_lib.h" 6 #include "ice_devlink.h" 7 #include "ice_fw_update.h" 8 9 /* context for devlink info version reporting */ 10 struct ice_info_ctx { 11 char buf[128]; 12 struct ice_orom_info pending_orom; 13 struct ice_nvm_info pending_nvm; 14 struct ice_netlist_info pending_netlist; 15 struct ice_hw_dev_caps dev_caps; 16 }; 17 18 /* The following functions are used to format specific strings for various 19 * devlink info versions. The ctx parameter is used to provide the storage 20 * buffer, as well as any ancillary information calculated when the info 21 * request was made. 22 * 23 * If a version does not exist, for example when attempting to get the 24 * inactive version of flash when there is no pending update, the function 25 * should leave the buffer in the ctx structure empty and return 0. 26 */ 27 28 static void ice_info_get_dsn(struct ice_pf *pf, struct ice_info_ctx *ctx) 29 { 30 u8 dsn[8]; 31 32 /* Copy the DSN into an array in Big Endian format */ 33 put_unaligned_be64(pci_get_dsn(pf->pdev), dsn); 34 35 snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn); 36 } 37 38 static int ice_info_pba(struct ice_pf *pf, struct ice_info_ctx *ctx) 39 { 40 struct ice_hw *hw = &pf->hw; 41 enum ice_status status; 42 43 status = ice_read_pba_string(hw, (u8 *)ctx->buf, sizeof(ctx->buf)); 44 if (status) 45 return -EIO; 46 47 return 0; 48 } 49 50 static int ice_info_fw_mgmt(struct ice_pf *pf, struct ice_info_ctx *ctx) 51 { 52 struct ice_hw *hw = &pf->hw; 53 54 snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", hw->fw_maj_ver, hw->fw_min_ver, 55 hw->fw_patch); 56 57 return 0; 58 } 59 60 static int ice_info_fw_api(struct ice_pf *pf, struct ice_info_ctx *ctx) 61 { 62 struct ice_hw *hw = &pf->hw; 63 64 snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u", hw->api_maj_ver, hw->api_min_ver); 65 66 return 0; 67 } 68 69 static int ice_info_fw_build(struct ice_pf *pf, struct ice_info_ctx *ctx) 70 { 71 struct ice_hw *hw = &pf->hw; 72 73 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build); 74 75 return 0; 76 } 77 78 static int ice_info_orom_ver(struct ice_pf *pf, struct ice_info_ctx *ctx) 79 { 80 struct ice_orom_info *orom = &pf->hw.flash.orom; 81 82 snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", orom->major, orom->build, orom->patch); 83 84 return 0; 85 } 86 87 static int 88 ice_info_pending_orom_ver(struct ice_pf __always_unused *pf, struct ice_info_ctx *ctx) 89 { 90 struct ice_orom_info *orom = &ctx->pending_orom; 91 92 if (ctx->dev_caps.common_cap.nvm_update_pending_orom) 93 snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", 94 orom->major, orom->build, orom->patch); 95 96 return 0; 97 } 98 99 static int ice_info_nvm_ver(struct ice_pf *pf, struct ice_info_ctx *ctx) 100 { 101 struct ice_nvm_info *nvm = &pf->hw.flash.nvm; 102 103 snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor); 104 105 return 0; 106 } 107 108 static int 109 ice_info_pending_nvm_ver(struct ice_pf __always_unused *pf, struct ice_info_ctx *ctx) 110 { 111 struct ice_nvm_info *nvm = &ctx->pending_nvm; 112 113 if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) 114 snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor); 115 116 return 0; 117 } 118 119 static int ice_info_eetrack(struct ice_pf *pf, struct ice_info_ctx *ctx) 120 { 121 struct ice_nvm_info *nvm = &pf->hw.flash.nvm; 122 123 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm->eetrack); 124 125 return 0; 126 } 127 128 static int 129 ice_info_pending_eetrack(struct ice_pf __always_unused *pf, struct ice_info_ctx *ctx) 130 { 131 struct ice_nvm_info *nvm = &ctx->pending_nvm; 132 133 if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) 134 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm->eetrack); 135 136 return 0; 137 } 138 139 static int ice_info_ddp_pkg_name(struct ice_pf *pf, struct ice_info_ctx *ctx) 140 { 141 struct ice_hw *hw = &pf->hw; 142 143 snprintf(ctx->buf, sizeof(ctx->buf), "%s", hw->active_pkg_name); 144 145 return 0; 146 } 147 148 static int ice_info_ddp_pkg_version(struct ice_pf *pf, struct ice_info_ctx *ctx) 149 { 150 struct ice_pkg_ver *pkg = &pf->hw.active_pkg_ver; 151 152 snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u.%u", pkg->major, pkg->minor, pkg->update, 153 pkg->draft); 154 155 return 0; 156 } 157 158 static int ice_info_ddp_pkg_bundle_id(struct ice_pf *pf, struct ice_info_ctx *ctx) 159 { 160 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", pf->hw.active_track_id); 161 162 return 0; 163 } 164 165 static int ice_info_netlist_ver(struct ice_pf *pf, struct ice_info_ctx *ctx) 166 { 167 struct ice_netlist_info *netlist = &pf->hw.flash.netlist; 168 169 /* The netlist version fields are BCD formatted */ 170 snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x", netlist->major, netlist->minor, 171 netlist->type >> 16, netlist->type & 0xFFFF, netlist->rev, 172 netlist->cust_ver); 173 174 return 0; 175 } 176 177 static int ice_info_netlist_build(struct ice_pf *pf, struct ice_info_ctx *ctx) 178 { 179 struct ice_netlist_info *netlist = &pf->hw.flash.netlist; 180 181 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash); 182 183 return 0; 184 } 185 186 static int 187 ice_info_pending_netlist_ver(struct ice_pf __always_unused *pf, struct ice_info_ctx *ctx) 188 { 189 struct ice_netlist_info *netlist = &ctx->pending_netlist; 190 191 /* The netlist version fields are BCD formatted */ 192 if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) 193 snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x", 194 netlist->major, netlist->minor, 195 netlist->type >> 16, netlist->type & 0xFFFF, netlist->rev, 196 netlist->cust_ver); 197 198 return 0; 199 } 200 201 static int 202 ice_info_pending_netlist_build(struct ice_pf __always_unused *pf, struct ice_info_ctx *ctx) 203 { 204 struct ice_netlist_info *netlist = &ctx->pending_netlist; 205 206 if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) 207 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash); 208 209 return 0; 210 } 211 212 #define fixed(key, getter) { ICE_VERSION_FIXED, key, getter, NULL } 213 #define running(key, getter) { ICE_VERSION_RUNNING, key, getter, NULL } 214 #define stored(key, getter, fallback) { ICE_VERSION_STORED, key, getter, fallback } 215 216 /* The combined() macro inserts both the running entry as well as a stored 217 * entry. The running entry will always report the version from the active 218 * handler. The stored entry will first try the pending handler, and fallback 219 * to the active handler if the pending function does not report a version. 220 * The pending handler should check the status of a pending update for the 221 * relevant flash component. It should only fill in the buffer in the case 222 * where a valid pending version is available. This ensures that the related 223 * stored and running versions remain in sync, and that stored versions are 224 * correctly reported as expected. 225 */ 226 #define combined(key, active, pending) \ 227 running(key, active), \ 228 stored(key, pending, active) 229 230 enum ice_version_type { 231 ICE_VERSION_FIXED, 232 ICE_VERSION_RUNNING, 233 ICE_VERSION_STORED, 234 }; 235 236 static const struct ice_devlink_version { 237 enum ice_version_type type; 238 const char *key; 239 int (*getter)(struct ice_pf *pf, struct ice_info_ctx *ctx); 240 int (*fallback)(struct ice_pf *pf, struct ice_info_ctx *ctx); 241 } ice_devlink_versions[] = { 242 fixed(DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, ice_info_pba), 243 running(DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, ice_info_fw_mgmt), 244 running("fw.mgmt.api", ice_info_fw_api), 245 running("fw.mgmt.build", ice_info_fw_build), 246 combined(DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, ice_info_orom_ver, ice_info_pending_orom_ver), 247 combined("fw.psid.api", ice_info_nvm_ver, ice_info_pending_nvm_ver), 248 combined(DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, ice_info_eetrack, ice_info_pending_eetrack), 249 running("fw.app.name", ice_info_ddp_pkg_name), 250 running(DEVLINK_INFO_VERSION_GENERIC_FW_APP, ice_info_ddp_pkg_version), 251 running("fw.app.bundle_id", ice_info_ddp_pkg_bundle_id), 252 combined("fw.netlist", ice_info_netlist_ver, ice_info_pending_netlist_ver), 253 combined("fw.netlist.build", ice_info_netlist_build, ice_info_pending_netlist_build), 254 }; 255 256 /** 257 * ice_devlink_info_get - .info_get devlink handler 258 * @devlink: devlink instance structure 259 * @req: the devlink info request 260 * @extack: extended netdev ack structure 261 * 262 * Callback for the devlink .info_get operation. Reports information about the 263 * device. 264 * 265 * Return: zero on success or an error code on failure. 266 */ 267 static int ice_devlink_info_get(struct devlink *devlink, 268 struct devlink_info_req *req, 269 struct netlink_ext_ack *extack) 270 { 271 struct ice_pf *pf = devlink_priv(devlink); 272 struct device *dev = ice_pf_to_dev(pf); 273 struct ice_hw *hw = &pf->hw; 274 struct ice_info_ctx *ctx; 275 enum ice_status status; 276 size_t i; 277 int err; 278 279 err = ice_wait_for_reset(pf, 10 * HZ); 280 if (err) { 281 NL_SET_ERR_MSG_MOD(extack, "Device is busy resetting"); 282 return err; 283 } 284 285 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 286 if (!ctx) 287 return -ENOMEM; 288 289 /* discover capabilities first */ 290 status = ice_discover_dev_caps(hw, &ctx->dev_caps); 291 if (status) { 292 dev_dbg(dev, "Failed to discover device capabilities, status %s aq_err %s\n", 293 ice_stat_str(status), ice_aq_str(hw->adminq.sq_last_status)); 294 NL_SET_ERR_MSG_MOD(extack, "Unable to discover device capabilities"); 295 err = -EIO; 296 goto out_free_ctx; 297 } 298 299 if (ctx->dev_caps.common_cap.nvm_update_pending_orom) { 300 status = ice_get_inactive_orom_ver(hw, &ctx->pending_orom); 301 if (status) { 302 dev_dbg(dev, "Unable to read inactive Option ROM version data, status %s aq_err %s\n", 303 ice_stat_str(status), ice_aq_str(hw->adminq.sq_last_status)); 304 305 /* disable display of pending Option ROM */ 306 ctx->dev_caps.common_cap.nvm_update_pending_orom = false; 307 } 308 } 309 310 if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) { 311 status = ice_get_inactive_nvm_ver(hw, &ctx->pending_nvm); 312 if (status) { 313 dev_dbg(dev, "Unable to read inactive NVM version data, status %s aq_err %s\n", 314 ice_stat_str(status), ice_aq_str(hw->adminq.sq_last_status)); 315 316 /* disable display of pending Option ROM */ 317 ctx->dev_caps.common_cap.nvm_update_pending_nvm = false; 318 } 319 } 320 321 if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) { 322 status = ice_get_inactive_netlist_ver(hw, &ctx->pending_netlist); 323 if (status) { 324 dev_dbg(dev, "Unable to read inactive Netlist version data, status %s aq_err %s\n", 325 ice_stat_str(status), ice_aq_str(hw->adminq.sq_last_status)); 326 327 /* disable display of pending Option ROM */ 328 ctx->dev_caps.common_cap.nvm_update_pending_netlist = false; 329 } 330 } 331 332 err = devlink_info_driver_name_put(req, KBUILD_MODNAME); 333 if (err) { 334 NL_SET_ERR_MSG_MOD(extack, "Unable to set driver name"); 335 goto out_free_ctx; 336 } 337 338 ice_info_get_dsn(pf, ctx); 339 340 err = devlink_info_serial_number_put(req, ctx->buf); 341 if (err) { 342 NL_SET_ERR_MSG_MOD(extack, "Unable to set serial number"); 343 goto out_free_ctx; 344 } 345 346 for (i = 0; i < ARRAY_SIZE(ice_devlink_versions); i++) { 347 enum ice_version_type type = ice_devlink_versions[i].type; 348 const char *key = ice_devlink_versions[i].key; 349 350 memset(ctx->buf, 0, sizeof(ctx->buf)); 351 352 err = ice_devlink_versions[i].getter(pf, ctx); 353 if (err) { 354 NL_SET_ERR_MSG_MOD(extack, "Unable to obtain version info"); 355 goto out_free_ctx; 356 } 357 358 /* If the default getter doesn't report a version, use the 359 * fallback function. This is primarily useful in the case of 360 * "stored" versions that want to report the same value as the 361 * running version in the normal case of no pending update. 362 */ 363 if (ctx->buf[0] == '\0' && ice_devlink_versions[i].fallback) { 364 err = ice_devlink_versions[i].fallback(pf, ctx); 365 if (err) { 366 NL_SET_ERR_MSG_MOD(extack, "Unable to obtain version info"); 367 goto out_free_ctx; 368 } 369 } 370 371 /* Do not report missing versions */ 372 if (ctx->buf[0] == '\0') 373 continue; 374 375 switch (type) { 376 case ICE_VERSION_FIXED: 377 err = devlink_info_version_fixed_put(req, key, ctx->buf); 378 if (err) { 379 NL_SET_ERR_MSG_MOD(extack, "Unable to set fixed version"); 380 goto out_free_ctx; 381 } 382 break; 383 case ICE_VERSION_RUNNING: 384 err = devlink_info_version_running_put(req, key, ctx->buf); 385 if (err) { 386 NL_SET_ERR_MSG_MOD(extack, "Unable to set running version"); 387 goto out_free_ctx; 388 } 389 break; 390 case ICE_VERSION_STORED: 391 err = devlink_info_version_stored_put(req, key, ctx->buf); 392 if (err) { 393 NL_SET_ERR_MSG_MOD(extack, "Unable to set stored version"); 394 goto out_free_ctx; 395 } 396 break; 397 } 398 } 399 400 out_free_ctx: 401 kfree(ctx); 402 return err; 403 } 404 405 /** 406 * ice_devlink_flash_update - Update firmware stored in flash on the device 407 * @devlink: pointer to devlink associated with device to update 408 * @params: flash update parameters 409 * @extack: netlink extended ACK structure 410 * 411 * Perform a device flash update. The bulk of the update logic is contained 412 * within the ice_flash_pldm_image function. 413 * 414 * Returns: zero on success, or an error code on failure. 415 */ 416 static int 417 ice_devlink_flash_update(struct devlink *devlink, 418 struct devlink_flash_update_params *params, 419 struct netlink_ext_ack *extack) 420 { 421 struct ice_pf *pf = devlink_priv(devlink); 422 struct ice_hw *hw = &pf->hw; 423 u8 preservation; 424 int err; 425 426 if (!params->overwrite_mask) { 427 /* preserve all settings and identifiers */ 428 preservation = ICE_AQC_NVM_PRESERVE_ALL; 429 } else if (params->overwrite_mask == DEVLINK_FLASH_OVERWRITE_SETTINGS) { 430 /* overwrite settings, but preserve the vital device identifiers */ 431 preservation = ICE_AQC_NVM_PRESERVE_SELECTED; 432 } else if (params->overwrite_mask == (DEVLINK_FLASH_OVERWRITE_SETTINGS | 433 DEVLINK_FLASH_OVERWRITE_IDENTIFIERS)) { 434 /* overwrite both settings and identifiers, preserve nothing */ 435 preservation = ICE_AQC_NVM_NO_PRESERVATION; 436 } else { 437 NL_SET_ERR_MSG_MOD(extack, "Requested overwrite mask is not supported"); 438 return -EOPNOTSUPP; 439 } 440 441 if (!hw->dev_caps.common_cap.nvm_unified_update) { 442 NL_SET_ERR_MSG_MOD(extack, "Current firmware does not support unified update"); 443 return -EOPNOTSUPP; 444 } 445 446 err = ice_check_for_pending_update(pf, NULL, extack); 447 if (err) 448 return err; 449 450 devlink_flash_update_status_notify(devlink, "Preparing to flash", NULL, 0, 0); 451 452 return ice_flash_pldm_image(pf, params->fw, preservation, extack); 453 } 454 455 static const struct devlink_ops ice_devlink_ops = { 456 .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, 457 .info_get = ice_devlink_info_get, 458 .flash_update = ice_devlink_flash_update, 459 }; 460 461 static void ice_devlink_free(void *devlink_ptr) 462 { 463 devlink_free((struct devlink *)devlink_ptr); 464 } 465 466 /** 467 * ice_allocate_pf - Allocate devlink and return PF structure pointer 468 * @dev: the device to allocate for 469 * 470 * Allocate a devlink instance for this device and return the private area as 471 * the PF structure. The devlink memory is kept track of through devres by 472 * adding an action to remove it when unwinding. 473 */ 474 struct ice_pf *ice_allocate_pf(struct device *dev) 475 { 476 struct devlink *devlink; 477 478 devlink = devlink_alloc(&ice_devlink_ops, sizeof(struct ice_pf)); 479 if (!devlink) 480 return NULL; 481 482 /* Add an action to teardown the devlink when unwinding the driver */ 483 if (devm_add_action(dev, ice_devlink_free, devlink)) { 484 devlink_free(devlink); 485 return NULL; 486 } 487 488 return devlink_priv(devlink); 489 } 490 491 /** 492 * ice_devlink_register - Register devlink interface for this PF 493 * @pf: the PF to register the devlink for. 494 * 495 * Register the devlink instance associated with this physical function. 496 * 497 * Return: zero on success or an error code on failure. 498 */ 499 int ice_devlink_register(struct ice_pf *pf) 500 { 501 struct devlink *devlink = priv_to_devlink(pf); 502 struct device *dev = ice_pf_to_dev(pf); 503 int err; 504 505 err = devlink_register(devlink, dev); 506 if (err) { 507 dev_err(dev, "devlink registration failed: %d\n", err); 508 return err; 509 } 510 511 return 0; 512 } 513 514 /** 515 * ice_devlink_unregister - Unregister devlink resources for this PF. 516 * @pf: the PF structure to cleanup 517 * 518 * Releases resources used by devlink and cleans up associated memory. 519 */ 520 void ice_devlink_unregister(struct ice_pf *pf) 521 { 522 devlink_unregister(priv_to_devlink(pf)); 523 } 524 525 /** 526 * ice_devlink_create_port - Create a devlink port for this VSI 527 * @vsi: the VSI to create a port for 528 * 529 * Create and register a devlink_port for this VSI. 530 * 531 * Return: zero on success or an error code on failure. 532 */ 533 int ice_devlink_create_port(struct ice_vsi *vsi) 534 { 535 struct devlink_port_attrs attrs = {}; 536 struct ice_port_info *pi; 537 struct devlink *devlink; 538 struct device *dev; 539 struct ice_pf *pf; 540 int err; 541 542 /* Currently we only create devlink_port instances for PF VSIs */ 543 if (vsi->type != ICE_VSI_PF) 544 return -EINVAL; 545 546 pf = vsi->back; 547 devlink = priv_to_devlink(pf); 548 dev = ice_pf_to_dev(pf); 549 pi = pf->hw.port_info; 550 551 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 552 attrs.phys.port_number = pi->lport; 553 devlink_port_attrs_set(&vsi->devlink_port, &attrs); 554 err = devlink_port_register(devlink, &vsi->devlink_port, vsi->idx); 555 if (err) { 556 dev_err(dev, "devlink_port_register failed: %d\n", err); 557 return err; 558 } 559 560 vsi->devlink_port_registered = true; 561 562 return 0; 563 } 564 565 /** 566 * ice_devlink_destroy_port - Destroy the devlink_port for this VSI 567 * @vsi: the VSI to cleanup 568 * 569 * Unregisters the devlink_port structure associated with this VSI. 570 */ 571 void ice_devlink_destroy_port(struct ice_vsi *vsi) 572 { 573 if (!vsi->devlink_port_registered) 574 return; 575 576 devlink_port_type_clear(&vsi->devlink_port); 577 devlink_port_unregister(&vsi->devlink_port); 578 579 vsi->devlink_port_registered = false; 580 } 581 582 /** 583 * ice_devlink_nvm_snapshot - Capture a snapshot of the Shadow RAM contents 584 * @devlink: the devlink instance 585 * @ops: the devlink region being snapshotted 586 * @extack: extended ACK response structure 587 * @data: on exit points to snapshot data buffer 588 * 589 * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for 590 * the shadow-ram devlink region. It captures a snapshot of the shadow ram 591 * contents. This snapshot can later be viewed via the devlink-region 592 * interface. 593 * 594 * @returns zero on success, and updates the data pointer. Returns a non-zero 595 * error code on failure. 596 */ 597 static int ice_devlink_nvm_snapshot(struct devlink *devlink, 598 const struct devlink_region_ops *ops, 599 struct netlink_ext_ack *extack, u8 **data) 600 { 601 struct ice_pf *pf = devlink_priv(devlink); 602 struct device *dev = ice_pf_to_dev(pf); 603 struct ice_hw *hw = &pf->hw; 604 enum ice_status status; 605 void *nvm_data; 606 u32 nvm_size; 607 608 nvm_size = hw->flash.flash_size; 609 nvm_data = vzalloc(nvm_size); 610 if (!nvm_data) 611 return -ENOMEM; 612 613 status = ice_acquire_nvm(hw, ICE_RES_READ); 614 if (status) { 615 dev_dbg(dev, "ice_acquire_nvm failed, err %d aq_err %d\n", 616 status, hw->adminq.sq_last_status); 617 NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore"); 618 vfree(nvm_data); 619 return -EIO; 620 } 621 622 status = ice_read_flat_nvm(hw, 0, &nvm_size, nvm_data, false); 623 if (status) { 624 dev_dbg(dev, "ice_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n", 625 nvm_size, status, hw->adminq.sq_last_status); 626 NL_SET_ERR_MSG_MOD(extack, "Failed to read NVM contents"); 627 ice_release_nvm(hw); 628 vfree(nvm_data); 629 return -EIO; 630 } 631 632 ice_release_nvm(hw); 633 634 *data = nvm_data; 635 636 return 0; 637 } 638 639 /** 640 * ice_devlink_devcaps_snapshot - Capture snapshot of device capabilities 641 * @devlink: the devlink instance 642 * @ops: the devlink region being snapshotted 643 * @extack: extended ACK response structure 644 * @data: on exit points to snapshot data buffer 645 * 646 * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for 647 * the device-caps devlink region. It captures a snapshot of the device 648 * capabilities reported by firmware. 649 * 650 * @returns zero on success, and updates the data pointer. Returns a non-zero 651 * error code on failure. 652 */ 653 static int 654 ice_devlink_devcaps_snapshot(struct devlink *devlink, 655 const struct devlink_region_ops *ops, 656 struct netlink_ext_ack *extack, u8 **data) 657 { 658 struct ice_pf *pf = devlink_priv(devlink); 659 struct device *dev = ice_pf_to_dev(pf); 660 struct ice_hw *hw = &pf->hw; 661 enum ice_status status; 662 void *devcaps; 663 664 devcaps = vzalloc(ICE_AQ_MAX_BUF_LEN); 665 if (!devcaps) 666 return -ENOMEM; 667 668 status = ice_aq_list_caps(hw, devcaps, ICE_AQ_MAX_BUF_LEN, NULL, 669 ice_aqc_opc_list_dev_caps, NULL); 670 if (status) { 671 dev_dbg(dev, "ice_aq_list_caps: failed to read device capabilities, err %d aq_err %d\n", 672 status, hw->adminq.sq_last_status); 673 NL_SET_ERR_MSG_MOD(extack, "Failed to read device capabilities"); 674 vfree(devcaps); 675 return -EIO; 676 } 677 678 *data = (u8 *)devcaps; 679 680 return 0; 681 } 682 683 static const struct devlink_region_ops ice_nvm_region_ops = { 684 .name = "nvm-flash", 685 .destructor = vfree, 686 .snapshot = ice_devlink_nvm_snapshot, 687 }; 688 689 static const struct devlink_region_ops ice_devcaps_region_ops = { 690 .name = "device-caps", 691 .destructor = vfree, 692 .snapshot = ice_devlink_devcaps_snapshot, 693 }; 694 695 /** 696 * ice_devlink_init_regions - Initialize devlink regions 697 * @pf: the PF device structure 698 * 699 * Create devlink regions used to enable access to dump the contents of the 700 * flash memory on the device. 701 */ 702 void ice_devlink_init_regions(struct ice_pf *pf) 703 { 704 struct devlink *devlink = priv_to_devlink(pf); 705 struct device *dev = ice_pf_to_dev(pf); 706 u64 nvm_size; 707 708 nvm_size = pf->hw.flash.flash_size; 709 pf->nvm_region = devlink_region_create(devlink, &ice_nvm_region_ops, 1, 710 nvm_size); 711 if (IS_ERR(pf->nvm_region)) { 712 dev_err(dev, "failed to create NVM devlink region, err %ld\n", 713 PTR_ERR(pf->nvm_region)); 714 pf->nvm_region = NULL; 715 } 716 717 pf->devcaps_region = devlink_region_create(devlink, 718 &ice_devcaps_region_ops, 10, 719 ICE_AQ_MAX_BUF_LEN); 720 if (IS_ERR(pf->devcaps_region)) { 721 dev_err(dev, "failed to create device-caps devlink region, err %ld\n", 722 PTR_ERR(pf->devcaps_region)); 723 pf->devcaps_region = NULL; 724 } 725 } 726 727 /** 728 * ice_devlink_destroy_regions - Destroy devlink regions 729 * @pf: the PF device structure 730 * 731 * Remove previously created regions for this PF. 732 */ 733 void ice_devlink_destroy_regions(struct ice_pf *pf) 734 { 735 if (pf->nvm_region) 736 devlink_region_destroy(pf->nvm_region); 737 if (pf->devcaps_region) 738 devlink_region_destroy(pf->devcaps_region); 739 } 740