Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2018, Intel Corporation. */
0003 
0004 #include <linux/vmalloc.h>
0005 
0006 #include "ice_common.h"
0007 
0008 /**
0009  * ice_aq_read_nvm
0010  * @hw: pointer to the HW struct
0011  * @module_typeid: module pointer location in words from the NVM beginning
0012  * @offset: byte offset from the module beginning
0013  * @length: length of the section to be read (in bytes from the offset)
0014  * @data: command buffer (size [bytes] = length)
0015  * @last_command: tells if this is the last command in a series
0016  * @read_shadow_ram: tell if this is a shadow RAM read
0017  * @cd: pointer to command details structure or NULL
0018  *
0019  * Read the NVM using the admin queue commands (0x0701)
0020  */
0021 static int
0022 ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
0023         void *data, bool last_command, bool read_shadow_ram,
0024         struct ice_sq_cd *cd)
0025 {
0026     struct ice_aq_desc desc;
0027     struct ice_aqc_nvm *cmd;
0028 
0029     cmd = &desc.params.nvm;
0030 
0031     if (offset > ICE_AQC_NVM_MAX_OFFSET)
0032         return -EINVAL;
0033 
0034     ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_read);
0035 
0036     if (!read_shadow_ram && module_typeid == ICE_AQC_NVM_START_POINT)
0037         cmd->cmd_flags |= ICE_AQC_NVM_FLASH_ONLY;
0038 
0039     /* If this is the last command in a series, set the proper flag. */
0040     if (last_command)
0041         cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
0042     cmd->module_typeid = cpu_to_le16(module_typeid);
0043     cmd->offset_low = cpu_to_le16(offset & 0xFFFF);
0044     cmd->offset_high = (offset >> 16) & 0xFF;
0045     cmd->length = cpu_to_le16(length);
0046 
0047     return ice_aq_send_cmd(hw, &desc, data, length, cd);
0048 }
0049 
0050 /**
0051  * ice_read_flat_nvm - Read portion of NVM by flat offset
0052  * @hw: pointer to the HW struct
0053  * @offset: offset from beginning of NVM
0054  * @length: (in) number of bytes to read; (out) number of bytes actually read
0055  * @data: buffer to return data in (sized to fit the specified length)
0056  * @read_shadow_ram: if true, read from shadow RAM instead of NVM
0057  *
0058  * Reads a portion of the NVM, as a flat memory space. This function correctly
0059  * breaks read requests across Shadow RAM sectors and ensures that no single
0060  * read request exceeds the maximum 4KB read for a single AdminQ command.
0061  *
0062  * Returns a status code on failure. Note that the data pointer may be
0063  * partially updated if some reads succeed before a failure.
0064  */
0065 int
0066 ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
0067           bool read_shadow_ram)
0068 {
0069     u32 inlen = *length;
0070     u32 bytes_read = 0;
0071     bool last_cmd;
0072     int status;
0073 
0074     *length = 0;
0075 
0076     /* Verify the length of the read if this is for the Shadow RAM */
0077     if (read_shadow_ram && ((offset + inlen) > (hw->flash.sr_words * 2u))) {
0078         ice_debug(hw, ICE_DBG_NVM, "NVM error: requested offset is beyond Shadow RAM limit\n");
0079         return -EINVAL;
0080     }
0081 
0082     do {
0083         u32 read_size, sector_offset;
0084 
0085         /* ice_aq_read_nvm cannot read more than 4KB at a time.
0086          * Additionally, a read from the Shadow RAM may not cross over
0087          * a sector boundary. Conveniently, the sector size is also
0088          * 4KB.
0089          */
0090         sector_offset = offset % ICE_AQ_MAX_BUF_LEN;
0091         read_size = min_t(u32, ICE_AQ_MAX_BUF_LEN - sector_offset,
0092                   inlen - bytes_read);
0093 
0094         last_cmd = !(bytes_read + read_size < inlen);
0095 
0096         status = ice_aq_read_nvm(hw, ICE_AQC_NVM_START_POINT,
0097                      offset, read_size,
0098                      data + bytes_read, last_cmd,
0099                      read_shadow_ram, NULL);
0100         if (status)
0101             break;
0102 
0103         bytes_read += read_size;
0104         offset += read_size;
0105     } while (!last_cmd);
0106 
0107     *length = bytes_read;
0108     return status;
0109 }
0110 
0111 /**
0112  * ice_aq_update_nvm
0113  * @hw: pointer to the HW struct
0114  * @module_typeid: module pointer location in words from the NVM beginning
0115  * @offset: byte offset from the module beginning
0116  * @length: length of the section to be written (in bytes from the offset)
0117  * @data: command buffer (size [bytes] = length)
0118  * @last_command: tells if this is the last command in a series
0119  * @command_flags: command parameters
0120  * @cd: pointer to command details structure or NULL
0121  *
0122  * Update the NVM using the admin queue commands (0x0703)
0123  */
0124 int
0125 ice_aq_update_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,
0126           u16 length, void *data, bool last_command, u8 command_flags,
0127           struct ice_sq_cd *cd)
0128 {
0129     struct ice_aq_desc desc;
0130     struct ice_aqc_nvm *cmd;
0131 
0132     cmd = &desc.params.nvm;
0133 
0134     /* In offset the highest byte must be zeroed. */
0135     if (offset & 0xFF000000)
0136         return -EINVAL;
0137 
0138     ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_write);
0139 
0140     cmd->cmd_flags |= command_flags;
0141 
0142     /* If this is the last command in a series, set the proper flag. */
0143     if (last_command)
0144         cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
0145     cmd->module_typeid = cpu_to_le16(module_typeid);
0146     cmd->offset_low = cpu_to_le16(offset & 0xFFFF);
0147     cmd->offset_high = (offset >> 16) & 0xFF;
0148     cmd->length = cpu_to_le16(length);
0149 
0150     desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
0151 
0152     return ice_aq_send_cmd(hw, &desc, data, length, cd);
0153 }
0154 
0155 /**
0156  * ice_aq_erase_nvm
0157  * @hw: pointer to the HW struct
0158  * @module_typeid: module pointer location in words from the NVM beginning
0159  * @cd: pointer to command details structure or NULL
0160  *
0161  * Erase the NVM sector using the admin queue commands (0x0702)
0162  */
0163 int ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd)
0164 {
0165     struct ice_aq_desc desc;
0166     struct ice_aqc_nvm *cmd;
0167 
0168     cmd = &desc.params.nvm;
0169 
0170     ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_erase);
0171 
0172     cmd->module_typeid = cpu_to_le16(module_typeid);
0173     cmd->length = cpu_to_le16(ICE_AQC_NVM_ERASE_LEN);
0174     cmd->offset_low = 0;
0175     cmd->offset_high = 0;
0176 
0177     return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
0178 }
0179 
0180 /**
0181  * ice_read_sr_word_aq - Reads Shadow RAM via AQ
0182  * @hw: pointer to the HW structure
0183  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
0184  * @data: word read from the Shadow RAM
0185  *
0186  * Reads one 16 bit word from the Shadow RAM using ice_read_flat_nvm.
0187  */
0188 static int ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
0189 {
0190     u32 bytes = sizeof(u16);
0191     __le16 data_local;
0192     int status;
0193 
0194     /* Note that ice_read_flat_nvm takes into account the 4Kb AdminQ and
0195      * Shadow RAM sector restrictions necessary when reading from the NVM.
0196      */
0197     status = ice_read_flat_nvm(hw, offset * sizeof(u16), &bytes,
0198                    (__force u8 *)&data_local, true);
0199     if (status)
0200         return status;
0201 
0202     *data = le16_to_cpu(data_local);
0203     return 0;
0204 }
0205 
0206 /**
0207  * ice_acquire_nvm - Generic request for acquiring the NVM ownership
0208  * @hw: pointer to the HW structure
0209  * @access: NVM access type (read or write)
0210  *
0211  * This function will request NVM ownership.
0212  */
0213 int ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
0214 {
0215     if (hw->flash.blank_nvm_mode)
0216         return 0;
0217 
0218     return ice_acquire_res(hw, ICE_NVM_RES_ID, access, ICE_NVM_TIMEOUT);
0219 }
0220 
0221 /**
0222  * ice_release_nvm - Generic request for releasing the NVM ownership
0223  * @hw: pointer to the HW structure
0224  *
0225  * This function will release NVM ownership.
0226  */
0227 void ice_release_nvm(struct ice_hw *hw)
0228 {
0229     if (hw->flash.blank_nvm_mode)
0230         return;
0231 
0232     ice_release_res(hw, ICE_NVM_RES_ID);
0233 }
0234 
0235 /**
0236  * ice_get_flash_bank_offset - Get offset into requested flash bank
0237  * @hw: pointer to the HW structure
0238  * @bank: whether to read from the active or inactive flash bank
0239  * @module: the module to read from
0240  *
0241  * Based on the module, lookup the module offset from the beginning of the
0242  * flash.
0243  *
0244  * Returns the flash offset. Note that a value of zero is invalid and must be
0245  * treated as an error.
0246  */
0247 static u32 ice_get_flash_bank_offset(struct ice_hw *hw, enum ice_bank_select bank, u16 module)
0248 {
0249     struct ice_bank_info *banks = &hw->flash.banks;
0250     enum ice_flash_bank active_bank;
0251     bool second_bank_active;
0252     u32 offset, size;
0253 
0254     switch (module) {
0255     case ICE_SR_1ST_NVM_BANK_PTR:
0256         offset = banks->nvm_ptr;
0257         size = banks->nvm_size;
0258         active_bank = banks->nvm_bank;
0259         break;
0260     case ICE_SR_1ST_OROM_BANK_PTR:
0261         offset = banks->orom_ptr;
0262         size = banks->orom_size;
0263         active_bank = banks->orom_bank;
0264         break;
0265     case ICE_SR_NETLIST_BANK_PTR:
0266         offset = banks->netlist_ptr;
0267         size = banks->netlist_size;
0268         active_bank = banks->netlist_bank;
0269         break;
0270     default:
0271         ice_debug(hw, ICE_DBG_NVM, "Unexpected value for flash module: 0x%04x\n", module);
0272         return 0;
0273     }
0274 
0275     switch (active_bank) {
0276     case ICE_1ST_FLASH_BANK:
0277         second_bank_active = false;
0278         break;
0279     case ICE_2ND_FLASH_BANK:
0280         second_bank_active = true;
0281         break;
0282     default:
0283         ice_debug(hw, ICE_DBG_NVM, "Unexpected value for active flash bank: %u\n",
0284               active_bank);
0285         return 0;
0286     }
0287 
0288     /* The second flash bank is stored immediately following the first
0289      * bank. Based on whether the 1st or 2nd bank is active, and whether
0290      * we want the active or inactive bank, calculate the desired offset.
0291      */
0292     switch (bank) {
0293     case ICE_ACTIVE_FLASH_BANK:
0294         return offset + (second_bank_active ? size : 0);
0295     case ICE_INACTIVE_FLASH_BANK:
0296         return offset + (second_bank_active ? 0 : size);
0297     }
0298 
0299     ice_debug(hw, ICE_DBG_NVM, "Unexpected value for flash bank selection: %u\n", bank);
0300     return 0;
0301 }
0302 
0303 /**
0304  * ice_read_flash_module - Read a word from one of the main NVM modules
0305  * @hw: pointer to the HW structure
0306  * @bank: which bank of the module to read
0307  * @module: the module to read
0308  * @offset: the offset into the module in bytes
0309  * @data: storage for the word read from the flash
0310  * @length: bytes of data to read
0311  *
0312  * Read data from the specified flash module. The bank parameter indicates
0313  * whether or not to read from the active bank or the inactive bank of that
0314  * module.
0315  *
0316  * The word will be read using flat NVM access, and relies on the
0317  * hw->flash.banks data being setup by ice_determine_active_flash_banks()
0318  * during initialization.
0319  */
0320 static int
0321 ice_read_flash_module(struct ice_hw *hw, enum ice_bank_select bank, u16 module,
0322               u32 offset, u8 *data, u32 length)
0323 {
0324     int status;
0325     u32 start;
0326 
0327     start = ice_get_flash_bank_offset(hw, bank, module);
0328     if (!start) {
0329         ice_debug(hw, ICE_DBG_NVM, "Unable to calculate flash bank offset for module 0x%04x\n",
0330               module);
0331         return -EINVAL;
0332     }
0333 
0334     status = ice_acquire_nvm(hw, ICE_RES_READ);
0335     if (status)
0336         return status;
0337 
0338     status = ice_read_flat_nvm(hw, start + offset, &length, data, false);
0339 
0340     ice_release_nvm(hw);
0341 
0342     return status;
0343 }
0344 
0345 /**
0346  * ice_read_nvm_module - Read from the active main NVM module
0347  * @hw: pointer to the HW structure
0348  * @bank: whether to read from active or inactive NVM module
0349  * @offset: offset into the NVM module to read, in words
0350  * @data: storage for returned word value
0351  *
0352  * Read the specified word from the active NVM module. This includes the CSS
0353  * header at the start of the NVM module.
0354  */
0355 static int
0356 ice_read_nvm_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
0357 {
0358     __le16 data_local;
0359     int status;
0360 
0361     status = ice_read_flash_module(hw, bank, ICE_SR_1ST_NVM_BANK_PTR, offset * sizeof(u16),
0362                        (__force u8 *)&data_local, sizeof(u16));
0363     if (!status)
0364         *data = le16_to_cpu(data_local);
0365 
0366     return status;
0367 }
0368 
0369 /**
0370  * ice_read_nvm_sr_copy - Read a word from the Shadow RAM copy in the NVM bank
0371  * @hw: pointer to the HW structure
0372  * @bank: whether to read from the active or inactive NVM module
0373  * @offset: offset into the Shadow RAM copy to read, in words
0374  * @data: storage for returned word value
0375  *
0376  * Read the specified word from the copy of the Shadow RAM found in the
0377  * specified NVM module.
0378  */
0379 static int
0380 ice_read_nvm_sr_copy(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
0381 {
0382     return ice_read_nvm_module(hw, bank, ICE_NVM_SR_COPY_WORD_OFFSET + offset, data);
0383 }
0384 
0385 /**
0386  * ice_read_netlist_module - Read data from the netlist module area
0387  * @hw: pointer to the HW structure
0388  * @bank: whether to read from the active or inactive module
0389  * @offset: offset into the netlist to read from
0390  * @data: storage for returned word value
0391  *
0392  * Read a word from the specified netlist bank.
0393  */
0394 static int
0395 ice_read_netlist_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
0396 {
0397     __le16 data_local;
0398     int status;
0399 
0400     status = ice_read_flash_module(hw, bank, ICE_SR_NETLIST_BANK_PTR, offset * sizeof(u16),
0401                        (__force u8 *)&data_local, sizeof(u16));
0402     if (!status)
0403         *data = le16_to_cpu(data_local);
0404 
0405     return status;
0406 }
0407 
0408 /**
0409  * ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary
0410  * @hw: pointer to the HW structure
0411  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
0412  * @data: word read from the Shadow RAM
0413  *
0414  * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
0415  */
0416 int ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
0417 {
0418     int status;
0419 
0420     status = ice_acquire_nvm(hw, ICE_RES_READ);
0421     if (!status) {
0422         status = ice_read_sr_word_aq(hw, offset, data);
0423         ice_release_nvm(hw);
0424     }
0425 
0426     return status;
0427 }
0428 
0429 /**
0430  * ice_get_pfa_module_tlv - Reads sub module TLV from NVM PFA
0431  * @hw: pointer to hardware structure
0432  * @module_tlv: pointer to module TLV to return
0433  * @module_tlv_len: pointer to module TLV length to return
0434  * @module_type: module type requested
0435  *
0436  * Finds the requested sub module TLV type from the Preserved Field
0437  * Area (PFA) and returns the TLV pointer and length. The caller can
0438  * use these to read the variable length TLV value.
0439  */
0440 int
0441 ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
0442                u16 module_type)
0443 {
0444     u16 pfa_len, pfa_ptr;
0445     u16 next_tlv;
0446     int status;
0447 
0448     status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr);
0449     if (status) {
0450         ice_debug(hw, ICE_DBG_INIT, "Preserved Field Array pointer.\n");
0451         return status;
0452     }
0453     status = ice_read_sr_word(hw, pfa_ptr, &pfa_len);
0454     if (status) {
0455         ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n");
0456         return status;
0457     }
0458     /* Starting with first TLV after PFA length, iterate through the list
0459      * of TLVs to find the requested one.
0460      */
0461     next_tlv = pfa_ptr + 1;
0462     while (next_tlv < pfa_ptr + pfa_len) {
0463         u16 tlv_sub_module_type;
0464         u16 tlv_len;
0465 
0466         /* Read TLV type */
0467         status = ice_read_sr_word(hw, next_tlv, &tlv_sub_module_type);
0468         if (status) {
0469             ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV type.\n");
0470             break;
0471         }
0472         /* Read TLV length */
0473         status = ice_read_sr_word(hw, next_tlv + 1, &tlv_len);
0474         if (status) {
0475             ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV length.\n");
0476             break;
0477         }
0478         if (tlv_sub_module_type == module_type) {
0479             if (tlv_len) {
0480                 *module_tlv = next_tlv;
0481                 *module_tlv_len = tlv_len;
0482                 return 0;
0483             }
0484             return -EINVAL;
0485         }
0486         /* Check next TLV, i.e. current TLV pointer + length + 2 words
0487          * (for current TLV's type and length)
0488          */
0489         next_tlv = next_tlv + tlv_len + 2;
0490     }
0491     /* Module does not exist */
0492     return -ENOENT;
0493 }
0494 
0495 /**
0496  * ice_read_pba_string - Reads part number string from NVM
0497  * @hw: pointer to hardware structure
0498  * @pba_num: stores the part number string from the NVM
0499  * @pba_num_size: part number string buffer length
0500  *
0501  * Reads the part number string from the NVM.
0502  */
0503 int ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size)
0504 {
0505     u16 pba_tlv, pba_tlv_len;
0506     u16 pba_word, pba_size;
0507     int status;
0508     u16 i;
0509 
0510     status = ice_get_pfa_module_tlv(hw, &pba_tlv, &pba_tlv_len,
0511                     ICE_SR_PBA_BLOCK_PTR);
0512     if (status) {
0513         ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block TLV.\n");
0514         return status;
0515     }
0516 
0517     /* pba_size is the next word */
0518     status = ice_read_sr_word(hw, (pba_tlv + 2), &pba_size);
0519     if (status) {
0520         ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Section size.\n");
0521         return status;
0522     }
0523 
0524     if (pba_tlv_len < pba_size) {
0525         ice_debug(hw, ICE_DBG_INIT, "Invalid PBA Block TLV size.\n");
0526         return -EINVAL;
0527     }
0528 
0529     /* Subtract one to get PBA word count (PBA Size word is included in
0530      * total size)
0531      */
0532     pba_size--;
0533     if (pba_num_size < (((u32)pba_size * 2) + 1)) {
0534         ice_debug(hw, ICE_DBG_INIT, "Buffer too small for PBA data.\n");
0535         return -EINVAL;
0536     }
0537 
0538     for (i = 0; i < pba_size; i++) {
0539         status = ice_read_sr_word(hw, (pba_tlv + 2 + 1) + i, &pba_word);
0540         if (status) {
0541             ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block word %d.\n", i);
0542             return status;
0543         }
0544 
0545         pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
0546         pba_num[(i * 2) + 1] = pba_word & 0xFF;
0547     }
0548     pba_num[(pba_size * 2)] = '\0';
0549 
0550     return status;
0551 }
0552 
0553 /**
0554  * ice_get_nvm_ver_info - Read NVM version information
0555  * @hw: pointer to the HW struct
0556  * @bank: whether to read from the active or inactive flash bank
0557  * @nvm: pointer to NVM info structure
0558  *
0559  * Read the NVM EETRACK ID and map version of the main NVM image bank, filling
0560  * in the NVM info structure.
0561  */
0562 static int
0563 ice_get_nvm_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_nvm_info *nvm)
0564 {
0565     u16 eetrack_lo, eetrack_hi, ver;
0566     int status;
0567 
0568     status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_DEV_STARTER_VER, &ver);
0569     if (status) {
0570         ice_debug(hw, ICE_DBG_NVM, "Failed to read DEV starter version.\n");
0571         return status;
0572     }
0573 
0574     nvm->major = (ver & ICE_NVM_VER_HI_MASK) >> ICE_NVM_VER_HI_SHIFT;
0575     nvm->minor = (ver & ICE_NVM_VER_LO_MASK) >> ICE_NVM_VER_LO_SHIFT;
0576 
0577     status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_EETRACK_LO, &eetrack_lo);
0578     if (status) {
0579         ice_debug(hw, ICE_DBG_NVM, "Failed to read EETRACK lo.\n");
0580         return status;
0581     }
0582     status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_EETRACK_HI, &eetrack_hi);
0583     if (status) {
0584         ice_debug(hw, ICE_DBG_NVM, "Failed to read EETRACK hi.\n");
0585         return status;
0586     }
0587 
0588     nvm->eetrack = (eetrack_hi << 16) | eetrack_lo;
0589 
0590     return 0;
0591 }
0592 
0593 /**
0594  * ice_get_inactive_nvm_ver - Read Option ROM version from the inactive bank
0595  * @hw: pointer to the HW structure
0596  * @nvm: storage for Option ROM version information
0597  *
0598  * Reads the NVM EETRACK ID, Map version, and security revision of the
0599  * inactive NVM bank. Used to access version data for a pending update that
0600  * has not yet been activated.
0601  */
0602 int ice_get_inactive_nvm_ver(struct ice_hw *hw, struct ice_nvm_info *nvm)
0603 {
0604     return ice_get_nvm_ver_info(hw, ICE_INACTIVE_FLASH_BANK, nvm);
0605 }
0606 
0607 /**
0608  * ice_get_orom_civd_data - Get the combo version information from Option ROM
0609  * @hw: pointer to the HW struct
0610  * @bank: whether to read from the active or inactive flash module
0611  * @civd: storage for the Option ROM CIVD data.
0612  *
0613  * Searches through the Option ROM flash contents to locate the CIVD data for
0614  * the image.
0615  */
0616 static int
0617 ice_get_orom_civd_data(struct ice_hw *hw, enum ice_bank_select bank,
0618                struct ice_orom_civd_info *civd)
0619 {
0620     u8 *orom_data;
0621     int status;
0622     u32 offset;
0623 
0624     /* The CIVD section is located in the Option ROM aligned to 512 bytes.
0625      * The first 4 bytes must contain the ASCII characters "$CIV".
0626      * A simple modulo 256 sum of all of the bytes of the structure must
0627      * equal 0.
0628      *
0629      * The exact location is unknown and varies between images but is
0630      * usually somewhere in the middle of the bank. We need to scan the
0631      * Option ROM bank to locate it.
0632      *
0633      * It's significantly faster to read the entire Option ROM up front
0634      * using the maximum page size, than to read each possible location
0635      * with a separate firmware command.
0636      */
0637     orom_data = vzalloc(hw->flash.banks.orom_size);
0638     if (!orom_data)
0639         return -ENOMEM;
0640 
0641     status = ice_read_flash_module(hw, bank, ICE_SR_1ST_OROM_BANK_PTR, 0,
0642                        orom_data, hw->flash.banks.orom_size);
0643     if (status) {
0644         vfree(orom_data);
0645         ice_debug(hw, ICE_DBG_NVM, "Unable to read Option ROM data\n");
0646         return status;
0647     }
0648 
0649     /* Scan the memory buffer to locate the CIVD data section */
0650     for (offset = 0; (offset + 512) <= hw->flash.banks.orom_size; offset += 512) {
0651         struct ice_orom_civd_info *tmp;
0652         u8 sum = 0, i;
0653 
0654         tmp = (struct ice_orom_civd_info *)&orom_data[offset];
0655 
0656         /* Skip forward until we find a matching signature */
0657         if (memcmp("$CIV", tmp->signature, sizeof(tmp->signature)) != 0)
0658             continue;
0659 
0660         ice_debug(hw, ICE_DBG_NVM, "Found CIVD section at offset %u\n",
0661               offset);
0662 
0663         /* Verify that the simple checksum is zero */
0664         for (i = 0; i < sizeof(*tmp); i++)
0665             /* cppcheck-suppress objectIndex */
0666             sum += ((u8 *)tmp)[i];
0667 
0668         if (sum) {
0669             ice_debug(hw, ICE_DBG_NVM, "Found CIVD data with invalid checksum of %u\n",
0670                   sum);
0671             goto err_invalid_checksum;
0672         }
0673 
0674         *civd = *tmp;
0675         vfree(orom_data);
0676         return 0;
0677     }
0678 
0679     ice_debug(hw, ICE_DBG_NVM, "Unable to locate CIVD data within the Option ROM\n");
0680 
0681 err_invalid_checksum:
0682     vfree(orom_data);
0683     return -EIO;
0684 }
0685 
0686 /**
0687  * ice_get_orom_ver_info - Read Option ROM version information
0688  * @hw: pointer to the HW struct
0689  * @bank: whether to read from the active or inactive flash module
0690  * @orom: pointer to Option ROM info structure
0691  *
0692  * Read Option ROM version and security revision from the Option ROM flash
0693  * section.
0694  */
0695 static int
0696 ice_get_orom_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_orom_info *orom)
0697 {
0698     struct ice_orom_civd_info civd;
0699     u32 combo_ver;
0700     int status;
0701 
0702     status = ice_get_orom_civd_data(hw, bank, &civd);
0703     if (status) {
0704         ice_debug(hw, ICE_DBG_NVM, "Failed to locate valid Option ROM CIVD data\n");
0705         return status;
0706     }
0707 
0708     combo_ver = le32_to_cpu(civd.combo_ver);
0709 
0710     orom->major = (u8)((combo_ver & ICE_OROM_VER_MASK) >> ICE_OROM_VER_SHIFT);
0711     orom->patch = (u8)(combo_ver & ICE_OROM_VER_PATCH_MASK);
0712     orom->build = (u16)((combo_ver & ICE_OROM_VER_BUILD_MASK) >> ICE_OROM_VER_BUILD_SHIFT);
0713 
0714     return 0;
0715 }
0716 
0717 /**
0718  * ice_get_inactive_orom_ver - Read Option ROM version from the inactive bank
0719  * @hw: pointer to the HW structure
0720  * @orom: storage for Option ROM version information
0721  *
0722  * Reads the Option ROM version and security revision data for the inactive
0723  * section of flash. Used to access version data for a pending update that has
0724  * not yet been activated.
0725  */
0726 int ice_get_inactive_orom_ver(struct ice_hw *hw, struct ice_orom_info *orom)
0727 {
0728     return ice_get_orom_ver_info(hw, ICE_INACTIVE_FLASH_BANK, orom);
0729 }
0730 
0731 /**
0732  * ice_get_netlist_info
0733  * @hw: pointer to the HW struct
0734  * @bank: whether to read from the active or inactive flash bank
0735  * @netlist: pointer to netlist version info structure
0736  *
0737  * Get the netlist version information from the requested bank. Reads the Link
0738  * Topology section to find the Netlist ID block and extract the relevant
0739  * information into the netlist version structure.
0740  */
0741 static int
0742 ice_get_netlist_info(struct ice_hw *hw, enum ice_bank_select bank,
0743              struct ice_netlist_info *netlist)
0744 {
0745     u16 module_id, length, node_count, i;
0746     u16 *id_blk;
0747     int status;
0748 
0749     status = ice_read_netlist_module(hw, bank, ICE_NETLIST_TYPE_OFFSET, &module_id);
0750     if (status)
0751         return status;
0752 
0753     if (module_id != ICE_NETLIST_LINK_TOPO_MOD_ID) {
0754         ice_debug(hw, ICE_DBG_NVM, "Expected netlist module_id ID of 0x%04x, but got 0x%04x\n",
0755               ICE_NETLIST_LINK_TOPO_MOD_ID, module_id);
0756         return -EIO;
0757     }
0758 
0759     status = ice_read_netlist_module(hw, bank, ICE_LINK_TOPO_MODULE_LEN, &length);
0760     if (status)
0761         return status;
0762 
0763     /* sanity check that we have at least enough words to store the netlist ID block */
0764     if (length < ICE_NETLIST_ID_BLK_SIZE) {
0765         ice_debug(hw, ICE_DBG_NVM, "Netlist Link Topology module too small. Expected at least %u words, but got %u words.\n",
0766               ICE_NETLIST_ID_BLK_SIZE, length);
0767         return -EIO;
0768     }
0769 
0770     status = ice_read_netlist_module(hw, bank, ICE_LINK_TOPO_NODE_COUNT, &node_count);
0771     if (status)
0772         return status;
0773     node_count &= ICE_LINK_TOPO_NODE_COUNT_M;
0774 
0775     id_blk = kcalloc(ICE_NETLIST_ID_BLK_SIZE, sizeof(*id_blk), GFP_KERNEL);
0776     if (!id_blk)
0777         return -ENOMEM;
0778 
0779     /* Read out the entire Netlist ID Block at once. */
0780     status = ice_read_flash_module(hw, bank, ICE_SR_NETLIST_BANK_PTR,
0781                        ICE_NETLIST_ID_BLK_OFFSET(node_count) * sizeof(u16),
0782                        (u8 *)id_blk, ICE_NETLIST_ID_BLK_SIZE * sizeof(u16));
0783     if (status)
0784         goto exit_error;
0785 
0786     for (i = 0; i < ICE_NETLIST_ID_BLK_SIZE; i++)
0787         id_blk[i] = le16_to_cpu(((__force __le16 *)id_blk)[i]);
0788 
0789     netlist->major = id_blk[ICE_NETLIST_ID_BLK_MAJOR_VER_HIGH] << 16 |
0790              id_blk[ICE_NETLIST_ID_BLK_MAJOR_VER_LOW];
0791     netlist->minor = id_blk[ICE_NETLIST_ID_BLK_MINOR_VER_HIGH] << 16 |
0792              id_blk[ICE_NETLIST_ID_BLK_MINOR_VER_LOW];
0793     netlist->type = id_blk[ICE_NETLIST_ID_BLK_TYPE_HIGH] << 16 |
0794             id_blk[ICE_NETLIST_ID_BLK_TYPE_LOW];
0795     netlist->rev = id_blk[ICE_NETLIST_ID_BLK_REV_HIGH] << 16 |
0796                id_blk[ICE_NETLIST_ID_BLK_REV_LOW];
0797     netlist->cust_ver = id_blk[ICE_NETLIST_ID_BLK_CUST_VER];
0798     /* Read the left most 4 bytes of SHA */
0799     netlist->hash = id_blk[ICE_NETLIST_ID_BLK_SHA_HASH_WORD(15)] << 16 |
0800             id_blk[ICE_NETLIST_ID_BLK_SHA_HASH_WORD(14)];
0801 
0802 exit_error:
0803     kfree(id_blk);
0804 
0805     return status;
0806 }
0807 
0808 /**
0809  * ice_get_inactive_netlist_ver
0810  * @hw: pointer to the HW struct
0811  * @netlist: pointer to netlist version info structure
0812  *
0813  * Read the netlist version data from the inactive netlist bank. Used to
0814  * extract version data of a pending flash update in order to display the
0815  * version data.
0816  */
0817 int ice_get_inactive_netlist_ver(struct ice_hw *hw, struct ice_netlist_info *netlist)
0818 {
0819     return ice_get_netlist_info(hw, ICE_INACTIVE_FLASH_BANK, netlist);
0820 }
0821 
0822 /**
0823  * ice_discover_flash_size - Discover the available flash size.
0824  * @hw: pointer to the HW struct
0825  *
0826  * The device flash could be up to 16MB in size. However, it is possible that
0827  * the actual size is smaller. Use bisection to determine the accessible size
0828  * of flash memory.
0829  */
0830 static int ice_discover_flash_size(struct ice_hw *hw)
0831 {
0832     u32 min_size = 0, max_size = ICE_AQC_NVM_MAX_OFFSET + 1;
0833     int status;
0834 
0835     status = ice_acquire_nvm(hw, ICE_RES_READ);
0836     if (status)
0837         return status;
0838 
0839     while ((max_size - min_size) > 1) {
0840         u32 offset = (max_size + min_size) / 2;
0841         u32 len = 1;
0842         u8 data;
0843 
0844         status = ice_read_flat_nvm(hw, offset, &len, &data, false);
0845         if (status == -EIO &&
0846             hw->adminq.sq_last_status == ICE_AQ_RC_EINVAL) {
0847             ice_debug(hw, ICE_DBG_NVM, "%s: New upper bound of %u bytes\n",
0848                   __func__, offset);
0849             status = 0;
0850             max_size = offset;
0851         } else if (!status) {
0852             ice_debug(hw, ICE_DBG_NVM, "%s: New lower bound of %u bytes\n",
0853                   __func__, offset);
0854             min_size = offset;
0855         } else {
0856             /* an unexpected error occurred */
0857             goto err_read_flat_nvm;
0858         }
0859     }
0860 
0861     ice_debug(hw, ICE_DBG_NVM, "Predicted flash size is %u bytes\n", max_size);
0862 
0863     hw->flash.flash_size = max_size;
0864 
0865 err_read_flat_nvm:
0866     ice_release_nvm(hw);
0867 
0868     return status;
0869 }
0870 
0871 /**
0872  * ice_read_sr_pointer - Read the value of a Shadow RAM pointer word
0873  * @hw: pointer to the HW structure
0874  * @offset: the word offset of the Shadow RAM word to read
0875  * @pointer: pointer value read from Shadow RAM
0876  *
0877  * Read the given Shadow RAM word, and convert it to a pointer value specified
0878  * in bytes. This function assumes the specified offset is a valid pointer
0879  * word.
0880  *
0881  * Each pointer word specifies whether it is stored in word size or 4KB
0882  * sector size by using the highest bit. The reported pointer value will be in
0883  * bytes, intended for flat NVM reads.
0884  */
0885 static int ice_read_sr_pointer(struct ice_hw *hw, u16 offset, u32 *pointer)
0886 {
0887     int status;
0888     u16 value;
0889 
0890     status = ice_read_sr_word(hw, offset, &value);
0891     if (status)
0892         return status;
0893 
0894     /* Determine if the pointer is in 4KB or word units */
0895     if (value & ICE_SR_NVM_PTR_4KB_UNITS)
0896         *pointer = (value & ~ICE_SR_NVM_PTR_4KB_UNITS) * 4 * 1024;
0897     else
0898         *pointer = value * 2;
0899 
0900     return 0;
0901 }
0902 
0903 /**
0904  * ice_read_sr_area_size - Read an area size from a Shadow RAM word
0905  * @hw: pointer to the HW structure
0906  * @offset: the word offset of the Shadow RAM to read
0907  * @size: size value read from the Shadow RAM
0908  *
0909  * Read the given Shadow RAM word, and convert it to an area size value
0910  * specified in bytes. This function assumes the specified offset is a valid
0911  * area size word.
0912  *
0913  * Each area size word is specified in 4KB sector units. This function reports
0914  * the size in bytes, intended for flat NVM reads.
0915  */
0916 static int ice_read_sr_area_size(struct ice_hw *hw, u16 offset, u32 *size)
0917 {
0918     int status;
0919     u16 value;
0920 
0921     status = ice_read_sr_word(hw, offset, &value);
0922     if (status)
0923         return status;
0924 
0925     /* Area sizes are always specified in 4KB units */
0926     *size = value * 4 * 1024;
0927 
0928     return 0;
0929 }
0930 
0931 /**
0932  * ice_determine_active_flash_banks - Discover active bank for each module
0933  * @hw: pointer to the HW struct
0934  *
0935  * Read the Shadow RAM control word and determine which banks are active for
0936  * the NVM, OROM, and Netlist modules. Also read and calculate the associated
0937  * pointer and size. These values are then cached into the ice_flash_info
0938  * structure for later use in order to calculate the correct offset to read
0939  * from the active module.
0940  */
0941 static int ice_determine_active_flash_banks(struct ice_hw *hw)
0942 {
0943     struct ice_bank_info *banks = &hw->flash.banks;
0944     u16 ctrl_word;
0945     int status;
0946 
0947     status = ice_read_sr_word(hw, ICE_SR_NVM_CTRL_WORD, &ctrl_word);
0948     if (status) {
0949         ice_debug(hw, ICE_DBG_NVM, "Failed to read the Shadow RAM control word\n");
0950         return status;
0951     }
0952 
0953     /* Check that the control word indicates validity */
0954     if ((ctrl_word & ICE_SR_CTRL_WORD_1_M) >> ICE_SR_CTRL_WORD_1_S != ICE_SR_CTRL_WORD_VALID) {
0955         ice_debug(hw, ICE_DBG_NVM, "Shadow RAM control word is invalid\n");
0956         return -EIO;
0957     }
0958 
0959     if (!(ctrl_word & ICE_SR_CTRL_WORD_NVM_BANK))
0960         banks->nvm_bank = ICE_1ST_FLASH_BANK;
0961     else
0962         banks->nvm_bank = ICE_2ND_FLASH_BANK;
0963 
0964     if (!(ctrl_word & ICE_SR_CTRL_WORD_OROM_BANK))
0965         banks->orom_bank = ICE_1ST_FLASH_BANK;
0966     else
0967         banks->orom_bank = ICE_2ND_FLASH_BANK;
0968 
0969     if (!(ctrl_word & ICE_SR_CTRL_WORD_NETLIST_BANK))
0970         banks->netlist_bank = ICE_1ST_FLASH_BANK;
0971     else
0972         banks->netlist_bank = ICE_2ND_FLASH_BANK;
0973 
0974     status = ice_read_sr_pointer(hw, ICE_SR_1ST_NVM_BANK_PTR, &banks->nvm_ptr);
0975     if (status) {
0976         ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM bank pointer\n");
0977         return status;
0978     }
0979 
0980     status = ice_read_sr_area_size(hw, ICE_SR_NVM_BANK_SIZE, &banks->nvm_size);
0981     if (status) {
0982         ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM bank area size\n");
0983         return status;
0984     }
0985 
0986     status = ice_read_sr_pointer(hw, ICE_SR_1ST_OROM_BANK_PTR, &banks->orom_ptr);
0987     if (status) {
0988         ice_debug(hw, ICE_DBG_NVM, "Failed to read OROM bank pointer\n");
0989         return status;
0990     }
0991 
0992     status = ice_read_sr_area_size(hw, ICE_SR_OROM_BANK_SIZE, &banks->orom_size);
0993     if (status) {
0994         ice_debug(hw, ICE_DBG_NVM, "Failed to read OROM bank area size\n");
0995         return status;
0996     }
0997 
0998     status = ice_read_sr_pointer(hw, ICE_SR_NETLIST_BANK_PTR, &banks->netlist_ptr);
0999     if (status) {
1000         ice_debug(hw, ICE_DBG_NVM, "Failed to read Netlist bank pointer\n");
1001         return status;
1002     }
1003 
1004     status = ice_read_sr_area_size(hw, ICE_SR_NETLIST_BANK_SIZE, &banks->netlist_size);
1005     if (status) {
1006         ice_debug(hw, ICE_DBG_NVM, "Failed to read Netlist bank area size\n");
1007         return status;
1008     }
1009 
1010     return 0;
1011 }
1012 
1013 /**
1014  * ice_init_nvm - initializes NVM setting
1015  * @hw: pointer to the HW struct
1016  *
1017  * This function reads and populates NVM settings such as Shadow RAM size,
1018  * max_timeout, and blank_nvm_mode
1019  */
1020 int ice_init_nvm(struct ice_hw *hw)
1021 {
1022     struct ice_flash_info *flash = &hw->flash;
1023     u32 fla, gens_stat;
1024     u8 sr_size;
1025     int status;
1026 
1027     /* The SR size is stored regardless of the NVM programming mode
1028      * as the blank mode may be used in the factory line.
1029      */
1030     gens_stat = rd32(hw, GLNVM_GENS);
1031     sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S;
1032 
1033     /* Switching to words (sr_size contains power of 2) */
1034     flash->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB;
1035 
1036     /* Check if we are in the normal or blank NVM programming mode */
1037     fla = rd32(hw, GLNVM_FLA);
1038     if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */
1039         flash->blank_nvm_mode = false;
1040     } else {
1041         /* Blank programming mode */
1042         flash->blank_nvm_mode = true;
1043         ice_debug(hw, ICE_DBG_NVM, "NVM init error: unsupported blank mode.\n");
1044         return -EIO;
1045     }
1046 
1047     status = ice_discover_flash_size(hw);
1048     if (status) {
1049         ice_debug(hw, ICE_DBG_NVM, "NVM init error: failed to discover flash size.\n");
1050         return status;
1051     }
1052 
1053     status = ice_determine_active_flash_banks(hw);
1054     if (status) {
1055         ice_debug(hw, ICE_DBG_NVM, "Failed to determine active flash banks.\n");
1056         return status;
1057     }
1058 
1059     status = ice_get_nvm_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->nvm);
1060     if (status) {
1061         ice_debug(hw, ICE_DBG_INIT, "Failed to read NVM info.\n");
1062         return status;
1063     }
1064 
1065     status = ice_get_orom_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->orom);
1066     if (status)
1067         ice_debug(hw, ICE_DBG_INIT, "Failed to read Option ROM info.\n");
1068 
1069     /* read the netlist version information */
1070     status = ice_get_netlist_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->netlist);
1071     if (status)
1072         ice_debug(hw, ICE_DBG_INIT, "Failed to read netlist info.\n");
1073 
1074     return 0;
1075 }
1076 
1077 /**
1078  * ice_nvm_validate_checksum
1079  * @hw: pointer to the HW struct
1080  *
1081  * Verify NVM PFA checksum validity (0x0706)
1082  */
1083 int ice_nvm_validate_checksum(struct ice_hw *hw)
1084 {
1085     struct ice_aqc_nvm_checksum *cmd;
1086     struct ice_aq_desc desc;
1087     int status;
1088 
1089     status = ice_acquire_nvm(hw, ICE_RES_READ);
1090     if (status)
1091         return status;
1092 
1093     cmd = &desc.params.nvm_checksum;
1094 
1095     ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_checksum);
1096     cmd->flags = ICE_AQC_NVM_CHECKSUM_VERIFY;
1097 
1098     status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1099     ice_release_nvm(hw);
1100 
1101     if (!status)
1102         if (le16_to_cpu(cmd->checksum) != ICE_AQC_NVM_CHECKSUM_CORRECT)
1103             status = -EIO;
1104 
1105     return status;
1106 }
1107 
1108 /**
1109  * ice_nvm_write_activate
1110  * @hw: pointer to the HW struct
1111  * @cmd_flags: flags for write activate command
1112  * @response_flags: response indicators from firmware
1113  *
1114  * Update the control word with the required banks' validity bits
1115  * and dumps the Shadow RAM to flash (0x0707)
1116  *
1117  * cmd_flags controls which banks to activate, and the preservation level to
1118  * use when activating the NVM bank.
1119  *
1120  * On successful return of the firmware command, the response_flags variable
1121  * is updated with the flags reported by firmware indicating certain status,
1122  * such as whether EMP reset is enabled.
1123  */
1124 int ice_nvm_write_activate(struct ice_hw *hw, u8 cmd_flags, u8 *response_flags)
1125 {
1126     struct ice_aqc_nvm *cmd;
1127     struct ice_aq_desc desc;
1128     int err;
1129 
1130     cmd = &desc.params.nvm;
1131     ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_write_activate);
1132 
1133     cmd->cmd_flags = cmd_flags;
1134 
1135     err = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1136     if (!err && response_flags)
1137         *response_flags = cmd->cmd_flags;
1138 
1139     return err;
1140 }
1141 
1142 /**
1143  * ice_aq_nvm_update_empr
1144  * @hw: pointer to the HW struct
1145  *
1146  * Update empr (0x0709). This command allows SW to
1147  * request an EMPR to activate new FW.
1148  */
1149 int ice_aq_nvm_update_empr(struct ice_hw *hw)
1150 {
1151     struct ice_aq_desc desc;
1152 
1153     ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_update_empr);
1154 
1155     return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1156 }
1157 
1158 /* ice_nvm_set_pkg_data
1159  * @hw: pointer to the HW struct
1160  * @del_pkg_data_flag: If is set then the current pkg_data store by FW
1161  *             is deleted.
1162  *             If bit is set to 1, then buffer should be size 0.
1163  * @data: pointer to buffer
1164  * @length: length of the buffer
1165  * @cd: pointer to command details structure or NULL
1166  *
1167  * Set package data (0x070A). This command is equivalent to the reception
1168  * of a PLDM FW Update GetPackageData cmd. This command should be sent
1169  * as part of the NVM update as the first cmd in the flow.
1170  */
1171 
1172 int
1173 ice_nvm_set_pkg_data(struct ice_hw *hw, bool del_pkg_data_flag, u8 *data,
1174              u16 length, struct ice_sq_cd *cd)
1175 {
1176     struct ice_aqc_nvm_pkg_data *cmd;
1177     struct ice_aq_desc desc;
1178 
1179     if (length != 0 && !data)
1180         return -EINVAL;
1181 
1182     cmd = &desc.params.pkg_data;
1183 
1184     ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_pkg_data);
1185     desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1186 
1187     if (del_pkg_data_flag)
1188         cmd->cmd_flags |= ICE_AQC_NVM_PKG_DELETE;
1189 
1190     return ice_aq_send_cmd(hw, &desc, data, length, cd);
1191 }
1192 
1193 /* ice_nvm_pass_component_tbl
1194  * @hw: pointer to the HW struct
1195  * @data: pointer to buffer
1196  * @length: length of the buffer
1197  * @transfer_flag: parameter for determining stage of the update
1198  * @comp_response: a pointer to the response from the 0x070B AQC.
1199  * @comp_response_code: a pointer to the response code from the 0x070B AQC.
1200  * @cd: pointer to command details structure or NULL
1201  *
1202  * Pass component table (0x070B). This command is equivalent to the reception
1203  * of a PLDM FW Update PassComponentTable cmd. This command should be sent once
1204  * per component. It can be only sent after Set Package Data cmd and before
1205  * actual update. FW will assume these commands are going to be sent until
1206  * the TransferFlag is set to End or StartAndEnd.
1207  */
1208 
1209 int
1210 ice_nvm_pass_component_tbl(struct ice_hw *hw, u8 *data, u16 length,
1211                u8 transfer_flag, u8 *comp_response,
1212                u8 *comp_response_code, struct ice_sq_cd *cd)
1213 {
1214     struct ice_aqc_nvm_pass_comp_tbl *cmd;
1215     struct ice_aq_desc desc;
1216     int status;
1217 
1218     if (!data || !comp_response || !comp_response_code)
1219         return -EINVAL;
1220 
1221     cmd = &desc.params.pass_comp_tbl;
1222 
1223     ice_fill_dflt_direct_cmd_desc(&desc,
1224                       ice_aqc_opc_nvm_pass_component_tbl);
1225     desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1226 
1227     cmd->transfer_flag = transfer_flag;
1228     status = ice_aq_send_cmd(hw, &desc, data, length, cd);
1229 
1230     if (!status) {
1231         *comp_response = cmd->component_response;
1232         *comp_response_code = cmd->component_response_code;
1233     }
1234     return status;
1235 }