New upstream version 18.11-rc1
[deb_dpdk.git] / drivers / net / ixgbe / base / ixgbe_x540.c
index 31dead0..f00f0ea 100644 (file)
@@ -1,35 +1,6 @@
-/*******************************************************************************
-
-Copyright (c) 2001-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.
-
-***************************************************************************/
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2001-2018
+ */
 
 #include "ixgbe_x540.h"
 #include "ixgbe_type.h"
@@ -208,6 +179,7 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
 {
        s32 status;
        u32 ctrl, i;
+       u32 swfw_mask = hw->phy.phy_semaphore_mask;
 
        DEBUGFUNC("ixgbe_reset_hw_X540");
 
@@ -220,10 +192,17 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
        ixgbe_clear_tx_pending(hw);
 
 mac_reset_top:
+       status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
+       if (status != IXGBE_SUCCESS) {
+               ERROR_REPORT2(IXGBE_ERROR_CAUTION,
+                       "semaphore failed with %d", status);
+               return IXGBE_ERR_SWFW_SYNC;
+       }
        ctrl = IXGBE_CTRL_RST;
        ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
        IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
        IXGBE_WRITE_FLUSH(hw);
+       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 
        /* Poll for reset bit to self-clear indicating reset is complete */
        for (i = 0; i < 10; i++) {
@@ -271,6 +250,7 @@ mac_reset_top:
        if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
                /* Save the SAN MAC RAR index */
                hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
+
                hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
                                    hw->mac.san_addr, 0, IXGBE_RAH_AV);
 
@@ -320,9 +300,9 @@ out:
  *
  *  Determines physical layer capabilities of the current configuration.
  **/
-u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
+u64 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
 {
-       u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+       u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
        u16 ext_ability = 0;
 
        DEBUGFUNC("ixgbe_get_supported_physical_layer_X540");
@@ -490,7 +470,6 @@ s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
        u16 length = 0;
        u16 pointer = 0;
        u16 word = 0;
-       u16 checksum_last_word = IXGBE_EEPROM_CHECKSUM;
        u16 ptr_start = IXGBE_PCIE_ANALOG_PTR;
 
        /* Do not use hw->eeprom.ops.read because we do not want to take
@@ -500,14 +479,15 @@ s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
 
        DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540");
 
-       /* Include 0x0-0x3F in the checksum */
-       for (i = 0; i <= checksum_last_word; i++) {
+       /* Include 0x0 up to IXGBE_EEPROM_CHECKSUM; do not include the
+        * checksum itself
+        */
+       for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
                if (ixgbe_read_eerd_generic(hw, i, &word)) {
                        DEBUGOUT("EEPROM read failed\n");
                        return IXGBE_ERR_EEPROM;
                }
-               if (i != IXGBE_EEPROM_CHECKSUM)
-                       checksum += word;
+               checksum += word;
        }
 
        /* Include all data from pointers 0x3, 0x6-0xE.  This excludes the
@@ -770,12 +750,17 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
 
        swmask |= swi2c_mask;
        fwmask |= swi2c_mask << 2;
+       if (hw->mac.type >= ixgbe_mac_X550)
+               timeout = 1000;
+
        for (i = 0; i < timeout; i++) {
                /* SW NVM semaphore bit is used for access to all
                 * SW_FW_SYNC bits (not just NVM)
                 */
-               if (ixgbe_get_swfw_sync_semaphore(hw))
+               if (ixgbe_get_swfw_sync_semaphore(hw)) {
+                       DEBUGOUT("Failed to get NVM access and register semaphore, returning IXGBE_ERR_SWFW_SYNC\n");
                        return IXGBE_ERR_SWFW_SYNC;
+               }
 
                swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
                if (!(swfw_sync & (fwmask | swmask | hwmask))) {
@@ -783,7 +768,6 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
                        IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw),
                                        swfw_sync);
                        ixgbe_release_swfw_sync_semaphore(hw);
-                       msec_delay(5);
                        return IXGBE_SUCCESS;
                }
                /* Firmware currently using resource (fwmask), hardware
@@ -794,20 +778,15 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
                msec_delay(5);
        }
 
-       /* Failed to get SW only semaphore */
-       if (swmask == IXGBE_GSSR_SW_MNG_SM) {
-               ERROR_REPORT1(IXGBE_ERROR_POLLING,
-                            "Failed to get SW only semaphore");
-               return IXGBE_ERR_SWFW_SYNC;
-       }
-
        /* If the resource is not released by the FW/HW the SW can assume that
         * the FW/HW malfunctions. In that case the SW should set the SW bit(s)
         * of the requested resource(s) while ignoring the corresponding FW/HW
         * bits in the SW_FW_SYNC register.
         */
