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