linux/drivers/net/ethernet/intel/ice/ice_nvm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (c) 2018, Intel Corporation. */
   3
   4#include "ice_common.h"
   5
   6/**
   7 * ice_aq_read_nvm
   8 * @hw: pointer to the HW struct
   9 * @module_typeid: module pointer location in words from the NVM beginning
  10 * @offset: byte offset from the module beginning
  11 * @length: length of the section to be read (in bytes from the offset)
  12 * @data: command buffer (size [bytes] = length)
  13 * @last_command: tells if this is the last command in a series
  14 * @read_shadow_ram: tell if this is a shadow RAM read
  15 * @cd: pointer to command details structure or NULL
  16 *
  17 * Read the NVM using the admin queue commands (0x0701)
  18 */
  19static enum ice_status
  20ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
  21                void *data, bool last_command, bool read_shadow_ram,
  22                struct ice_sq_cd *cd)
  23{
  24        struct ice_aq_desc desc;
  25        struct ice_aqc_nvm *cmd;
  26
  27        cmd = &desc.params.nvm;
  28
  29        if (offset > ICE_AQC_NVM_MAX_OFFSET)
  30                return ICE_ERR_PARAM;
  31
  32        ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_read);
  33
  34        if (!read_shadow_ram && module_typeid == ICE_AQC_NVM_START_POINT)
  35                cmd->cmd_flags |= ICE_AQC_NVM_FLASH_ONLY;
  36
  37        /* If this is the last command in a series, set the proper flag. */
  38        if (last_command)
  39                cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
  40        cmd->module_typeid = cpu_to_le16(module_typeid);
  41        cmd->offset_low = cpu_to_le16(offset & 0xFFFF);
  42        cmd->offset_high = (offset >> 16) & 0xFF;
  43        cmd->length = cpu_to_le16(length);
  44
  45        return ice_aq_send_cmd(hw, &desc, data, length, cd);
  46}
  47
  48/**
  49 * ice_read_flat_nvm - Read portion of NVM by flat offset
  50 * @hw: pointer to the HW struct
  51 * @offset: offset from beginning of NVM
  52 * @length: (in) number of bytes to read; (out) number of bytes actually read
  53 * @data: buffer to return data in (sized to fit the specified length)
  54 * @read_shadow_ram: if true, read from shadow RAM instead of NVM
  55 *
  56 * Reads a portion of the NVM, as a flat memory space. This function correctly
  57 * breaks read requests across Shadow RAM sectors and ensures that no single
  58 * read request exceeds the maximum 4KB read for a single AdminQ command.
  59 *
  60 * Returns a status code on failure. Note that the data pointer may be
  61 * partially updated if some reads succeed before a failure.
  62 */
  63enum ice_status
  64ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
  65                  bool read_shadow_ram)
  66{
  67        enum ice_status status;
  68        u32 inlen = *length;
  69        u32 bytes_read = 0;
  70        bool last_cmd;
  71
  72        *length = 0;
  73
  74        /* Verify the length of the read if this is for the Shadow RAM */
  75        if (read_shadow_ram && ((offset + inlen) > (hw->flash.sr_words * 2u))) {
  76                ice_debug(hw, ICE_DBG_NVM, "NVM error: requested offset is beyond Shadow RAM limit\n");
  77                return ICE_ERR_PARAM;
  78        }
  79
  80        do {
  81                u32 read_size, sector_offset;
  82
  83                /* ice_aq_read_nvm cannot read more than 4KB at a time.
  84                 * Additionally, a read from the Shadow RAM may not cross over
  85                 * a sector boundary. Conveniently, the sector size is also
  86                 * 4KB.
  87                 */
  88                sector_offset = offset % ICE_AQ_MAX_BUF_LEN;
  89                read_size = min_t(u32, ICE_AQ_MAX_BUF_LEN - sector_offset,
  90                                  inlen - bytes_read);
  91
  92                last_cmd = !(bytes_read + read_size < inlen);
  93
  94                status = ice_aq_read_nvm(hw, ICE_AQC_NVM_START_POINT,
  95                                         offset, read_size,
  96                                         data + bytes_read, last_cmd,
  97                                         read_shadow_ram, NULL);
  98                if (status)
  99                        break;
 100
 101                bytes_read += read_size;
 102                offset += read_size;
 103        } while (!last_cmd);
 104
 105        *length = bytes_read;
 106        return status;
 107}
 108
 109/**
 110 * ice_aq_update_nvm
 111 * @hw: pointer to the HW struct
 112 * @module_typeid: module pointer location in words from the NVM beginning
 113 * @offset: byte offset from the module beginning
 114 * @length: length of the section to be written (in bytes from the offset)
 115 * @data: command buffer (size [bytes] = length)
 116 * @last_command: tells if this is the last command in a series
 117 * @command_flags: command parameters
 118 * @cd: pointer to command details structure or NULL
 119 *
 120 * Update the NVM using the admin queue commands (0x0703)
 121 */
 122enum ice_status
 123ice_aq_update_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,
 124                  u16 length, void *data, bool last_command, u8 command_flags,
 125                  struct ice_sq_cd *cd)
 126{
 127        struct ice_aq_desc desc;
 128        struct ice_aqc_nvm *cmd;
 129
 130        cmd = &desc.params.nvm;
 131
 132        /* In offset the highest byte must be zeroed. */
 133        if (offset & 0xFF000000)
 134                return ICE_ERR_PARAM;
 135
 136        ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_write);
 137
 138        cmd->cmd_flags |= command_flags;
 139
 140        /* If this is the last command in a series, set the proper flag. */
 141        if (last_command)
 142                cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
 143        cmd->module_typeid = cpu_to_le16(module_typeid);
 144        cmd->offset_low = cpu_to_le16(offset & 0xFFFF);
 145        cmd->offset_high = (offset >> 16) & 0xFF;
 146        cmd->length = cpu_to_le16(length);
 147
 148        desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
 149
 150        return ice_aq_send_cmd(hw, &desc, data, length, cd);
 151}
 152
 153/**
 154 * ice_aq_erase_nvm
 155 * @hw: pointer to the HW struct
 156 * @module_typeid: module pointer location in words from the NVM beginning
 157 * @cd: pointer to command details structure or NULL
 158 *
 159 * Erase the NVM sector using the admin queue commands (0x0702)
 160 */
 161enum ice_status
 162ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd)
 163{
 164        struct ice_aq_desc desc;
 165        struct ice_aqc_nvm *cmd;
 166
 167        cmd = &desc.params.nvm;
 168
 169        ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_erase);
 170
 171        cmd->module_typeid = cpu_to_le16(module_typeid);
 172        cmd->length = cpu_to_le16(ICE_AQC_NVM_ERASE_LEN);
 173        cmd->offset_low = 0;
 174        cmd->offset_high = 0;
 175
 176        return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
 177}
 178
 179/**
 180 * ice_read_sr_word_aq - Reads Shadow RAM via AQ
 181 * @hw: pointer to the HW structure
 182 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
 183 * @data: word read from the Shadow RAM
 184 *
 185 * Reads one 16 bit word from the Shadow RAM using ice_read_flat_nvm.
 186 */
 187static enum ice_status
 188ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
 189{
 190        u32 bytes = sizeof(u16);
 191        enum ice_status status;
 192        __le16 data_local;
 193
 194        /* Note that ice_read_flat_nvm takes into account the 4Kb AdminQ and
 195         * Shadow RAM sector restrictions necessary when reading from the NVM.
 196         */
 197        status = ice_read_flat_nvm(hw, offset * sizeof(u16), &bytes,
 198                                   (__force u8 *)&data_local, true);
 199        if (status)
 200                return status;
 201
 202        *data = le16_to_cpu(data_local);
 203        return 0;
 204}
 205
 206/**
 207 * ice_acquire_nvm - Generic request for acquiring the NVM ownership
 208 * @hw: pointer to the HW structure
 209 * @access: NVM access type (read or write)
 210 *
 211 * This function will request NVM ownership.
 212 */
 213enum ice_status
 214ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
 215{
 216        if (hw->flash.blank_nvm_mode)
 217                return 0;
 218
 219        return ice_acquire_res(hw, ICE_NVM_RES_ID, access, ICE_NVM_TIMEOUT);
 220}
 221
 222/**
 223 * ice_release_nvm - Generic request for releasing the NVM ownership
 224 * @hw: pointer to the HW structure
 225 *
 226 * This function will release NVM ownership.
 227 */
 228void ice_release_nvm(struct ice_hw *hw)
 229{
 230        if (hw->flash.blank_nvm_mode)
 231                return;
 232
 233        ice_release_res(hw, ICE_NVM_RES_ID);
 234}
 235
 236/**
 237 * ice_get_flash_bank_offset - Get offset into requested flash bank
 238 * @hw: pointer to the HW structure
 239 * @bank: whether to read from the active or inactive flash bank
 240 * @module: the module to read from
 241 *
 242 * Based on the module, lookup the module offset from the beginning of the
 243 * flash.
 244 *
 245 * Returns the flash offset. Note that a value of zero is invalid and must be
 246 * treated as an error.
 247 */
 248static u32 ice_get_flash_bank_offset(struct ice_hw *hw, enum ice_bank_select bank, u16 module)
 249{
 250        struct ice_bank_info *banks = &hw->flash.banks;
 251        enum ice_flash_bank active_bank;
 252        bool second_bank_active;
 253        u32 offset, size;
 254
 255        switch (module) {
 256        case ICE_SR_1ST_NVM_BANK_PTR:
 257                offset = banks->nvm_ptr;
 258                size = banks->nvm_size;
 259                active_bank = banks->nvm_bank;
 260                break;
 261        case ICE_SR_1ST_OROM_BANK_PTR:
 262                offset = banks->orom_ptr;
 263                size = banks->orom_size;
 264                active_bank = banks->orom_bank;
 265                break;
 266        case ICE_SR_NETLIST_BANK_PTR:
 267                offset = banks->netlist_ptr;
 268                size = banks->netlist_size;
 269                active_bank = banks->netlist_bank;
 270                break;
 271        default:
 272                ice_debug(hw, ICE_DBG_NVM, "Unexpected value for flash module: 0x%04x\n", module);
 273                return 0;
 274        }
 275
 276        switch (active_bank) {
 277        case ICE_1ST_FLASH_BANK:
 278                second_bank_active = false;
 279                break;
 280        case ICE_2ND_FLASH_BANK:
 281                second_bank_active = true;
 282                break;
 283        default:
 284                ice_debug(hw, ICE_DBG_NVM, "Unexpected value for active flash bank: %u\n",
 285                          active_bank);
 286                return 0;
 287        }
 288
 289        /* The second flash bank is stored immediately following the first
 290         * bank. Based on whether the 1st or 2nd bank is active, and whether
 291         * we want the active or inactive bank, calculate the desired offset.
 292         */
 293        switch (bank) {
 294        case ICE_ACTIVE_FLASH_BANK:
 295                return offset + (second_bank_active ? size : 0);
 296        case ICE_INACTIVE_FLASH_BANK:
 297                return offset + (second_bank_active ? 0 : size);
 298        }
 299
 300        ice_debug(hw, ICE_DBG_NVM, "Unexpected value for flash bank selection: %u\n", bank);
 301        return 0;
 302}
 303
 304/**
 305 * ice_read_flash_module - Read a word from one of the main NVM modules
 306 * @hw: pointer to the HW structure
 307 * @bank: which bank of the module to read
 308 * @module: the module to read
 309 * @offset: the offset into the module in bytes
 310 * @data: storage for the word read from the flash
 311 * @length: bytes of data to read
 312 *
 313 * Read data from the specified flash module. The bank parameter indicates
 314 * whether or not to read from the active bank or the inactive bank of that
 315 * module.
 316 *
 317 * The word will be read using flat NVM access, and relies on the
 318 * hw->flash.banks data being setup by ice_determine_active_flash_banks()
 319 * during initialization.
 320 */
 321static enum ice_status
 322ice_read_flash_module(struct ice_hw *hw, enum ice_bank_select bank, u16 module,
 323                      u32 offset, u8 *data, u32 length)
 324{
 325        enum ice_status status;
 326        u32 start;
 327
 328        start = ice_get_flash_bank_offset(hw, bank, module);
 329        if (!start) {
 330                ice_debug(hw, ICE_DBG_NVM, "Unable to calculate flash bank offset for module 0x%04x\n",
 331                          module);
 332                return ICE_ERR_PARAM;
 333        }
 334
 335        status = ice_acquire_nvm(hw, ICE_RES_READ);
 336        if (status)
 337                return status;
 338
 339        status = ice_read_flat_nvm(hw, start + offset, &length, data, false);
 340
 341        ice_release_nvm(hw);
 342
 343        return status;
 344}
 345
 346/**
 347 * ice_read_nvm_module - Read from the active main NVM module
 348 * @hw: pointer to the HW structure
 349 * @bank: whether to read from active or inactive NVM module
 350 * @offset: offset into the NVM module to read, in words
 351 * @data: storage for returned word value
 352 *
 353 * Read the specified word from the active NVM module. This includes the CSS
 354 * header at the start of the NVM module.
 355 */
 356static enum ice_status
 357ice_read_nvm_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
 358{
 359        enum ice_status status;
 360        __le16 data_local;
 361
 362        status = ice_read_flash_module(hw, bank, ICE_SR_1ST_NVM_BANK_PTR, offset * sizeof(u16),
 363                                       (__force u8 *)&data_local, sizeof(u16));
 364        if (!status)
 365                *data = le16_to_cpu(data_local);
 366
 367        return status;
 368}
 369
 370/**
 371 * ice_read_nvm_sr_copy - Read a word from the Shadow RAM copy in the NVM bank
 372 * @hw: pointer to the HW structure
 373 * @bank: whether to read from the active or inactive NVM module
 374 * @offset: offset into the Shadow RAM copy to read, in words
 375 * @data: storage for returned word value
 376 *
 377 * Read the specified word from the copy of the Shadow RAM found in the
 378 * specified NVM module.
 379 */
 380static enum ice_status
 381ice_read_nvm_sr_copy(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
 382{
 383        return ice_read_nvm_module(hw, bank, ICE_NVM_SR_COPY_WORD_OFFSET + offset, data);
 384}
 385
 386/**
 387 * ice_read_netlist_module - Read data from the netlist module area
 388 * @hw: pointer to the HW structure
 389 * @bank: whether to read from the active or inactive module
 390 * @offset: offset into the netlist to read from
 391 * @data: storage for returned word value
 392 *
 393 * Read a word from the specified netlist bank.
 394 */
 395static enum ice_status
 396ice_read_netlist_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
 397{
 398        enum ice_status status;
 399        __le16 data_local;
 400
 401        status = ice_read_flash_module(hw, bank, ICE_SR_NETLIST_BANK_PTR, offset * sizeof(u16),
 402                                       (__force u8 *)&data_local, sizeof(u16));
 403        if (!status)
 404                *data = le16_to_cpu(data_local);
 405
 406        return status;
 407}
 408
 409/**
 410 * ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary
 411 * @hw: pointer to the HW structure
 412 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
 413 * @data: word read from the Shadow RAM
 414 *
 415 * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
 416 */
 417enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
 418{
 419        enum ice_status status;
 420
 421        status = ice_acquire_nvm(hw, ICE_RES_READ);
 422        if (!status) {
 423                status = ice_read_sr_word_aq(hw, offset, data);
 424                ice_release_nvm(hw);
 425        }
 426
 427        return status;
 428}
 429
 430/**
 431 * ice_get_pfa_module_tlv - Reads sub module TLV from NVM PFA
 432 * @hw: pointer to hardware structure
 433 * @module_tlv: pointer to module TLV to return
 434 * @module_tlv_len: pointer to module TLV length to return
 435 * @module_type: module type requested
 436 *
 437 * Finds the requested sub module TLV type from the Preserved Field
 438 * Area (PFA) and returns the TLV pointer and length. The caller can
 439 * use these to read the variable length TLV value.
 440 */
 441enum ice_status
 442ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
 443                       u16 module_type)
 444{
 445        enum ice_status status;
 446        u16 pfa_len, pfa_ptr;
 447        u16 next_tlv;
 448
 449        status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr);
 450        if (status) {
 451                ice_debug(hw, ICE_DBG_INIT, "Preserved Field Array pointer.\n");
 452                return status;
 453        }
 454        status = ice_read_sr_word(hw, pfa_ptr, &pfa_len);
 455        if (status) {
 456                ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n");
 457                return status;
 458        }
 459        /* Starting with first TLV after PFA length, iterate through the list
 460         * of TLVs to find the requested one.
 461         */
 462        next_tlv = pfa_ptr + 1;
 463        while (next_tlv < pfa_ptr + pfa_len) {
 464                u16 tlv_sub_module_type;
 465                u16 tlv_len;
 466
 467                /* Read TLV type */
 468                status = ice_read_sr_word(hw, next_tlv, &tlv_sub_module_type);
 469                if (status) {
 470                        ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV type.\n");
 471                        break;
 472                }
 473                /* Read TLV length */
 474                status = ice_read_sr_word(hw, next_tlv + 1, &tlv_len);
 475                if (status) {
 476                        ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV length.\n");
 477                        break;
 478                }
 479                if (tlv_sub_module_type == module_type) {
 480                        if (tlv_len) {
 481                                *module_tlv = next_tlv;
 482                                *module_tlv_len = tlv_len;
 483                                return 0;
 484                        }
 485                        return ICE_ERR_INVAL_SIZE;
 486                }
 487                /* Check next TLV, i.e. current TLV pointer + length + 2 words
 488                 * (for current TLV's type and length)
 489                 */
 490                next_tlv = next_tlv + tlv_len + 2;
 491        }
 492        /* Module does not exist */
 493        return ICE_ERR_DOES_NOT_EXIST;
 494}
 495
 496/**
 497 * ice_read_pba_string - Reads part number string from NVM
 498 * @hw: pointer to hardware structure
 499 * @pba_num: stores the part number string from the NVM
 500 * @pba_num_size: part number string buffer length
 501 *
 502 * Reads the part number string from the NVM.
 503 */
 504enum ice_status
 505ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size)
 506{
 507        u16 pba_tlv, pba_tlv_len;
 508        enum ice_status status;
 509        u16 pba_word, pba_size;
 510        u16 i;
 511
 512        status = ice_get_pfa_module_tlv(hw, &pba_tlv, &pba_tlv_len,
 513                                        ICE_SR_PBA_BLOCK_PTR);
 514        if (status) {
 515                ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block TLV.\n");
 516                return status;
 517        }
 518
 519        /* pba_size is the next word */
 520        status = ice_read_sr_word(hw, (pba_tlv + 2), &pba_size);
 521        if (status) {
 522                ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Section size.\n");
 523                return status;
 524        }
 525
 526        if (pba_tlv_len < pba_size) {
 527                ice_debug(hw, ICE_DBG_INIT, "Invalid PBA Block TLV size.\n");
 528                return ICE_ERR_INVAL_SIZE;
 529        }
 530
 531        /* Subtract one to get PBA word count (PBA Size word is included in
 532         * total size)
 533         */
 534        pba_size--;
 535        if (pba_num_size < (((u32)pba_size * 2) + 1)) {
 536                ice_debug(hw, ICE_DBG_INIT, "Buffer too small for PBA data.\n");
 537                return ICE_ERR_PARAM;
 538        }
 539
 540        for (i = 0; i < pba_size; i++) {
 541                status = ice_read_sr_word(hw, (pba_tlv + 2 + 1) + i, &pba_word);
 542                if (status) {
 543                        ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block word %d.\n", i);
 544                        return status;
 545                }
 546
 547                pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
 548                pba_num[(i * 2) + 1] = pba_word & 0xFF;
 549        }
 550        pba_num[(pba_size * 2)] = '\0';
 551
 552        return status;
 553}
 554
 555/**
 556 * ice_get_nvm_ver_info - Read NVM version information
 557 * @hw: pointer to the HW struct
 558 * @bank: whether to read from the active or inactive flash bank
 559 * @nvm: pointer to NVM info structure
 560 *
 561 * Read the NVM EETRACK ID and map version of the main NVM image bank, filling
 562 * in the NVM info structure.
 563 */
 564static enum ice_status
 565ice_get_nvm_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_nvm_info *nvm)
 566{
 567        u16 eetrack_lo, eetrack_hi, ver;
 568        enum ice_status status;
 569
 570        status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_DEV_STARTER_VER, &ver);
 571        if (status) {
 572                ice_debug(hw, ICE_DBG_NVM, "Failed to read DEV starter version.\n");
 573                return status;
 574        }
 575
 576        nvm->major = (ver & ICE_NVM_VER_HI_MASK) >> ICE_NVM_VER_HI_SHIFT;
 577        nvm->minor = (ver & ICE_NVM_VER_LO_MASK) >> ICE_NVM_VER_LO_SHIFT;
 578
 579        status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_EETRACK_LO, &eetrack_lo);
 580        if (status) {
 581                ice_debug(hw, ICE_DBG_NVM, "Failed to read EETRACK lo.\n");
 582                return status;
 583        }
 584        status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_EETRACK_HI, &eetrack_hi);
 585        if (status) {
 586                ice_debug(hw, ICE_DBG_NVM, "Failed to read EETRACK hi.\n");
 587                return status;
 588        }
 589
 590        nvm->eetrack = (eetrack_hi << 16) | eetrack_lo;
 591
 592        return 0;
 593}
 594
 595/**
 596 * ice_get_inactive_nvm_ver - Read Option ROM version from the inactive bank
 597 * @hw: pointer to the HW structure
 598 * @nvm: storage for Option ROM version information
 599 *
 600 * Reads the NVM EETRACK ID, Map version, and security revision of the
 601 * inactive NVM bank. Used to access version data for a pending update that
 602 * has not yet been activated.
 603 */
 604enum ice_status ice_get_inactive_nvm_ver(struct ice_hw *hw, struct ice_nvm_info *nvm)
 605{
 606        return ice_get_nvm_ver_info(hw, ICE_INACTIVE_FLASH_BANK, nvm);
 607}
 608
 609/**
 610 * ice_get_orom_civd_data - Get the combo version information from Option ROM
 611 * @hw: pointer to the HW struct
 612 * @bank: whether to read from the active or inactive flash module
 613 * @civd: storage for the Option ROM CIVD data.
 614 *
 615 * Searches through the Option ROM flash contents to locate the CIVD data for
 616 * the image.
 617 */
 618static enum ice_status
 619ice_get_orom_civd_data(struct ice_hw *hw, enum ice_bank_select bank,
 620                       struct ice_orom_civd_info *civd)
 621{
 622        struct ice_orom_civd_info tmp;
 623        enum ice_status status;
 624        u32 offset;
 625
 626        /* The CIVD section is located in the Option ROM aligned to 512 bytes.
 627         * The first 4 bytes must contain the ASCII characters "$CIV".
 628         * A simple modulo 256 sum of all of the bytes of the structure must
 629         * equal 0.
 630         */
 631        for (offset = 0; (offset + 512) <= hw->flash.banks.orom_size; offset += 512) {
 632                u8 sum = 0, i;
 633
 634                status = ice_read_flash_module(hw, bank, ICE_SR_1ST_OROM_BANK_PTR,
 635                                               offset, (u8 *)&tmp, sizeof(tmp));
 636                if (status) {
 637                        ice_debug(hw, ICE_DBG_NVM, "Unable to read Option ROM CIVD data\n");
 638                        return status;
 639                }
 640
 641                /* Skip forward until we find a matching signature */
 642                if (memcmp("$CIV", tmp.signature, sizeof(tmp.signature)) != 0)
 643                        continue;
 644
 645                /* Verify that the simple checksum is zero */
 646                for (i = 0; i < sizeof(tmp); i++)
 647                        /* cppcheck-suppress objectIndex */
 648                        sum += ((u8 *)&tmp)[i];
 649
 650                if (sum) {
 651                        ice_debug(hw, ICE_DBG_NVM, "Found CIVD data with invalid checksum of %u\n",
 652                                  sum);
 653                        return ICE_ERR_NVM;
 654                }
 655
 656                *civd = tmp;
 657                return 0;
 658        }
 659
 660        return ICE_ERR_NVM;
 661}
 662
 663/**
 664 * ice_get_orom_ver_info - Read Option ROM version information
 665 * @hw: pointer to the HW struct
 666 * @bank: whether to read from the active or inactive flash module
 667 * @orom: pointer to Option ROM info structure
 668 *
 669 * Read Option ROM version and security revision from the Option ROM flash
 670 * section.
 671 */
 672static enum ice_status
 673ice_get_orom_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_orom_info *orom)
 674{
 675        struct ice_orom_civd_info civd;
 676        enum ice_status status;
 677        u32 combo_ver;
 678
 679        status = ice_get_orom_civd_data(hw, bank, &civd);
 680        if (status) {
 681                ice_debug(hw, ICE_DBG_NVM, "Failed to locate valid Option ROM CIVD data\n");
 682                return status;
 683        }
 684
 685        combo_ver = le32_to_cpu(civd.combo_ver);
 686
 687        orom->major = (u8)((combo_ver & ICE_OROM_VER_MASK) >> ICE_OROM_VER_SHIFT);
 688        orom->patch = (u8)(combo_ver & ICE_OROM_VER_PATCH_MASK);
 689        orom->build = (u16)((combo_ver & ICE_OROM_VER_BUILD_MASK) >> ICE_OROM_VER_BUILD_SHIFT);
 690
 691        return 0;
 692}
 693
 694/**
 695 * ice_get_inactive_orom_ver - Read Option ROM version from the inactive bank
 696 * @hw: pointer to the HW structure
 697 * @orom: storage for Option ROM version information
 698 *
 699 * Reads the Option ROM version and security revision data for the inactive
 700 * section of flash. Used to access version data for a pending update that has
 701 * not yet been activated.
 702 */
 703enum ice_status ice_get_inactive_orom_ver(struct ice_hw *hw, struct ice_orom_info *orom)
 704{
 705        return ice_get_orom_ver_info(hw, ICE_INACTIVE_FLASH_BANK, orom);
 706}
 707
 708/**
 709 * ice_get_netlist_info
 710 * @hw: pointer to the HW struct
 711 * @bank: whether to read from the active or inactive flash bank
 712 * @netlist: pointer to netlist version info structure
 713 *
 714 * Get the netlist version information from the requested bank. Reads the Link
 715 * Topology section to find the Netlist ID block and extract the relevant
 716 * information into the netlist version structure.
 717 */
 718static enum ice_status
 719ice_get_netlist_info(struct ice_hw *hw, enum ice_bank_select bank,
 720                     struct ice_netlist_info *netlist)
 721{
 722        u16 module_id, length, node_count, i;
 723        enum ice_status status;
 724        u16 *id_blk;
 725
 726        status = ice_read_netlist_module(hw, bank, ICE_NETLIST_TYPE_OFFSET, &module_id);
 727        if (status)
 728                return status;
 729
 730        if (module_id != ICE_NETLIST_LINK_TOPO_MOD_ID) {
 731                ice_debug(hw, ICE_DBG_NVM, "Expected netlist module_id ID of 0x%04x, but got 0x%04x\n",
 732                          ICE_NETLIST_LINK_TOPO_MOD_ID, module_id);
 733                return ICE_ERR_NVM;
 734        }
 735
 736        status = ice_read_netlist_module(hw, bank, ICE_LINK_TOPO_MODULE_LEN, &length);
 737        if (status)
 738                return status;
 739
 740        /* sanity check that we have at least enough words to store the netlist ID block */
 741        if (length < ICE_NETLIST_ID_BLK_SIZE) {
 742                ice_debug(hw, ICE_DBG_NVM, "Netlist Link Topology module too small. Expected at least %u words, but got %u words.\n",
 743                          ICE_NETLIST_ID_BLK_SIZE, length);
 744                return ICE_ERR_NVM;
 745        }
 746
 747        status = ice_read_netlist_module(hw, bank, ICE_LINK_TOPO_NODE_COUNT, &node_count);
 748        if (status)
 749                return status;
 750        node_count &= ICE_LINK_TOPO_NODE_COUNT_M;
 751
 752        id_blk = kcalloc(ICE_NETLIST_ID_BLK_SIZE, sizeof(*id_blk), GFP_KERNEL);
 753        if (!id_blk)
 754                return ICE_ERR_NO_MEMORY;
 755
 756        /* Read out the entire Netlist ID Block at once. */
 757        status = ice_read_flash_module(hw, bank, ICE_SR_NETLIST_BANK_PTR,
 758                                       ICE_NETLIST_ID_BLK_OFFSET(node_count) * sizeof(u16),
 759                                       (u8 *)id_blk, ICE_NETLIST_ID_BLK_SIZE * sizeof(u16));
 760        if (status)
 761                goto exit_error;
 762
 763        for (i = 0; i < ICE_NETLIST_ID_BLK_SIZE; i++)
 764                id_blk[i] = le16_to_cpu(((__force __le16 *)id_blk)[i]);
 765
 766        netlist->major = id_blk[ICE_NETLIST_ID_BLK_MAJOR_VER_HIGH] << 16 |
 767                         id_blk[ICE_NETLIST_ID_BLK_MAJOR_VER_LOW];
 768        netlist->minor = id_blk[ICE_NETLIST_ID_BLK_MINOR_VER_HIGH] << 16 |
 769                         id_blk[ICE_NETLIST_ID_BLK_MINOR_VER_LOW];
 770        netlist->type = id_blk[ICE_NETLIST_ID_BLK_TYPE_HIGH] << 16 |
 771                        id_blk[ICE_NETLIST_ID_BLK_TYPE_LOW];
 772        netlist->rev = id_blk[ICE_NETLIST_ID_BLK_REV_HIGH] << 16 |
 773                       id_blk[ICE_NETLIST_ID_BLK_REV_LOW];
 774        netlist->cust_ver = id_blk[ICE_NETLIST_ID_BLK_CUST_VER];
 775        /* Read the left most 4 bytes of SHA */
 776        netlist->hash = id_blk[ICE_NETLIST_ID_BLK_SHA_HASH_WORD(15)] << 16 |
 777                        id_blk[ICE_NETLIST_ID_BLK_SHA_HASH_WORD(14)];
 778
 779exit_error:
 780        kfree(id_blk);
 781
 782        return status;
 783}
 784
 785/**
 786 * ice_get_inactive_netlist_ver
 787 * @hw: pointer to the HW struct
 788 * @netlist: pointer to netlist version info structure
 789 *
 790 * Read the netlist version data from the inactive netlist bank. Used to
 791 * extract version data of a pending flash update in order to display the
 792 * version data.
 793 */
 794enum ice_status ice_get_inactive_netlist_ver(struct ice_hw *hw, struct ice_netlist_info *netlist)
 795{
 796        return ice_get_netlist_info(hw, ICE_INACTIVE_FLASH_BANK, netlist);
 797}
 798
 799/**
 800 * ice_discover_flash_size - Discover the available flash size.
 801 * @hw: pointer to the HW struct
 802 *
 803 * The device flash could be up to 16MB in size. However, it is possible that
 804 * the actual size is smaller. Use bisection to determine the accessible size
 805 * of flash memory.
 806 */
 807static enum ice_status ice_discover_flash_size(struct ice_hw *hw)
 808{
 809        u32 min_size = 0, max_size = ICE_AQC_NVM_MAX_OFFSET + 1;
 810        enum ice_status status;
 811
 812        status = ice_acquire_nvm(hw, ICE_RES_READ);
 813        if (status)
 814                return status;
 815
 816        while ((max_size - min_size) > 1) {
 817                u32 offset = (max_size + min_size) / 2;
 818                u32 len = 1;
 819                u8 data;
 820
 821                status = ice_read_flat_nvm(hw, offset, &len, &data, false);
 822                if (status == ICE_ERR_AQ_ERROR &&
 823                    hw->adminq.sq_last_status == ICE_AQ_RC_EINVAL) {
 824                        ice_debug(hw, ICE_DBG_NVM, "%s: New upper bound of %u bytes\n",
 825                                  __func__, offset);
 826                        status = 0;
 827                        max_size = offset;
 828                } else if (!status) {
 829                        ice_debug(hw, ICE_DBG_NVM, "%s: New lower bound of %u bytes\n",
 830                                  __func__, offset);
 831                        min_size = offset;
 832                } else {
 833                        /* an unexpected error occurred */
 834                        goto err_read_flat_nvm;
 835                }
 836        }
 837
 838        ice_debug(hw, ICE_DBG_NVM, "Predicted flash size is %u bytes\n", max_size);
 839
 840        hw->flash.flash_size = max_size;
 841
 842err_read_flat_nvm:
 843        ice_release_nvm(hw);
 844
 845        return status;
 846}
 847
 848/**
 849 * ice_read_sr_pointer - Read the value of a Shadow RAM pointer word
 850 * @hw: pointer to the HW structure
 851 * @offset: the word offset of the Shadow RAM word to read
 852 * @pointer: pointer value read from Shadow RAM
 853 *
 854 * Read the given Shadow RAM word, and convert it to a pointer value specified
 855 * in bytes. This function assumes the specified offset is a valid pointer
 856 * word.
 857 *
 858 * Each pointer word specifies whether it is stored in word size or 4KB
 859 * sector size by using the highest bit. The reported pointer value will be in
 860 * bytes, intended for flat NVM reads.
 861 */
 862static enum ice_status
 863ice_read_sr_pointer(struct ice_hw *hw, u16 offset, u32 *pointer)
 864{
 865        enum ice_status status;
 866        u16 value;
 867
 868        status = ice_read_sr_word(hw, offset, &value);
 869        if (status)
 870                return status;
 871
 872        /* Determine if the pointer is in 4KB or word units */
 873        if (value & ICE_SR_NVM_PTR_4KB_UNITS)
 874                *pointer = (value & ~ICE_SR_NVM_PTR_4KB_UNITS) * 4 * 1024;
 875        else
 876                *pointer = value * 2;
 877
 878        return 0;
 879}
 880
 881/**
 882 * ice_read_sr_area_size - Read an area size from a Shadow RAM word
 883 * @hw: pointer to the HW structure
 884 * @offset: the word offset of the Shadow RAM to read
 885 * @size: size value read from the Shadow RAM
 886 *
 887 * Read the given Shadow RAM word, and convert it to an area size value
 888 * specified in bytes. This function assumes the specified offset is a valid
 889 * area size word.
 890 *
 891 * Each area size word is specified in 4KB sector units. This function reports
 892 * the size in bytes, intended for flat NVM reads.
 893 */
 894static enum ice_status
 895ice_read_sr_area_size(struct ice_hw *hw, u16 offset, u32 *size)
 896{
 897        enum ice_status status;
 898        u16 value;
 899
 900        status = ice_read_sr_word(hw, offset, &value);
 901        if (status)
 902                return status;
 903
 904        /* Area sizes are always specified in 4KB units */
 905        *size = value * 4 * 1024;
 906
 907        return 0;
 908}
 909
 910/**
 911 * ice_determine_active_flash_banks - Discover active bank for each module
 912 * @hw: pointer to the HW struct
 913 *
 914 * Read the Shadow RAM control word and determine which banks are active for
 915 * the NVM, OROM, and Netlist modules. Also read and calculate the associated
 916 * pointer and size. These values are then cached into the ice_flash_info
 917 * structure for later use in order to calculate the correct offset to read
 918 * from the active module.
 919 */
 920static enum ice_status
 921ice_determine_active_flash_banks(struct ice_hw *hw)
 922{
 923        struct ice_bank_info *banks = &hw->flash.banks;
 924        enum ice_status status;
 925        u16 ctrl_word;
 926
 927        status = ice_read_sr_word(hw, ICE_SR_NVM_CTRL_WORD, &ctrl_word);
 928        if (status) {
 929                ice_debug(hw, ICE_DBG_NVM, "Failed to read the Shadow RAM control word\n");
 930                return status;
 931        }
 932
 933        /* Check that the control word indicates validity */
 934        if ((ctrl_word & ICE_SR_CTRL_WORD_1_M) >> ICE_SR_CTRL_WORD_1_S != ICE_SR_CTRL_WORD_VALID) {
 935                ice_debug(hw, ICE_DBG_NVM, "Shadow RAM control word is invalid\n");
 936                return ICE_ERR_CFG;
 937        }
 938
 939        if (!(ctrl_word & ICE_SR_CTRL_WORD_NVM_BANK))
 940                banks->nvm_bank = ICE_1ST_FLASH_BANK;
 941        else
 942                banks->nvm_bank = ICE_2ND_FLASH_BANK;
 943
 944        if (!(ctrl_word & ICE_SR_CTRL_WORD_OROM_BANK))
 945                banks->orom_bank = ICE_1ST_FLASH_BANK;
 946        else
 947                banks->orom_bank = ICE_2ND_FLASH_BANK;
 948
 949        if (!(ctrl_word & ICE_SR_CTRL_WORD_NETLIST_BANK))
 950                banks->netlist_bank = ICE_1ST_FLASH_BANK;
 951        else
 952                banks->netlist_bank = ICE_2ND_FLASH_BANK;
 953
 954        status = ice_read_sr_pointer(hw, ICE_SR_1ST_NVM_BANK_PTR, &banks->nvm_ptr);
 955        if (status) {
 956                ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM bank pointer\n");
 957                return status;
 958        }
 959
 960        status = ice_read_sr_area_size(hw, ICE_SR_NVM_BANK_SIZE, &banks->nvm_size);
 961        if (status) {
 962                ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM bank area size\n");
 963                return status;
 964        }
 965
 966        status = ice_read_sr_pointer(hw, ICE_SR_1ST_OROM_BANK_PTR, &banks->orom_ptr);
 967        if (status) {
 968                ice_debug(hw, ICE_DBG_NVM, "Failed to read OROM bank pointer\n");
 969                return status;
 970        }
 971
 972        status = ice_read_sr_area_size(hw, ICE_SR_OROM_BANK_SIZE, &banks->orom_size);
 973        if (status) {
 974                ice_debug(hw, ICE_DBG_NVM, "Failed to read OROM bank area size\n");
 975                return status;
 976        }
 977
 978        status = ice_read_sr_pointer(hw, ICE_SR_NETLIST_BANK_PTR, &banks->netlist_ptr);
 979        if (status) {
 980                ice_debug(hw, ICE_DBG_NVM, "Failed to read Netlist bank pointer\n");
 981                return status;
 982        }
 983
 984        status = ice_read_sr_area_size(hw, ICE_SR_NETLIST_BANK_SIZE, &banks->netlist_size);
 985        if (status) {
 986                ice_debug(hw, ICE_DBG_NVM, "Failed to read Netlist bank area size\n");
 987                return status;
 988        }
 989
 990        return 0;
 991}
 992
 993/**
 994 * ice_init_nvm - initializes NVM setting
 995 * @hw: pointer to the HW struct
 996 *
 997 * This function reads and populates NVM settings such as Shadow RAM size,
 998 * max_timeout, and blank_nvm_mode
 999 */