-       if (ixgbe_get_swfw_sync_semaphore(hw))
+       if (ixgbe_get_swfw_sync_semaphore(hw)) {
+               DEBUGOUT("Failed to get NVM sempahore and register semaphore while forcefully ignoring FW sempahore bit(s) and setting SW semaphore bit(s), returning IXGBE_ERR_SWFW_SYNC\n");
                return IXGBE_ERR_SWFW_SYNC;
+       }
        swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
        if (swfw_sync & (fwmask | hwmask)) {
                swfw_sync |= swmask;
@@ -823,15 +802,18 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
         */
        if (swfw_sync & swmask) {
                u32 rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM |
-                           IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM;
+                           IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM |
+                           IXGBE_GSSR_SW_MNG_SM;
 
                if (swi2c_mask)
                        rmask |= IXGBE_GSSR_I2C_MASK;
                ixgbe_release_swfw_sync_X540(hw, rmask);
                ixgbe_release_swfw_sync_semaphore(hw);
+               DEBUGOUT("Resource not released by other SW, returning IXGBE_ERR_SWFW_SYNC\n");
                return IXGBE_ERR_SWFW_SYNC;
        }
        ixgbe_release_swfw_sync_semaphore(hw);
+       DEBUGOUT("Returning error IXGBE_ERR_SWFW_SYNC\n");
 
        return IXGBE_ERR_SWFW_SYNC;
 }
@@ -860,7 +842,7 @@ void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
        IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync);
 
        ixgbe_release_swfw_sync_semaphore(hw);
-       msec_delay(5);
+       msec_delay(2);
 }
 
 /**
@@ -955,14 +937,25 @@ STATIC void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
  **/
 void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw)
 {
+       u32 rmask;
+
        /* First try to grab the semaphore but we don't need to bother
-        * looking to see whether we got the lock or  not since we do
+        * looking to see whether we got the lock or not since we do
         * the same thing regardless of whether we got the lock or not.
         * We got the lock - we release it.
         * We timeout trying to get the lock - we force its release.
         */
        ixgbe_get_swfw_sync_semaphore(hw);
        ixgbe_release_swfw_sync_semaphore(hw);
+
+       /* Acquire and release all software resources. */
+       rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM |
+               IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM |
+               IXGBE_GSSR_SW_MNG_SM;
+
+       rmask |= IXGBE_GSSR_I2C_MASK;
+       ixgbe_acquire_swfw_sync_X540(hw, rmask);
+       ixgbe_release_swfw_sync_X540(hw, rmask);
 }
 
 /**
@@ -982,6 +975,9 @@ s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
 
        DEBUGFUNC("ixgbe_blink_led_start_X540");
 
+       if (index > 3)
+               return IXGBE_ERR_PARAM;
+
        /*
         * Link should be up in order for the blink bit in the LED control
         * register to work. Force link and speed in the MAC if link is down.
@@ -1016,6 +1012,9 @@ s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
        u32 macc_reg;
        u32 ledctl_reg;
 
+       if (index > 3)
+               return IXGBE_ERR_PARAM;
+
        DEBUGFUNC("ixgbe_blink_led_stop_X540");
 
        /* Restore the LED to its default value. */