LCOV - code coverage report
Current view: top level - drivers/net/ice/base - ice_nvm.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 412 0.0 %
Date: 2024-01-22 15:55:54 Functions: 0 35 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 321 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2001-2023 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "ice_common.h"
       6                 :            : 
       7                 :            : #define GL_MNG_DEF_DEVID 0x000B611C
       8                 :            : 
       9                 :            : /**
      10                 :            :  * ice_aq_read_nvm
      11                 :            :  * @hw: pointer to the HW struct
      12                 :            :  * @module_typeid: module pointer location in words from the NVM beginning
      13                 :            :  * @offset: byte offset from the module beginning
      14                 :            :  * @length: length of the section to be read (in bytes from the offset)
      15                 :            :  * @data: command buffer (size [bytes] = length)
      16                 :            :  * @last_command: tells if this is the last command in a series
      17                 :            :  * @read_shadow_ram: tell if this is a shadow RAM read
      18                 :            :  * @cd: pointer to command details structure or NULL
      19                 :            :  *
      20                 :            :  * Read the NVM using the admin queue commands (0x0701)
      21                 :            :  */
      22                 :            : enum ice_status
      23                 :          0 : ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
      24                 :            :                 void *data, bool last_command, bool read_shadow_ram,
      25                 :            :                 struct ice_sq_cd *cd)
      26                 :            : {
      27                 :            :         struct ice_aq_desc desc;
      28                 :            :         struct ice_aqc_nvm *cmd;
      29                 :            : 
      30         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
      31                 :            : 
      32                 :            :         cmd = &desc.params.nvm;
      33                 :            : 
      34         [ #  # ]:          0 :         if (offset > ICE_AQC_NVM_MAX_OFFSET)
      35                 :            :                 return ICE_ERR_PARAM;
      36                 :            : 
      37                 :          0 :         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_read);
      38                 :            : 
      39         [ #  # ]:          0 :         if (!read_shadow_ram && module_typeid == ICE_AQC_NVM_START_POINT)
      40                 :          0 :                 cmd->cmd_flags |= ICE_AQC_NVM_FLASH_ONLY;
      41                 :            : 
      42                 :            :         /* If this is the last command in a series, set the proper flag. */
      43         [ #  # ]:          0 :         if (last_command)
      44                 :          0 :                 cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
      45                 :          0 :         cmd->module_typeid = CPU_TO_LE16(module_typeid);
      46                 :          0 :         cmd->offset_low = CPU_TO_LE16(offset & 0xFFFF);
      47                 :          0 :         cmd->offset_high = (offset >> 16) & 0xFF;
      48                 :          0 :         cmd->length = CPU_TO_LE16(length);
      49                 :            : 
      50                 :          0 :         return ice_aq_send_cmd(hw, &desc, data, length, cd);
      51                 :            : }
      52                 :            : 
      53                 :            : /**
      54                 :            :  * ice_read_flat_nvm - Read portion of NVM by flat offset
      55                 :            :  * @hw: pointer to the HW struct
      56                 :            :  * @offset: offset from beginning of NVM
      57                 :            :  * @length: (in) number of bytes to read; (out) number of bytes actually read
      58                 :            :  * @data: buffer to return data in (sized to fit the specified length)
      59                 :            :  * @read_shadow_ram: if true, read from shadow RAM instead of NVM
      60                 :            :  *
      61                 :            :  * Reads a portion of the NVM, as a flat memory space. This function correctly
      62                 :            :  * breaks read requests across Shadow RAM sectors and ensures that no single
      63                 :            :  * read request exceeds the maximum 4KB read for a single AdminQ command.
      64                 :            :  *
      65                 :            :  * Returns a status code on failure. Note that the data pointer may be
      66                 :            :  * partially updated if some reads succeed before a failure.
      67                 :            :  */
      68                 :            : enum ice_status
      69                 :          0 : ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
      70                 :            :                   bool read_shadow_ram)
      71                 :            : {
      72                 :            :         enum ice_status status;
      73                 :          0 :         u32 inlen = *length;
      74                 :            :         u32 bytes_read = 0;
      75                 :            :         bool last_cmd;
      76                 :            : 
      77         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
      78                 :            : 
      79                 :          0 :         *length = 0;
      80                 :            : 
      81                 :            :         /* Verify the length of the read if this is for the Shadow RAM */
      82   [ #  #  #  # ]:          0 :         if (read_shadow_ram && ((offset + inlen) > (hw->flash.sr_words * 2u))) {
      83         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "NVM error: requested data is beyond Shadow RAM limit\n");
      84                 :          0 :                 return ICE_ERR_PARAM;
      85                 :            :         }
      86                 :            : 
      87                 :            :         do {
      88                 :            :                 u32 read_size, sector_offset;
      89                 :            : 
      90                 :            :                 /* ice_aq_read_nvm cannot read more than 4KB at a time.
      91                 :            :                  * Additionally, a read from the Shadow RAM may not cross over
      92                 :            :                  * a sector boundary. Conveniently, the sector size is also
      93                 :            :                  * 4KB.
      94                 :            :                  */
      95                 :          0 :                 sector_offset = offset % ICE_AQ_MAX_BUF_LEN;
      96                 :          0 :                 read_size = MIN_T(u32, ICE_AQ_MAX_BUF_LEN - sector_offset,
      97                 :            :                                   inlen - bytes_read);
      98                 :            : 
      99                 :          0 :                 last_cmd = !(bytes_read + read_size < inlen);
     100                 :            : 
     101                 :            :                 /* ice_aq_read_nvm takes the length as a u16. Our read_size is
     102                 :            :                  * calculated using a u32, but the ICE_AQ_MAX_BUF_LEN maximum
     103                 :            :                  * size guarantees that it will fit within the 2 bytes.
     104                 :            :                  */
     105                 :          0 :                 status = ice_aq_read_nvm(hw, ICE_AQC_NVM_START_POINT,
     106                 :            :                                          offset, (u16)read_size,
     107                 :          0 :                                          data + bytes_read, last_cmd,
     108                 :            :                                          read_shadow_ram, NULL);
     109         [ #  # ]:          0 :                 if (status)
     110                 :            :                         break;
     111                 :            : 
     112                 :            :                 bytes_read += read_size;
     113                 :          0 :                 offset += read_size;
     114         [ #  # ]:          0 :         } while (!last_cmd);
     115                 :            : 
     116                 :          0 :         *length = bytes_read;
     117                 :          0 :         return status;
     118                 :            : }
     119                 :            : 
     120                 :            : /**
     121                 :            :  * ice_read_sr_word_aq - Reads Shadow RAM via AQ
     122                 :            :  * @hw: pointer to the HW structure
     123                 :            :  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
     124                 :            :  * @data: word read from the Shadow RAM
     125                 :            :  *
     126                 :            :  * Reads one 16 bit word from the Shadow RAM using ice_read_flat_nvm.
     127                 :            :  */
     128                 :            : static enum ice_status
     129                 :          0 : ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
     130                 :            : {
     131                 :          0 :         u32 bytes = sizeof(u16);
     132                 :            :         enum ice_status status;
     133                 :            :         __le16 data_local;
     134                 :            : 
     135         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
     136                 :            : 
     137                 :            :         /* Note that ice_read_flat_nvm checks if the read is past the Shadow
     138                 :            :          * RAM size, and ensures we don't read across a Shadow RAM sector
     139                 :            :          * boundary
     140                 :            :          */
     141                 :          0 :         status = ice_read_flat_nvm(hw, offset * sizeof(u16), &bytes,
     142                 :            :                                    (_FORCE_ u8 *)&data_local, true);
     143         [ #  # ]:          0 :         if (status)
     144                 :            :                 return status;
     145                 :            : 
     146                 :          0 :         *data = LE16_TO_CPU(data_local);
     147                 :          0 :         return ICE_SUCCESS;
     148                 :            : }
     149                 :            : 
     150                 :            : /**
     151                 :            :  * ice_read_sr_buf_aq - Reads Shadow RAM buf via AQ
     152                 :            :  * @hw: pointer to the HW structure
     153                 :            :  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
     154                 :            :  * @words: (in) number of words to read; (out) number of words actually read
     155                 :            :  * @data: words read from the Shadow RAM
     156                 :            :  *
     157                 :            :  * Reads 16 bit words (data buf) from the Shadow RAM. Ownership of the NVM is
     158                 :            :  * taken before reading the buffer and later released.
     159                 :            :  */
     160                 :            : static enum ice_status
     161                 :          0 : ice_read_sr_buf_aq(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
     162                 :            : {
     163                 :          0 :         u32 bytes = *words * 2, i;
     164                 :            :         enum ice_status status;
     165                 :            : 
     166         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
     167                 :            : 
     168                 :            :         /* ice_read_flat_nvm takes into account the 4KB AdminQ and Shadow RAM
     169                 :            :          * sector restrictions necessary when reading from the NVM.
     170                 :            :          */
     171                 :          0 :         status = ice_read_flat_nvm(hw, offset * 2, &bytes, (u8 *)data, true);
     172                 :            : 
     173                 :            :         /* Report the number of words successfully read */
     174                 :          0 :         *words = (u16)(bytes / 2);
     175                 :            : 
     176                 :            :         /* Byte swap the words up to the amount we actually read */
     177                 :            :         for (i = 0; i < *words; i++)
     178                 :            :                 data[i] = LE16_TO_CPU(((_FORCE_ __le16 *)data)[i]);
     179                 :            : 
     180                 :          0 :         return status;
     181                 :            : }
     182                 :            : 
     183                 :            : /**
     184                 :            :  * ice_acquire_nvm - Generic request for acquiring the NVM ownership
     185                 :            :  * @hw: pointer to the HW structure
     186                 :            :  * @access: NVM access type (read or write)
     187                 :            :  *
     188                 :            :  * This function will request NVM ownership.
     189                 :            :  */
     190                 :            : enum ice_status
     191                 :          0 : ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
     192                 :            : {
     193         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
     194                 :            : 
     195         [ #  # ]:          0 :         if (hw->flash.blank_nvm_mode)
     196                 :            :                 return ICE_SUCCESS;
     197                 :            : 
     198                 :          0 :         return ice_acquire_res(hw, ICE_NVM_RES_ID, access, ICE_NVM_TIMEOUT);
     199                 :            : }
     200                 :            : 
     201                 :            : /**
     202                 :            :  * ice_release_nvm - Generic request for releasing the NVM ownership
     203                 :            :  * @hw: pointer to the HW structure
     204                 :            :  *
     205                 :            :  * This function will release NVM ownership.
     206                 :            :  */
     207                 :          0 : void ice_release_nvm(struct ice_hw *hw)
     208                 :            : {
     209         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
     210                 :            : 
     211         [ #  # ]:          0 :         if (hw->flash.blank_nvm_mode)
     212                 :            :                 return;
     213                 :            : 
     214                 :          0 :         ice_release_res(hw, ICE_NVM_RES_ID);
     215                 :            : }
     216                 :            : 
     217                 :            : /**
     218                 :            :  * ice_get_flash_bank_offset - Get offset into requested flash bank
     219                 :            :  * @hw: pointer to the HW structure
     220                 :            :  * @bank: whether to read from the active or inactive flash bank
     221                 :            :  * @module: the module to read from
     222                 :            :  *
     223                 :            :  * Based on the module, lookup the module offset from the beginning of the
     224                 :            :  * flash.
     225                 :            :  *
     226                 :            :  * Returns the flash offset. Note that a value of zero is invalid and must be
     227                 :            :  * treated as an error.
     228                 :            :  */
     229                 :          0 : static u32 ice_get_flash_bank_offset(struct ice_hw *hw, enum ice_bank_select bank, u16 module)
     230                 :            : {
     231                 :            :         struct ice_bank_info *banks = &hw->flash.banks;
     232                 :            :         enum ice_flash_bank active_bank;
     233                 :            :         bool second_bank_active;
     234                 :            :         u32 offset, size;
     235                 :            : 
     236   [ #  #  #  # ]:          0 :         switch (module) {
     237                 :          0 :         case ICE_SR_1ST_NVM_BANK_PTR:
     238                 :          0 :                 offset = banks->nvm_ptr;
     239                 :          0 :                 size = banks->nvm_size;
     240                 :          0 :                 active_bank = banks->nvm_bank;
     241                 :          0 :                 break;
     242                 :          0 :         case ICE_SR_1ST_OROM_BANK_PTR:
     243                 :          0 :                 offset = banks->orom_ptr;
     244                 :          0 :                 size = banks->orom_size;
     245                 :          0 :                 active_bank = banks->orom_bank;
     246                 :          0 :                 break;
     247                 :          0 :         case ICE_SR_NETLIST_BANK_PTR:
     248                 :          0 :                 offset = banks->netlist_ptr;
     249                 :          0 :                 size = banks->netlist_size;
     250                 :          0 :                 active_bank = banks->netlist_bank;
     251                 :          0 :                 break;
     252                 :          0 :         default:
     253         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Unexpected value for flash module: 0x%04x\n", module);
     254                 :            :                 return 0;
     255                 :            :         }
     256                 :            : 
     257      [ #  #  # ]:          0 :         switch (active_bank) {
     258                 :            :         case ICE_1ST_FLASH_BANK:
     259                 :            :                 second_bank_active = false;
     260                 :            :                 break;
     261                 :          0 :         case ICE_2ND_FLASH_BANK:
     262                 :            :                 second_bank_active = true;
     263                 :          0 :                 break;
     264                 :          0 :         default:
     265         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Unexpected value for active flash bank: %u\n",
     266                 :            :                           active_bank);
     267                 :            :                 return 0;
     268                 :            :         }
     269                 :            : 
     270                 :            :         /* The second flash bank is stored immediately following the first
     271                 :            :          * bank. Based on whether the 1st or 2nd bank is active, and whether
     272                 :            :          * we want the active or inactive bank, calculate the desired offset.
     273                 :            :          */
     274      [ #  #  # ]:          0 :         switch (bank) {
     275                 :          0 :         case ICE_ACTIVE_FLASH_BANK:
     276         [ #  # ]:          0 :                 return offset + (second_bank_active ? size : 0);
     277                 :          0 :         case ICE_INACTIVE_FLASH_BANK:
     278         [ #  # ]:          0 :                 return offset + (second_bank_active ? 0 : size);
     279                 :            :         }
     280                 :            : 
     281         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_NVM, "Unexpected value for flash bank selection: %u\n", bank);
     282                 :            :         return 0;
     283                 :            : }
     284                 :            : 
     285                 :            : /**
     286                 :            :  * ice_read_flash_module - Read a word from one of the main NVM modules
     287                 :            :  * @hw: pointer to the HW structure
     288                 :            :  * @bank: which bank of the module to read
     289                 :            :  * @module: the module to read
     290                 :            :  * @offset: the offset into the module in bytes
     291                 :            :  * @data: storage for the word read from the flash
     292                 :            :  * @length: bytes of data to read
     293                 :            :  *
     294                 :            :  * Read data from the specified flash module. The bank parameter indicates
     295                 :            :  * whether or not to read from the active bank or the inactive bank of that
     296                 :            :  * module.
     297                 :            :  *
     298                 :            :  * The word will be read using flat NVM access, and relies on the
     299                 :            :  * hw->flash.banks data being setup by ice_determine_active_flash_banks()
     300                 :            :  * during initialization.
     301                 :            :  */
     302                 :            : static enum ice_status
     303                 :          0 : ice_read_flash_module(struct ice_hw *hw, enum ice_bank_select bank, u16 module,
     304                 :            :                       u32 offset, u8 *data, u32 length)
     305                 :            : {
     306                 :            :         enum ice_status status;
     307                 :            :         u32 start;
     308                 :            : 
     309         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
     310                 :            : 
     311                 :          0 :         start = ice_get_flash_bank_offset(hw, bank, module);
     312         [ #  # ]:          0 :         if (!start) {
     313         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Unable to calculate flash bank offset for module 0x%04x\n",
     314                 :            :                           module);
     315                 :          0 :                 return ICE_ERR_PARAM;
     316                 :            :         }
     317                 :            : 
     318                 :          0 :         status = ice_acquire_nvm(hw, ICE_RES_READ);
     319         [ #  # ]:          0 :         if (status)
     320                 :            :                 return status;
     321                 :            : 
     322                 :          0 :         status = ice_read_flat_nvm(hw, start + offset, &length, data, false);
     323                 :            : 
     324                 :          0 :         ice_release_nvm(hw);
     325                 :            : 
     326                 :          0 :         return status;
     327                 :            : }
     328                 :            : 
     329                 :            : /**
     330                 :            :  * ice_read_nvm_module - Read from the active main NVM module
     331                 :            :  * @hw: pointer to the HW structure
     332                 :            :  * @bank: whether to read from active or inactive NVM module
     333                 :            :  * @offset: offset into the NVM module to read, in words
     334                 :            :  * @data: storage for returned word value
     335                 :            :  *
     336                 :            :  * Read the specified word from the active NVM module. This includes the CSS
     337                 :            :  * header at the start of the NVM module.
     338                 :            :  */
     339                 :            : static enum ice_status
     340                 :            : ice_read_nvm_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
     341                 :            : {
     342                 :            :         enum ice_status status;
     343                 :            :         __le16 data_local;
     344                 :            : 
     345                 :          0 :         status = ice_read_flash_module(hw, bank, ICE_SR_1ST_NVM_BANK_PTR, offset * sizeof(u16),
     346                 :            :                                        (_FORCE_ u8 *)&data_local, sizeof(u16));
     347   [ #  #  #  #  :          0 :         if (!status)
          #  #  #  #  #  
                      # ]
     348                 :          0 :                 *data = LE16_TO_CPU(data_local);
     349                 :            : 
     350                 :            :         return status;
     351                 :            : }
     352                 :            : 
     353                 :            : /**
     354                 :            :  * ice_get_nvm_css_hdr_len - Read the CSS header length from the NVM CSS header
     355                 :            :  * @hw: pointer to the HW struct
     356                 :            :  * @bank: whether to read from the active or inactive flash bank
     357                 :            :  * @hdr_len: storage for header length in words
     358                 :            :  *
     359                 :            :  * Read the CSS header length from the NVM CSS header and add the Authentication
     360                 :            :  * header size, and then convert to words.
     361                 :            :  */
     362                 :            : static enum ice_status
     363                 :          0 : ice_get_nvm_css_hdr_len(struct ice_hw *hw, enum ice_bank_select bank,
     364                 :            :                         u32 *hdr_len)
     365                 :            : {
     366                 :            :         u16 hdr_len_l, hdr_len_h;
     367                 :            :         enum ice_status status;
     368                 :            :         u32 hdr_len_dword;
     369                 :            : 
     370                 :            :         status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_L,
     371                 :            :                                      &hdr_len_l);
     372         [ #  # ]:          0 :         if (status)
     373                 :            :                 return status;
     374                 :            : 
     375                 :            :         status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_H,
     376                 :            :                                      &hdr_len_h);
     377         [ #  # ]:          0 :         if (status)
     378                 :            :                 return status;
     379                 :            : 
     380                 :            :         /* CSS header length is in DWORD, so convert to words and add
     381                 :            :          * authentication header size
     382                 :            :          */
     383                 :          0 :         hdr_len_dword = hdr_len_h << 16 | hdr_len_l;
     384                 :          0 :         *hdr_len = (hdr_len_dword * 2) + ICE_NVM_AUTH_HEADER_LEN;
     385                 :            : 
     386                 :          0 :         return ICE_SUCCESS;
     387                 :            : }
     388                 :            : 
     389                 :            : /**
     390                 :            :  * ice_read_nvm_sr_copy - Read a word from the Shadow RAM copy in the NVM bank
     391                 :            :  * @hw: pointer to the HW structure
     392                 :            :  * @bank: whether to read from the active or inactive NVM module
     393                 :            :  * @offset: offset into the Shadow RAM copy to read, in words
     394                 :            :  * @data: storage for returned word value
     395                 :            :  *
     396                 :            :  * Read the specified word from the copy of the Shadow RAM found in the
     397                 :            :  * specified NVM module.
     398                 :            :  */
     399                 :            : static enum ice_status
     400                 :          0 : ice_read_nvm_sr_copy(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
     401                 :            : {
     402                 :            :         enum ice_status status;
     403                 :            :         u32 hdr_len;
     404                 :            : 
     405                 :          0 :         status = ice_get_nvm_css_hdr_len(hw, bank, &hdr_len);
     406         [ #  # ]:          0 :         if (status)
     407                 :            :                 return status;
     408                 :            : 
     409                 :          0 :         hdr_len = ROUND_UP(hdr_len, 32);
     410                 :            : 
     411                 :          0 :         return ice_read_nvm_module(hw, bank, hdr_len + offset, data);
     412                 :            : }
     413                 :            : 
     414                 :            : /**
     415                 :            :  * ice_read_orom_module - Read from the active Option ROM module
     416                 :            :  * @hw: pointer to the HW structure
     417                 :            :  * @bank: whether to read from active or inactive OROM module
     418                 :            :  * @offset: offset into the OROM module to read, in words
     419                 :            :  * @data: storage for returned word value
     420                 :            :  *
     421                 :            :  * Read the specified word from the active Option ROM module of the flash.
     422                 :            :  * Note that unlike the NVM module, the CSS data is stored at the end of the
     423                 :            :  * module instead of at the beginning.
     424                 :            :  */
     425                 :            : static enum ice_status
     426                 :            : ice_read_orom_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
     427                 :            : {
     428                 :            :         enum ice_status status;
     429                 :            :         __le16 data_local;
     430                 :            : 
     431                 :          0 :         status = ice_read_flash_module(hw, bank, ICE_SR_1ST_OROM_BANK_PTR, offset * sizeof(u16),
     432                 :            :                                        (_FORCE_ u8 *)&data_local, sizeof(u16));
     433   [ #  #  #  # ]:          0 :         if (!status)
     434                 :          0 :                 *data = LE16_TO_CPU(data_local);
     435                 :            : 
     436                 :            :         return status;
     437                 :            : }
     438                 :            : 
     439                 :            : /**
     440                 :            :  * ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary
     441                 :            :  * @hw: pointer to the HW structure
     442                 :            :  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
     443                 :            :  * @data: word read from the Shadow RAM
     444                 :            :  *
     445                 :            :  * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
     446                 :            :  */
     447                 :          0 : enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
     448                 :            : {
     449                 :            :         enum ice_status status;
     450                 :            : 
     451                 :          0 :         status = ice_acquire_nvm(hw, ICE_RES_READ);
     452         [ #  # ]:          0 :         if (!status) {
     453                 :          0 :                 status = ice_read_sr_word_aq(hw, offset, data);
     454                 :          0 :                 ice_release_nvm(hw);
     455                 :            :         }
     456                 :            : 
     457                 :          0 :         return status;
     458                 :            : }
     459                 :            : 
     460                 :            : /**
     461                 :            :  * ice_get_pfa_module_tlv - Reads sub module TLV from NVM PFA
     462                 :            :  * @hw: pointer to hardware structure
     463                 :            :  * @module_tlv: pointer to module TLV to return
     464                 :            :  * @module_tlv_len: pointer to module TLV length to return
     465                 :            :  * @module_type: module type requested
     466                 :            :  *
     467                 :            :  * Finds the requested sub module TLV type from the Preserved Field
     468                 :            :  * Area (PFA) and returns the TLV pointer and length. The caller can
     469                 :            :  * use these to read the variable length TLV value.
     470                 :            :  */
     471                 :            : enum ice_status
     472                 :          0 : ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
     473                 :            :                        u16 module_type)
     474                 :            : {
     475                 :            :         enum ice_status status;
     476                 :            :         u16 pfa_len, pfa_ptr;
     477                 :            :         u16 next_tlv;
     478                 :            : 
     479                 :          0 :         status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr);
     480         [ #  # ]:          0 :         if (status != ICE_SUCCESS) {
     481         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Preserved Field Array pointer.\n");
     482                 :          0 :                 return status;
     483                 :            :         }
     484                 :          0 :         status = ice_read_sr_word(hw, pfa_ptr, &pfa_len);
     485         [ #  # ]:          0 :         if (status != ICE_SUCCESS) {
     486         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n");
     487                 :          0 :                 return status;
     488                 :            :         }
     489                 :            :         /* Starting with first TLV after PFA length, iterate through the list
     490                 :            :          * of TLVs to find the requested one.
     491                 :            :          */
     492                 :          0 :         next_tlv = pfa_ptr + 1;
     493         [ #  # ]:          0 :         while (next_tlv < pfa_ptr + pfa_len) {
     494                 :            :                 u16 tlv_sub_module_type;
     495                 :            :                 u16 tlv_len;
     496                 :            : 
     497                 :            :                 /* Read TLV type */
     498                 :          0 :                 status = ice_read_sr_word(hw, next_tlv, &tlv_sub_module_type);
     499         [ #  # ]:          0 :                 if (status != ICE_SUCCESS) {
     500         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV type.\n");
     501                 :          0 :                         break;
     502                 :            :                 }
     503                 :            :                 /* Read TLV length */
     504                 :          0 :                 status = ice_read_sr_word(hw, next_tlv + 1, &tlv_len);
     505         [ #  # ]:          0 :                 if (status != ICE_SUCCESS) {
     506         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV length.\n");
     507                 :            :                         break;
     508                 :            :                 }
     509         [ #  # ]:          0 :                 if (tlv_sub_module_type == module_type) {
     510         [ #  # ]:          0 :                         if (tlv_len) {
     511                 :          0 :                                 *module_tlv = next_tlv;
     512                 :          0 :                                 *module_tlv_len = tlv_len;
     513                 :          0 :                                 return ICE_SUCCESS;
     514                 :            :                         }
     515                 :            :                         return ICE_ERR_INVAL_SIZE;
     516                 :            :                 }
     517                 :            :                 /* Check next TLV, i.e. current TLV pointer + length + 2 words
     518                 :            :                  * (for current TLV's type and length)
     519                 :            :                  */
     520                 :          0 :                 next_tlv = next_tlv + tlv_len + 2;
     521                 :            :         }
     522                 :            :         /* Module does not exist */
     523                 :            :         return ICE_ERR_DOES_NOT_EXIST;
     524                 :            : }
     525                 :            : 
     526                 :            : /**
     527                 :            :  * ice_read_pba_string - Reads part number string from NVM
     528                 :            :  * @hw: pointer to hardware structure
     529                 :            :  * @pba_num: stores the part number string from the NVM
     530                 :            :  * @pba_num_size: part number string buffer length
     531                 :            :  *
     532                 :            :  * Reads the part number string from the NVM.
     533                 :            :  */
     534                 :            : enum ice_status
     535                 :          0 : ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size)
     536                 :            : {
     537                 :            :         u16 pba_tlv, pba_tlv_len;
     538                 :            :         enum ice_status status;
     539                 :            :         u16 pba_word, pba_size;
     540                 :            :         u16 i;
     541                 :            : 
     542                 :          0 :         status = ice_get_pfa_module_tlv(hw, &pba_tlv, &pba_tlv_len,
     543                 :            :                                         ICE_SR_PBA_BLOCK_PTR);
     544         [ #  # ]:          0 :         if (status != ICE_SUCCESS) {
     545         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block TLV.\n");
     546                 :          0 :                 return status;
     547                 :            :         }
     548                 :            : 
     549                 :            :         /* pba_size is the next word */
     550                 :          0 :         status = ice_read_sr_word(hw, (pba_tlv + 2), &pba_size);
     551         [ #  # ]:          0 :         if (status != ICE_SUCCESS) {
     552         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Section size.\n");
     553                 :          0 :                 return status;
     554                 :            :         }
     555                 :            : 
     556         [ #  # ]:          0 :         if (pba_tlv_len < pba_size) {
     557         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Invalid PBA Block TLV size.\n");
     558                 :          0 :                 return ICE_ERR_INVAL_SIZE;
     559                 :            :         }
     560                 :            : 
     561                 :            :         /* Subtract one to get PBA word count (PBA Size word is included in
     562                 :            :          * total size)
     563                 :            :          */
     564                 :          0 :         pba_size--;
     565         [ #  # ]:          0 :         if (pba_num_size < (((u32)pba_size * 2) + 1)) {
     566         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Buffer too small for PBA data.\n");
     567                 :          0 :                 return ICE_ERR_PARAM;
     568                 :            :         }
     569                 :            : 
     570         [ #  # ]:          0 :         for (i = 0; i < pba_size; i++) {
     571                 :          0 :                 status = ice_read_sr_word(hw, (pba_tlv + 2 + 1) + i, &pba_word);
     572         [ #  # ]:          0 :                 if (status != ICE_SUCCESS) {
     573         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block word %d.\n", i);
     574                 :          0 :                         return status;
     575                 :            :                 }
     576                 :            : 
     577                 :          0 :                 pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
     578                 :          0 :                 pba_num[(i * 2) + 1] = pba_word & 0xFF;
     579                 :            :         }
     580                 :          0 :         pba_num[(pba_size * 2)] = '\0';
     581                 :            : 
     582                 :          0 :         return status;
     583                 :            : }
     584                 :            : 
     585                 :            : /**
     586                 :            :  * ice_get_nvm_srev - Read the security revision from the NVM CSS header
     587                 :            :  * @hw: pointer to the HW struct
     588                 :            :  * @bank: whether to read from the active or inactive flash bank
     589                 :            :  * @srev: storage for security revision
     590                 :            :  *
     591                 :            :  * Read the security revision out of the CSS header of the active NVM module
     592                 :            :  * bank.
     593                 :            :  */
     594                 :          0 : static enum ice_status ice_get_nvm_srev(struct ice_hw *hw, enum ice_bank_select bank, u32 *srev)
     595                 :            : {
     596                 :            :         enum ice_status status;
     597                 :            :         u16 srev_l, srev_h;
     598                 :            : 
     599                 :            :         status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_SREV_L, &srev_l);
     600         [ #  # ]:          0 :         if (status)
     601                 :            :                 return status;
     602                 :            : 
     603                 :            :         status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_SREV_H, &srev_h);
     604         [ #  # ]:          0 :         if (status)
     605                 :            :                 return status;
     606                 :            : 
     607                 :          0 :         *srev = srev_h << 16 | srev_l;
     608                 :            : 
     609                 :          0 :         return ICE_SUCCESS;
     610                 :            : }
     611                 :            : 
     612                 :            : /**
     613                 :            :  * ice_get_nvm_ver_info - Read NVM version information
     614                 :            :  * @hw: pointer to the HW struct
     615                 :            :  * @bank: whether to read from the active or inactive flash bank
     616                 :            :  * @nvm: pointer to NVM info structure
     617                 :            :  *
     618                 :            :  * Read the NVM EETRACK ID and map version of the main NVM image bank, filling
     619                 :            :  * in the nvm info structure.
     620                 :            :  */
     621                 :            : static enum ice_status
     622                 :          0 : ice_get_nvm_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_nvm_info *nvm)
     623                 :            : {
     624                 :            :         u16 eetrack_lo, eetrack_hi, ver;
     625                 :            :         enum ice_status status;
     626                 :            : 
     627                 :          0 :         status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_DEV_STARTER_VER, &ver);
     628         [ #  # ]:          0 :         if (status) {
     629         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read DEV starter version.\n");
     630                 :          0 :                 return status;
     631                 :            :         }
     632                 :            : 
     633                 :          0 :         nvm->major = (ver & ICE_NVM_VER_HI_MASK) >> ICE_NVM_VER_HI_SHIFT;
     634                 :          0 :         nvm->minor = (ver & ICE_NVM_VER_LO_MASK) >> ICE_NVM_VER_LO_SHIFT;
     635                 :            : 
     636                 :          0 :         status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_EETRACK_LO, &eetrack_lo);
     637         [ #  # ]:          0 :         if (status) {
     638         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read EETRACK lo.\n");
     639                 :          0 :                 return status;
     640                 :            :         }
     641                 :          0 :         status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_EETRACK_HI, &eetrack_hi);
     642         [ #  # ]:          0 :         if (status) {
     643         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read EETRACK hi.\n");
     644                 :          0 :                 return status;
     645                 :            :         }
     646                 :            : 
     647                 :          0 :         nvm->eetrack = (eetrack_hi << 16) | eetrack_lo;
     648                 :            : 
     649                 :          0 :         status = ice_get_nvm_srev(hw, bank, &nvm->srev);
     650         [ #  # ]:          0 :         if (status)
     651         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM security revision.\n");
     652                 :            : 
     653                 :            :         return ICE_SUCCESS;
     654                 :            : }
     655                 :            : 
     656                 :            : /**
     657                 :            :  * ice_get_inactive_nvm_ver - Read Option ROM version from the inactive bank
     658                 :            :  * @hw: pointer to the HW structure
     659                 :            :  * @nvm: storage for Option ROM version information
     660                 :            :  *
     661                 :            :  * Reads the NVM EETRACK ID, Map version, and security revision of the
     662                 :            :  * inactive NVM bank. Used to access version data for a pending update that
     663                 :            :  * has not yet been activated.
     664                 :            :  */
     665                 :          0 : enum ice_status ice_get_inactive_nvm_ver(struct ice_hw *hw, struct ice_nvm_info *nvm)
     666                 :            : {
     667                 :          0 :         return ice_get_nvm_ver_info(hw, ICE_INACTIVE_FLASH_BANK, nvm);
     668                 :            : }
     669                 :            : 
     670                 :            : /**
     671                 :            :  * ice_get_orom_srev - Read the security revision from the OROM CSS header
     672                 :            :  * @hw: pointer to the HW struct
     673                 :            :  * @bank: whether to read from active or inactive flash module
     674                 :            :  * @srev: storage for security revision
     675                 :            :  *
     676                 :            :  * Read the security revision out of the CSS header of the active OROM module
     677                 :            :  * bank.
     678                 :            :  */
     679                 :          0 : static enum ice_status ice_get_orom_srev(struct ice_hw *hw, enum ice_bank_select bank, u32 *srev)
     680                 :            : {
     681                 :          0 :         u32 orom_size_word = hw->flash.banks.orom_size / 2;
     682                 :            :         enum ice_status status;
     683                 :            :         u16 srev_l, srev_h;
     684                 :            :         u32 css_start;
     685                 :            :         u32 hdr_len;
     686                 :            : 
     687                 :          0 :         status = ice_get_nvm_css_hdr_len(hw, bank, &hdr_len);
     688         [ #  # ]:          0 :         if (status)
     689                 :            :                 return status;
     690                 :            : 
     691         [ #  # ]:          0 :         if (orom_size_word < hdr_len) {
     692         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Unexpected Option ROM Size of %u\n",
     693                 :            :                           hw->flash.banks.orom_size);
     694                 :          0 :                 return ICE_ERR_CFG;
     695                 :            :         }
     696                 :            : 
     697                 :            :         /* calculate how far into the Option ROM the CSS header starts. Note
     698                 :            :          * that ice_read_orom_module takes a word offset
     699                 :            :          */
     700                 :          0 :         css_start = orom_size_word - hdr_len;
     701                 :          0 :         status = ice_read_orom_module(hw, bank, css_start + ICE_NVM_CSS_SREV_L, &srev_l);
     702         [ #  # ]:          0 :         if (status)
     703                 :            :                 return status;
     704                 :            : 
     705                 :          0 :         status = ice_read_orom_module(hw, bank, css_start + ICE_NVM_CSS_SREV_H, &srev_h);
     706         [ #  # ]:          0 :         if (status)
     707                 :            :                 return status;
     708                 :            : 
     709                 :          0 :         *srev = srev_h << 16 | srev_l;
     710                 :            : 
     711                 :          0 :         return ICE_SUCCESS;
     712                 :            : }
     713                 :            : 
     714                 :            : /**
     715                 :            :  * ice_get_orom_civd_data - Get the combo version information from Option ROM
     716                 :            :  * @hw: pointer to the HW struct
     717                 :            :  * @bank: whether to read from the active or inactive flash module
     718                 :            :  * @civd: storage for the Option ROM CIVD data.
     719                 :            :  *
     720                 :            :  * Searches through the Option ROM flash contents to locate the CIVD data for
     721                 :            :  * the image.
     722                 :            :  */
     723                 :            : static enum ice_status
     724                 :          0 : ice_get_orom_civd_data(struct ice_hw *hw, enum ice_bank_select bank,
     725                 :            :                        struct ice_orom_civd_info *civd)
     726                 :            : {
     727                 :            :         u8 *orom_data;
     728                 :            :         enum ice_status status;
     729                 :            :         u32 offset;
     730                 :            : 
     731                 :            :         /* The CIVD section is located in the Option ROM aligned to 512 bytes.
     732                 :            :          * The first 4 bytes must contain the ASCII characters "$CIV".
     733                 :            :          * A simple modulo 256 sum of all of the bytes of the structure must
     734                 :            :          * equal 0.
     735                 :            :          *
     736                 :            :          * The exact location is unknown and varies between images but is
     737                 :            :          * usually somewhere in the middle of the bank. We need to scan the
     738                 :            :          * Option ROM bank to locate it.
     739                 :            :          *
     740                 :            :          * It's significantly faster to read the entire Option ROM up front
     741                 :            :          * using the maximum page size, than to read each possible location
     742                 :            :          * with a separate firmware command.
     743                 :            :          */
     744                 :          0 :         orom_data = (u8 *)ice_calloc(hw, hw->flash.banks.orom_size, sizeof(u8));
     745         [ #  # ]:          0 :         if (!orom_data)
     746                 :            :                 return ICE_ERR_NO_MEMORY;
     747                 :            : 
     748                 :          0 :         status = ice_read_flash_module(hw, bank, ICE_SR_1ST_OROM_BANK_PTR, 0,
     749                 :            :                                        orom_data, hw->flash.banks.orom_size);
     750         [ #  # ]:          0 :         if (status) {
     751         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Unable to read Option ROM data\n");
     752                 :          0 :                 return status;
     753                 :            :         }
     754                 :            : 
     755                 :            :         /* Scan the memory buffer to locate the CIVD data section */
     756         [ #  # ]:          0 :         for (offset = 0; (offset + 512) <= hw->flash.banks.orom_size; offset += 512) {
     757                 :            :                 struct ice_orom_civd_info *tmp;
     758                 :            :                 u8 sum = 0, i;
     759                 :            : 
     760                 :          0 :                 tmp = (struct ice_orom_civd_info *)&orom_data[offset];
     761                 :            : 
     762                 :            :                 /* Skip forward until we find a matching signature */
     763         [ #  # ]:          0 :                 if (memcmp("$CIV", tmp->signature, sizeof(tmp->signature)) != 0)
     764                 :            :                         continue;
     765                 :            : 
     766         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Found CIVD section at offset %u\n",
     767                 :            :                           offset);
     768                 :            : 
     769                 :            :                 /* Verify that the simple checksum is zero */
     770         [ #  # ]:          0 :                 for (i = 0; i < sizeof(*tmp); i++)
     771                 :          0 :                         sum += ((u8 *)tmp)[i];
     772                 :            : 
     773         [ #  # ]:          0 :                 if (sum) {
     774         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_NVM, "Found CIVD data with invalid checksum of %u\n",
     775                 :            :                                   sum);
     776                 :          0 :                         goto err_invalid_checksum;
     777                 :            :                 }
     778                 :            : 
     779                 :          0 :                 *civd = *tmp;
     780                 :          0 :                 ice_free(hw, orom_data);
     781                 :          0 :                 return ICE_SUCCESS;
     782                 :            :         }
     783                 :            : 
     784         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_NVM, "Unable to locate CIVD data within the Option ROM\n");
     785                 :            : 
     786                 :          0 : err_invalid_checksum:
     787                 :          0 :         ice_free(hw, orom_data);
     788                 :          0 :         return ICE_ERR_NVM;
     789                 :            : }
     790                 :            : 
     791                 :            : /**
     792                 :            :  * ice_get_orom_ver_info - Read Option ROM version information
     793                 :            :  * @hw: pointer to the HW struct
     794                 :            :  * @bank: whether to read from the active or inactive flash module
     795                 :            :  * @orom: pointer to Option ROM info structure
     796                 :            :  *
     797                 :            :  * Read Option ROM version and security revision from the Option ROM flash
     798                 :            :  * section.
     799                 :            :  */
     800                 :            : static enum ice_status
     801                 :          0 : ice_get_orom_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_orom_info *orom)
     802                 :            : {
     803                 :            :         struct ice_orom_civd_info civd;
     804                 :            :         enum ice_status status;
     805                 :            :         u32 combo_ver;
     806                 :            : 
     807                 :          0 :         status = ice_get_orom_civd_data(hw, bank, &civd);
     808         [ #  # ]:          0 :         if (status) {
     809         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to locate valid Option ROM CIVD data\n");
     810                 :          0 :                 return status;
     811                 :            :         }
     812                 :            : 
     813                 :          0 :         combo_ver = LE32_TO_CPU(civd.combo_ver);
     814                 :            : 
     815                 :          0 :         orom->major = (u8)((combo_ver & ICE_OROM_VER_MASK) >> ICE_OROM_VER_SHIFT);
     816                 :          0 :         orom->patch = (u8)(combo_ver & ICE_OROM_VER_PATCH_MASK);
     817                 :          0 :         orom->build = (u16)((combo_ver & ICE_OROM_VER_BUILD_MASK) >> ICE_OROM_VER_BUILD_SHIFT);
     818                 :            : 
     819                 :          0 :         status = ice_get_orom_srev(hw, bank, &orom->srev);
     820         [ #  # ]:          0 :         if (status) {
     821         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read Option ROM security revision.\n");
     822                 :          0 :                 return status;
     823                 :            :         }
     824                 :            : 
     825                 :            :         return ICE_SUCCESS;
     826                 :            : }
     827                 :            : 
     828                 :            : /**
     829                 :            :  * ice_get_inactive_orom_ver - Read Option ROM version from the inactive bank
     830                 :            :  * @hw: pointer to the HW structure
     831                 :            :  * @orom: storage for Option ROM version information
     832                 :            :  *
     833                 :            :  * Reads the Option ROM version and security revision data for the inactive
     834                 :            :  * section of flash. Used to access version data for a pending update that has
     835                 :            :  * not yet been activated.
     836                 :            :  */
     837                 :          0 : enum ice_status ice_get_inactive_orom_ver(struct ice_hw *hw, struct ice_orom_info *orom)
     838                 :            : {
     839                 :          0 :         return ice_get_orom_ver_info(hw, ICE_INACTIVE_FLASH_BANK, orom);
     840                 :            : }
     841                 :            : 
     842                 :            : /**
     843                 :            :  * ice_discover_flash_size - Discover the available flash size.
     844                 :            :  * @hw: pointer to the HW struct
     845                 :            :  *
     846                 :            :  * The device flash could be up to 16MB in size. However, it is possible that
     847                 :            :  * the actual size is smaller. Use bisection to determine the accessible size
     848                 :            :  * of flash memory.
     849                 :            :  */
     850                 :          0 : static enum ice_status ice_discover_flash_size(struct ice_hw *hw)
     851                 :            : {
     852                 :            :         u32 min_size = 0, max_size = ICE_AQC_NVM_MAX_OFFSET + 1;
     853                 :            :         enum ice_status status;
     854                 :            : 
     855         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
     856                 :            : 
     857                 :          0 :         status = ice_acquire_nvm(hw, ICE_RES_READ);
     858         [ #  # ]:          0 :         if (status)
     859                 :            :                 return status;
     860                 :            : 
     861         [ #  # ]:          0 :         while ((max_size - min_size) > 1) {
     862                 :          0 :                 u32 offset = (max_size + min_size) / 2;
     863                 :          0 :                 u32 len = 1;
     864                 :            :                 u8 data;
     865                 :            : 
     866                 :          0 :                 status = ice_read_flat_nvm(hw, offset, &len, &data, false);
     867         [ #  # ]:          0 :                 if (status == ICE_ERR_AQ_ERROR &&
     868         [ #  # ]:          0 :                     hw->adminq.sq_last_status == ICE_AQ_RC_EINVAL) {
     869         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_NVM, "%s: New upper bound of %u bytes\n",
     870                 :            :                                   __func__, offset);
     871                 :            :                         status = ICE_SUCCESS;
     872                 :            :                         max_size = offset;
     873         [ #  # ]:          0 :                 } else if (!status) {
     874         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_NVM, "%s: New lower bound of %u bytes\n",
     875                 :            :                                   __func__, offset);
     876                 :            :                         min_size = offset;
     877                 :            :                 } else {
     878                 :            :                         /* an unexpected error occurred */
     879                 :          0 :                         goto err_read_flat_nvm;
     880                 :            :                 }
     881                 :            :         }
     882                 :            : 
     883         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_NVM, "Predicted flash size is %u bytes\n", max_size);
     884                 :            : 
     885                 :          0 :         hw->flash.flash_size = max_size;
     886                 :            : 
     887                 :          0 : err_read_flat_nvm:
     888                 :          0 :         ice_release_nvm(hw);
     889                 :            : 
     890                 :          0 :         return status;
     891                 :            : }
     892                 :            : 
     893                 :            : /**
     894                 :            :  * ice_read_sr_pointer - Read the value of a Shadow RAM pointer word
     895                 :            :  * @hw: pointer to the HW structure
     896                 :            :  * @offset: the word offset of the Shadow RAM word to read
     897                 :            :  * @pointer: pointer value read from Shadow RAM
     898                 :            :  *
     899                 :            :  * Read the given Shadow RAM word, and convert it to a pointer value specified
     900                 :            :  * in bytes. This function assumes the specified offset is a valid pointer
     901                 :            :  * word.
     902                 :            :  *
     903                 :            :  * Each pointer word specifies whether it is stored in word size or 4KB
     904                 :            :  * sector size by using the highest bit. The reported pointer value will be in
     905                 :            :  * bytes, intended for flat NVM reads.
     906                 :            :  */
     907                 :            : static enum ice_status
     908                 :          0 : ice_read_sr_pointer(struct ice_hw *hw, u16 offset, u32 *pointer)
     909                 :            : {
     910                 :            :         enum ice_status status;
     911                 :            :         u16 value;
     912                 :            : 
     913                 :          0 :         status = ice_read_sr_word(hw, offset, &value);
     914         [ #  # ]:          0 :         if (status)
     915                 :            :                 return status;
     916                 :            : 
     917                 :            :         /* Determine if the pointer is in 4KB or word units */
     918         [ #  # ]:          0 :         if (value & ICE_SR_NVM_PTR_4KB_UNITS)
     919                 :          0 :                 *pointer = (value & ~ICE_SR_NVM_PTR_4KB_UNITS) * 4 * 1024;
     920                 :            :         else
     921                 :          0 :                 *pointer = value * 2;
     922                 :            : 
     923                 :            :         return ICE_SUCCESS;
     924                 :            : }
     925                 :            : 
     926                 :            : /**
     927                 :            :  * ice_read_sr_area_size - Read an area size from a Shadow RAM word
     928                 :            :  * @hw: pointer to the HW structure
     929                 :            :  * @offset: the word offset of the Shadow RAM to read
     930                 :            :  * @size: size value read from the Shadow RAM
     931                 :            :  *
     932                 :            :  * Read the given Shadow RAM word, and convert it to an area size value
     933                 :            :  * specified in bytes. This function assumes the specified offset is a valid
     934                 :            :  * area size word.
     935                 :            :  *
     936                 :            :  * Each area size word is specified in 4KB sector units. This function reports
     937                 :            :  * the size in bytes, intended for flat NVM reads.
     938                 :            :  */
     939                 :            : static enum ice_status
     940                 :            : ice_read_sr_area_size(struct ice_hw *hw, u16 offset, u32 *size)
     941                 :            : {
     942                 :            :         enum ice_status status;
     943                 :            :         u16 value;
     944                 :            : 
     945                 :          0 :         status = ice_read_sr_word(hw, offset, &value);
     946   [ #  #  #  #  :          0 :         if (status)
                   #  # ]
     947                 :            :                 return status;
     948                 :            : 
     949                 :            :         /* Area sizes are always specified in 4KB units */
     950                 :          0 :         *size = value * 4 * 1024;
     951                 :            : 
     952                 :            :         return ICE_SUCCESS;
     953                 :            : }
     954                 :            : 
     955                 :            : /**
     956                 :            :  * ice_determine_active_flash_banks - Discover active bank for each module
     957                 :            :  * @hw: pointer to the HW struct
     958                 :            :  *
     959                 :            :  * Read the Shadow RAM control word and determine which banks are active for
     960                 :            :  * the NVM, OROM, and Netlist modules. Also read and calculate the associated
     961                 :            :  * pointer and size. These values are then cached into the ice_flash_info
     962                 :            :  * structure for later use in order to calculate the correct offset to read
     963                 :            :  * from the active module.
     964                 :            :  */
     965                 :            : static enum ice_status
     966                 :          0 : ice_determine_active_flash_banks(struct ice_hw *hw)
     967                 :            : {
     968                 :            :         struct ice_bank_info *banks = &hw->flash.banks;
     969                 :            :         enum ice_status status;
     970                 :            :         u16 ctrl_word;
     971                 :            : 
     972                 :          0 :         status = ice_read_sr_word(hw, ICE_SR_NVM_CTRL_WORD, &ctrl_word);
     973         [ #  # ]:          0 :         if (status) {
     974         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read the Shadow RAM control word\n");
     975                 :          0 :                 return status;
     976                 :            :         }
     977                 :            : 
     978                 :            :         /* Check that the control word indicates validity */
     979         [ #  # ]:          0 :         if ((ctrl_word & ICE_SR_CTRL_WORD_1_M) >> ICE_SR_CTRL_WORD_1_S != ICE_SR_CTRL_WORD_VALID) {
     980         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Shadow RAM control word is invalid\n");
     981                 :          0 :                 return ICE_ERR_CFG;
     982                 :            :         }
     983                 :            : 
     984         [ #  # ]:          0 :         if (!(ctrl_word & ICE_SR_CTRL_WORD_NVM_BANK))
     985                 :          0 :                 banks->nvm_bank = ICE_1ST_FLASH_BANK;
     986                 :            :         else
     987                 :          0 :                 banks->nvm_bank = ICE_2ND_FLASH_BANK;
     988                 :            : 
     989         [ #  # ]:          0 :         if (!(ctrl_word & ICE_SR_CTRL_WORD_OROM_BANK))
     990                 :          0 :                 banks->orom_bank = ICE_1ST_FLASH_BANK;
     991                 :            :         else
     992                 :          0 :                 banks->orom_bank = ICE_2ND_FLASH_BANK;
     993                 :            : 
     994         [ #  # ]:          0 :         if (!(ctrl_word & ICE_SR_CTRL_WORD_NETLIST_BANK))
     995                 :          0 :                 banks->netlist_bank = ICE_1ST_FLASH_BANK;
     996                 :            :         else
     997                 :          0 :                 banks->netlist_bank = ICE_2ND_FLASH_BANK;
     998                 :            : 
     999                 :          0 :         status = ice_read_sr_pointer(hw, ICE_SR_1ST_NVM_BANK_PTR, &banks->nvm_ptr);
    1000         [ #  # ]:          0 :         if (status) {
    1001         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM bank pointer\n");
    1002                 :          0 :                 return status;
    1003                 :            :         }
    1004                 :            : 
    1005                 :            :         status = ice_read_sr_area_size(hw, ICE_SR_NVM_BANK_SIZE, &banks->nvm_size);
    1006                 :            :         if (status) {
    1007         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM bank area size\n");
    1008                 :          0 :                 return status;
    1009                 :            :         }
    1010                 :            : 
    1011                 :          0 :         status = ice_read_sr_pointer(hw, ICE_SR_1ST_OROM_BANK_PTR, &banks->orom_ptr);
    1012         [ #  # ]:          0 :         if (status) {
    1013         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read OROM bank pointer\n");
    1014                 :          0 :                 return status;
    1015                 :            :         }
    1016                 :            : 
    1017                 :            :         status = ice_read_sr_area_size(hw, ICE_SR_OROM_BANK_SIZE, &banks->orom_size);
    1018                 :            :         if (status) {
    1019         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read OROM bank area size\n");
    1020                 :          0 :                 return status;
    1021                 :            :         }
    1022                 :            : 
    1023                 :          0 :         status = ice_read_sr_pointer(hw, ICE_SR_NETLIST_BANK_PTR, &banks->netlist_ptr);
    1024         [ #  # ]:          0 :         if (status) {
    1025         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read Netlist bank pointer\n");
    1026                 :          0 :                 return status;
    1027                 :            :         }
    1028                 :            : 
    1029                 :            :         status = ice_read_sr_area_size(hw, ICE_SR_NETLIST_BANK_SIZE, &banks->netlist_size);
    1030                 :            :         if (status) {
    1031         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to read Netlist bank area size\n");
    1032                 :          0 :                 return status;
    1033                 :            :         }
    1034                 :            : 
    1035                 :            :         return ICE_SUCCESS;
    1036                 :            : }
    1037                 :            : 
    1038                 :            : /**
    1039                 :            :  * ice_init_nvm - initializes NVM setting
    1040                 :            :  * @hw: pointer to the HW struct
    1041                 :            :  *
    1042                 :            :  * This function reads and populates NVM settings such as Shadow RAM size,
    1043                 :            :  * max_timeout, and blank_nvm_mode
    1044                 :            :  */
    1045                 :          0 : enum ice_status ice_init_nvm(struct ice_hw *hw)
    1046                 :            : {
    1047                 :            :         struct ice_flash_info *flash = &hw->flash;
    1048                 :            :         enum ice_status status;
    1049                 :            :         u32 fla, gens_stat;
    1050                 :            :         u8 sr_size;
    1051                 :            : 
    1052         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
    1053                 :            : 
    1054                 :            :         /* The SR size is stored regardless of the NVM programming mode
    1055                 :            :          * as the blank mode may be used in the factory line.
    1056                 :            :          */
    1057                 :          0 :         gens_stat = rd32(hw, GLNVM_GENS);
    1058                 :          0 :         sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S;
    1059                 :            : 
    1060                 :            :         /* Switching to words (sr_size contains power of 2) */
    1061                 :          0 :         flash->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB;
    1062                 :            : 
    1063                 :            :         /* Check if we are in the normal or blank NVM programming mode */
    1064                 :          0 :         fla = rd32(hw, GLNVM_FLA);
    1065         [ #  # ]:          0 :         if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */
    1066                 :          0 :                 flash->blank_nvm_mode = false;
    1067                 :            :         } else {
    1068                 :            :                 /* Blank programming mode */
    1069                 :          0 :                 flash->blank_nvm_mode = true;
    1070         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "NVM init error: unsupported blank mode.\n");
    1071                 :          0 :                 return ICE_ERR_NVM_BLANK_MODE;
    1072                 :            :         }
    1073                 :            : 
    1074                 :          0 :         status = ice_discover_flash_size(hw);
    1075         [ #  # ]:          0 :         if (status) {
    1076         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "NVM init error: failed to discover flash size.\n");
    1077                 :          0 :                 return status;
    1078                 :            :         }
    1079                 :            : 
    1080                 :          0 :         status = ice_determine_active_flash_banks(hw);
    1081         [ #  # ]:          0 :         if (status) {
    1082         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_NVM, "Failed to determine active flash banks.\n");
    1083                 :          0 :                 return status;
    1084                 :            :         }
    1085                 :            : 
    1086                 :          0 :         status = ice_get_nvm_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->nvm);
    1087         [ #  # ]:          0 :         if (status) {
    1088         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Failed to read NVM info.\n");
    1089                 :          0 :                 return status;
    1090                 :            :         }
    1091                 :            : 
    1092                 :          0 :         status = ice_get_orom_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->orom);
    1093         [ #  # ]:          0 :         if (status)
    1094         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Failed to read Option ROM info.\n");
    1095                 :            : 
    1096                 :            :         return ICE_SUCCESS;
    1097                 :            : }
    1098                 :            : 
    1099                 :            : /**
    1100                 :            :  * ice_read_sr_buf - Reads Shadow RAM buf and acquire lock if necessary
    1101                 :            :  * @hw: pointer to the HW structure
    1102                 :            :  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
    1103                 :            :  * @words: (in) number of words to read; (out) number of words actually read
    1104                 :            :  * @data: words read from the Shadow RAM
    1105                 :            :  *
    1106                 :            :  * Reads 16 bit words (data buf) from the SR using the ice_read_nvm_buf_aq
    1107                 :            :  * method. The buf read is preceded by the NVM ownership take
    1108                 :            :  * and followed by the release.
    1109                 :            :  */
    1110                 :            : enum ice_status
    1111                 :          0 : ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
    1112                 :            : {
    1113                 :            :         enum ice_status status;
    1114                 :            : 
    1115                 :          0 :         status = ice_acquire_nvm(hw, ICE_RES_READ);
    1116         [ #  # ]:          0 :         if (!status) {
    1117                 :          0 :                 status = ice_read_sr_buf_aq(hw, offset, words, data);
    1118                 :          0 :                 ice_release_nvm(hw);
    1119                 :            :         }
    1120                 :            : 
    1121                 :          0 :         return status;
    1122                 :            : }
    1123                 :            : 
    1124                 :            : /**
    1125                 :            :  * ice_nvm_validate_checksum
    1126                 :            :  * @hw: pointer to the HW struct
    1127                 :            :  *
    1128                 :            :  * Verify NVM PFA checksum validity (0x0706)
    1129                 :            :  */
    1130                 :          0 : enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw)
    1131                 :            : {
    1132                 :            :         struct ice_aqc_nvm_checksum *cmd;
    1133                 :            :         struct ice_aq_desc desc;
    1134                 :            :         enum ice_status status;
    1135                 :            : 
    1136                 :          0 :         status = ice_acquire_nvm(hw, ICE_RES_READ);
    1137         [ #  # ]:          0 :         if (status)
    1138                 :            :                 return status;
    1139                 :            : 
    1140                 :            :         cmd = &desc.params.nvm_checksum;
    1141                 :            : 
    1142                 :          0 :         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_checksum);
    1143                 :          0 :         cmd->flags = ICE_AQC_NVM_CHECKSUM_VERIFY;
    1144                 :            : 
    1145                 :          0 :         status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
    1146                 :          0 :         ice_release_nvm(hw);
    1147                 :            : 
    1148         [ #  # ]:          0 :         if (!status)
    1149         [ #  # ]:          0 :                 if (LE16_TO_CPU(cmd->checksum) != ICE_AQC_NVM_CHECKSUM_CORRECT)
    1150                 :            :                         status = ICE_ERR_NVM_CHECKSUM;
    1151                 :            : 
    1152                 :            :         return status;
    1153                 :            : }
    1154                 :            : 
    1155                 :            : /**
    1156                 :            :  * ice_nvm_recalculate_checksum
    1157                 :            :  * @hw: pointer to the HW struct
    1158                 :            :  *
    1159                 :            :  * Recalculate NVM PFA checksum (0x0706)
    1160                 :            :  */
    1161                 :          0 : enum ice_status ice_nvm_recalculate_checksum(struct ice_hw *hw)
    1162                 :            : {
    1163                 :            :         struct ice_aqc_nvm_checksum *cmd;
    1164                 :            :         struct ice_aq_desc desc;
    1165                 :            :         enum ice_status status;
    1166                 :            : 
    1167                 :          0 :         status = ice_acquire_nvm(hw, ICE_RES_READ);
    1168         [ #  # ]:          0 :         if (status)
    1169                 :            :                 return status;
    1170                 :            : 
    1171                 :            :         cmd = &desc.params.nvm_checksum;
    1172                 :            : 
    1173                 :          0 :         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_checksum);
    1174                 :          0 :         cmd->flags = ICE_AQC_NVM_CHECKSUM_RECALC;
    1175                 :            : 
    1176                 :          0 :         status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
    1177                 :            : 
    1178                 :          0 :         ice_release_nvm(hw);
    1179                 :            : 
    1180                 :          0 :         return status;
    1181                 :            : }
    1182                 :            : 
    1183                 :            : /**
    1184                 :            :  * ice_nvm_access_get_features - Return the NVM access features structure
    1185                 :            :  * @cmd: NVM access command to process
    1186                 :            :  * @data: storage for the driver NVM features
    1187                 :            :  *
    1188                 :            :  * Fill in the data section of the NVM access request with a copy of the NVM
    1189                 :            :  * features structure.
    1190                 :            :  */
    1191                 :            : enum ice_status
    1192                 :          0 : ice_nvm_access_get_features(struct ice_nvm_access_cmd *cmd,
    1193                 :            :                             union ice_nvm_access_data *data)
    1194                 :            : {
    1195                 :            :         /* The provided data_size must be at least as large as our NVM
    1196                 :            :          * features structure. A larger size should not be treated as an
    1197                 :            :          * error, to allow future extensions to the features structure to
    1198                 :            :          * work on older drivers.
    1199                 :            :          */
    1200         [ #  # ]:          0 :         if (cmd->data_size < sizeof(struct ice_nvm_features))
    1201                 :            :                 return ICE_ERR_NO_MEMORY;
    1202                 :            : 
    1203                 :            :         /* Initialize the data buffer to zeros */
    1204                 :          0 :         ice_memset(data, 0, cmd->data_size, ICE_NONDMA_MEM);
    1205                 :            : 
    1206                 :            :         /* Fill in the features data */
    1207                 :          0 :         data->drv_features.major = ICE_NVM_ACCESS_MAJOR_VER;
    1208                 :          0 :         data->drv_features.minor = ICE_NVM_ACCESS_MINOR_VER;
    1209                 :          0 :         data->drv_features.size = sizeof(struct ice_nvm_features);
    1210                 :          0 :         data->drv_features.features[0] = ICE_NVM_FEATURES_0_REG_ACCESS;
    1211                 :            : 
    1212                 :          0 :         return ICE_SUCCESS;
    1213                 :            : }
    1214                 :            : 
    1215                 :            : /**
    1216                 :            :  * ice_nvm_access_get_module - Helper function to read module value
    1217                 :            :  * @cmd: NVM access command structure
    1218                 :            :  *
    1219                 :            :  * Reads the module value out of the NVM access config field.
    1220                 :            :  */
    1221                 :          0 : u32 ice_nvm_access_get_module(struct ice_nvm_access_cmd *cmd)
    1222                 :            : {
    1223                 :          0 :         return ((cmd->config & ICE_NVM_CFG_MODULE_M) >> ICE_NVM_CFG_MODULE_S);
    1224                 :            : }
    1225                 :            : 
    1226                 :            : /**
    1227                 :            :  * ice_nvm_access_get_flags - Helper function to read flags value
    1228                 :            :  * @cmd: NVM access command structure
    1229                 :            :  *
    1230                 :            :  * Reads the flags value out of the NVM access config field.
    1231                 :            :  */
    1232                 :          0 : u32 ice_nvm_access_get_flags(struct ice_nvm_access_cmd *cmd)
    1233                 :            : {
    1234                 :          0 :         return ((cmd->config & ICE_NVM_CFG_FLAGS_M) >> ICE_NVM_CFG_FLAGS_S);
    1235                 :            : }
    1236                 :            : 
    1237                 :            : /**
    1238                 :            :  * ice_nvm_access_get_adapter - Helper function to read adapter info
    1239                 :            :  * @cmd: NVM access command structure
    1240                 :            :  *
    1241                 :            :  * Read the adapter info value out of the NVM access config field.
    1242                 :            :  */
    1243                 :          0 : u32 ice_nvm_access_get_adapter(struct ice_nvm_access_cmd *cmd)
    1244                 :            : {
    1245                 :          0 :         return ((cmd->config & ICE_NVM_CFG_ADAPTER_INFO_M) >>
    1246                 :            :                 ICE_NVM_CFG_ADAPTER_INFO_S);
    1247                 :            : }
    1248                 :            : 
    1249                 :            : /**
    1250                 :            :  * ice_validate_nvm_rw_reg - Check than an NVM access request is valid
    1251                 :            :  * @cmd: NVM access command structure
    1252                 :            :  *
    1253                 :            :  * Validates that an NVM access structure is request to read or write a valid
    1254                 :            :  * register offset. First validates that the module and flags are correct, and
    1255                 :            :  * then ensures that the register offset is one of the accepted registers.
    1256                 :            :  */
    1257                 :            : static enum ice_status
    1258                 :          0 : ice_validate_nvm_rw_reg(struct ice_nvm_access_cmd *cmd)
    1259                 :            : {
    1260                 :            :         u32 module, flags, offset;
    1261                 :            :         u16 i;
    1262                 :            : 
    1263                 :          0 :         module = ice_nvm_access_get_module(cmd);
    1264                 :          0 :         flags = ice_nvm_access_get_flags(cmd);
    1265                 :          0 :         offset = cmd->offset;
    1266                 :            : 
    1267                 :            :         /* Make sure the module and flags indicate a read/write request */
    1268                 :          0 :         if (module != ICE_NVM_REG_RW_MODULE ||
    1269         [ #  # ]:          0 :             flags != ICE_NVM_REG_RW_FLAGS ||
    1270         [ #  # ]:          0 :             cmd->data_size != FIELD_SIZEOF(union ice_nvm_access_data, regval))
    1271                 :            :                 return ICE_ERR_PARAM;
    1272                 :            : 
    1273         [ #  # ]:          0 :         switch (offset) {
    1274                 :            :         case GL_HICR:
    1275                 :            :         case GL_HICR_EN: /* Note, this register is read only */
    1276                 :            :         case GL_FWSTS:
    1277                 :            :         case GL_MNG_FWSM:
    1278                 :            :         case GLGEN_CSR_DEBUG_C:
    1279                 :            :         case GLGEN_RSTAT:
    1280                 :            :         case GLPCI_LBARCTRL:
    1281                 :            :         case GL_MNG_DEF_DEVID:
    1282                 :            :         case GLNVM_GENS:
    1283                 :            :         case GLNVM_FLA:
    1284                 :            :         case PF_FUNC_RID:
    1285                 :            :                 return ICE_SUCCESS;
    1286                 :            :         default:
    1287                 :            :                 break;
    1288                 :            :         }
    1289                 :            : 
    1290         [ #  # ]:          0 :         for (i = 0; i <= GL_HIDA_MAX_INDEX; i++)
    1291         [ #  # ]:          0 :                 if (offset == (u32)GL_HIDA(i))
    1292                 :            :                         return ICE_SUCCESS;
    1293                 :            : 
    1294         [ #  # ]:          0 :         for (i = 0; i <= GL_HIBA_MAX_INDEX; i++)
    1295         [ #  # ]:          0 :                 if (offset == (u32)GL_HIBA(i))
    1296                 :            :                         return ICE_SUCCESS;
    1297                 :            : 
    1298                 :            :         /* All other register offsets are not valid */
    1299                 :            :         return ICE_ERR_OUT_OF_RANGE;
    1300                 :            : }
    1301                 :            : 
    1302                 :            : /**
    1303                 :            :  * ice_nvm_access_read - Handle an NVM read request
    1304                 :            :  * @hw: pointer to the HW struct
    1305                 :            :  * @cmd: NVM access command to process
    1306                 :            :  * @data: storage for the register value read
    1307                 :            :  *
    1308                 :            :  * Process an NVM access request to read a register.
    1309                 :            :  */
    1310                 :            : enum ice_status
    1311                 :          0 : ice_nvm_access_read(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
    1312                 :            :                     union ice_nvm_access_data *data)
    1313                 :            : {
    1314                 :            :         enum ice_status status;
    1315                 :            : 
    1316         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
    1317                 :            : 
    1318                 :            :         /* Always initialize the output data, even on failure */
    1319                 :          0 :         ice_memset(data, 0, cmd->data_size, ICE_NONDMA_MEM);
    1320                 :            : 
    1321                 :            :         /* Make sure this is a valid read/write access request */
    1322                 :          0 :         status = ice_validate_nvm_rw_reg(cmd);
    1323         [ #  # ]:          0 :         if (status)
    1324                 :            :                 return status;
    1325                 :            : 
    1326         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_NVM, "NVM access: reading register %08x\n",
    1327                 :            :                   cmd->offset);
    1328                 :            : 
    1329                 :            :         /* Read the register and store the contents in the data field */
    1330                 :          0 :         data->regval = rd32(hw, cmd->offset);
    1331                 :            : 
    1332                 :          0 :         return ICE_SUCCESS;
    1333                 :            : }
    1334                 :            : 
    1335                 :            : /**
    1336                 :            :  * ice_nvm_access_write - Handle an NVM write request
    1337                 :            :  * @hw: pointer to the HW struct
    1338                 :            :  * @cmd: NVM access command to process
    1339                 :            :  * @data: NVM access data to write
    1340                 :            :  *
    1341                 :            :  * Process an NVM access request to write a register.
    1342                 :            :  */
    1343                 :            : enum ice_status
    1344                 :          0 : ice_nvm_access_write(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
    1345                 :            :                      union ice_nvm_access_data *data)
    1346                 :            : {
    1347                 :            :         enum ice_status status;
    1348                 :            : 
    1349         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
    1350                 :            : 
    1351                 :            :         /* Make sure this is a valid read/write access request */
    1352                 :          0 :         status = ice_validate_nvm_rw_reg(cmd);
    1353         [ #  # ]:          0 :         if (status)
    1354                 :            :                 return status;
    1355                 :            : 
    1356                 :            :         /* Reject requests to write to read-only registers */
    1357         [ #  # ]:          0 :         switch (cmd->offset) {
    1358                 :            :         case GL_HICR_EN:
    1359                 :            :         case GLGEN_RSTAT:
    1360                 :            :                 return ICE_ERR_OUT_OF_RANGE;
    1361                 :            :         default:
    1362                 :            :                 break;
    1363                 :            :         }
    1364                 :            : 
    1365         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_NVM, "NVM access: writing register %08x with value %08x\n",
    1366                 :            :                   cmd->offset, data->regval);
    1367                 :            : 
    1368                 :            :         /* Write the data field to the specified register */
    1369                 :          0 :         wr32(hw, cmd->offset, data->regval);
    1370                 :            : 
    1371                 :          0 :         return ICE_SUCCESS;
    1372                 :            : }
    1373                 :            : 
    1374                 :            : /**
    1375                 :            :  * ice_handle_nvm_access - Handle an NVM access request
    1376                 :            :  * @hw: pointer to the HW struct
    1377                 :            :  * @cmd: NVM access command info
    1378                 :            :  * @data: pointer to read or return data
    1379                 :            :  *
    1380                 :            :  * Process an NVM access request. Read the command structure information and
    1381                 :            :  * determine if it is valid. If not, report an error indicating the command
    1382                 :            :  * was invalid.
    1383                 :            :  *
    1384                 :            :  * For valid commands, perform the necessary function, copying the data into
    1385                 :            :  * the provided data buffer.
    1386                 :            :  */
    1387                 :            : enum ice_status
    1388                 :          0 : ice_handle_nvm_access(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
    1389                 :            :                       union ice_nvm_access_data *data)
    1390                 :            : {
    1391                 :            :         u32 module, flags, adapter_info;
    1392                 :            : 
    1393         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
    1394                 :            : 
    1395                 :            :         /* Extended flags are currently reserved and must be zero */
    1396         [ #  # ]:          0 :         if ((cmd->config & ICE_NVM_CFG_EXT_FLAGS_M) != 0)
    1397                 :            :                 return ICE_ERR_PARAM;
    1398                 :            : 
    1399                 :            :         /* Adapter info must match the HW device ID */
    1400                 :          0 :         adapter_info = ice_nvm_access_get_adapter(cmd);
    1401         [ #  # ]:          0 :         if (adapter_info != hw->device_id)
    1402                 :            :                 return ICE_ERR_PARAM;
    1403                 :            : 
    1404      [ #  #  # ]:          0 :         switch (cmd->command) {
    1405                 :          0 :         case ICE_NVM_CMD_READ:
    1406                 :          0 :                 module = ice_nvm_access_get_module(cmd);
    1407                 :          0 :                 flags = ice_nvm_access_get_flags(cmd);
    1408                 :            : 
    1409                 :            :                 /* Getting the driver's NVM features structure shares the same
    1410                 :            :                  * command type as reading a register. Read the config field
    1411                 :            :                  * to determine if this is a request to get features.
    1412                 :            :                  */
    1413                 :          0 :                 if (module == ICE_NVM_GET_FEATURES_MODULE &&
    1414         [ #  # ]:          0 :                     flags == ICE_NVM_GET_FEATURES_FLAGS &&
    1415         [ #  # ]:          0 :                     cmd->offset == 0)
    1416                 :          0 :                         return ice_nvm_access_get_features(cmd, data);
    1417                 :            :                 else
    1418                 :          0 :                         return ice_nvm_access_read(hw, cmd, data);
    1419                 :          0 :         case ICE_NVM_CMD_WRITE:
    1420                 :          0 :                 return ice_nvm_access_write(hw, cmd, data);
    1421                 :            :         default:
    1422                 :            :                 return ICE_ERR_PARAM;
    1423                 :            :         }
    1424                 :            : }

Generated by: LCOV version 1.14