net/e1000/base: expose more future extended NVM
[dpdk.git] / drivers / net / e1000 / base / e1000_ich8lan.c
index 7ab0f7c..b79e3ba 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 - 2015 Intel Corporation
+ */
 
 /* 82562G 10/100 Network Connection
  * 82562G-2 10/100 Network Connection
@@ -346,6 +317,7 @@ STATIC s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
        switch (hw->mac.type) {
        case e1000_pch_lpt:
        case e1000_pch_spt:
+       case e1000_pch_cnp:
                if (e1000_phy_is_accessible_pchlan(hw))
                        break;
 
@@ -494,6 +466,7 @@ STATIC s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
                case e1000_pch2lan:
                case e1000_pch_lpt:
                case e1000_pch_spt:
+               case e1000_pch_cnp:
                        /* In case the PHY needs to be in mdio slow mode,
                         * set slow mode and try to get the PHY id again.
                         */
@@ -798,6 +771,7 @@ STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
                /* fall-through */
        case e1000_pch_lpt:
        case e1000_pch_spt:
+       case e1000_pch_cnp:
 #ifndef NO_NON_BLOCKING_PHY_MTA_UPDATE_SUPPORT
                /* multicast address update for pch2 */
                mac->ops.update_mc_addr_list =
@@ -848,7 +822,7 @@ STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
 /**
  *  __e1000_access_emi_reg_locked - Read/write EMI register
  *  @hw: pointer to the HW structure
- *  @addr: EMI address to program
+ *  @address: EMI address to program
  *  @data: pointer to value to read/write from/to the EMI address
  *  @read: boolean flag to indicate read or write
  *
@@ -1294,6 +1268,7 @@ out:
 s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force)
 {
        s32 ret_val = E1000_SUCCESS;
+       u8 ulp_exit_timeout = 30;
        u32 mac_reg;
        u16 phy_reg;
        int i = 0;
@@ -1315,10 +1290,12 @@ s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force)
                        E1000_WRITE_REG(hw, E1000_H2ME, mac_reg);
                }
 
-               /* Poll up to 300msec for ME to clear ULP_CFG_DONE. */
+               if (hw->mac.type == e1000_pch_cnp)
+                       ulp_exit_timeout = 100;
+
                while (E1000_READ_REG(hw, E1000_FWSM) &
                       E1000_FWSM_ULP_CFG_DONE) {
-                       if (i++ == 30) {
+                       if (i++ == ulp_exit_timeout) {
                                ret_val = -E1000_ERR_PHY;
                                goto out;
                        }
@@ -1572,8 +1549,6 @@ STATIC s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 
 
                if (hw->mac.type >= e1000_pch_lpt) {
-                       u16 phy_reg;
-
                        hw->phy.ops.read_reg_locked(hw, I217_PLL_CLOCK_GATE_REG,
                                                    &phy_reg);
                        phy_reg &= ~I217_PLL_CLOCK_GATE_MASK;
@@ -1584,6 +1559,16 @@ STATIC s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
                        hw->phy.ops.write_reg_locked(hw,
                                                     I217_PLL_CLOCK_GATE_REG,
                                                     phy_reg);
+
+                       if (speed == SPEED_1000) {
+                               hw->phy.ops.read_reg_locked(hw, HV_PM_CTRL,
+                                                           &phy_reg);
+
+                               phy_reg |= HV_PM_CTRL_K1_CLK_REQ;
+
+                               hw->phy.ops.write_reg_locked(hw, HV_PM_CTRL,
+                                                            phy_reg);
+                               }
                 }
                hw->phy.ops.release(hw);
 
@@ -1678,6 +1663,9 @@ STATIC s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
                                fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE;
                }
 
+               if (hw->dev_spec.ich8lan.disable_k1_off == true)
+                       fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE;
+
                E1000_WRITE_REG(hw, E1000_FEXTNVM6, fextnvm6);
        }
 
@@ -1775,6 +1763,7 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw)
        case e1000_pch2lan:
        case e1000_pch_lpt:
        case e1000_pch_spt:
