This source file includes following definitions.
- ice_aq_read_nvm
- ice_check_sr_access_params
- ice_read_sr_aq
- ice_read_sr_word_aq
- ice_read_sr_buf_aq
- ice_acquire_nvm
- ice_release_nvm
- ice_read_sr_word
- ice_init_nvm
- ice_read_sr_buf
- ice_nvm_validate_checksum
   1 
   2 
   3 
   4 #include "ice_common.h"
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  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         
  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         
  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 
  46 
  47 
  48 
  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                 
  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                 
  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 
  80 
  81 
  82 
  83 
  84 
  85 
  86 
  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         
  97 
  98 
  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 
 109 
 110 
 111 
 112 
 113 
 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 
 129 
 130 
 131 
 132 
 133 
 134 
 135 
 136 
 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                 
 150 
 151 
 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                 
 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                 
 170 
 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 
 186 
 187 
 188 
 189 
 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 
 202 
 203 
 204 
 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 
 216 
 217 
 218 
 219 
 220 
 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 
 238 
 239 
 240 
 241 
 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         
 252 
 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         
 258         nvm->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB;
 259 
 260         
 261         fla = rd32(hw, GLNVM_FLA);
 262         if (fla & GLNVM_FLA_LOCKED_M) { 
 263                 nvm->blank_nvm_mode = false;
 264         } else { 
 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 
 297 
 298 
 299 
 300 
 301 
 302 
 303 
 304 
 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 
 322 
 323 
 324 
 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 }