1 /****************************************************************************** 2 3 Copyright (c) 2013-2015, 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 through 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 = BIT(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 enum i40e_status_code ret_code = I40E_SUCCESS; 162 u32 total_delay = 0; 163 164 DEBUGFUNC("i40e_release_nvm"); 165 166 if (hw->nvm.blank_nvm_mode) 167 return; 168 169 ret_code = i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL); 170 171 /* there are some rare cases when trying to release the resource 172 * results in an admin Q timeout, so handle them correctly 173 */ 174 while ((ret_code == I40E_ERR_ADMIN_QUEUE_TIMEOUT) && 175 (total_delay < hw->aq.asq_cmd_timeout)) { 176 i40e_msec_delay(1); 177 ret_code = i40e_aq_release_resource(hw, 178 I40E_NVM_RESOURCE_ID, 0, NULL); 179 total_delay++; 180 } 181 } 182 183 /** 184 * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit 185 * @hw: pointer to the HW structure 186 * 187 * Polls the SRCTL Shadow RAM register done bit. 188 **/ 189 static enum i40e_status_code i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw) 190 { 191 enum i40e_status_code ret_code = I40E_ERR_TIMEOUT; 192 u32 srctl, wait_cnt; 193 194 DEBUGFUNC("i40e_poll_sr_srctl_done_bit"); 195 196 /* Poll the I40E_GLNVM_SRCTL until the done bit is set */ 197 for (wait_cnt = 0; wait_cnt < I40E_SRRD_SRCTL_ATTEMPTS; wait_cnt++) { 198 srctl = rd32(hw, I40E_GLNVM_SRCTL); 199 if (srctl & I40E_GLNVM_SRCTL_DONE_MASK) { 200 ret_code = I40E_SUCCESS; 201 break; 202 } 203 i40e_usec_delay(5); 204 } 205 if (ret_code == I40E_ERR_TIMEOUT) 206 i40e_debug(hw, I40E_DEBUG_NVM, "Done bit in GLNVM_SRCTL not set"); 207 return ret_code; 208 } 209 210 /** 211 * i40e_read_nvm_word - Reads nvm word and acquire lock if necessary 212 * @hw: pointer to the HW structure 213 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 214 * @data: word read from the Shadow RAM 215 * 216 * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. 217 **/ 218 enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, 219 u16 *data) 220 { 221 enum i40e_status_code ret_code = I40E_SUCCESS; 222 223 ret_code = i40e_read_nvm_word_srctl(hw, offset, data); 224 return ret_code; 225 } 226 227 /** 228 * __i40e_read_nvm_word - Reads nvm word, assumes caller does the locking 229 * @hw: pointer to the HW structure 230 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 231 * @data: word read from the Shadow RAM 232 * 233 * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. 234 **/ 235 enum i40e_status_code __i40e_read_nvm_word(struct i40e_hw *hw, 236 u16 offset, 237 u16 *data) 238 { 239 enum i40e_status_code ret_code = I40E_SUCCESS; 240 241 ret_code = i40e_read_nvm_word_srctl(hw, offset, data); 242 return ret_code; 243 } 244 245 /** 246 * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register 247 * @hw: pointer to the HW structure 248 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 249 * @data: word read from the Shadow RAM 250 * 251 * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. 252 **/ 253 enum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset, 254 u16 *data) 255 { 256 enum i40e_status_code ret_code = I40E_ERR_TIMEOUT; 257 u32 sr_reg; 258 259 DEBUGFUNC("i40e_read_nvm_word_srctl"); 260 261 if (offset >= hw->nvm.sr_size) { 262 i40e_debug(hw, I40E_DEBUG_NVM, 263 "NVM read error: Offset %d beyond Shadow RAM limit %d\n", 264 offset, hw->nvm.sr_size); 265 ret_code = I40E_ERR_PARAM; 266 goto read_nvm_exit; 267 } 268 269 /* Poll the done bit first */ 270 ret_code = i40e_poll_sr_srctl_done_bit(hw); 271 if (ret_code == I40E_SUCCESS) { 272 /* Write the address and start reading */ 273 sr_reg = ((u32)offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) | 274 BIT(I40E_GLNVM_SRCTL_START_SHIFT); 275 wr32(hw, I40E_GLNVM_SRCTL, sr_reg); 276 277 /* Poll I40E_GLNVM_SRCTL until the done bit is set */ 278 ret_code = i40e_poll_sr_srctl_done_bit(hw); 279 if (ret_code == I40E_SUCCESS) { 280 sr_reg = rd32(hw, I40E_GLNVM_SRDATA); 281 *data = (u16)((sr_reg & 282 I40E_GLNVM_SRDATA_RDDATA_MASK) 283 >> I40E_GLNVM_SRDATA_RDDATA_SHIFT); 284 } 285 } 286 if (ret_code != I40E_SUCCESS) 287 i40e_debug(hw, I40E_DEBUG_NVM, 288 "NVM read error: Couldn't access Shadow RAM address: 0x%x\n", 289 offset); 290 291 read_nvm_exit: 292 return ret_code; 293 } 294 295 /** 296 * i40e_read_nvm_word_aq - Reads Shadow RAM via AQ 297 * @hw: pointer to the HW structure 298 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 299 * @data: word read from the Shadow RAM 300 * 301 * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. 302 **/ 303 enum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset, 304 u16 *data) 305 { 306 enum i40e_status_code ret_code = I40E_ERR_TIMEOUT; 307 308 DEBUGFUNC("i40e_read_nvm_word_aq"); 309 310 ret_code = i40e_read_nvm_aq(hw, 0x0, offset, 1, data, TRUE); 311 *data = LE16_TO_CPU(*(__le16 *)data); 312 313 return ret_code; 314 } 315 316 /** 317 * __i40e_read_nvm_buffer - Reads nvm buffer, caller must acquire lock 318 * @hw: pointer to the HW structure 319 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). 320 * @words: (in) number of words to read; (out) number of words actually read 321 * @data: words read from the Shadow RAM 322 * 323 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() 324 * method. The buffer read is preceded by the NVM ownership take 325 * and followed by the release. 326 **/ 327 enum i40e_status_code __i40e_read_nvm_buffer(struct i40e_hw *hw, 328 u16 offset, 329 u16 *words, u16 *data) 330 { 331 enum i40e_status_code ret_code = I40E_SUCCESS; 332 333 ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data); 334 return ret_code; 335 } 336 337 /** 338 * i40e_read_nvm_buffer - Reads Shadow RAM buffer and acuire lock if necessary 339 * @hw: pointer to the HW structure 340 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). 341 * @words: (in) number of words to read; (out) number of words actually read 342 * @data: words read from the Shadow RAM 343 * 344 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() 345 * method. The buffer read is preceded by the NVM ownership take 346 * and followed by the release. 347 **/ 348 enum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, 349 u16 *words, u16 *data) 350 { 351 enum i40e_status_code ret_code = I40E_SUCCESS; 352 353 ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data); 354 return ret_code; 355 } 356 357 /** 358 * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register 359 * @hw: pointer to the HW structure 360 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). 361 * @words: (in) number of words to read; (out) number of words actually read 362 * @data: words read from the Shadow RAM 363 * 364 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() 365 * method. The buffer read is preceded by the NVM ownership take 366 * and followed by the release. 367 **/ 368 enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset, 369 u16 *words, u16 *data) 370 { 371 enum i40e_status_code ret_code = I40E_SUCCESS; 372 u16 index, word; 373 374 DEBUGFUNC("i40e_read_nvm_buffer_srctl"); 375 376 /* Loop through the selected region */ 377 for (word = 0; word < *words; word++) { 378 index = offset + word; 379 ret_code = i40e_read_nvm_word_srctl(hw, index, &data[word]); 380 if (ret_code != I40E_SUCCESS) 381 break; 382 } 383 384 /* Update the number of words read from the Shadow RAM */ 385 *words = word; 386 387 return ret_code; 388 } 389 390 /** 391 * i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ 392 * @hw: pointer to the HW structure 393 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). 394 * @words: (in) number of words to read; (out) number of words actually read 395 * @data: words read from the Shadow RAM 396 * 397 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq() 398 * method. The buffer read is preceded by the NVM ownership take 399 * and followed by the release. 400 **/ 401 enum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset, 402 u16 *words, u16 *data) 403 { 404 enum i40e_status_code ret_code; 405 u16 read_size = *words; 406 bool last_cmd = FALSE; 407 u16 words_read = 0; 408 u16 i = 0; 409 410 DEBUGFUNC("i40e_read_nvm_buffer_aq"); 411 412 do { 413 /* Calculate number of bytes we should read in this step. 414 * FVL AQ do not allow to read more than one page at a time or 415 * to cross page boundaries. 416 */ 417 if (offset % I40E_SR_SECTOR_SIZE_IN_WORDS) 418 read_size = min(*words, 419 (u16)(I40E_SR_SECTOR_SIZE_IN_WORDS - 420 (offset % I40E_SR_SECTOR_SIZE_IN_WORDS))); 421 else 422 read_size = min((*words - words_read), 423 I40E_SR_SECTOR_SIZE_IN_WORDS); 424 425 /* Check if this is last command, if so set proper flag */ 426 if ((words_read + read_size) >= *words) 427 last_cmd = TRUE; 428 429 ret_code = i40e_read_nvm_aq(hw, 0x0, offset, read_size, 430 data + words_read, last_cmd); 431 if (ret_code != I40E_SUCCESS) 432 goto read_nvm_buffer_aq_exit; 433 434 /* Increment counter for words already read and move offset to 435 * new read location 436 */ 437 words_read += read_size; 438 offset += read_size; 439 } while (words_read < *words); 440 441 for (i = 0; i < *words; i++) 442 data[i] = LE16_TO_CPU(((__le16 *)data)[i]); 443 444 read_nvm_buffer_aq_exit: 445 *words = words_read; 446 return ret_code; 447 } 448 449 /** 450 * i40e_read_nvm_aq - Read Shadow RAM. 451 * @hw: pointer to the HW structure. 452 * @module_pointer: module pointer location in words from the NVM beginning 453 * @offset: offset in words from module start 454 * @words: number of words to write 455 * @data: buffer with words to write to the Shadow RAM 456 * @last_command: tells the AdminQ that this is the last command 457 * 458 * Writes a 16 bit words buffer to the Shadow RAM using the admin command. 459 **/ 460 enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer, 461 u32 offset, u16 words, void *data, 462 bool last_command) 463 { 464 enum i40e_status_code ret_code = I40E_ERR_NVM; 465 struct i40e_asq_cmd_details cmd_details; 466 467 DEBUGFUNC("i40e_read_nvm_aq"); 468 469 memset(&cmd_details, 0, sizeof(cmd_details)); 470 cmd_details.wb_desc = &hw->nvm_wb_desc; 471 472 /* Here we are checking the SR limit only for the flat memory model. 473 * We cannot do it for the module-based model, as we did not acquire 474 * the NVM resource yet (we cannot get the module pointer value). 475 * Firmware will check the module-based model. 476 */ 477 if ((offset + words) > hw->nvm.sr_size) 478 i40e_debug(hw, I40E_DEBUG_NVM, 479 "NVM write error: offset %d beyond Shadow RAM limit %d\n", 480 (offset + words), hw->nvm.sr_size); 481 else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS) 482 /* We can write only up to 4KB (one sector), in one AQ write */ 483 i40e_debug(hw, I40E_DEBUG_NVM, 484 "NVM write fail error: tried to write %d words, limit is %d.\n", 485 words, I40E_SR_SECTOR_SIZE_IN_WORDS); 486 else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS) 487 != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS)) 488 /* A single write cannot spread over two sectors */ 489 i40e_debug(hw, I40E_DEBUG_NVM, 490 "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n", 491 offset, words); 492 else 493 ret_code = i40e_aq_read_nvm(hw, module_pointer, 494 2 * offset, /*bytes*/ 495 2 * words, /*bytes*/ 496 data, last_command, &cmd_details); 497 498 return ret_code; 499 } 500 501 /** 502 * i40e_write_nvm_aq - Writes Shadow RAM. 503 * @hw: pointer to the HW structure. 504 * @module_pointer: module pointer location in words from the NVM beginning 505 * @offset: offset in words from module start 506 * @words: number of words to write 507 * @data: buffer with words to write to the Shadow RAM 508 * @last_command: tells the AdminQ that this is the last command 509 * 510 * Writes a 16 bit words buffer to the Shadow RAM using the admin command. 511 **/ 512 enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer, 513 u32 offset, u16 words, void *data, 514 bool last_command) 515 { 516 enum i40e_status_code ret_code = I40E_ERR_NVM; 517 struct i40e_asq_cmd_details cmd_details; 518 519 DEBUGFUNC("i40e_write_nvm_aq"); 520 521 memset(&cmd_details, 0, sizeof(cmd_details)); 522 cmd_details.wb_desc = &hw->nvm_wb_desc; 523 524 /* Here we are checking the SR limit only for the flat memory model. 525 * We cannot do it for the module-based model, as we did not acquire 526 * the NVM resource yet (we cannot get the module pointer value). 527 * Firmware will check the module-based model. 528 */ 529 if ((offset + words) > hw->nvm.sr_size) 530 DEBUGOUT("NVM write error: offset beyond Shadow RAM limit.\n"); 531 else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS) 532 /* We can write only up to 4KB (one sector), in one AQ write */ 533 DEBUGOUT("NVM write fail error: cannot write more than 4KB in a single write.\n"); 534 else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS) 535 != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS)) 536 /* A single write cannot spread over two sectors */ 537 DEBUGOUT("NVM write error: cannot spread over two sectors in a single write.\n"); 538 else 539 ret_code = i40e_aq_update_nvm(hw, module_pointer, 540 2 * offset, /*bytes*/ 541 2 * words, /*bytes*/ 542 data, last_command, &cmd_details); 543 544 return ret_code; 545 } 546 547 /** 548 * __i40e_write_nvm_word - Writes Shadow RAM word 549 * @hw: pointer to the HW structure 550 * @offset: offset of the Shadow RAM word to write 551 * @data: word to write to the Shadow RAM 552 * 553 * Writes a 16 bit word to the SR using the i40e_write_nvm_aq() method. 554 * NVM ownership have to be acquired and released (on ARQ completion event 555 * reception) by caller. To commit SR to NVM update checksum function 556 * should be called. 557 **/ 558 enum i40e_status_code __i40e_write_nvm_word(struct i40e_hw *hw, u32 offset, 559 void *data) 560 { 561 DEBUGFUNC("i40e_write_nvm_word"); 562 563 *((__le16 *)data) = CPU_TO_LE16(*((u16 *)data)); 564 565 /* Value 0x00 below means that we treat SR as a flat mem */ 566 return i40e_write_nvm_aq(hw, 0x00, offset, 1, data, FALSE); 567 } 568 569 /** 570 * __i40e_write_nvm_buffer - Writes Shadow RAM buffer 571 * @hw: pointer to the HW structure 572 * @module_pointer: module pointer location in words from the NVM beginning 573 * @offset: offset of the Shadow RAM buffer to write 574 * @words: number of words to write 575 * @data: words to write to the Shadow RAM 576 * 577 * Writes a 16 bit words buffer to the Shadow RAM using the admin command. 578 * NVM ownership must be acquired before calling this function and released 579 * on ARQ completion event reception by caller. To commit SR to NVM update 580 * checksum function should be called. 581 **/ 582 enum i40e_status_code __i40e_write_nvm_buffer(struct i40e_hw *hw, 583 u8 module_pointer, u32 offset, 584 u16 words, void *data) 585 { 586 __le16 *le_word_ptr = (__le16 *)data; 587 u16 *word_ptr = (u16 *)data; 588 u32 i = 0; 589 590 DEBUGFUNC("i40e_write_nvm_buffer"); 591 592 for (i = 0; i < words; i++) 593 le_word_ptr[i] = CPU_TO_LE16(word_ptr[i]); 594 595 /* Here we will only write one buffer as the size of the modules 596 * mirrored in the Shadow RAM is always less than 4K. 597 */ 598 return i40e_write_nvm_aq(hw, module_pointer, offset, words, 599 data, FALSE); 600 } 601 602 /** 603 * i40e_calc_nvm_checksum - Calculates and returns the checksum 604 * @hw: pointer to hardware structure 605 * @checksum: pointer to the checksum 606 * 607 * This function calculates SW Checksum that covers the whole 64kB shadow RAM 608 * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD 609 * is customer specific and unknown. Therefore, this function skips all maximum 610 * possible size of VPD (1kB). 611 **/ 612 enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum) 613 { 614 enum i40e_status_code ret_code = I40E_SUCCESS; 615 struct i40e_virt_mem vmem; 616 u16 pcie_alt_module = 0; 617 u16 checksum_local = 0; 618 u16 vpd_module = 0; 619 u16 *data; 620 u16 i = 0; 621 622 DEBUGFUNC("i40e_calc_nvm_checksum"); 623 624 ret_code = i40e_allocate_virt_mem(hw, &vmem, 625 I40E_SR_SECTOR_SIZE_IN_WORDS * sizeof(u16)); 626 if (ret_code) 627 goto i40e_calc_nvm_checksum_exit; 628 data = (u16 *)vmem.va; 629 630 /* read pointer to VPD area */ 631 ret_code = __i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, 632 &vpd_module); 633 if (ret_code != I40E_SUCCESS) { 634 ret_code = I40E_ERR_NVM_CHECKSUM; 635 goto i40e_calc_nvm_checksum_exit; 636 } 637 638 /* read pointer to PCIe Alt Auto-load module */ 639 ret_code = __i40e_read_nvm_word(hw, 640 I40E_SR_PCIE_ALT_AUTO_LOAD_PTR, 641 &pcie_alt_module); 642 if (ret_code != I40E_SUCCESS) { 643 ret_code = I40E_ERR_NVM_CHECKSUM; 644 goto i40e_calc_nvm_checksum_exit; 645 } 646 647 /* Calculate SW checksum that covers the whole 64kB shadow RAM 648 * except the VPD and PCIe ALT Auto-load modules 649 */ 650 for (i = 0; i < hw->nvm.sr_size; i++) { 651 /* Read SR page */ 652 if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) { 653 u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS; 654 655 ret_code = __i40e_read_nvm_buffer(hw, i, &words, data); 656 if (ret_code != I40E_SUCCESS) { 657 ret_code = I40E_ERR_NVM_CHECKSUM; 658 goto i40e_calc_nvm_checksum_exit; 659 } 660 } 661 662 /* Skip Checksum word */ 663 if (i == I40E_SR_SW_CHECKSUM_WORD) 664 continue; 665 /* Skip VPD module (convert byte size to word count) */ 666 if ((i >= (u32)vpd_module) && 667 (i < ((u32)vpd_module + 668 (I40E_SR_VPD_MODULE_MAX_SIZE / 2)))) { 669 continue; 670 } 671 /* Skip PCIe ALT module (convert byte size to word count) */ 672 if ((i >= (u32)pcie_alt_module) && 673 (i < ((u32)pcie_alt_module + 674 (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2)))) { 675 continue; 676 } 677 678 checksum_local += data[i % I40E_SR_SECTOR_SIZE_IN_WORDS]; 679 } 680 681 *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local; 682 683 i40e_calc_nvm_checksum_exit: 684 i40e_free_virt_mem(hw, &vmem); 685 return ret_code; 686 } 687 688 /** 689 * i40e_update_nvm_checksum - Updates the NVM checksum 690 * @hw: pointer to hardware structure 691 * 692 * NVM ownership must be acquired before calling this function and released 693 * on ARQ completion event reception by caller. 694 * This function will commit SR to NVM. 695 **/ 696 enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw) 697 { 698 enum i40e_status_code ret_code = I40E_SUCCESS; 699 u16 checksum; 700 __le16 le_sum; 701 702 DEBUGFUNC("i40e_update_nvm_checksum"); 703 704 ret_code = i40e_calc_nvm_checksum(hw, &checksum); 705 le_sum = CPU_TO_LE16(checksum); 706 if (ret_code == I40E_SUCCESS) 707 ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD, 708 1, &le_sum, TRUE); 709 710 return ret_code; 711 } 712 713 /** 714 * i40e_validate_nvm_checksum - Validate EEPROM checksum 715 * @hw: pointer to hardware structure 716 * @checksum: calculated checksum 717 * 718 * Performs checksum calculation and validates the NVM SW checksum. If the 719 * caller does not need checksum, the value can be NULL. 720 **/ 721 enum i40e_status_code i40e_validate_nvm_checksum(struct i40e_hw *hw, 722 u16 *checksum) 723 { 724 enum i40e_status_code ret_code = I40E_SUCCESS; 725 u16 checksum_sr = 0; 726 u16 checksum_local = 0; 727 728 DEBUGFUNC("i40e_validate_nvm_checksum"); 729 730 if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) 731 ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); 732 if (!ret_code) { 733 ret_code = i40e_calc_nvm_checksum(hw, &checksum_local); 734 if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) 735 i40e_release_nvm(hw); 736 if (ret_code != I40E_SUCCESS) 737 goto i40e_validate_nvm_checksum_exit; 738 } else { 739 goto i40e_validate_nvm_checksum_exit; 740 } 741 742 i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr); 743 744 /* Verify read checksum from EEPROM is the same as 745 * calculated checksum 746 */ 747 if (checksum_local != checksum_sr) 748 ret_code = I40E_ERR_NVM_CHECKSUM; 749 750 /* If the user cares, return the calculated checksum */ 751 if (checksum) 752 *checksum = checksum_local; 753 754 i40e_validate_nvm_checksum_exit: 755 return ret_code; 756 } 757 758 static enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw, 759 struct i40e_nvm_access *cmd, 760 u8 *bytes, int *perrno); 761 static enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw, 762 struct i40e_nvm_access *cmd, 763 u8 *bytes, int *perrno); 764 static enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw, 765 struct i40e_nvm_access *cmd, 766 u8 *bytes, int *perrno); 767 static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw, 768 struct i40e_nvm_access *cmd, 769 int *perrno); 770 static enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw, 771 struct i40e_nvm_access *cmd, 772 int *perrno); 773 static enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw, 774 struct i40e_nvm_access *cmd, 775 u8 *bytes, int *perrno); 776 static enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw, 777 struct i40e_nvm_access *cmd, 778 u8 *bytes, int *perrno); 779 static enum i40e_status_code i40e_nvmupd_exec_aq(struct i40e_hw *hw, 780 struct i40e_nvm_access *cmd, 781 u8 *bytes, int *perrno); 782 static enum i40e_status_code i40e_nvmupd_get_aq_result(struct i40e_hw *hw, 783 struct i40e_nvm_access *cmd, 784 u8 *bytes, int *perrno); 785 static INLINE u8 i40e_nvmupd_get_module(u32 val) 786 { 787 return (u8)(val & I40E_NVM_MOD_PNT_MASK); 788 } 789 static INLINE u8 i40e_nvmupd_get_transaction(u32 val) 790 { 791 return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT); 792 } 793 794 static const char *i40e_nvm_update_state_str[] = { 795 "I40E_NVMUPD_INVALID", 796 "I40E_NVMUPD_READ_CON", 797 "I40E_NVMUPD_READ_SNT", 798 "I40E_NVMUPD_READ_LCB", 799 "I40E_NVMUPD_READ_SA", 800 "I40E_NVMUPD_WRITE_ERA", 801 "I40E_NVMUPD_WRITE_CON", 802 "I40E_NVMUPD_WRITE_SNT", 803 "I40E_NVMUPD_WRITE_LCB", 804 "I40E_NVMUPD_WRITE_SA", 805 "I40E_NVMUPD_CSUM_CON", 806 "I40E_NVMUPD_CSUM_SA", 807 "I40E_NVMUPD_CSUM_LCB", 808 "I40E_NVMUPD_STATUS", 809 "I40E_NVMUPD_EXEC_AQ", 810 "I40E_NVMUPD_GET_AQ_RESULT", 811 }; 812 813 /** 814 * i40e_nvmupd_command - Process an NVM update command 815 * @hw: pointer to hardware structure 816 * @cmd: pointer to nvm update command 817 * @bytes: pointer to the data buffer 818 * @perrno: pointer to return error code 819 * 820 * Dispatches command depending on what update state is current 821 **/ 822 enum i40e_status_code i40e_nvmupd_command(struct i40e_hw *hw, 823 struct i40e_nvm_access *cmd, 824 u8 *bytes, int *perrno) 825 { 826 enum i40e_status_code status; 827 enum i40e_nvmupd_cmd upd_cmd; 828 829 DEBUGFUNC("i40e_nvmupd_command"); 830 831 /* assume success */ 832 *perrno = 0; 833 834 /* early check for status command and debug msgs */ 835 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno); 836 837 i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d cmd 0x%08x config 0x%08x offset 0x%08x data_size 0x%08x\n", 838 i40e_nvm_update_state_str[upd_cmd], 839 hw->nvmupd_state, 840 hw->aq.nvm_release_on_done, 841 cmd->command, cmd->config, cmd->offset, cmd->data_size); 842 843 if (upd_cmd == I40E_NVMUPD_INVALID) { 844 *perrno = -EFAULT; 845 i40e_debug(hw, I40E_DEBUG_NVM, 846 "i40e_nvmupd_validate_command returns %d errno %d\n", 847 upd_cmd, *perrno); 848 } 849 850 /* a status request returns immediately rather than 851 * going into the state machine 852 */ 853 if (upd_cmd == I40E_NVMUPD_STATUS) { 854 bytes[0] = hw->nvmupd_state; 855 return I40E_SUCCESS; 856 } 857 858 switch (hw->nvmupd_state) { 859 case I40E_NVMUPD_STATE_INIT: 860 status = i40e_nvmupd_state_init(hw, cmd, bytes, perrno); 861 break; 862 863 case I40E_NVMUPD_STATE_READING: 864 status = i40e_nvmupd_state_reading(hw, cmd, bytes, perrno); 865 break; 866 867 case I40E_NVMUPD_STATE_WRITING: 868 status = i40e_nvmupd_state_writing(hw, cmd, bytes, perrno); 869 break; 870 871 case I40E_NVMUPD_STATE_INIT_WAIT: 872 case I40E_NVMUPD_STATE_WRITE_WAIT: 873 status = I40E_ERR_NOT_READY; 874 *perrno = -EBUSY; 875 break; 876 877 default: 878 /* invalid state, should never happen */ 879 i40e_debug(hw, I40E_DEBUG_NVM, 880 "NVMUPD: no such state %d\n", hw->nvmupd_state); 881 status = I40E_NOT_SUPPORTED; 882 *perrno = -ESRCH; 883 break; 884 } 885 return status; 886 } 887 888 /** 889 * i40e_nvmupd_state_init - Handle NVM update state Init 890 * @hw: pointer to hardware structure 891 * @cmd: pointer to nvm update command buffer 892 * @bytes: pointer to the data buffer 893 * @perrno: pointer to return error code 894 * 895 * Process legitimate commands of the Init state and conditionally set next 896 * state. Reject all other commands. 897 **/ 898 static enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw, 899 struct i40e_nvm_access *cmd, 900 u8 *bytes, int *perrno) 901 { 902 enum i40e_status_code status = I40E_SUCCESS; 903 enum i40e_nvmupd_cmd upd_cmd; 904 905 DEBUGFUNC("i40e_nvmupd_state_init"); 906 907 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno); 908 909 switch (upd_cmd) { 910 case I40E_NVMUPD_READ_SA: 911 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); 912 if (status) { 913 *perrno = i40e_aq_rc_to_posix(status, 914 hw->aq.asq_last_status); 915 } else { 916 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno); 917 i40e_release_nvm(hw); 918 } 919 break; 920 921 case I40E_NVMUPD_READ_SNT: 922 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); 923 if (status) { 924 *perrno = i40e_aq_rc_to_posix(status, 925 hw->aq.asq_last_status); 926 } else { 927 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno); 928 if (status) 929 i40e_release_nvm(hw); 930 else 931 hw->nvmupd_state = I40E_NVMUPD_STATE_READING; 932 } 933 break; 934 935 case I40E_NVMUPD_WRITE_ERA: 936 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE); 937 if (status) { 938 *perrno = i40e_aq_rc_to_posix(status, 939 hw->aq.asq_last_status); 940 } else { 941 status = i40e_nvmupd_nvm_erase(hw, cmd, perrno); 942 if (status) { 943 i40e_release_nvm(hw); 944 } else { 945 hw->aq.nvm_release_on_done = TRUE; 946 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT; 947 } 948 } 949 break; 950 951 case I40E_NVMUPD_WRITE_SA: 952 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE); 953 if (status) { 954 *perrno = i40e_aq_rc_to_posix(status, 955 hw->aq.asq_last_status); 956 } else { 957 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno); 958 if (status) { 959 i40e_release_nvm(hw); 960 } else { 961 hw->aq.nvm_release_on_done = TRUE; 962 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT; 963 } 964 } 965 break; 966 967 case I40E_NVMUPD_WRITE_SNT: 968 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE); 969 if (status) { 970 *perrno = i40e_aq_rc_to_posix(status, 971 hw->aq.asq_last_status); 972 } else { 973 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno); 974 if (status) 975 i40e_release_nvm(hw); 976 else 977 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT; 978 } 979 break; 980 981 case I40E_NVMUPD_CSUM_SA: 982 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE); 983 if (status) { 984 *perrno = i40e_aq_rc_to_posix(status, 985 hw->aq.asq_last_status); 986 } else { 987 status = i40e_update_nvm_checksum(hw); 988 if (status) { 989 *perrno = hw->aq.asq_last_status ? 990 i40e_aq_rc_to_posix(status, 991 hw->aq.asq_last_status) : 992 -EIO; 993 i40e_release_nvm(hw); 994 } else { 995 hw->aq.nvm_release_on_done = TRUE; 996 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT; 997 } 998 } 999 break; 1000 1001 case I40E_NVMUPD_EXEC_AQ: 1002 status = i40e_nvmupd_exec_aq(hw, cmd, bytes, perrno); 1003 break; 1004 1005 case I40E_NVMUPD_GET_AQ_RESULT: 1006 status = i40e_nvmupd_get_aq_result(hw, cmd, bytes, perrno); 1007 break; 1008 1009 default: 1010 i40e_debug(hw, I40E_DEBUG_NVM, 1011 "NVMUPD: bad cmd %s in init state\n", 1012 i40e_nvm_update_state_str[upd_cmd]); 1013 status = I40E_ERR_NVM; 1014 *perrno = -ESRCH; 1015 break; 1016 } 1017 return status; 1018 } 1019 1020 /** 1021 * i40e_nvmupd_state_reading - Handle NVM update state Reading 1022 * @hw: pointer to hardware structure 1023 * @cmd: pointer to nvm update command buffer 1024 * @bytes: pointer to the data buffer 1025 * @perrno: pointer to return error code 1026 * 1027 * NVM ownership is already held. Process legitimate commands and set any 1028 * change in state; reject all other commands. 1029 **/ 1030 static enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw, 1031 struct i40e_nvm_access *cmd, 1032 u8 *bytes, int *perrno) 1033 { 1034 enum i40e_status_code status = I40E_SUCCESS; 1035 enum i40e_nvmupd_cmd upd_cmd; 1036 1037 DEBUGFUNC("i40e_nvmupd_state_reading"); 1038 1039 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno); 1040 1041 switch (upd_cmd) { 1042 case I40E_NVMUPD_READ_SA: 1043 case I40E_NVMUPD_READ_CON: 1044 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno); 1045 break; 1046 1047 case I40E_NVMUPD_READ_LCB: 1048 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno); 1049 i40e_release_nvm(hw); 1050 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT; 1051 break; 1052 1053 default: 1054 i40e_debug(hw, I40E_DEBUG_NVM, 1055 "NVMUPD: bad cmd %s in reading state.\n", 1056 i40e_nvm_update_state_str[upd_cmd]); 1057 status = I40E_NOT_SUPPORTED; 1058 *perrno = -ESRCH; 1059 break; 1060 } 1061 return status; 1062 } 1063 1064 /** 1065 * i40e_nvmupd_state_writing - Handle NVM update state Writing 1066 * @hw: pointer to hardware structure 1067 * @cmd: pointer to nvm update command buffer 1068 * @bytes: pointer to the data buffer 1069 * @perrno: pointer to return error code 1070 * 1071 * NVM ownership is already held. Process legitimate commands and set any 1072 * change in state; reject all other commands 1073 **/ 1074 static enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw, 1075 struct i40e_nvm_access *cmd, 1076 u8 *bytes, int *perrno) 1077 { 1078 enum i40e_status_code status = I40E_SUCCESS; 1079 enum i40e_nvmupd_cmd upd_cmd; 1080 bool retry_attempt = FALSE; 1081 1082 DEBUGFUNC("i40e_nvmupd_state_writing"); 1083 1084 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno); 1085 1086 retry: 1087 switch (upd_cmd) { 1088 case I40E_NVMUPD_WRITE_CON: 1089 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno); 1090 if (!status) 1091 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT; 1092 break; 1093 1094 case I40E_NVMUPD_WRITE_LCB: 1095 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno); 1096 if (status) { 1097 *perrno = hw->aq.asq_last_status ? 1098 i40e_aq_rc_to_posix(status, 1099 hw->aq.asq_last_status) : 1100 -EIO; 1101 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT; 1102 } else { 1103 hw->aq.nvm_release_on_done = TRUE; 1104 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT; 1105 } 1106 break; 1107 1108 case I40E_NVMUPD_CSUM_CON: 1109 /* Assumes the caller has acquired the nvm */ 1110 status = i40e_update_nvm_checksum(hw); 1111 if (status) { 1112 *perrno = hw->aq.asq_last_status ? 1113 i40e_aq_rc_to_posix(status, 1114 hw->aq.asq_last_status) : 1115 -EIO; 1116 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT; 1117 } else { 1118 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT; 1119 } 1120 break; 1121 1122 case I40E_NVMUPD_CSUM_LCB: 1123 /* Assumes the caller has acquired the nvm */ 1124 status = i40e_update_nvm_checksum(hw); 1125 if (status) { 1126 *perrno = hw->aq.asq_last_status ? 1127 i40e_aq_rc_to_posix(status, 1128 hw->aq.asq_last_status) : 1129 -EIO; 1130 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT; 1131 } else { 1132 hw->aq.nvm_release_on_done = TRUE; 1133 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT; 1134 } 1135 break; 1136 1137 default: 1138 i40e_debug(hw, I40E_DEBUG_NVM, 1139 "NVMUPD: bad cmd %s in writing state.\n", 1140 i40e_nvm_update_state_str[upd_cmd]); 1141 status = I40E_NOT_SUPPORTED; 1142 *perrno = -ESRCH; 1143 break; 1144 } 1145 1146 /* In some circumstances, a multi-write transaction takes longer 1147 * than the default 3 minute timeout on the write semaphore. If 1148 * the write failed with an EBUSY status, this is likely the problem, 1149 * so here we try to reacquire the semaphore then retry the write. 1150 * We only do one retry, then give up. 1151 */ 1152 if (status && (hw->aq.asq_last_status == I40E_AQ_RC_EBUSY) && 1153 !retry_attempt) { 1154 enum i40e_status_code old_status = status; 1155 u32 old_asq_status = hw->aq.asq_last_status; 1156 u32 gtime; 1157 1158 gtime = rd32(hw, I40E_GLVFGEN_TIMER); 1159 if (gtime >= hw->nvm.hw_semaphore_timeout) { 1160 i40e_debug(hw, I40E_DEBUG_ALL, 1161 "NVMUPD: write semaphore expired (%d >= %lld), retrying\n", 1162 gtime, hw->nvm.hw_semaphore_timeout); 1163 i40e_release_nvm(hw); 1164 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE); 1165 if (status) { 1166 i40e_debug(hw, I40E_DEBUG_ALL, 1167 "NVMUPD: write semaphore reacquire failed aq_err = %d\n", 1168 hw->aq.asq_last_status); 1169 status = old_status; 1170 hw->aq.asq_last_status = old_asq_status; 1171 } else { 1172 retry_attempt = TRUE; 1173 goto retry; 1174 } 1175 } 1176 } 1177 1178 return status; 1179 } 1180 1181 /** 1182 * i40e_nvmupd_validate_command - Validate given command 1183 * @hw: pointer to hardware structure 1184 * @cmd: pointer to nvm update command buffer 1185 * @perrno: pointer to return error code 1186 * 1187 * Return one of the valid command types or I40E_NVMUPD_INVALID 1188 **/ 1189 static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw, 1190 struct i40e_nvm_access *cmd, 1191 int *perrno) 1192 { 1193 enum i40e_nvmupd_cmd upd_cmd; 1194 u8 module, transaction; 1195 1196 DEBUGFUNC("i40e_nvmupd_validate_command\n"); 1197 1198 /* anything that doesn't match a recognized case is an error */ 1199 upd_cmd = I40E_NVMUPD_INVALID; 1200 1201 transaction = i40e_nvmupd_get_transaction(cmd->config); 1202 module = i40e_nvmupd_get_module(cmd->config); 1203 1204 /* limits on data size */ 1205 if ((cmd->data_size < 1) || 1206 (cmd->data_size > I40E_NVMUPD_MAX_DATA)) { 1207 i40e_debug(hw, I40E_DEBUG_NVM, 1208 "i40e_nvmupd_validate_command data_size %d\n", 1209 cmd->data_size); 1210 *perrno = -EFAULT; 1211 return I40E_NVMUPD_INVALID; 1212 } 1213 1214 switch (cmd->command) { 1215 case I40E_NVM_READ: 1216 switch (transaction) { 1217 case I40E_NVM_CON: 1218 upd_cmd = I40E_NVMUPD_READ_CON; 1219 break; 1220 case I40E_NVM_SNT: 1221 upd_cmd = I40E_NVMUPD_READ_SNT; 1222 break; 1223 case I40E_NVM_LCB: 1224 upd_cmd = I40E_NVMUPD_READ_LCB; 1225 break; 1226 case I40E_NVM_SA: 1227 upd_cmd = I40E_NVMUPD_READ_SA; 1228 break; 1229 case I40E_NVM_EXEC: 1230 if (module == 0xf) 1231 upd_cmd = I40E_NVMUPD_STATUS; 1232 else if (module == 0) 1233 upd_cmd = I40E_NVMUPD_GET_AQ_RESULT; 1234 break; 1235 } 1236 break; 1237 1238 case I40E_NVM_WRITE: 1239 switch (transaction) { 1240 case I40E_NVM_CON: 1241 upd_cmd = I40E_NVMUPD_WRITE_CON; 1242 break; 1243 case I40E_NVM_SNT: 1244 upd_cmd = I40E_NVMUPD_WRITE_SNT; 1245 break; 1246 case I40E_NVM_LCB: 1247 upd_cmd = I40E_NVMUPD_WRITE_LCB; 1248 break; 1249 case I40E_NVM_SA: 1250 upd_cmd = I40E_NVMUPD_WRITE_SA; 1251 break; 1252 case I40E_NVM_ERA: 1253 upd_cmd = I40E_NVMUPD_WRITE_ERA; 1254 break; 1255 case I40E_NVM_CSUM: 1256 upd_cmd = I40E_NVMUPD_CSUM_CON; 1257 break; 1258 case (I40E_NVM_CSUM|I40E_NVM_SA): 1259 upd_cmd = I40E_NVMUPD_CSUM_SA; 1260 break; 1261 case (I40E_NVM_CSUM|I40E_NVM_LCB): 1262 upd_cmd = I40E_NVMUPD_CSUM_LCB; 1263 break; 1264 case I40E_NVM_EXEC: 1265 if (module == 0) 1266 upd_cmd = I40E_NVMUPD_EXEC_AQ; 1267 break; 1268 } 1269 break; 1270 } 1271 1272 return upd_cmd; 1273 } 1274 1275 /** 1276 * i40e_nvmupd_exec_aq - Run an AQ command 1277 * @hw: pointer to hardware structure 1278 * @cmd: pointer to nvm update command buffer 1279 * @bytes: pointer to the data buffer 1280 * @perrno: pointer to return error code 1281 * 1282 * cmd structure contains identifiers and data buffer 1283 **/ 1284 static enum i40e_status_code i40e_nvmupd_exec_aq(struct i40e_hw *hw, 1285 struct i40e_nvm_access *cmd, 1286 u8 *bytes, int *perrno) 1287 { 1288 struct i40e_asq_cmd_details cmd_details; 1289 enum i40e_status_code status; 1290 struct i40e_aq_desc *aq_desc; 1291 u32 buff_size = 0; 1292 u8 *buff = NULL; 1293 u32 aq_desc_len; 1294 u32 aq_data_len; 1295 1296 i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__); 1297 memset(&cmd_details, 0, sizeof(cmd_details)); 1298 cmd_details.wb_desc = &hw->nvm_wb_desc; 1299 1300 aq_desc_len = sizeof(struct i40e_aq_desc); 1301 memset(&hw->nvm_wb_desc, 0, aq_desc_len); 1302 1303 /* get the aq descriptor */ 1304 if (cmd->data_size < aq_desc_len) { 1305 i40e_debug(hw, I40E_DEBUG_NVM, 1306 "NVMUPD: not enough aq desc bytes for exec, size %d < %d\n", 1307 cmd->data_size, aq_desc_len); 1308 *perrno = -EINVAL; 1309 return I40E_ERR_PARAM; 1310 } 1311 aq_desc = (struct i40e_aq_desc *)bytes; 1312 1313 /* if data buffer needed, make sure it's ready */ 1314 aq_data_len = cmd->data_size - aq_desc_len; 1315 buff_size = max(aq_data_len, (u32)LE16_TO_CPU(aq_desc->datalen)); 1316 if (buff_size) { 1317 if (!hw->nvm_buff.va) { 1318 status = i40e_allocate_virt_mem(hw, &hw->nvm_buff, 1319 hw->aq.asq_buf_size); 1320 if (status) 1321 i40e_debug(hw, I40E_DEBUG_NVM, 1322 "NVMUPD: i40e_allocate_virt_mem for exec buff failed, %d\n", 1323 status); 1324 } 1325 1326 if (hw->nvm_buff.va) { 1327 buff = hw->nvm_buff.va; 1328 memcpy(buff, &bytes[aq_desc_len], aq_data_len); 1329 } 1330 } 1331 1332 /* and away we go! */ 1333 status = i40e_asq_send_command(hw, aq_desc, buff, 1334 buff_size, &cmd_details); 1335 if (status) { 1336 i40e_debug(hw, I40E_DEBUG_NVM, 1337 "i40e_nvmupd_exec_aq err %s aq_err %s\n", 1338 i40e_stat_str(hw, status), 1339 i40e_aq_str(hw, hw->aq.asq_last_status)); 1340 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status); 1341 } 1342 1343 return status; 1344 } 1345 1346 /** 1347 * i40e_nvmupd_get_aq_result - Get the results from the previous exec_aq 1348 * @hw: pointer to hardware structure 1349 * @cmd: pointer to nvm update command buffer 1350 * @bytes: pointer to the data buffer 1351 * @perrno: pointer to return error code 1352 * 1353 * cmd structure contains identifiers and data buffer 1354 **/ 1355 static enum i40e_status_code i40e_nvmupd_get_aq_result(struct i40e_hw *hw, 1356 struct i40e_nvm_access *cmd, 1357 u8 *bytes, int *perrno) 1358 { 1359 u32 aq_total_len; 1360 u32 aq_desc_len; 1361 int remainder; 1362 u8 *buff; 1363 1364 i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__); 1365 1366 aq_desc_len = sizeof(struct i40e_aq_desc); 1367 aq_total_len = aq_desc_len + LE16_TO_CPU(hw->nvm_wb_desc.datalen); 1368 1369 /* check offset range */ 1370 if (cmd->offset > aq_total_len) { 1371 i40e_debug(hw, I40E_DEBUG_NVM, "%s: offset too big %d > %d\n", 1372 __func__, cmd->offset, aq_total_len); 1373 *perrno = -EINVAL; 1374 return I40E_ERR_PARAM; 1375 } 1376 1377 /* check copylength range */ 1378 if (cmd->data_size > (aq_total_len - cmd->offset)) { 1379 int new_len = aq_total_len - cmd->offset; 1380 1381 i40e_debug(hw, I40E_DEBUG_NVM, "%s: copy length %d too big, trimming to %d\n", 1382 __func__, cmd->data_size, new_len); 1383 cmd->data_size = new_len; 1384 } 1385 1386 remainder = cmd->data_size; 1387 if (cmd->offset < aq_desc_len) { 1388 u32 len = aq_desc_len - cmd->offset; 1389 1390 len = min(len, cmd->data_size); 1391 i40e_debug(hw, I40E_DEBUG_NVM, "%s: aq_desc bytes %d to %d\n", 1392 __func__, cmd->offset, cmd->offset + len); 1393 1394 buff = ((u8 *)&hw->nvm_wb_desc) + cmd->offset; 1395 memcpy(bytes, buff, len); 1396 1397 bytes += len; 1398 remainder -= len; 1399 buff = hw->nvm_buff.va; 1400 } else { 1401 buff = (u8 *)hw->nvm_buff.va + (cmd->offset - aq_desc_len); 1402 } 1403 1404 if (remainder > 0) { 1405 int start_byte = buff - (u8 *)hw->nvm_buff.va; 1406 1407 i40e_debug(hw, I40E_DEBUG_NVM, "%s: databuf bytes %d to %d\n", 1408 __func__, start_byte, start_byte + remainder); 1409 memcpy(bytes, buff, remainder); 1410 } 1411 1412 return I40E_SUCCESS; 1413 } 1414 1415 /** 1416 * i40e_nvmupd_nvm_read - Read NVM 1417 * @hw: pointer to hardware structure 1418 * @cmd: pointer to nvm update command buffer 1419 * @bytes: pointer to the data buffer 1420 * @perrno: pointer to return error code 1421 * 1422 * cmd structure contains identifiers and data buffer 1423 **/ 1424 static enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw, 1425 struct i40e_nvm_access *cmd, 1426 u8 *bytes, int *perrno) 1427 { 1428 struct i40e_asq_cmd_details cmd_details; 1429 enum i40e_status_code status; 1430 u8 module, transaction; 1431 bool last; 1432 1433 transaction = i40e_nvmupd_get_transaction(cmd->config); 1434 module = i40e_nvmupd_get_module(cmd->config); 1435 last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA); 1436 1437 memset(&cmd_details, 0, sizeof(cmd_details)); 1438 cmd_details.wb_desc = &hw->nvm_wb_desc; 1439 1440 status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size, 1441 bytes, last, &cmd_details); 1442 if (status) { 1443 i40e_debug(hw, I40E_DEBUG_NVM, 1444 "i40e_nvmupd_nvm_read mod 0x%x off 0x%x len 0x%x\n", 1445 module, cmd->offset, cmd->data_size); 1446 i40e_debug(hw, I40E_DEBUG_NVM, 1447 "i40e_nvmupd_nvm_read status %d aq %d\n", 1448 status, hw->aq.asq_last_status); 1449 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status); 1450 } 1451 1452 return status; 1453 } 1454 1455 /** 1456 * i40e_nvmupd_nvm_erase - Erase an NVM module 1457 * @hw: pointer to hardware structure 1458 * @cmd: pointer to nvm update command buffer 1459 * @perrno: pointer to return error code 1460 * 1461 * module, offset, data_size and data are in cmd structure 1462 **/ 1463 static enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw, 1464 struct i40e_nvm_access *cmd, 1465 int *perrno) 1466 { 1467 enum i40e_status_code status = I40E_SUCCESS; 1468 struct i40e_asq_cmd_details cmd_details; 1469 u8 module, transaction; 1470 bool last; 1471 1472 transaction = i40e_nvmupd_get_transaction(cmd->config); 1473 module = i40e_nvmupd_get_module(cmd->config); 1474 last = (transaction & I40E_NVM_LCB); 1475 1476 memset(&cmd_details, 0, sizeof(cmd_details)); 1477 cmd_details.wb_desc = &hw->nvm_wb_desc; 1478 1479 status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size, 1480 last, &cmd_details); 1481 if (status) { 1482 i40e_debug(hw, I40E_DEBUG_NVM, 1483 "i40e_nvmupd_nvm_erase mod 0x%x off 0x%x len 0x%x\n", 1484 module, cmd->offset, cmd->data_size); 1485 i40e_debug(hw, I40E_DEBUG_NVM, 1486 "i40e_nvmupd_nvm_erase status %d aq %d\n", 1487 status, hw->aq.asq_last_status); 1488 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status); 1489 } 1490 1491 return status; 1492 } 1493 1494 /** 1495 * i40e_nvmupd_nvm_write - Write NVM 1496 * @hw: pointer to hardware structure 1497 * @cmd: pointer to nvm update command buffer 1498 * @bytes: pointer to the data buffer 1499 * @perrno: pointer to return error code 1500 * 1501 * module, offset, data_size and data are in cmd structure 1502 **/ 1503 static enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw, 1504 struct i40e_nvm_access *cmd, 1505 u8 *bytes, int *perrno) 1506 { 1507 enum i40e_status_code status = I40E_SUCCESS; 1508 struct i40e_asq_cmd_details cmd_details; 1509 u8 module, transaction; 1510 bool last; 1511 1512 transaction = i40e_nvmupd_get_transaction(cmd->config); 1513 module = i40e_nvmupd_get_module(cmd->config); 1514 last = (transaction & I40E_NVM_LCB); 1515 1516 memset(&cmd_details, 0, sizeof(cmd_details)); 1517 cmd_details.wb_desc = &hw->nvm_wb_desc; 1518 1519 status = i40e_aq_update_nvm(hw, module, cmd->offset, 1520 (u16)cmd->data_size, bytes, last, 1521 &cmd_details); 1522 if (status) { 1523 i40e_debug(hw, I40E_DEBUG_NVM, 1524 "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n", 1525 module, cmd->offset, cmd->data_size); 1526 i40e_debug(hw, I40E_DEBUG_NVM, 1527 "i40e_nvmupd_nvm_write status %d aq %d\n", 1528 status, hw->aq.asq_last_status); 1529 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status); 1530 } 1531 1532 return status; 1533 } 1534