+       case e1000_pch_cnp:
                hw->phy.ops.init_params = e1000_init_phy_params_pchlan;
                break;
        default:
@@ -2241,6 +2230,7 @@ STATIC s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
        case e1000_pch2lan:
        case e1000_pch_lpt:
        case e1000_pch_spt:
+       case e1000_pch_cnp:
                sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
                break;
        default:
@@ -2412,7 +2402,7 @@ release:
 /**
  *  e1000_configure_k1_ich8lan - Configure K1 power state
  *  @hw: pointer to the HW structure
- *  @enable: K1 state to configure
+ *  @k1_enable: K1 state to configure
  *
  *  Configure the K1 power state based on the provided parameter.
  *  Assumes semaphore already acquired.
@@ -2560,6 +2550,7 @@ STATIC s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw)
 /**
  *  e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
  *  done after every PHY reset.
+ *  @hw: pointer to the HW structure
  **/
 STATIC s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
 {
@@ -2886,6 +2877,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
 /**
  *  e1000_lv_phy_workarounds_ich8lan - A series of Phy workarounds to be
  *  done after every PHY reset.
+ *  @hw: pointer to the HW structure
  **/
 STATIC s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw)
 {
@@ -3365,6 +3357,7 @@ STATIC s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
 
        switch (hw->mac.type) {
        case e1000_pch_spt:
+       case e1000_pch_cnp:
                bank1_offset = nvm->flash_bank_size;
                act_offset = E1000_ICH_NVM_SIG_WORD;
 
@@ -3489,8 +3482,9 @@ STATIC s32 e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words,
 
        for (i = 0; i < words; i += 2) {
                if (words - i == 1) {
-                       if (dev_spec->shadow_ram[offset+i].modified) {
-                               data[i] = dev_spec->shadow_ram[offset+i].value;
+                       if (dev_spec->shadow_ram[offset + i].modified) {
+                               data[i] =
+                                   dev_spec->shadow_ram[offset + i].value;
                        } else {
                                offset_to_read = act_offset + i -
                                                 ((act_offset + i) % 2);
@@ -3507,8 +3501,8 @@ STATIC s32 e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words,
                        }
                } else {
                        offset_to_read = act_offset + i;
-                       if (!(dev_spec->shadow_ram[offset+i].modified) ||
-                           !(dev_spec->shadow_ram[offset+i+1].modified)) {
+                       if (!(dev_spec->shadow_ram[offset + i].modified) ||
+                           !(dev_spec->shadow_ram[offset + i + 1].modified)) {
                                ret_val =
                                   e1000_read_flash_dword_ich8lan(hw,
                                                                 offset_to_read,
@@ -3516,15 +3510,16 @@ STATIC s32 e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words,
                                if (ret_val)
                                        break;
                        }
-                       if (dev_spec->shadow_ram[offset+i].modified)
-                               data[i] = dev_spec->shadow_ram[offset+i].value;
+                       if (dev_spec->shadow_ram[offset + i].modified)
+                               data[i] =
+                                   dev_spec->shadow_ram[offset + i].value;
                        else
-                               data[i] = (u16) (dword & 0xFFFF);
-                       if (dev_spec->shadow_ram[offset+i].modified)
-                               data[i+1] =
-                                  dev_spec->shadow_ram[offset+i+1].value;
+                               data[i] = (u16)(dword & 0xFFFF);
+                       if (dev_spec->shadow_ram[offset + i + 1].modified)
+                               data[i + 1] =
+                                  dev_spec->shadow_ram[offset + i + 1].value;
                        else
-                               data[i+1] = (u16) (dword >> 16 & 0xFFFF);
+                               data[i + 1] = (u16)(dword >> 16 & 0xFFFF);
                }
        }
 
@@ -3578,8 +3573,8 @@ STATIC s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
 
        ret_val = E1000_SUCCESS;
        for (i = 0; i < words; i++) {
-               if (dev_spec->shadow_ram[offset+i].modified) {
-                       data[i] = dev_spec->shadow_ram[offset+i].value;
+               if (dev_spec->shadow_ram[offset + i].modified) {
+                       data[i] = dev_spec->shadow_ram[offset + i].value;
                } else {
                        ret_val = e1000_read_flash_word_ich8lan(hw,
                                                                act_offset + i,
@@ -3984,8 +3979,8 @@ STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
        nvm->ops.acquire(hw);
 
        for (i = 0; i < words; i++) {
-               dev_spec->shadow_ram[offset+i].modified = true;
-               dev_spec->shadow_ram[offset+i].value = data[i];
+               dev_spec->shadow_ram[offset + i].modified = true;
+               dev_spec->shadow_ram[offset + i].value = data[i];
        }
 
        nvm->ops.release(hw);
@@ -4340,6 +4335,7 @@ STATIC s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
        switch (hw->mac.type) {
        case e1000_pch_lpt:
        case e1000_pch_spt:
+       case e1000_pch_cnp:
                word = NVM_COMPAT;
                valid_csum_mask = NVM_COMPAT_VALID_CSUM;
                break;
@@ -4868,7 +4864,7 @@ STATIC s32 e1000_id_led_init_pchlan(struct e1000_hw *hw)
  *  @hw: pointer to the HW structure
  *
  *  ICH8 use the PCI Express bus, but does not contain a PCI Express Capability
- *  register, so the the bus width is hard coded.
+ *  register, so the bus width is hard coded.
  **/
 STATIC s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw)
 {
@@ -4903,6 +4899,7 @@ STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
        u16 kum_cfg;
        u32 ctrl, reg;
        s32 ret_val;
+       u16 pci_cfg;
 
        DEBUGFUNC("e1000_reset_hw_ich8lan");
 
@@ -4963,11 +4960,28 @@ STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
                        e1000_gate_hw_phy_config_ich8lan(hw, true);
        }
        ret_val = e1000_acquire_swflag_ich8lan(hw);
+
+       /* Read from EXTCNF_CTRL in e1000_acquire_swflag_ich8lan function
+        * may occur during global reset and cause system hang.
+        * Configuration space access creates the needed delay.
+        * Write to E1000_STRAP RO register E1000_PCI_VENDOR_ID_REGISTER value
+        * insures configuration space read is done before global reset.
+        */
+       e1000_read_pci_cfg(hw, E1000_PCI_VENDOR_ID_REGISTER, &pci_cfg);
+       E1000_WRITE_REG(hw, E1000_STRAP, pci_cfg);
        DEBUGOUT("Issuing a global reset to ich8lan\n");
        E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_RST));
        /* cannot issue a flush here because it hangs the hardware */
        msec_delay(20);
 
+       /* Configuration space access improve HW level time sync mechanism.
+        * Write to E1000_STRAP RO register E1000_PCI_VENDOR_ID_REGISTER
+        * value to insure configuration space read is done
+        * before any access to mac register.
+        */
+       e1000_read_pci_cfg(hw, E1000_PCI_VENDOR_ID_REGISTER, &pci_cfg);
+       E1000_WRITE_REG(hw, E1000_STRAP, pci_cfg);
+
        /* Set Phy Config Counter to 50msec */
        if (hw->mac.type == e1000_pch2lan) {
                reg = E1000_READ_REG(hw, E1000_FEXTNVM3);
@@ -5146,7 +5160,7 @@ STATIC void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
        /* Device Status */
        if (hw->mac.type == e1000_ich8lan) {
                reg = E1000_READ_REG(hw, E1000_STATUS);
-               reg &= ~(1 << 31);
+               reg &= ~(1U << 31);
                E1000_WRITE_REG(hw, E1000_STATUS, reg);
        }
 
@@ -5542,7 +5556,7 @@ void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
 void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
 {
        s32 ret_val;
-       u16 reg_data;
+       u16 reg_data = 0;
 
        DEBUGFUNC("e1000_gig_downshift_workaround_ich8lan");