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