net/i40e: fix parsing packet type for NEON
[dpdk.git] / drivers / net / i40e / base / i40e_nvm.c
index c77dac0..561ed21 100644 (file)
@@ -1,35 +1,8 @@
-/*******************************************************************************
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2001-2020 Intel Corporation
+ */
 
-Copyright (c) 2013 - 2015, Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
-    this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-***************************************************************************/
+#include <inttypes.h>
 
 #include "i40e_prototype.h"
 
@@ -106,7 +79,7 @@ enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw,
 
        if (ret_code)
                i40e_debug(hw, I40E_DEBUG_NVM,
-                          "NVM acquire type %d failed time_left=%llu ret=%d aq_err=%d\n",
+                          "NVM acquire type %d failed time_left=%" PRIu64 " ret=%d aq_err=%d\n",
                           access, time_left, ret_code, hw->aq.asq_last_status);
 
        if (ret_code && time_left) {
@@ -128,7 +101,7 @@ enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw,
                if (ret_code != I40E_SUCCESS) {
                        hw->nvm.hw_semaphore_timeout = 0;
                        i40e_debug(hw, I40E_DEBUG_NVM,
-                                  "NVM acquire timed out, wait %llu ms before trying again. status=%d aq_err=%d\n",
+                                  "NVM acquire timed out, wait %" PRIu64 " ms before trying again. status=%d aq_err=%d\n",
                                   time_left, ret_code, hw->aq.asq_last_status);
                }
        }
@@ -366,6 +339,77 @@ enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
        return ret_code;
 }
 
