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

Generated by: LCOV version 1.14