1 /****************************************************************************** 2 3 Copyright (c) 2013-2014, Intel Corporation 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions are met: 8 9 1. Redistributions of source code must retain the above copyright notice, 10 this list of conditions and the following disclaimer. 11 12 2. Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions and the following disclaimer in the 14 documentation and/or other materials provided with the distribution. 15 16 3. Neither the name of the Intel Corporation nor the names of its 17 contributors may be used to endorse or promote products derived from 18 this software without specific prior written permission. 19 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 POSSIBILITY OF SUCH DAMAGE. 31 32 ******************************************************************************/ 33 /*$FreeBSD$*/ 34 35 #include "i40e_prototype.h" 36 37 enum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset, 38 u16 *data); 39 enum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset, 40 u16 *data); 41 enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset, 42 u16 *words, u16 *data); 43 enum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset, 44 u16 *words, u16 *data); 45 enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer, 46 u32 offset, u16 words, void *data, 47 bool last_command); 48 49 /** 50 * i40e_init_nvm_ops - Initialize NVM function pointers 51 * @hw: pointer to the HW structure 52 * 53 * Setup the function pointers and the NVM info structure. Should be called 54 * once per NVM initialization, e.g. inside the i40e_init_shared_code(). 55 * Please notice that the NVM term is used here (& in all methods covered 56 * in this file) as an equivalent of the FLASH part mapped into the SR. 57 * We are accessing FLASH always thru the Shadow RAM. 58 **/ 59 enum i40e_status_code i40e_init_nvm(struct i40e_hw *hw) 60 { 61 struct i40e_nvm_info *nvm = &hw->nvm; 62 enum i40e_status_code ret_code = I40E_SUCCESS; 63 u32 fla, gens; 64 u8 sr_size; 65 66 DEBUGFUNC("i40e_init_nvm"); 67 68 /* The SR size is stored regardless of the nvm programming mode 69 * as the blank mode may be used in the factory line. 70 */ 71 gens = rd32(hw, I40E_GLNVM_GENS); 72 sr_size = ((gens & I40E_GLNVM_GENS_SR_SIZE_MASK) >> 73 I40E_GLNVM_GENS_SR_SIZE_SHIFT); 74 /* Switching to words (sr_size contains power of 2KB) */ 75 nvm->sr_size = (1 << sr_size) * I40E_SR_WORDS_IN_1KB; 76 77 /* Check if we are in the normal or blank NVM programming mode */ 78 fla = rd32(hw, I40E_GLNVM_FLA); 79 if (fla & I40E_GLNVM_FLA_LOCKED_MASK) { /* Normal programming mode */ 80 /* Max NVM timeout */ 81 nvm->timeout = I40E_MAX_NVM_TIMEOUT; 82 nvm->blank_nvm_mode = FALSE; 83 } else { /* Blank programming mode */ 84 nvm->blank_nvm_mode = TRUE; 85 ret_code = I40E_ERR_NVM_BLANK_MODE; 86 i40e_debug(hw, I40E_DEBUG_NVM, "NVM init error: unsupported blank mode.\n"); 87 } 88 89 return ret_code; 90 } 91 92 /** 93 * i40e_acquire_nvm - Generic request for acquiring the NVM ownership 94 * @hw: pointer to the HW structure 95 * @access: NVM access type (read or write) 96 * 97 * This function will request NVM ownership for reading 98 * via the proper Admin Command. 99 **/ 100 enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw, 101 enum i40e_aq_resource_access_type access) 102 { 103 enum i40e_status_code ret_code = I40E_SUCCESS; 104 u64 gtime, timeout; 105 u64 time_left = 0; 106 107 DEBUGFUNC("i40e_acquire_nvm"); 108 109 if (hw->nvm.blank_nvm_mode) 110 goto i40e_i40e_acquire_nvm_exit; 111 112 ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access, 113 0, &time_left, NULL); 114 /* Reading the Global Device Timer */ 115 gtime = rd32(hw, I40E_GLVFGEN_TIMER); 116 117 /* Store the timeout */ 118 hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime; 119 120 if (ret_code) 121 i40e_debug(hw, I40E_DEBUG_NVM, 122 "NVM acquire type %d failed time_left=%llu ret=%d aq_err=%d\n", 123 access, time_left, ret_code, hw->aq.asq_last_status); 124 125 if (ret_code && time_left) { 126 /* Poll until the current NVM owner timeouts */ 127 timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) + gtime; 128 while ((gtime < timeout) && time_left) { 129 i40e_msec_delay(10); 130 gtime = rd32(hw, I40E_GLVFGEN_TIMER); 131 ret_code = i40e_aq_request_resource(hw, 132 I40E_NVM_RESOURCE_ID, 133 access, 0, &time_left, 134 NULL); 135 if (ret_code == I40E_SUCCESS) { 136 hw->nvm.hw_semaphore_timeout = 137 I40E_MS_TO_GTIME(time_left) + gtime; 138 break; 139 } 140 } 141 if (ret_code != I40E_SUCCESS) { 142 hw->nvm.hw_semaphore_timeout = 0; 143 i40e_debug(hw, I40E_DEBUG_NVM, 144 "NVM acquire timed out, wait %llu ms before trying again. status=%d aq_err=%d\n", 145 time_left, ret_code, hw->aq.asq_last_status); 146 } 147 } 148 149 i40e_i40e_acquire_nvm_exit: 150 return ret_code; 151 } 152 153 /** 154 * i40e_release_nvm - Generic request for releasing the NVM ownership 155 * @hw: pointer to the HW structure 156 * 157 * This function will release NVM resource via the proper Admin Command. 158 **/ 159 void i40e_release_nvm(struct i40e_hw *hw) 160 { 161 DEBUGFUNC("i40e_release_nvm"); 162 163 if (!hw->nvm.blank_nvm_mode) 164 i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL); 165 } 166 167 /** 168 * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit 169 * @hw: pointer to the HW structure 170 * 171 * Polls the SRCTL Shadow RAM register done bit. 172 **/ 173 static enum i40e_status_code i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw) 174 { 175 enum i40e_status_code ret_code = I40E_ERR_TIMEOUT; 176 u32 srctl, wait_cnt; 177 178 DEBUGFUNC("i40e_poll_sr_srctl_done_bit"); 179 180 /* Poll the I40E_GLNVM_SRCTL until the done bit is set */ 181 for (wait_cnt = 0; wait_cnt < I40E_SRRD_SRCTL_ATTEMPTS; wait_cnt++) { 182 srctl = rd32(hw, I40E_GLNVM_SRCTL); 183 if (srctl & I40E_GLNVM_SRCTL_DONE_MASK) { 184 ret_code = I40E_SUCCESS; 185 break; 186 } 187 i40e_usec_delay(5); 188 } 189 if (ret_code == I40E_ERR_TIMEOUT) 190 i40e_debug(hw, I40E_DEBUG_NVM, "Done bit in GLNVM_SRCTL not set"); 191 return ret_code; 192 } 193 194 /** 195 * i40e_read_nvm_word - Reads Shadow RAM 196 * @hw: pointer to the HW structure 197 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 198 * @data: word read from the Shadow RAM 199 * 200 * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. 201 **/ 202 enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, 203 u16 *data) 204 { 205 return i40e_read_nvm_word_srctl(hw, offset, data); 206 } 207 208 /** 209 * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register 210 * @hw: pointer to the HW structure 211 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 212 * @data: word read from the Shadow RAM 213 * 214 * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. 215 **/ 216 enum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset, 217 u16 *data) 218 { 219 enum i40e_status_code ret_code = I40E_ERR_TIMEOUT; 220 u32 sr_reg; 221 222 DEBUGFUNC("i40e_read_nvm_word_srctl"); 223 224 if (offset >= hw->nvm.sr_size) { 225 i40e_debug(hw, I40E_DEBUG_NVM, 226 "NVM read error: Offset %d beyond Shadow RAM limit %d\n", 227 offset, hw->nvm.sr_size); 228 ret_code = I40E_ERR_PARAM; 229 goto read_nvm_exit; 230 } 231 232 /* Poll the done bit first */ 233 ret_code = i40e_poll_sr_srctl_done_bit(hw); 234 if (ret_code == I40E_SUCCESS) { 235 /* Write the address and start reading */ 236 sr_reg = (u32)(offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) | 237 (1 << I40E_GLNVM_SRCTL_START_SHIFT); 238 wr32(hw, I40E_GLNVM_SRCTL, sr_reg); 239 240 /* Poll I40E_GLNVM_SRCTL until the done bit is set */ 241 ret_code = i40e_poll_sr_srctl_done_bit(hw); 242 if (ret_code == I40E_SUCCESS) { 243 sr_reg = rd32(hw, I40E_GLNVM_SRDATA); 244 *data = (u16)((sr_reg & 245 I40E_GLNVM_SRDATA_RDDATA_MASK) 246 >> I40E_GLNVM_SRDATA_RDDATA_SHIFT); 247 } 248 } 249 if (ret_code != I40E_SUCCESS) 250 i40e_debug(hw, I40E_DEBUG_NVM, 251 "NVM read error: Couldn't access Shadow RAM address: 0x%x\n", 252 offset); 253 254 read_nvm_exit: 255 return ret_code; 256 } 257 258 /** 259 * i40e_read_nvm_word_aq - Reads Shadow RAM via AQ 260 * @hw: pointer to the HW structure 261 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 262 * @data: word read from the Shadow RAM 263 * 264 * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. 265 **/ 266 enum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset, 267 u16 *data) 268 { 269 enum i40e_status_code ret_code = I40E_ERR_TIMEOUT; 270 271 DEBUGFUNC("i40e_read_nvm_word_aq"); 272 273 ret_code = i40e_read_nvm_aq(hw, 0x0, offset, 1, data, TRUE); 274 *data = LE16_TO_CPU(*(__le16 *)data); 275 276 return ret_code; 277 } 278 279 /** 280 * i40e_read_nvm_buffer - Reads Shadow RAM buffer 281 * @hw: pointer to the HW structure 282 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). 283 * @words: (in) number of words to read; (out) number of words actually read 284 * @data: words read from the Shadow RAM 285 * 286 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() 287 * method. The buffer read is preceded by the NVM ownership take 288 * and followed by the release. 289 **/ 290 enum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, 291 u16 *words, u16 *data) 292 { 293 return i40e_read_nvm_buffer_srctl(hw, offset, words, data); 294 } 295 296 /** 297 * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register 298 * @hw: pointer to the HW structure 299 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). 300 * @words: (in) number of words to read; (out) number of words actually read 301 * @data: words read from the Shadow RAM 302 * 303 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() 304 * method. The buffer read is preceded by the NVM ownership take 305 * and followed by the release. 306 **/ 307 enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset, 308 u16 *words, u16 *data) 309 { 310 enum i40e_status_code ret_code = I40E_SUCCESS; 311 u16 index, word; 312 313 DEBUGFUNC("i40e_read_nvm_buffer_srctl"); 314 315 /* Loop thru the selected region */ 316 for (word = 0; word < *words; word++) { 317 index = offset + word; 318 ret_code = i40e_read_nvm_word_srctl(hw, index, &data[word]); 319 if (ret_code != I40E_SUCCESS) 320 break; 321 } 322 323 /* Update the number of words read from the Shadow RAM */ 324 *words = word; 325 326 return ret_code; 327 } 328 329 /** 330 * i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ 331 * @hw: pointer to the HW structure 332 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). 333 * @words: (in) number of words to read; (out) number of words actually read 334 * @data: words read from the Shadow RAM 335 * 336 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq() 337 * method. The buffer read is preceded by the NVM ownership take 338 * and followed by the release. 339 **/ 340 enum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset, 341 u16 *words, u16 *data) 342 { 343 enum i40e_status_code ret_code; 344 u16 read_size = *words; 345 bool last_cmd = FALSE; 346 u16 words_read = 0; 347 u16 i = 0; 348 349 DEBUGFUNC("i40e_read_nvm_buffer_aq"); 350 351 do { 352 /* Calculate number of bytes we should read in this step. 353 * FVL AQ do not allow to read more than one page at a time or 354 * to cross page boundaries. 355 */ 356 if (offset % I40E_SR_SECTOR_SIZE_IN_WORDS) 357 read_size = min(*words, 358 (u16)(I40E_SR_SECTOR_SIZE_IN_WORDS - 359 (offset % I40E_SR_SECTOR_SIZE_IN_WORDS))); 360 else 361 read_size = min((*words - words_read), 362 I40E_SR_SECTOR_SIZE_IN_WORDS); 363 364 /* Check if this is last command, if so set proper flag */ 365 if ((words_read + read_size) >= *words) 366 last_cmd = TRUE; 367 368 ret_code = i40e_read_nvm_aq(hw, 0x0, offset, read_size, 369 data + words_read, last_cmd); 370 if (ret_code != I40E_SUCCESS) 371 goto read_nvm_buffer_aq_exit; 372 373 /* Increment counter for words already read and move offset to 374 * new read location 375 */ 376 words_read += read_size; 377 offset += read_size; 378 } while (words_read < *words); 379 380 for (i = 0; i < *words; i++) 381 data[i] = LE16_TO_CPU(((__le16 *)data)[i]); 382 383 read_nvm_buffer_aq_exit: 384 *words = words_read; 385 return ret_code; 386 } 387 388 /** 389 * i40e_read_nvm_aq - Read Shadow RAM. 390 * @hw: pointer to the HW structure. 391 * @module_pointer: module pointer location in words from the NVM beginning 392 * @offset: offset in words from module start 393 * @words: number of words to write 394 * @data: buffer with words to write to the Shadow RAM 395 * @last_command: tells the AdminQ that this is the last command 396 * 397 * Writes a 16 bit words buffer to the Shadow RAM using the admin command. 398 **/ 399 enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer, 400 u32 offset, u16 words, void *data, 401 bool last_command) 402 { 403 enum i40e_status_code ret_code = I40E_ERR_NVM; 404 405 DEBUGFUNC("i40e_read_nvm_aq"); 406 407 /* Here we are checking the SR limit only for the flat memory model. 408 * We cannot do it for the module-based model, as we did not acquire 409 * the NVM resource yet (we cannot get the module pointer value). 410 * Firmware will check the module-based model. 411 */ 412 if ((offset + words) > hw->nvm.sr_size) 413 i40e_debug(hw, I40E_DEBUG_NVM, 414 "NVM write error: offset %d beyond Shadow RAM limit %d\n", 415 (offset + words), hw->nvm.sr_size); 416 else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS) 417 /* We can write only up to 4KB (one sector), in one AQ write */ 418 i40e_debug(hw, I40E_DEBUG_NVM, 419 "NVM write fail error: tried to write %d words, limit is %d.\n", 420 words, I40E_SR_SECTOR_SIZE_IN_WORDS); 421 else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS) 422 != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS)) 423 /* A single write cannot spread over two sectors */ 424 i40e_debug(hw, I40E_DEBUG_NVM, 425 "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n", 426 offset, words); 427 else 428 ret_code = i40e_aq_read_nvm(hw, module_pointer, 429 2 * offset, /*bytes*/ 430 2 * words, /*bytes*/ 431 data, last_command, NULL); 432 433 return ret_code; 434 } 435 436 /** 437 * i40e_write_nvm_aq - Writes Shadow RAM. 438 * @hw: pointer to the HW structure. 439 * @module_pointer: module pointer location in words from the NVM beginning 440 * @offset: offset in words from module start 441 * @words: number of words to write 442 * @data: buffer with words to write to the Shadow RAM 443 * @last_command: tells the AdminQ that this is the last command 444 * 445 * Writes a 16 bit words buffer to the Shadow RAM using the admin command. 446 **/ 447 enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer, 448 u32 offset, u16 words, void *data, 449 bool last_command) 450 { 451 enum i40e_status_code ret_code = I40E_ERR_NVM; 452 453 DEBUGFUNC("i40e_write_nvm_aq"); 454 455 /* Here we are checking the SR limit only for the flat memory model. 456 * We cannot do it for the module-based model, as we did not acquire 457 * the NVM resource yet (we cannot get the module pointer value). 458 * Firmware will check the module-based model. 459 */ 460 if ((offset + words) > hw->nvm.sr_size) 461 DEBUGOUT("NVM write error: offset beyond Shadow RAM limit.\n"); 462 else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS) 463 /* We can write only up to 4KB (one sector), in one AQ write */ 464 DEBUGOUT("NVM write fail error: cannot write more than 4KB in a single write.\n"); 465 else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS) 466 != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS)) 467 /* A single write cannot spread over two sectors */ 468 DEBUGOUT("NVM write error: cannot spread over two sectors in a single write.\n"); 469 else 470 ret_code = i40e_aq_update_nvm(hw, module_pointer, 471 2 * offset, /*bytes*/ 472 2 * words, /*bytes*/ 473 data, last_command, NULL); 474 475 return ret_code; 476 } 477 478 /** 479 * i40e_write_nvm_word - Writes Shadow RAM word 480 * @hw: pointer to the HW structure 481 * @offset: offset of the Shadow RAM word to write 482 * @data: word to write to the Shadow RAM 483 * 484 * Writes a 16 bit word to the SR using the i40e_write_nvm_aq() method. 485 * NVM ownership have to be acquired and released (on ARQ completion event 486 * reception) by caller. To commit SR to NVM update checksum function 487 * should be called. 488 **/ 489 enum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset, 490 void *data) 491 { 492 DEBUGFUNC("i40e_write_nvm_word"); 493 494 *((__le16 *)data) = CPU_TO_LE16(*((u16 *)data)); 495 496 /* Value 0x00 below means that we treat SR as a flat mem */ 497 return i40e_write_nvm_aq(hw, 0x00, offset, 1, data, FALSE); 498 } 499 500 /** 501 * i40e_write_nvm_buffer - Writes Shadow RAM buffer 502 * @hw: pointer to the HW structure 503 * @module_pointer: module pointer location in words from the NVM beginning 504 * @offset: offset of the Shadow RAM buffer to write 505 * @words: number of words to write 506 * @data: words to write to the Shadow RAM 507 * 508 * Writes a 16 bit words buffer to the Shadow RAM using the admin command. 509 * NVM ownership must be acquired before calling this function and released 510 * on ARQ completion event reception by caller. To commit SR to NVM update 511 * checksum function should be called. 512 **/ 513 enum i40e_status_code i40e_write_nvm_buffer(struct i40e_hw *hw, 514 u8 module_pointer, u32 offset, 515 u16 words, void *data) 516 { 517 __le16 *le_word_ptr = (__le16 *)data; 518 u16 *word_ptr = (u16 *)data; 519 u32 i = 0; 520 521 DEBUGFUNC("i40e_write_nvm_buffer"); 522 523 for (i = 0; i < words; i++) 524 le_word_ptr[i] = CPU_TO_LE16(word_ptr[i]); 525 526 /* Here we will only write one buffer as the size of the modules 527 * mirrored in the Shadow RAM is always less than 4K. 528 */ 529 return i40e_write_nvm_aq(hw, module_pointer, offset, words, 530 data, FALSE); 531 } 532 533 /** 534 * i40e_calc_nvm_checksum - Calculates and returns the checksum 535 * @hw: pointer to hardware structure 536 * @checksum: pointer to the checksum 537 * 538 * This function calculates SW Checksum that covers the whole 64kB shadow RAM 539 * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD 540 * is customer specific and unknown. Therefore, this function skips all maximum 541 * possible size of VPD (1kB). 542 **/ 543 enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum) 544 { 545 enum i40e_status_code ret_code = I40E_SUCCESS; 546 struct i40e_virt_mem vmem; 547 u16 pcie_alt_module = 0; 548 u16 checksum_local = 0; 549 u16 vpd_module = 0; 550 u16 *data; 551 u16 i = 0; 552 553 DEBUGFUNC("i40e_calc_nvm_checksum"); 554 555 ret_code = i40e_allocate_virt_mem(hw, &vmem, 556 I40E_SR_SECTOR_SIZE_IN_WORDS * sizeof(u16)); 557 if (ret_code) 558 goto i40e_calc_nvm_checksum_exit; 559 data = (u16 *)vmem.va; 560 561 /* read pointer to VPD area */ 562 ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module); 563 if (ret_code != I40E_SUCCESS) { 564 ret_code = I40E_ERR_NVM_CHECKSUM; 565 goto i40e_calc_nvm_checksum_exit; 566 } 567 568 /* read pointer to PCIe Alt Auto-load module */ 569 ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR, 570 &pcie_alt_module); 571 if (ret_code != I40E_SUCCESS) { 572 ret_code = I40E_ERR_NVM_CHECKSUM; 573 goto i40e_calc_nvm_checksum_exit; 574 } 575 576 /* Calculate SW checksum that covers the whole 64kB shadow RAM 577 * except the VPD and PCIe ALT Auto-load modules 578 */ 579 for (i = 0; i < hw->nvm.sr_size; i++) { 580 /* Read SR page */ 581 if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) { 582 u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS; 583 ret_code = i40e_read_nvm_buffer(hw, i, &words, data); 584 if (ret_code != I40E_SUCCESS) { 585 ret_code = I40E_ERR_NVM_CHECKSUM; 586 goto i40e_calc_nvm_checksum_exit; 587 } 588 } 589 590 /* Skip Checksum word */ 591 if (i == I40E_SR_SW_CHECKSUM_WORD) 592 continue; 593 /* Skip VPD module (convert byte size to word count) */ 594 if ((i >= (u32)vpd_module) && 595 (i < ((u32)vpd_module + 596 (I40E_SR_VPD_MODULE_MAX_SIZE / 2)))) { 597 continue; 598 } 599 /* Skip PCIe ALT module (convert byte size to word count) */ 600 if ((i >= (u32)pcie_alt_module) && 601 (i < ((u32)pcie_alt_module + 602 (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2)))) { 603 continue; 604 } 605 606 checksum_local += data[i % I40E_SR_SECTOR_SIZE_IN_WORDS]; 607 } 608 609 *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local; 610 611 i40e_calc_nvm_checksum_exit: 612 i40e_free_virt_mem(hw, &vmem); 613 return ret_code; 614 } 615 616 /** 617 * i40e_update_nvm_checksum - Updates the NVM checksum 618 * @hw: pointer to hardware structure 619 * 620 * NVM ownership must be acquired before calling this function and released 621 * on ARQ completion event reception by caller. 622 * This function will commit SR to NVM. 623 **/ 624 enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw) 625 { 626 enum i40e_status_code ret_code = I40E_SUCCESS; 627 u16 checksum; 628 629 DEBUGFUNC("i40e_update_nvm_checksum"); 630 631 ret_code = i40e_calc_nvm_checksum(hw, &checksum); 632 if (ret_code == I40E_SUCCESS) 633 ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD, 634 1, &checksum, TRUE); 635 636 return ret_code; 637 } 638 639 /** 640 * i40e_validate_nvm_checksum - Validate EEPROM checksum 641 * @hw: pointer to hardware structure 642 * @checksum: calculated checksum 643 * 644 * Performs checksum calculation and validates the NVM SW checksum. If the 645 * caller does not need checksum, the value can be NULL. 646 **/ 647 enum i40e_status_code i40e_validate_nvm_checksum(struct i40e_hw *hw, 648 u16 *checksum) 649 { 650 enum i40e_status_code ret_code = I40E_SUCCESS; 651 u16 checksum_sr = 0; 652 u16 checksum_local = 0; 653 654 DEBUGFUNC("i40e_validate_nvm_checksum"); 655 656 ret_code = i40e_calc_nvm_checksum(hw, &checksum_local); 657 if (ret_code != I40E_SUCCESS) 658 goto i40e_validate_nvm_checksum_exit; 659 660 /* Do not use i40e_read_nvm_word() because we do not want to take 661 * the synchronization semaphores twice here. 662 */ 663 i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr); 664 665 /* Verify read checksum from EEPROM is the same as 666 * calculated checksum 667 */ 668 if (checksum_local != checksum_sr) 669 ret_code = I40E_ERR_NVM_CHECKSUM; 670 671 /* If the user cares, return the calculated checksum */ 672 if (checksum) 673 *checksum = checksum_local; 674 675 i40e_validate_nvm_checksum_exit: 676 return ret_code; 677 } 678