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 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 280 if (!ctx) 281 return -ENOMEM; 282 283 /* discover capabilities first */ 284 status = ice_discover_dev_caps(hw, &ctx->dev_caps); 285 if (status) { 286 err = -EIO; 287 goto out_free_ctx; 288 } 289 290 if (ctx->dev_caps.common_cap.nvm_update_pending_orom) { 291 status = ice_get_inactive_orom_ver(hw, &ctx->pending_orom); 292 if (status) { 293 dev_dbg(dev, "Unable to read inactive Option ROM version data, status %s aq_err %s\n", 294 ice_stat_str(status), ice_aq_str(hw->adminq.sq_last_status)); 295 296 /* disable display of pending Option ROM */ 297 ctx->dev_caps.common_cap.nvm_update_pending_orom = false; 298 } 299 } 300 301 if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) { 302 status = ice_get_inactive_nvm_ver(hw, &ctx->pending_nvm); 303 if (status) { 304 dev_dbg(dev, "Unable to read inactive NVM version data, status %s aq_err %s\n", 305 ice_stat_str(status), ice_aq_str(hw->adminq.sq_last_status)); 306 307 /* disable display of pending Option ROM */ 308 ctx->dev_caps.common_cap.nvm_update_pending_nvm = false; 309 } 310 } 311 312 if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) { 313 status = ice_get_inactive_netlist_ver(hw, &ctx->pending_netlist); 314 if (status) { 315 dev_dbg(dev, "Unable to read inactive Netlist version data, status %s aq_err %s\n", 316 ice_stat_str(status), ice_aq_str(hw->adminq.sq_last_status)); 317 318 /* disable display of pending Option ROM */ 319 ctx->dev_caps.common_cap.nvm_update_pending_netlist = false; 320 } 321 } 322 323 err = devlink_info_driver_name_put(req, KBUILD_MODNAME); 324 if (err) { 325 NL_SET_ERR_MSG_MOD(extack, "Unable to set driver name"); 326 goto out_free_ctx; 327 } 328 329 ice_info_get_dsn(pf, ctx); 330 331 err = devlink_info_serial_number_put(req, ctx->buf); 332 if (err) { 333 NL_SET_ERR_MSG_MOD(extack, "Unable to set serial number"); 334 goto out_free_ctx; 335 } 336 337 for (i = 0; i < ARRAY_SIZE(ice_devlink_versions); i++) { 338 enum ice_version_type type = ice_devlink_versions[i].type; 339 const char *key = ice_devlink_versions[i].key; 340 341 memset(ctx->buf, 0, sizeof(ctx->buf)); 342 343 err = ice_devlink_versions[i].getter(pf, ctx); 344 if (err) { 345 NL_SET_ERR_MSG_MOD(extack, "Unable to obtain version info"); 346 goto out_free_ctx; 347 } 348 349 /* If the default getter doesn't report a version, use the 350 * fallback function. This is primarily useful in the case of 351 * "stored" versions that want to report the same value as the 352 * running version in the normal case of no pending update. 353 */ 354 if (ctx->buf[0] == '\0' && ice_devlink_versions[i].fallback) { 355 err = ice_devlink_versions[i].fallback(pf, ctx); 356 if (err) { 357 NL_SET_ERR_MSG_MOD(extack, "Unable to obtain version info"); 358 goto out_free_ctx; 359 } 360 } 361 362 /* Do not report missing versions */ 363 if (ctx->buf[0] == '\0') 364 continue; 365 366 switch (type) { 367 case ICE_VERSION_FIXED: 368 err = devlink_info_version_fixed_put(req, key, ctx->buf); 369 if (err) { 370 NL_SET_ERR_MSG_MOD(extack, "Unable to set fixed version"); 371 goto out_free_ctx; 372 } 373 break; 374 case ICE_VERSION_RUNNING: 375 err = devlink_info_version_running_put(req, key, ctx->buf); 376 if (err) { 377 NL_SET_ERR_MSG_MOD(extack, "Unable to set running version"); 378 goto out_free_ctx; 379 } 380 break; 381 case ICE_VERSION_STORED: 382 err = devlink_info_version_stored_put(req, key, ctx->buf); 383 if (err) { 384 NL_SET_ERR_MSG_MOD(extack, "Unable to set stored version"); 385 goto out_free_ctx; 386 } 387 break; 388 } 389 } 390 391 out_free_ctx: 392 kfree(ctx); 393 return err; 394 } 395 396 /** 397 * ice_devlink_flash_update - Update firmware stored in flash on the device 398 * @devlink: pointer to devlink associated with device to update 399 * @params: flash update parameters 400 * @extack: netlink extended ACK structure 401 * 402 * Perform a device flash update. The bulk of the update logic is contained 403 * within the ice_flash_pldm_image function. 404 * 405 * Returns: zero on success, or an error code on failure. 406 */ 407 static int 408 ice_devlink_flash_update(struct devlink *devlink, 409 struct devlink_flash_update_params *params, 410 struct netlink_ext_ack *extack) 411 { 412 struct ice_pf *pf = devlink_priv(devlink); 413 struct ice_hw *hw = &pf->hw; 414 u8 preservation; 415 int err; 416 417 if (!params->overwrite_mask) { 418 /* preserve all settings and identifiers */ 419 preservation = ICE_AQC_NVM_PRESERVE_ALL; 420 } else if (params->overwrite_mask == DEVLINK_FLASH_OVERWRITE_SETTINGS) { 421 /* overwrite settings, but preserve the vital device identifiers */ 422 preservation = ICE_AQC_NVM_PRESERVE_SELECTED; 423 } else if (params->overwrite_mask == (DEVLINK_FLASH_OVERWRITE_SETTINGS | 424 DEVLINK_FLASH_OVERWRITE_IDENTIFIERS)) { 425 /* overwrite both settings and identifiers, preserve nothing */ 426 preservation = ICE_AQC_NVM_NO_PRESERVATION; 427 } else { 428 NL_SET_ERR_MSG_MOD(extack, "Requested overwrite mask is not supported"); 429 return -EOPNOTSUPP; 430 } 431 432 if (!hw->dev_caps.common_cap.nvm_unified_update) { 433 NL_SET_ERR_MSG_MOD(extack, "Current firmware does not support unified update"); 434 return -EOPNOTSUPP; 435 } 436 437 err = ice_check_for_pending_update(pf, NULL, extack); 438 if (err) 439 return err; 440 441 devlink_flash_update_status_notify(devlink, "Preparing to flash", NULL, 0, 0); 442 443 return ice_flash_pldm_image(pf, params->fw, preservation, extack); 444 } 445 446 static const struct devlink_ops ice_devlink_ops = { 447 .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, 448 .info_get = ice_devlink_info_get, 449 .flash_update = ice_devlink_flash_update, 450 }; 451 452 static void ice_devlink_free(void *devlink_ptr) 453 { 454 devlink_free((struct devlink *)devlink_ptr); 455 } 456 457 /** 458 * ice_allocate_pf - Allocate devlink and return PF structure pointer 459 * @dev: the device to allocate for 460 * 461 * Allocate a devlink instance for this device and return the private area as 462 * the PF structure. The devlink memory is kept track of through devres by 463 * adding an action to remove it when unwinding. 464 */ 465 struct ice_pf *ice_allocate_pf(struct device *dev) 466 { 467 struct devlink *devlink; 468 469 devlink = devlink_alloc(&ice_devlink_ops, sizeof(struct ice_pf)); 470 if (!devlink) 471 return NULL; 472 473 /* Add an action to teardown the devlink when unwinding the driver */ 474 if (devm_add_action(dev, ice_devlink_free, devlink)) { 475 devlink_free(devlink); 476 return NULL; 477 } 478 479 return devlink_priv(devlink); 480 } 481 482 /** 483 * ice_devlink_register - Register devlink interface for this PF 484 * @pf: the PF to register the devlink for. 485 * 486 * Register the devlink instance associated with this physical function. 487 * 488 * Return: zero on success or an error code on failure. 489 */ 490 int ice_devlink_register(struct ice_pf *pf) 491 { 492 struct devlink *devlink = priv_to_devlink(pf); 493 struct device *dev = ice_pf_to_dev(pf); 494 int err; 495 496 err = devlink_register(devlink, dev); 497 if (err) { 498 dev_err(dev, "devlink registration failed: %d\n", err); 499 return err; 500 } 501 502 return 0; 503 } 504 505 /** 506 * ice_devlink_unregister - Unregister devlink resources for this PF. 507 * @pf: the PF structure to cleanup 508 * 509 * Releases resources used by devlink and cleans up associated memory. 510 */ 511 void ice_devlink_unregister(struct ice_pf *pf) 512 { 513 devlink_unregister(priv_to_devlink(pf)); 514 } 515 516 /** 517 * ice_devlink_create_port - Create a devlink port for this VSI 518 * @vsi: the VSI to create a port for 519 * 520 * Create and register a devlink_port for this VSI. 521 * 522 * Return: zero on success or an error code on failure. 523 */ 524 int ice_devlink_create_port(struct ice_vsi *vsi) 525 { 526 struct devlink_port_attrs attrs = {}; 527 struct ice_port_info *pi; 528 struct devlink *devlink; 529 struct device *dev; 530 struct ice_pf *pf; 531 int err; 532 533 /* Currently we only create devlink_port instances for PF VSIs */ 534 if (vsi->type != ICE_VSI_PF) 535 return -EINVAL; 536 537 pf = vsi->back; 538 devlink = priv_to_devlink(pf); 539 dev = ice_pf_to_dev(pf); 540 pi = pf->hw.port_info; 541 542 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 543 attrs.phys.port_number = pi->lport; 544 devlink_port_attrs_set(&vsi->devlink_port, &attrs); 545 err = devlink_port_register(devlink, &vsi->devlink_port, vsi->idx); 546 if (err) { 547 dev_err(dev, "devlink_port_register failed: %d\n", err); 548 return err; 549 } 550 551 vsi->devlink_port_registered = true; 552 553 return 0; 554 } 555 556 /** 557 * ice_devlink_destroy_port - Destroy the devlink_port for this VSI 558 * @vsi: the VSI to cleanup 559 * 560 * Unregisters the devlink_port structure associated with this VSI. 561 */ 562 void ice_devlink_destroy_port(struct ice_vsi *vsi) 563 { 564 if (!vsi->devlink_port_registered) 565 return; 566 567 devlink_port_type_clear(&vsi->devlink_port); 568 devlink_port_unregister(&vsi->devlink_port); 569 570 vsi->devlink_port_registered = false; 571 } 572 573 /** 574 * ice_devlink_nvm_snapshot - Capture a snapshot of the Shadow RAM contents 575 * @devlink: the devlink instance 576 * @ops: the devlink region being snapshotted 577 * @extack: extended ACK response structure 578 * @data: on exit points to snapshot data buffer 579 * 580 * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for 581 * the shadow-ram devlink region. It captures a snapshot of the shadow ram 582 * contents. This snapshot can later be viewed via the devlink-region 583 * interface. 584 * 585 * @returns zero on success, and updates the data pointer. Returns a non-zero 586 * error code on failure. 587 */ 588 static int ice_devlink_nvm_snapshot(struct devlink *devlink, 589 const struct devlink_region_ops *ops, 590 struct netlink_ext_ack *extack, u8 **data) 591 { 592 struct ice_pf *pf = devlink_priv(devlink); 593 struct device *dev = ice_pf_to_dev(pf); 594 struct ice_hw *hw = &pf->hw; 595 enum ice_status status; 596 void *nvm_data; 597 u32 nvm_size; 598 599 nvm_size = hw->flash.flash_size; 600 nvm_data = vzalloc(nvm_size); 601 if (!nvm_data) 602 return -ENOMEM; 603 604 status = ice_acquire_nvm(hw, ICE_RES_READ); 605 if (status) { 606 dev_dbg(dev, "ice_acquire_nvm failed, err %d aq_err %d\n", 607 status, hw->adminq.sq_last_status); 608 NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore"); 609 vfree(nvm_data); 610 return -EIO; 611 } 612 613 status = ice_read_flat_nvm(hw, 0, &nvm_size, nvm_data, false); 614 if (status) { 615 dev_dbg(dev, "ice_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n", 616 nvm_size, status, hw->adminq.sq_last_status); 617 NL_SET_ERR_MSG_MOD(extack, "Failed to read NVM contents"); 618 ice_release_nvm(hw); 619 vfree(nvm_data); 620 return -EIO; 621 } 622 623 ice_release_nvm(hw); 624 625 *data = nvm_data; 626 627 return 0; 628 } 629 630 /** 631 * ice_devlink_devcaps_snapshot - Capture snapshot of device capabilities 632 * @devlink: the devlink instance 633 * @ops: the devlink region being snapshotted 634 * @extack: extended ACK response structure 635 * @data: on exit points to snapshot data buffer 636 * 637 * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for 638 * the device-caps devlink region. It captures a snapshot of the device 639 * capabilities reported by firmware. 640 * 641 * @returns zero on success, and updates the data pointer. Returns a non-zero 642 * error code on failure. 643 */ 644 static int 645 ice_devlink_devcaps_snapshot(struct devlink *devlink, 646 const struct devlink_region_ops *ops, 647 struct netlink_ext_ack *extack, u8 **data) 648 { 649 struct ice_pf *pf = devlink_priv(devlink); 650 struct device *dev = ice_pf_to_dev(pf); 651 struct ice_hw *hw = &pf->hw; 652 enum ice_status status; 653 void *devcaps; 654 655 devcaps = vzalloc(ICE_AQ_MAX_BUF_LEN); 656 if (!devcaps) 657 return -ENOMEM; 658 659 status = ice_aq_list_caps(hw, devcaps, ICE_AQ_MAX_BUF_LEN, NULL, 660 ice_aqc_opc_list_dev_caps, NULL); 661 if (status) { 662 dev_dbg(dev, "ice_aq_list_caps: failed to read device capabilities, err %d aq_err %d\n", 663 status, hw->adminq.sq_last_status); 664 NL_SET_ERR_MSG_MOD(extack, "Failed to read device capabilities"); 665 vfree(devcaps); 666 return -EIO; 667 } 668 669 *data = (u8 *)devcaps; 670 671 return 0; 672 } 673 674 static const struct devlink_region_ops ice_nvm_region_ops = { 675 .name = "nvm-flash", 676 .destructor = vfree, 677 .snapshot = ice_devlink_nvm_snapshot, 678 }; 679 680 static const struct devlink_region_ops ice_devcaps_region_ops = { 681 .name = "device-caps", 682 .destructor = vfree, 683 .snapshot = ice_devlink_devcaps_snapshot, 684 }; 685 686 /** 687 * ice_devlink_init_regions - Initialize devlink regions 688 * @pf: the PF device structure 689 * 690 * Create devlink regions used to enable access to dump the contents of the 691 * flash memory on the device. 692 */ 693 void ice_devlink_init_regions(struct ice_pf *pf) 694 { 695 struct devlink *devlink = priv_to_devlink(pf); 696 struct device *dev = ice_pf_to_dev(pf); 697 u64 nvm_size; 698 699 nvm_size = pf->hw.flash.flash_size; 700 pf->nvm_region = devlink_region_create(devlink, &ice_nvm_region_ops, 1, 701 nvm_size); 702 if (IS_ERR(pf->nvm_region)) { 703 dev_err(dev, "failed to create NVM devlink region, err %ld\n", 704 PTR_ERR(pf->nvm_region)); 705 pf->nvm_region = NULL; 706 } 707 708 pf->devcaps_region = devlink_region_create(devlink, 709 &ice_devcaps_region_ops, 10, 710 ICE_AQ_MAX_BUF_LEN); 711 if (IS_ERR(pf->devcaps_region)) { 712 dev_err(dev, "failed to create device-caps devlink region, err %ld\n", 713 PTR_ERR(pf->devcaps_region)); 714 pf->devcaps_region = NULL; 715 } 716 } 717 718 /** 719 * ice_devlink_destroy_regions - Destroy devlink regions 720 * @pf: the PF device structure 721 * 722 * Remove previously created regions for this PF. 723 */ 724 void ice_devlink_destroy_regions(struct ice_pf *pf) 725 { 726 if (pf->nvm_region) 727 devlink_region_destroy(pf->nvm_region); 728 if (pf->devcaps_region) 729 devlink_region_destroy(pf->devcaps_region); 730 } 731