doc: adapt features tables header height
[dpdk.git] / lib / librte_eal / linuxapp / kni / ethtool / igb / e1000_manage.c
index 91942dc..2f75bc3 100644 (file)
@@ -1,23 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2012 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
+  Copyright(c) 2007-2013 Intel Corporation.
 
   Contact Information:
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -75,7 +60,7 @@ s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
 
        /* Check that the host interface is enabled. */
        hicr = E1000_READ_REG(hw, E1000_HICR);
-       if ((hicr & E1000_HICR_EN) == 0) {
+       if (!(hicr & E1000_HICR_EN)) {
                DEBUGOUT("E1000_HOST_EN bit disabled.\n");
                return -E1000_ERR_HOST_INTERFACE_COMMAND;
        }
@@ -138,11 +123,10 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
                return hw->mac.tx_pkt_filtering;
        }
 
-       /*
-        * If we can't read from the host interface for whatever
+       /* If we can't read from the host interface for whatever
         * reason, disable filtering.
         */
-       ret_val = hw->mac.ops.mng_enable_host_if(hw);
+       ret_val = e1000_mng_enable_host_if_generic(hw);
        if (ret_val != E1000_SUCCESS) {
                hw->mac.tx_pkt_filtering = false;
                return hw->mac.tx_pkt_filtering;
@@ -158,8 +142,7 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
        hdr->checksum = 0;
        csum = e1000_calculate_checksum((u8 *)hdr,
                                        E1000_MNG_DHCP_COOKIE_LENGTH);
-       /*
-        * If either the checksums or signature don't match, then
+       /* If either the checksums or signature don't match, then
         * the cookie area isn't considered valid, in which case we
         * take the safe route of assuming Tx filtering is enabled.
         */
@@ -252,8 +235,7 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
        /* Calculate length in DWORDs */
        length >>= 2;
 
-       /*
-        * The device driver writes the relevant command block into the
+       /* The device driver writes the relevant command block into the
         * ram area.
         */
        for (i = 0; i < length; i++) {
@@ -305,18 +287,18 @@ s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
        hdr.checksum = 0;
 
        /* Enable the host interface */
-       ret_val = hw->mac.ops.mng_enable_host_if(hw);
+       ret_val = e1000_mng_enable_host_if_generic(hw);
        if (ret_val)
                return ret_val;
 
        /* Populate the host interface with the contents of "buffer". */
-       ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
-                                               sizeof(hdr), &(hdr.checksum));
+       ret_val = e1000_mng_host_if_write_generic(hw, buffer, length,
+                                                 sizeof(hdr), &(hdr.checksum));
        if (ret_val)
                return ret_val;
 
        /* Write the manageability command header */
-       ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
+       ret_val = e1000_mng_write_cmd_header_generic(hw, &hdr);
        if (ret_val)
                return ret_val;
 
@@ -359,7 +341,7 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
                        return true;
        } else if ((manc & E1000_MANC_SMBUS_EN) &&
                   !(manc & E1000_MANC_ASF_EN)) {
-                       return true;
+               return true;
        }
 
        return false;
@@ -398,7 +380,7 @@ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
 
        /* Check that the host interface is enabled. */
        hicr = E1000_READ_REG(hw, E1000_HICR);
-       if ((hicr & E1000_HICR_EN) == 0) {
+       if (!(hicr & E1000_HICR_EN)) {
                DEBUGOUT("E1000_HOST_EN bit disabled.\n");
                return -E1000_ERR_HOST_INTERFACE_COMMAND;
        }
@@ -406,8 +388,7 @@ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
        /* Calculate length in DWORDs */
        length >>= 2;
 
-       /*
-        * The device driver writes the relevant command block
+       /* The device driver writes the relevant command block
         * into the ram area.
         */
        for (i = 0; i < length; i++)
@@ -438,4 +419,121 @@ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
 
        return E1000_SUCCESS;
 }