+/**
+ * i40e_read_nvm_module_data - Reads NVM Buffer to specified memory location
+ * @hw: Pointer to the HW structure
+ * @module_ptr: Pointer to module in words with respect to NVM beginning
+ * @module_offset: Offset in words from module start
+ * @data_offset: Offset in words from reading data area start
+ * @words_data_size: Words to read from NVM
+ * @data_ptr: Pointer to memory location where resulting buffer will be stored
+ **/
+enum i40e_status_code
+i40e_read_nvm_module_data(struct i40e_hw *hw, u8 module_ptr, u16 module_offset,
+                         u16 data_offset, u16 words_data_size, u16 *data_ptr)
+{
+       enum i40e_status_code status;
+       u16 specific_ptr = 0;
+       u16 ptr_value = 0;
+       u16 offset = 0;
+
+       if (module_ptr != 0) {
+               status = i40e_read_nvm_word(hw, module_ptr, &ptr_value);
+               if (status != I40E_SUCCESS) {
+                       i40e_debug(hw, I40E_DEBUG_ALL,
+                                  "Reading nvm word failed.Error code: %d.\n",
+                                  status);
+                       return I40E_ERR_NVM;
+               }
+       }
+#define I40E_NVM_INVALID_PTR_VAL 0x7FFF
+#define I40E_NVM_INVALID_VAL 0xFFFF
+
+       /* Pointer not initialized */
+       if (ptr_value == I40E_NVM_INVALID_PTR_VAL ||
+           ptr_value == I40E_NVM_INVALID_VAL) {
+               i40e_debug(hw, I40E_DEBUG_ALL, "Pointer not initialized.\n");
+               return I40E_ERR_BAD_PTR;
+       }
+
+       /* Check whether the module is in SR mapped area or outside */
+       if (ptr_value & I40E_PTR_TYPE) {
+               /* Pointer points outside of the Shared RAM mapped area */
+               i40e_debug(hw, I40E_DEBUG_ALL,
+                          "Reading nvm data failed. Pointer points outside of the Shared RAM mapped area.\n");
+
+               return I40E_ERR_PARAM;
+       } else {
+               /* Read from the Shadow RAM */
+
+               status = i40e_read_nvm_word(hw, ptr_value + module_offset,
+                                           &specific_ptr);
+               if (status != I40E_SUCCESS) {
+                       i40e_debug(hw, I40E_DEBUG_ALL,
+                                  "Reading nvm word failed.Error code: %d.\n",
+                                  status);
+                       return I40E_ERR_NVM;
+               }
+
+               offset = ptr_value + module_offset + specific_ptr +
+                       data_offset;
+
+               status = i40e_read_nvm_buffer(hw, offset, &words_data_size,
+                                             data_ptr);
+               if (status != I40E_SUCCESS) {
+                       i40e_debug(hw, I40E_DEBUG_ALL,
+                                  "Reading nvm buffer failed.Error code: %d.\n",
+                                  status);
+               }
+       }
+
+       return status;
+}
+
 /**
  * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register
  * @hw: pointer to the HW structure
@@ -826,6 +870,7 @@ STATIC const char *i40e_nvm_update_state_str[] = {
        "I40E_NVMUPD_EXEC_AQ",
        "I40E_NVMUPD_GET_AQ_RESULT",
        "I40E_NVMUPD_GET_AQ_EVENT",
+       "I40E_NVMUPD_GET_FEATURES",
 };
 
 /**
@@ -888,6 +933,31 @@ enum i40e_status_code i40e_nvmupd_command(struct i40e_hw *hw,
                return I40E_SUCCESS;
        }
 
+       /*
+        * A supported features request returns immediately
+        * rather than going into state machine
+        */
+       if (upd_cmd == I40E_NVMUPD_FEATURES) {
+               if (cmd->data_size < hw->nvmupd_features.size) {
+                       *perrno = -EFAULT;
+                       return I40E_ERR_BUF_TOO_SHORT;
+               }
+
+               /*
+                * If buffer is bigger than i40e_nvmupd_features structure,
+                * make sure the trailing bytes are set to 0x0.
+                */
+               if (cmd->data_size > hw->nvmupd_features.size)
+                       i40e_memset(bytes + hw->nvmupd_features.size, 0x0,
+                                   cmd->data_size - hw->nvmupd_features.size,
+                                   I40E_NONDMA_MEM);
+
+               i40e_memcpy(bytes, &hw->nvmupd_features,
+                           hw->nvmupd_features.size, I40E_NONDMA_MEM);
+
+               return I40E_SUCCESS;
+       }
+
        /* Clear status even it is not read and log */
        if (hw->nvmupd_state == I40E_NVMUPD_STATE_ERROR) {
                i40e_debug(hw, I40E_DEBUG_NVM,
@@ -1232,7 +1302,7 @@ retry:
                gtime = rd32(hw, I40E_GLVFGEN_TIMER);
                if (gtime >= hw->nvm.hw_semaphore_timeout) {
                        i40e_debug(hw, I40E_DEBUG_ALL,
-                                  "NVMUPD: write semaphore expired (%d >= %lld), retrying\n",
+                                  "NVMUPD: write semaphore expired (%d >= %" PRIu64 "), retrying\n",
                                   gtime, hw->nvm.hw_semaphore_timeout);
                        i40e_release_nvm(hw);
                        status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
@@ -1354,10 +1424,20 @@ STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
                        upd_cmd = I40E_NVMUPD_READ_SA;
                        break;
                case I40E_NVM_EXEC:
-                       if (module == 0xf)
-                               upd_cmd = I40E_NVMUPD_STATUS;
-                       else if (module == 0)
+                       switch (module) {
+                       case I40E_NVM_EXEC_GET_AQ_RESULT:
                                upd_cmd = I40E_NVMUPD_GET_AQ_RESULT;
+                               break;
+                       case I40E_NVM_EXEC_FEATURES:
+                               upd_cmd = I40E_NVMUPD_FEATURES;
+                               break;
+                       case I40E_NVM_EXEC_STATUS:
+                               upd_cmd = I40E_NVMUPD_STATUS;
+                               break;
+                       default:
+                               *perrno = -EFAULT;
+                               return I40E_NVMUPD_INVALID;
+                       }
                        break;
                case I40E_NVM_AQE:
                        upd_cmd = I40E_NVMUPD_GET_AQ_EVENT;