1000enum ice_status ice_init_nvm(struct ice_hw *hw)
1001{
1002        struct ice_flash_info *flash = &hw->flash;
1003        enum ice_status status;
1004        u32 fla, gens_stat;
1005        u8 sr_size;
1006
1007        /* The SR size is stored regardless of the NVM programming mode
1008         * as the blank mode may be used in the factory line.
1009         */
1010        gens_stat = rd32(hw, GLNVM_GENS);
1011        sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S;
1012
1013        /* Switching to words (sr_size contains power of 2) */
1014        flash->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB;
1015
1016        /* Check if we are in the normal or blank NVM programming mode */
1017        fla = rd32(hw, GLNVM_FLA);
1018        if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */
1019                flash->blank_nvm_mode = false;
1020        } else {
1021                /* Blank programming mode */
1022                flash->blank_nvm_mode = true;
1023                ice_debug(hw, ICE_DBG_NVM, "NVM init error: unsupported blank mode.\n");
1024                return ICE_ERR_NVM_BLANK_MODE;
1025        }
1026
1027        status = ice_discover_flash_size(hw);
1028        if (status) {
1029                ice_debug(hw, ICE_DBG_NVM, "NVM init error: failed to discover flash size.\n");
1030                return status;
1031        }
1032
1033        status = ice_determine_active_flash_banks(hw);
1034        if (status) {
1035                ice_debug(hw, ICE_DBG_NVM, "Failed to determine active flash banks.\n");
1036                return status;
1037        }
1038
1039        status = ice_get_nvm_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->nvm);
1040        if (status) {
1041                ice_debug(hw, ICE_DBG_INIT, "Failed to read NVM info.\n");
1042                return status;
1043        }
1044
1045        status = ice_get_orom_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->orom);
1046        if (status)
1047                ice_debug(hw, ICE_DBG_INIT, "Failed to read Option ROM info.\n");
1048
1049        /* read the netlist version information */
1050        status = ice_get_netlist_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->netlist);
1051        if (status)
1052                ice_debug(hw, ICE_DBG_INIT, "Failed to read netlist info.\n");
1053
1054        return 0;
1055}
1056
1057/**
1058 * ice_nvm_validate_checksum
1059 * @hw: pointer to the HW struct
1060 *
1061 * Verify NVM PFA checksum validity (0x0706)
1062 */
1063enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw)
1064{
1065        struct ice_aqc_nvm_checksum *cmd;
1066        struct ice_aq_desc desc;
1067        enum ice_status status;
1068
1069        status = ice_acquire_nvm(hw, ICE_RES_READ);
1070        if (status)
1071                return status;
1072
1073        cmd = &desc.params.nvm_checksum;
1074
1075        ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_checksum);
1076        cmd->flags = ICE_AQC_NVM_CHECKSUM_VERIFY;
1077
1078        status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1079        ice_release_nvm(hw);
1080
1081        if (!status)
1082                if (le16_to_cpu(cmd->checksum) != ICE_AQC_NVM_CHECKSUM_CORRECT)
1083                        status = ICE_ERR_NVM_CHECKSUM;
1084
1085        return status;
1086}
1087
1088/**
1089 * ice_nvm_write_activate
1090 * @hw: pointer to the HW struct
1091 * @cmd_flags: NVM activate admin command bits (banks to be validated)
1092 *
1093 * Update the control word with the required banks' validity bits
1094 * and dumps the Shadow RAM to flash (0x0707)
1095 */
1096enum ice_status ice_nvm_write_activate(struct ice_hw *hw, u8 cmd_flags)
1097{
1098        struct ice_aqc_nvm *cmd;
1099        struct ice_aq_desc desc;
1100
1101        cmd = &desc.params.nvm;
1102        ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_write_activate);
1103
1104        cmd->cmd_flags = cmd_flags;
1105
1106        return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1107}
1108
1109/**
1110 * ice_aq_nvm_update_empr
1111 * @hw: pointer to the HW struct
1112 *
1113 * Update empr (0x0709). This command allows SW to
1114 * request an EMPR to activate new FW.
1115 */
1116enum ice_status ice_aq_nvm_update_empr(struct ice_hw *hw)
1117{
1118        struct ice_aq_desc desc;
1119
1120        ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_update_empr);
1121
1122        return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1123}
1124
1125/* ice_nvm_set_pkg_data
1126 * @hw: pointer to the HW struct
1127 * @del_pkg_data_flag: If is set then the current pkg_data store by FW
1128 *                     is deleted.
1129 *                     If bit is set to 1, then buffer should be size 0.
1130 * @data: pointer to buffer
1131 * @length: length of the buffer
1132 * @cd: pointer to command details structure or NULL
1133 *
1134 * Set package data (0x070A). This command is equivalent to the reception
1135 * of a PLDM FW Update GetPackageData cmd. This command should be sent
1136 * as part of the NVM update as the first cmd in the flow.
1137 */
1138
1139enum ice_status
1140ice_nvm_set_pkg_data(struct ice_hw *hw, bool del_pkg_data_flag, u8 *data,
1141                     u16 length, struct ice_sq_cd *cd)
1142{
1143        struct ice_aqc_nvm_pkg_data *cmd;
1144        struct ice_aq_desc desc;
1145
1146        if (length != 0 && !data)
1147                return ICE_ERR_PARAM;
1148
1149        cmd = &desc.params.pkg_data;
1150
1151        ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_pkg_data);
1152        desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1153
1154        if (del_pkg_data_flag)
1155                cmd->cmd_flags |= ICE_AQC_NVM_PKG_DELETE;
1156
1157        return ice_aq_send_cmd(hw, &desc, data, length, cd);
1158}
1159
1160/* ice_nvm_pass_component_tbl
1161 * @hw: pointer to the HW struct
1162 * @data: pointer to buffer
1163 * @length: length of the buffer
1164 * @transfer_flag: parameter for determining stage of the update
1165 * @comp_response: a pointer to the response from the 0x070B AQC.
1166 * @comp_response_code: a pointer to the response code from the 0x070B AQC.
1167 * @cd: pointer to command details structure or NULL
1168 *
1169 * Pass component table (0x070B). This command is equivalent to the reception
1170 * of a PLDM FW Update PassComponentTable cmd. This command should be sent once
1171 * per component. It can be only sent after Set Package Data cmd and before
1172 * actual update. FW will assume these commands are going to be sent until
1173 * the TransferFlag is set to End or StartAndEnd.
1174 */
1175
1176enum ice_status
1177ice_nvm_pass_component_tbl(struct ice_hw *hw, u8 *data, u16 length,
1178                           u8 transfer_flag, u8 *comp_response,
1179                           u8 *comp_response_code, struct ice_sq_cd *cd)
1180{
1181        struct ice_aqc_nvm_pass_comp_tbl *cmd;
1182        struct ice_aq_desc desc;
1183        enum ice_status status;
1184
1185        if (!data || !comp_response || !comp_response_code)
1186                return ICE_ERR_PARAM;
1187
1188        cmd = &desc.params.pass_comp_tbl;
1189
1190        ice_fill_dflt_direct_cmd_desc(&desc,
1191                                      ice_aqc_opc_nvm_pass_component_tbl);
1192        desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1193
1194        cmd->transfer_flag = transfer_flag;
1195        status = ice_aq_send_cmd(hw, &desc, data, length, cd);
1196
1197        if (!status) {
1198                *comp_response = cmd->component_response;
1199                *comp_response_code = cmd->component_response_code;
1200        }
1201        return status;
1202}
1203