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