root/drivers/net/ethernet/intel/ice/ice_nvm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ice_aq_read_nvm
  2. ice_check_sr_access_params
  3. ice_read_sr_aq
  4. ice_read_sr_word_aq
  5. ice_read_sr_buf_aq
  6. ice_acquire_nvm
  7. ice_release_nvm
  8. ice_read_sr_word
  9. ice_init_nvm
  10. ice_read_sr_buf
  11. ice_nvm_validate_checksum

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright (c) 2018, Intel Corporation. */
   3 
   4 #include "ice_common.h"
   5 
   6 /**
   7  * ice_aq_read_nvm
   8  * @hw: pointer to the HW struct
   9  * @module_typeid: module pointer location in words from the NVM beginning
  10  * @offset: byte offset from the module beginning
  11  * @length: length of the section to be read (in bytes from the offset)
  12  * @data: command buffer (size [bytes] = length)
  13  * @last_command: tells if this is the last command in a series
  14  * @cd: pointer to command details structure or NULL
  15  *
  16  * Read the NVM using the admin queue commands (0x0701)
  17  */
  18 static enum ice_status
  19 ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
  20                 void *data, bool last_command, struct ice_sq_cd *cd)
  21 {
  22         struct ice_aq_desc desc;
  23         struct ice_aqc_nvm *cmd;
  24 
  25         cmd = &desc.params.nvm;
  26 
  27         /* In offset the highest byte must be zeroed. */
  28         if (offset & 0xFF000000)
  29                 return ICE_ERR_PARAM;
  30 
  31         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_read);
  32 
  33         /* If this is the last command in a series, set the proper flag. */
  34         if (last_command)
  35                 cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
  36         cmd->module_typeid = cpu_to_le16(module_typeid);
  37         cmd->offset_low = cpu_to_le16(offset & 0xFFFF);
  38         cmd->offset_high = (offset >> 16) & 0xFF;
  39         cmd->length = cpu_to_le16(length);
  40 
  41         return ice_aq_send_cmd(hw, &desc, data, length, cd);
  42 }
  43 
  44 /**
  45  * ice_check_sr_access_params - verify params for Shadow RAM R/W operations.
  46  * @hw: pointer to the HW structure
  47  * @offset: offset in words from module start
  48  * @words: number of words to access
  49  */
  50 static enum ice_status
  51 ice_check_sr_access_params(struct ice_hw *hw, u32 offset, u16 words)
  52 {
  53         if ((offset + words) > hw->nvm.sr_words) {
  54                 ice_debug(hw, ICE_DBG_NVM,
  55                           "NVM error: offset beyond SR lmt.\n");
  56                 return ICE_ERR_PARAM;
  57         }
  58 
  59         if (words > ICE_SR_SECTOR_SIZE_IN_WORDS) {
  60                 /* We can access only up to 4KB (one sector), in one AQ write */
  61                 ice_debug(hw, ICE_DBG_NVM,
  62                           "NVM error: tried to access %d words, limit is %d.\n",
  63                           words, ICE_SR_SECTOR_SIZE_IN_WORDS);
  64                 return ICE_ERR_PARAM;
  65         }
  66 
  67         if (((offset + (words - 1)) / ICE_SR_SECTOR_SIZE_IN_WORDS) !=
  68             (offset / ICE_SR_SECTOR_SIZE_IN_WORDS)) {
  69                 /* A single access cannot spread over two sectors */
  70                 ice_debug(hw, ICE_DBG_NVM,
  71                           "NVM error: cannot spread over two sectors.\n");
  72                 return ICE_ERR_PARAM;
  73         }
  74 
  75         return 0;
  76 }
  77 
  78 /**
  79  * ice_read_sr_aq - Read Shadow RAM.
  80  * @hw: pointer to the HW structure
  81  * @offset: offset in words from module start
  82  * @words: number of words to read
  83  * @data: buffer for words reads from Shadow RAM
  84  * @last_command: tells the AdminQ that this is the last command
  85  *
  86  * Reads 16-bit word buffers from the Shadow RAM using the admin command.
  87  */
  88 static enum ice_status
  89 ice_read_sr_aq(struct ice_hw *hw, u32 offset, u16 words, u16 *data,
  90                bool last_command)
  91 {
  92         enum ice_status status;
  93 
  94         status = ice_check_sr_access_params(hw, offset, words);
  95 
  96         /* values in "offset" and "words" parameters are sized as words
  97          * (16 bits) but ice_aq_read_nvm expects these values in bytes.
  98          * So do this conversion while calling ice_aq_read_nvm.
  99          */
 100         if (!status)
 101                 status = ice_aq_read_nvm(hw, 0, 2 * offset, 2 * words, data,
 102                                          last_command, NULL);
 103 
 104         return status;
 105 }
 106 
 107 /**
 108  * ice_read_sr_word_aq - Reads Shadow RAM via AQ
 109  * @hw: pointer to the HW structure
 110  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
 111  * @data: word read from the Shadow RAM
 112  *
 113  * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_aq method.
 114  */
 115 static enum ice_status
 116 ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
 117 {
 118         enum ice_status status;
 119 
 120         status = ice_read_sr_aq(hw, offset, 1, data, true);
 121         if (!status)
 122                 *data = le16_to_cpu(*(__force __le16 *)data);
 123 
 124         return status;
 125 }
 126 
 127 /**
 128  * ice_read_sr_buf_aq - Reads Shadow RAM buf via AQ
 129  * @hw: pointer to the HW structure
 130  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
 131  * @words: (in) number of words to read; (out) number of words actually read
 132  * @data: words read from the Shadow RAM
 133  *
 134  * Reads 16 bit words (data buf) from the SR using the ice_read_sr_aq
 135  * method. Ownership of the NVM is taken before reading the buffer and later
 136  * released.
 137  */
 138 static enum ice_status
 139 ice_read_sr_buf_aq(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
 140 {
 141         enum ice_status status;
 142         bool last_cmd = false;
 143         u16 words_read = 0;
 144         u16 i = 0;
 145 
 146         do {
 147                 u16 read_size, off_w;
 148 
 149                 /* Calculate number of bytes we should read in this step.
 150                  * It's not allowed to read more than one page at a time or
 151                  * to cross page boundaries.
 152                  */
 153                 off_w = offset % ICE_SR_SECTOR_SIZE_IN_WORDS;
 154                 read_size = off_w ?
 155                         min_t(u16, *words,
 156                               (ICE_SR_SECTOR_SIZE_IN_WORDS - off_w)) :
 157                         min_t(u16, (*words - words_read),
 158                               ICE_SR_SECTOR_SIZE_IN_WORDS);
 159 
 160                 /* Check if this is last command, if so set proper flag */
 161                 if ((words_read + read_size) >= *words)
 162                         last_cmd = true;
 163 
 164                 status = ice_read_sr_aq(hw, offset, read_size,
 165                                         data + words_read, last_cmd);
 166                 if (status)
 167                         goto read_nvm_buf_aq_exit;
 168 
 169                 /* Increment counter for words already read and move offset to
 170                  * new read location
 171                  */
 172                 words_read += read_size;
 173                 offset += read_size;
 174         } while (words_read < *words);
 175 
 176         for (i = 0; i < *words; i++)
 177                 data[i] = le16_to_cpu(((__force __le16 *)data)[i]);
 178 
 179 read_nvm_buf_aq_exit:
 180         *words = words_read;
 181         return status;
 182 }
 183 
 184 /**
 185  * ice_acquire_nvm - Generic request for acquiring the NVM ownership
 186  * @hw: pointer to the HW structure
 187  * @access: NVM access type (read or write)
 188  *
 189  * This function will request NVM ownership.
 190  */
 191 static enum ice_status
 192 ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
 193 {
 194         if (hw->nvm.blank_nvm_mode)
 195                 return 0;
 196 
 197         return ice_acquire_res(hw, ICE_NVM_RES_ID, access, ICE_NVM_TIMEOUT);
 198 }
 199 
 200 /**
 201  * ice_release_nvm - Generic request for releasing the NVM ownership
 202  * @hw: pointer to the HW structure
 203  *
 204  * This function will release NVM ownership.
 205  */
 206 static void ice_release_nvm(struct ice_hw *hw)
 207 {
 208         if (hw->nvm.blank_nvm_mode)
 209                 return;
 210 
 211         ice_release_res(hw, ICE_NVM_RES_ID);
 212 }
 213 
 214 /**
 215  * ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary
 216  * @hw: pointer to the HW structure
 217  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
 218  * @data: word read from the Shadow RAM
 219  *
 220  * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
 221  */
 222 static enum ice_status
 223 ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
 224 {
 225         enum ice_status status;
 226 
 227         status = ice_acquire_nvm(hw, ICE_RES_READ);
 228         if (!status) {
 229                 status = ice_read_sr_word_aq(hw, offset, data);
 230                 ice_release_nvm(hw);
 231         }
 232 
 233         return status;
 234 }
 235 
 236 /**
 237  * ice_init_nvm - initializes NVM setting
 238  * @hw: pointer to the HW struct
 239  *
 240  * This function reads and populates NVM settings such as Shadow RAM size,
 241  * max_timeout, and blank_nvm_mode
 242  */
 243 enum ice_status ice_init_nvm(struct ice_hw *hw)
 244 {
 245         struct ice_nvm_info *nvm = &hw->nvm;
 246         u16 eetrack_lo, eetrack_hi;
 247         enum ice_status status = 0;
 248         u32 fla, gens_stat;
 249         u8 sr_size;
 250 
 251         /* The SR size is stored regardless of the NVM programming mode
 252          * as the blank mode may be used in the factory line.
 253          */
 254         gens_stat = rd32(hw, GLNVM_GENS);
 255         sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S;
 256 
 257         /* Switching to words (sr_size contains power of 2) */
 258         nvm->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB;
 259 
 260         /* Check if we are in the normal or blank NVM programming mode */
 261         fla = rd32(hw, GLNVM_FLA);
 262         if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */
 263                 nvm->blank_nvm_mode = false;
 264         } else { /* Blank programming mode */
 265                 nvm->blank_nvm_mode = true;
 266                 status = ICE_ERR_NVM_BLANK_MODE;
 267                 ice_debug(hw, ICE_DBG_NVM,
 268                           "NVM init error: unsupported blank mode.\n");
 269                 return status;
 270         }
 271 
 272         status = ice_read_sr_word(hw, ICE_SR_NVM_DEV_STARTER_VER, &hw->nvm.ver);
 273         if (status) {
 274                 ice_debug(hw, ICE_DBG_INIT,
 275                           "Failed to read DEV starter version.\n");
 276                 return status;
 277         }
 278 
 279         status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_LO, &eetrack_lo);
 280         if (status) {
 281                 ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK lo.\n");
 282                 return status;
 283         }
 284         status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_HI, &eetrack_hi);
 285         if (status) {
 286                 ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK hi.\n");
 287                 return status;
 288         }
 289 
 290         hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
 291 
 292         return status;
 293 }
 294 
 295 /**
 296  * ice_read_sr_buf - Reads Shadow RAM buf and acquire lock if necessary
 297  * @hw: pointer to the HW structure
 298  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
 299  * @words: (in) number of words to read; (out) number of words actually read
 300  * @data: words read from the Shadow RAM
 301  *
 302  * Reads 16 bit words (data buf) from the SR using the ice_read_nvm_buf_aq
 303  * method. The buf read is preceded by the NVM ownership take
 304  * and followed by the release.
 305  */
 306 enum ice_status
 307 ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
 308 {
 309         enum ice_status status;
 310 
 311         status = ice_acquire_nvm(hw, ICE_RES_READ);
 312         if (!status) {
 313                 status = ice_read_sr_buf_aq(hw, offset, words, data);
 314                 ice_release_nvm(hw);
 315         }
 316 
 317         return status;
 318 }
 319 
 320 /**
 321  * ice_nvm_validate_checksum
 322  * @hw: pointer to the HW struct
 323  *
 324  * Verify NVM PFA checksum validity (0x0706)
 325  */
 326 enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw)
 327 {
 328         struct ice_aqc_nvm_checksum *cmd;
 329         struct ice_aq_desc desc;
 330         enum ice_status status;
 331 
 332         status = ice_acquire_nvm(hw, ICE_RES_READ);
 333         if (status)
 334                 return status;
 335 
 336         cmd = &desc.params.nvm_checksum;
 337 
 338         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_checksum);
 339         cmd->flags = ICE_AQC_NVM_CHECKSUM_VERIFY;
 340 
 341         status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
 342         ice_release_nvm(hw);
 343 
 344         if (!status)
 345                 if (le16_to_cpu(cmd->checksum) != ICE_AQC_NVM_CHECKSUM_CORRECT)
 346                         status = ICE_ERR_NVM_CHECKSUM;
 347 
 348         return status;
 349 }

/* [<][>][^][v][top][bottom][index][help] */