+/**
+ *  e1000_load_firmware - Writes proxy FW code buffer to host interface
+ *                        and execute.
+ *  @hw: pointer to the HW structure
+ *  @buffer: contains a firmware to write
+ *  @length: the byte length of the buffer, must be multiple of 4 bytes
+ *
+ *  Upon success returns E1000_SUCCESS, returns E1000_ERR_CONFIG if not enabled
+ *  in HW else returns E1000_ERR_HOST_INTERFACE_COMMAND.
+ **/
+s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
+{
+       u32 hicr, hibba, fwsm, icr, i;
+
+       DEBUGFUNC("e1000_load_firmware");
+
+       if (hw->mac.type < e1000_i210) {
+               DEBUGOUT("Hardware doesn't support loading FW by the driver\n");
+               return -E1000_ERR_CONFIG;
+       }
+
+       /* Check that the host interface is enabled. */
+       hicr = E1000_READ_REG(hw, E1000_HICR);
+       if (!(hicr & E1000_HICR_EN)) {
+               DEBUGOUT("E1000_HOST_EN bit disabled.\n");
+               return -E1000_ERR_CONFIG;
+       }
+       if (!(hicr & E1000_HICR_MEMORY_BASE_EN)) {
+               DEBUGOUT("E1000_HICR_MEMORY_BASE_EN bit disabled.\n");
+               return -E1000_ERR_CONFIG;
+       }
 
+       if (length == 0 || length & 0x3 || length > E1000_HI_FW_MAX_LENGTH) {
+               DEBUGOUT("Buffer length failure.\n");
+               return -E1000_ERR_INVALID_ARGUMENT;
+       }
+
+       /* Clear notification from ROM-FW by reading ICR register */
+       icr = E1000_READ_REG(hw, E1000_ICR_V2);
+
+       /* Reset ROM-FW */
+       hicr = E1000_READ_REG(hw, E1000_HICR);
+       hicr |= E1000_HICR_FW_RESET_ENABLE;
+       E1000_WRITE_REG(hw, E1000_HICR, hicr);
+       hicr |= E1000_HICR_FW_RESET;
+       E1000_WRITE_REG(hw, E1000_HICR, hicr);
+       E1000_WRITE_FLUSH(hw);
+
+       /* Wait till MAC notifies about its readiness after ROM-FW reset */
+       for (i = 0; i < (E1000_HI_COMMAND_TIMEOUT * 2); i++) {
+               icr = E1000_READ_REG(hw, E1000_ICR_V2);
+               if (icr & E1000_ICR_MNG)
+                       break;
+               msec_delay(1);
+       }
+
+       /* Check for timeout */
+       if (i == E1000_HI_COMMAND_TIMEOUT) {
+               DEBUGOUT("FW reset failed.\n");
+               return -E1000_ERR_HOST_INTERFACE_COMMAND;
+       }
+
+       /* Wait till MAC is ready to accept new FW code */
+       for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
+               fwsm = E1000_READ_REG(hw, E1000_FWSM);
+               if ((fwsm & E1000_FWSM_FW_VALID) &&
+                   ((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT ==
+                   E1000_FWSM_HI_EN_ONLY_MODE))
+                       break;
+               msec_delay(1);
+       }
+
+       /* Check for timeout */
+       if (i == E1000_HI_COMMAND_TIMEOUT) {
+               DEBUGOUT("FW reset failed.\n");
+               return -E1000_ERR_HOST_INTERFACE_COMMAND;
+       }
+
+       /* Calculate length in DWORDs */
+       length >>= 2;
+
+       /* The device driver writes the relevant FW code block
+        * into the ram area in DWORDs via 1kB ram addressing window.
+        */
+       for (i = 0; i < length; i++) {
+               if (!(i % E1000_HI_FW_BLOCK_DWORD_LENGTH)) {
+                       /* Point to correct 1kB ram window */
+                       hibba = E1000_HI_FW_BASE_ADDRESS +
+                               ((E1000_HI_FW_BLOCK_DWORD_LENGTH << 2) *
+                               (i / E1000_HI_FW_BLOCK_DWORD_LENGTH));
+
+                       E1000_WRITE_REG(hw, E1000_HIBBA, hibba);
+               }
+
+               E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
+                                           i % E1000_HI_FW_BLOCK_DWORD_LENGTH,
+                                           *((u32 *)buffer + i));
+       }
+
+       /* Setting this bit tells the ARC that a new FW is ready to execute. */
+       hicr = E1000_READ_REG(hw, E1000_HICR);
+       E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
+
+       for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
+               hicr = E1000_READ_REG(hw, E1000_HICR);
+               if (!(hicr & E1000_HICR_C))
+                       break;
+               msec_delay(1);
+       }
+
+       /* Check for successful FW start. */
+       if (i == E1000_HI_COMMAND_TIMEOUT) {
+               DEBUGOUT("New FW did not start within timeout period.\n");
+               return -E1000_ERR_HOST_INTERFACE_COMMAND;
+       }
+
+       return E1000_SUCCESS;
+}