net/i40e: remove duplicate tunnel type check
[dpdk.git] / drivers / net / ixgbe / base / ixgbe_common.c
index ec61408..aa843bd 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-2020 Intel Corporation
+ */
 
 #include "ixgbe_common.h"
 #include "ixgbe_phy.h"
@@ -60,10 +31,10 @@ STATIC s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
                                                 u16 offset);
 
 /**
- *  ixgbe_init_ops_generic - Inits function ptrs
- *  @hw: pointer to the hardware structure
+ * ixgbe_init_ops_generic - Inits function ptrs
+ * @hw: pointer to the hardware structure
  *
- *  Initialize the function pointers.
+ * Initialize the function pointers.
  **/
 s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
 {
@@ -113,6 +84,7 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
        mac->ops.led_off = ixgbe_led_off_generic;
        mac->ops.blink_led_start = ixgbe_blink_led_start_generic;
        mac->ops.blink_led_stop = ixgbe_blink_led_stop_generic;
+       mac->ops.init_led_link_act = ixgbe_init_led_link_act_generic;
 
        /* RAR, Multicast, VLAN */
        mac->ops.set_rar = ixgbe_set_rar_generic;
@@ -135,6 +107,7 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
        /* Flow Control */
        mac->ops.fc_enable = ixgbe_fc_enable_generic;
        mac->ops.setup_fc = ixgbe_setup_fc_generic;
+       mac->ops.fc_autoneg = ixgbe_fc_autoneg;
 
        /* Link */
        mac->ops.get_link_capabilities = NULL;
@@ -167,16 +140,30 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
        switch (hw->phy.media_type) {
        case ixgbe_media_type_fiber_qsfp:
        case ixgbe_media_type_fiber:
-               hw->mac.ops.check_link(hw, &speed, &link_up, false);
-               /* if link is down, assume supported */
-               if (link_up)
-                       supported = speed == IXGBE_LINK_SPEED_1GB_FULL ?
+               /* flow control autoneg black list */
+               switch (hw->device_id) {
+               case IXGBE_DEV_ID_X550EM_A_SFP:
+               case IXGBE_DEV_ID_X550EM_A_SFP_N:
+               case IXGBE_DEV_ID_X550EM_A_QSFP:
+               case IXGBE_DEV_ID_X550EM_A_QSFP_N:
+                       supported = false;
+                       break;
+               default:
+                       hw->mac.ops.check_link(hw, &speed, &link_up, false);
+                       /* if link is down, assume supported */
+                       if (link_up)
+                               supported = speed == IXGBE_LINK_SPEED_1GB_FULL ?
                                true : false;
-               else
-                       supported = true;
+                       else
+                               supported = true;
+               }
+
                break;
        case ixgbe_media_type_backplane:
-               supported = true;
+               if (hw->device_id == IXGBE_DEV_ID_X550EM_X_XFI)
+                       supported = false;
+               else
+                       supported = true;
                break;
        case ixgbe_media_type_copper:
                /* only some copper devices support flow control autoneg */
@@ -187,6 +174,9 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
                case IXGBE_DEV_ID_X550T:
                case IXGBE_DEV_ID_X550T1:
                case IXGBE_DEV_ID_X550EM_X_10G_T:
+               case IXGBE_DEV_ID_X550EM_A_10G_T:
+               case IXGBE_DEV_ID_X550EM_A_1G_T:
+               case IXGBE_DEV_ID_X550EM_A_1G_T_L:
                        supported = true;
                        break;
                default:
@@ -196,17 +186,14 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
                break;
        }
 
-       ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED,
-                     "Device %x does not support flow control autoneg",
-                     hw->device_id);
        return supported;
 }
 
 /**
- *  ixgbe_setup_fc_generic - Set up flow control
- *  @hw: pointer to hardware structure
+ * ixgbe_setup_fc_generic - Set up flow control
+ * @hw: pointer to hardware structure
  *
- *  Called at init time to set up flow control.
+ * Called at init time to set up flow control.
  **/
 s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw)
 {
@@ -244,7 +231,7 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw)
                if (ret_val != IXGBE_SUCCESS)
                        goto out;
 
-               /* only backplane uses autoc so fall though */
+               /* fall through - only backplane uses autoc */
        case ixgbe_media_type_fiber_qsfp:
        case ixgbe_media_type_fiber:
                reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
@@ -358,18 +345,19 @@ out:
 }
 
 /**
- *  ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
- *  @hw: pointer to hardware structure
+ * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
+ * @hw: pointer to hardware structure
  *
- *  Starts the hardware by filling the bus info structure and media type, clears
- *  all on chip counters, initializes receive address registers, multicast
- *  table, VLAN filter table, calls routine to set up link and flow control
- *  settings, and leaves transmit and receive units disabled and uninitialized
+ * Starts the hardware by filling the bus info structure and media type, clears
+ * all on chip counters, initializes receive address registers, multicast
+ * table, VLAN filter table, calls routine to set up link and flow control
+ * settings, and leaves transmit and receive units disabled and uninitialized
  **/
 s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
 {
        s32 ret_val;
        u32 ctrl_ext;
+       u16 device_caps;
 
        DEBUGFUNC("ixgbe_start_hw_generic");
 
@@ -392,27 +380,44 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
 
        /* Setup flow control */
        ret_val = ixgbe_setup_fc(hw);
-       if (ret_val != IXGBE_SUCCESS)
-               goto out;
+       if (ret_val != IXGBE_SUCCESS && ret_val != IXGBE_NOT_IMPLEMENTED) {
+               DEBUGOUT1("Flow control setup failed, returning %d\n", ret_val);
+               return ret_val;
+       }
+
+       /* Cache bit indicating need for crosstalk fix */
+       switch (hw->mac.type) {
+       case ixgbe_mac_82599EB:
+       case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_X550EM_a:
+               hw->mac.ops.get_device_caps(hw, &device_caps);
+               if (device_caps & IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR)
+                       hw->need_crosstalk_fix = false;
+               else
+                       hw->need_crosstalk_fix = true;
+               break;
+       default:
+               hw->need_crosstalk_fix = false;
+               break;
+       }
 
        /* Clear adapter stopped flag */
        hw->adapter_stopped = false;
 
-out:
-       return ret_val;
+       return IXGBE_SUCCESS;
 }
 
 /**
- *  ixgbe_start_hw_gen2 - Init sequence for common device family
- *  @hw: pointer to hw structure
+ * ixgbe_start_hw_gen2 - Init sequence for common device family
+ * @hw: pointer to hw structure
  *
  * Performs the init sequence common to the second generation
  * of 10 GbE devices.
  * Devices in the second generation:
- *     82599
- *     X540
+ *    82599
+ *    X540
  **/
-s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
+void ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
 {
        u32 i;
        u32 regval;
@@ -437,19 +442,17 @@ s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
                            IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
                IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
        }
-
-       return IXGBE_SUCCESS;
 }
 
 /**
- *  ixgbe_init_hw_generic - Generic hardware initialization
- *  @hw: pointer to hardware structure
+ * ixgbe_init_hw_generic - Generic hardware initialization
+ * @hw: pointer to hardware structure
  *
- *  Initialize the hardware by resetting the hardware, filling the bus info
- *  structure and media type, clears all on chip counters, initializes receive
- *  address registers, multicast table, VLAN filter table, calls routine to set
- *  up link and flow control settings, and leaves transmit and receive units
- *  disabled and uninitialized
+ * Initialize the hardware by resetting the hardware, filling the bus info
+ * structure and media type, clears all on chip counters, initializes receive
+ * address registers, multicast table, VLAN filter table, calls routine to set
+ * up link and flow control settings, and leaves transmit and receive units
+ * disabled and uninitialized
  **/
 s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
 {
@@ -460,20 +463,27 @@ s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
        /* Reset the hardware */
        status = hw->mac.ops.reset_hw(hw);
 
-       if (status == IXGBE_SUCCESS) {
+       if (status == IXGBE_SUCCESS || status == IXGBE_ERR_SFP_NOT_PRESENT) {
                /* Start the HW */
                status = hw->mac.ops.start_hw(hw);
        }
 
+       /* Initialize the LED link active for LED blink support */
+       if (hw->mac.ops.init_led_link_act)
+               hw->mac.ops.init_led_link_act(hw);
+
+       if (status != IXGBE_SUCCESS)
+               DEBUGOUT1("Failed to initialize HW, STATUS = %d\n", status);
+
        return status;
 }
 
 /**
- *  ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters
- *  @hw: pointer to hardware structure
+ * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters
+ * @hw: pointer to hardware structure
  *
- *  Clears all hardware statistics counters by reading them from the hardware
- *  Statistics counters are clear on read.
+ * Clears all hardware statistics counters by reading them from the hardware
+ * Statistics counters are clear on read.
  **/
 s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
 {
@@ -583,12 +593,12 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_read_pba_string_generic - Reads part number string from EEPROM
- *  @hw: pointer to hardware structure
- *  @pba_num: stores the part number string from the EEPROM
- *  @pba_num_size: part number string buffer length
+ * ixgbe_read_pba_string_generic - Reads part number string from EEPROM
+ * @hw: pointer to hardware structure
+ * @pba_num: stores the part number string from the EEPROM
+ * @pba_num_size: part number string buffer length
  *
- *  Reads the part number string from the EEPROM.
+ * Reads the part number string from the EEPROM.
  **/
 s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
                                  u32 pba_num_size)
@@ -694,11 +704,11 @@ s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
 }
 
 /**
- *  ixgbe_read_pba_num_generic - Reads part number from EEPROM
- *  @hw: pointer to hardware structure
- *  @pba_num: stores the part number from the EEPROM
+ * ixgbe_read_pba_num_generic - Reads part number from EEPROM
+ * @hw: pointer to hardware structure
+ * @pba_num: stores the part number from the EEPROM
  *
- *  Reads the part number from the EEPROM.
+ * Reads the part number from the EEPROM.
  **/
 s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
 {
@@ -722,21 +732,21 @@ s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
                DEBUGOUT("NVM Read Error\n");
                return ret_val;
        }
-       *pba_num |= data;
+       *pba_num |= (u32)data;
 
        return IXGBE_SUCCESS;
 }
 
 /**
- *  ixgbe_read_pba_raw
- *  @hw: pointer to the HW structure
- *  @eeprom_buf: optional pointer to EEPROM image
- *  @eeprom_buf_size: size of EEPROM image in words
- *  @max_pba_block_size: PBA block size limit
- *  @pba: pointer to output PBA structure
+ * ixgbe_read_pba_raw
+ * @hw: pointer to the HW structure
+ * @eeprom_buf: optional pointer to EEPROM image
+ * @eeprom_buf_size: size of EEPROM image in words
+ * @max_pba_block_size: PBA block size limit
+ * @pba: pointer to output PBA structure
  *
- *  Reads PBA from EEPROM image when eeprom_buf is not NULL.
- *  Reads PBA from physical EEPROM device when eeprom_buf is NULL.
+ * Reads PBA from EEPROM image when eeprom_buf is not NULL.
+ * Reads PBA from physical EEPROM device when eeprom_buf is NULL.
  *
  **/
 s32 ixgbe_read_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
@@ -798,14 +808,14 @@ s32 ixgbe_read_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
 }
 
 /**
- *  ixgbe_write_pba_raw
- *  @hw: pointer to the HW structure
- *  @eeprom_buf: optional pointer to EEPROM image
- *  @eeprom_buf_size: size of EEPROM image in words
- *  @pba: pointer to PBA structure
+ * ixgbe_write_pba_raw
+ * @hw: pointer to the HW structure
+ * @eeprom_buf: optional pointer to EEPROM image
+ * @eeprom_buf_size: size of EEPROM image in words
+ * @pba: pointer to PBA structure
  *
- *  Writes PBA to EEPROM image when eeprom_buf is not NULL.
- *  Writes PBA to physical EEPROM device when eeprom_buf is NULL.
+ * Writes PBA to EEPROM image when eeprom_buf is not NULL.
+ * Writes PBA to physical EEPROM device when eeprom_buf is NULL.
  *
  **/
 s32 ixgbe_write_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
@@ -856,15 +866,15 @@ s32 ixgbe_write_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
 }
 
 /**
- *  ixgbe_get_pba_block_size
- *  @hw: pointer to the HW structure
- *  @eeprom_buf: optional pointer to EEPROM image
- *  @eeprom_buf_size: size of EEPROM image in words
- *  @pba_data_size: pointer to output variable
+ * ixgbe_get_pba_block_size
+ * @hw: pointer to the HW structure
+ * @eeprom_buf: optional pointer to EEPROM image
+ * @eeprom_buf_size: size of EEPROM image in words
+ * @pba_data_size: pointer to output variable
  *
- *  Returns the size of the PBA block in words. Function operates on EEPROM
- *  image if the eeprom_buf pointer is not NULL otherwise it accesses physical
- *  EEPROM device.
+ * Returns the size of the PBA block in words. Function operates on EEPROM
+ * image if the eeprom_buf pointer is not NULL otherwise it accesses physical
+ * EEPROM device.
  *
  **/
 s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf,
@@ -917,13 +927,13 @@ s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf,
 }
 
 /**
- *  ixgbe_get_mac_addr_generic - Generic get MAC address
- *  @hw: pointer to hardware structure
- *  @mac_addr: Adapter MAC address
+ * ixgbe_get_mac_addr_generic - Generic get MAC address
+ * @hw: pointer to hardware structure
+ * @mac_addr: Adapter MAC address
  *
- *  Reads the adapter's MAC address from first Receive Address Register (RAR0)
- *  A reset of the adapter must be performed prior to calling this function
- *  in order for the MAC address to have been loaded from the EEPROM into RAR0
+ * Reads the adapter's MAC address from first Receive Address Register (RAR0)
+ * A reset of the adapter must be performed prior to calling this function
+ * in order for the MAC address to have been loaded from the EEPROM into RAR0
  **/
 s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
 {
@@ -946,11 +956,11 @@ s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
 }
 
 /**
- *  ixgbe_set_pci_config_data_generic - Generic store PCI bus info
- *  @hw: pointer to hardware structure
- *  @link_status: the link status returned by the PCI config space
+ * ixgbe_set_pci_config_data_generic - Generic store PCI bus info
+ * @hw: pointer to hardware structure
+ * @link_status: the link status returned by the PCI config space
  *
- *  Stores the PCI bus info (speed, width, type) within the ixgbe_hw structure
+ * Stores the PCI bus info (speed, width, type) within the ixgbe_hw structure
  **/
 void ixgbe_set_pci_config_data_generic(struct ixgbe_hw *hw, u16 link_status)
 {
@@ -996,11 +1006,11 @@ void ixgbe_set_pci_config_data_generic(struct ixgbe_hw *hw, u16 link_status)
 }
 
 /**
- *  ixgbe_get_bus_info_generic - Generic set PCI bus info
- *  @hw: pointer to hardware structure
+ * ixgbe_get_bus_info_generic - Generic set PCI bus info
+ * @hw: pointer to hardware structure
  *
- *  Gets the PCI bus info (speed, width, type) then calls helper function to
- *  store this data within the ixgbe_hw structure.
+ * Gets the PCI bus info (speed, width, type) then calls helper function to
+ * store this data within the ixgbe_hw structure.
  **/
 s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
 {
@@ -1017,37 +1027,46 @@ s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
- *  @hw: pointer to the HW structure
+ * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
+ * @hw: pointer to the HW structure
  *
- *  Determines the LAN function id by reading memory-mapped registers
- *  and swaps the port value if requested.
+ * Determines the LAN function id by reading memory-mapped registers and swaps
+ * the port value if requested, and set MAC instance for devices that share
+ * CS4227.
  **/
 void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
 {
        struct ixgbe_bus_info *bus = &hw->bus;
        u32 reg;
+       u16 ee_ctrl_4;
 
        DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie");
 
        reg = IXGBE_READ_REG(hw, IXGBE_STATUS);
        bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT;
-       bus->lan_id = bus->func;
+       bus->lan_id = (u8)bus->func;
 
        /* check for a port swap */
        reg = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw));
        if (reg & IXGBE_FACTPS_LFS)
                bus->func ^= 0x1;
+
+       /* Get MAC instance from EEPROM for configuring CS4227 */
+       if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP) {
+               hw->eeprom.ops.read(hw, IXGBE_EEPROM_CTRL_4, &ee_ctrl_4);
+               bus->instance_id = (ee_ctrl_4 & IXGBE_EE_CTRL_4_INST_ID) >>
+                                  IXGBE_EE_CTRL_4_INST_ID_SHIFT;
+       }
 }
 
 /**
- *  ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
- *  @hw: pointer to hardware structure
+ * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
+ * @hw: pointer to hardware structure
  *
- *  Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
- *  disables transmit and receive units. The adapter_stopped flag is used by
- *  the shared code and drivers to determine if the adapter is in a stopped
- *  state and should not touch the hardware.
+ * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
+ * disables transmit and receive units. The adapter_stopped flag is used by
+ * the shared code and drivers to determine if the adapter is in a stopped
+ * state and should not touch the hardware.
  **/
 s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
 {
@@ -1095,9 +1114,50 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_led_on_generic - Turns on the software controllable LEDs.
- *  @hw: pointer to hardware structure
- *  @index: led number to turn on
+ * ixgbe_init_led_link_act_generic - Store the LED index link/activity.
+ * @hw: pointer to hardware structure
+ *
+ * Store the index for the link active LED. This will be used to support
+ * blinking the LED.
+ **/
+s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw)
+{
+       struct ixgbe_mac_info *mac = &hw->mac;
+       u32 led_reg, led_mode;
+       u8 i;
+
+       led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+       /* Get LED link active from the LEDCTL register */
+       for (i = 0; i < 4; i++) {
+               led_mode = led_reg >> IXGBE_LED_MODE_SHIFT(i);
+
+               if ((led_mode & IXGBE_LED_MODE_MASK_BASE) ==
+                    IXGBE_LED_LINK_ACTIVE) {
+                       mac->led_link_act = i;
+                       return IXGBE_SUCCESS;
+               }
+       }
+
+       /*
+        * If LEDCTL register does not have the LED link active set, then use
+        * known MAC defaults.
+        */
+       switch (hw->mac.type) {
+       case ixgbe_mac_X550EM_a:
+       case ixgbe_mac_X550EM_x:
+               mac->led_link_act = 1;
+               break;
+       default:
+               mac->led_link_act = 2;
+       }
+       return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_led_on_generic - Turns on the software controllable LEDs.
+ * @hw: pointer to hardware structure
+ * @index: led number to turn on
  **/
 s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
 {
@@ -1105,6 +1165,9 @@ s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
 
        DEBUGFUNC("ixgbe_led_on_generic");
 
+       if (index > 3)
+               return IXGBE_ERR_PARAM;
+
        /* To turn on the LED, set mode to ON. */
        led_reg &= ~IXGBE_LED_MODE_MASK(index);
        led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index);
@@ -1115,9 +1178,9 @@ s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
 }
 
 /**
- *  ixgbe_led_off_generic - Turns off the software controllable LEDs.
- *  @hw: pointer to hardware structure
- *  @index: led number to turn off
+ * ixgbe_led_off_generic - Turns off the software controllable LEDs.
+ * @hw: pointer to hardware structure
+ * @index: led number to turn off
  **/
 s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
 {
@@ -1125,6 +1188,9 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
 
        DEBUGFUNC("ixgbe_led_off_generic");
 
+       if (index > 3)
+               return IXGBE_ERR_PARAM;
+
        /* To turn off the LED, set mode to OFF. */
        led_reg &= ~IXGBE_LED_MODE_MASK(index);
        led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index);
@@ -1135,11 +1201,11 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
 }
 
 /**
- *  ixgbe_init_eeprom_params_generic - Initialize EEPROM params
- *  @hw: pointer to hardware structure
+ * ixgbe_init_eeprom_params_generic - Initialize EEPROM params
+ * @hw: pointer to hardware structure
  *
- *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
- *  ixgbe_hw struct in order to set up EEPROM access.
+ * Initializes the EEPROM parameters ixgbe_eeprom_info within the
+ * ixgbe_hw struct in order to set up EEPROM access.
  **/
 s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
 {
@@ -1188,13 +1254,13 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang
- *  @hw: pointer to hardware structure
- *  @offset: offset within the EEPROM to write
- *  @words: number of word(s)
- *  @data: 16 bit word(s) to write to EEPROM
+ * ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to write
+ * @words: number of word(s)
+ * @data: 16 bit word(s) to write to EEPROM
  *
- *  Reads 16 bit word(s) from EEPROM through bit-bang method
+ * Reads 16 bit word(s) from EEPROM through bit-bang method
  **/
 s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
                                               u16 words, u16 *data)
@@ -1244,14 +1310,14 @@ out:
 }
 
 /**
- *  ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM
- *  @hw: pointer to hardware structure
- *  @offset: offset within the EEPROM to be written to
- *  @words: number of word(s)
- *  @data: 16 bit word(s) to be written to the EEPROM
+ * ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be written to
+ * @words: number of word(s)
+ * @data: 16 bit word(s) to be written to the EEPROM
  *
- *  If ixgbe_eeprom_update_checksum is not called after this function, the
- *  EEPROM will most likely contain an invalid checksum.
+ * If ixgbe_eeprom_update_checksum is not called after this function, the
+ * EEPROM will most likely contain an invalid checksum.
  **/
 STATIC s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
                                              u16 words, u16 *data)
@@ -1327,13 +1393,13 @@ STATIC s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
 }
 
 /**
- *  ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
- *  @hw: pointer to hardware structure
- *  @offset: offset within the EEPROM to be written to
- *  @data: 16 bit word to be written to the EEPROM
+ * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be written to
+ * @data: 16 bit word to be written to the EEPROM
  *
- *  If ixgbe_eeprom_update_checksum is not called after this function, the
- *  EEPROM will most likely contain an invalid checksum.
+ * If ixgbe_eeprom_update_checksum is not called after this function, the
+ * EEPROM will most likely contain an invalid checksum.
  **/
 s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
 {
@@ -1355,13 +1421,13 @@ out:
 }
 
 /**
- *  ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang
- *  @hw: pointer to hardware structure
- *  @offset: offset within the EEPROM to be read
- *  @data: read 16 bit words(s) from EEPROM
- *  @words: number of word(s)
+ * ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @data: read 16 bit words(s) from EEPROM
+ * @words: number of word(s)
  *
- *  Reads 16 bit word(s) from EEPROM through bit-bang method
+ * Reads 16 bit word(s) from EEPROM through bit-bang method
  **/
 s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
                                              u16 words, u16 *data)
@@ -1404,13 +1470,13 @@ out:
 }
 
 /**
- *  ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang
- *  @hw: pointer to hardware structure
- *  @offset: offset within the EEPROM to be read
- *  @words: number of word(s)
- *  @data: read 16 bit word(s) from EEPROM
+ * ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @words: number of word(s)
+ * @data: read 16 bit word(s) from EEPROM
  *
- *  Reads 16 bit word(s) from EEPROM through bit-bang method
+ * Reads 16 bit word(s) from EEPROM through bit-bang method
  **/
 STATIC s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
                                             u16 words, u16 *data)
@@ -1462,12 +1528,12 @@ STATIC s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
 }
 
 /**
- *  ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
- *  @hw: pointer to hardware structure
- *  @offset: offset within the EEPROM to be read
- *  @data: read 16 bit value from EEPROM
+ * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @data: read 16 bit value from EEPROM
  *
- *  Reads 16 bit value from EEPROM through bit-bang method
+ * Reads 16 bit value from EEPROM through bit-bang method
  **/
 s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
                                       u16 *data)
@@ -1490,13 +1556,13 @@ out:
 }
 
 /**
- *  ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD
- *  @hw: pointer to hardware structure
- *  @offset: offset of word in the EEPROM to read
- *  @words: number of word(s)
- *  @data: 16 bit word(s) from the EEPROM
+ * ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @words: number of word(s)
+ * @data: 16 bit word(s) from the EEPROM
  *
- *  Reads a 16 bit word(s) from the EEPROM using the EERD register.
+ * Reads a 16 bit word(s) from the EEPROM using the EERD register.
  **/
 s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
                                   u16 words, u16 *data)
@@ -1541,13 +1607,13 @@ out:
 }
 
 /**
- *  ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size
- *  @hw: pointer to hardware structure
- *  @offset: offset within the EEPROM to be used as a scratch pad
+ * ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be used as a scratch pad
  *
- *  Discover EEPROM page size by writing marching data at given offset.
- *  This function is called only when we are writing a new large buffer
- *  at given offset so the data would be overwritten anyway.
+ * Discover EEPROM page size by writing marching data at given offset.
+ * This function is called only when we are writing a new large buffer
+ * at given offset so the data would be overwritten anyway.
  **/
 STATIC s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
                                                 u16 offset)
@@ -1585,12 +1651,12 @@ out:
 }
 
 /**
- *  ixgbe_read_eerd_generic - Read EEPROM word using EERD
- *  @hw: pointer to hardware structure
- *  @offset: offset of  word in the EEPROM to read
- *  @data: word read from the EEPROM
+ * ixgbe_read_eerd_generic - Read EEPROM word using EERD
+ * @hw: pointer to hardware structure
+ * @offset: offset of  word in the EEPROM to read
+ * @data: word read from the EEPROM
  *
- *  Reads a 16 bit word from the EEPROM using the EERD register.
+ * Reads a 16 bit word from the EEPROM using the EERD register.
  **/
 s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
 {
@@ -1598,13 +1664,13 @@ s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
 }
 
 /**
- *  ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR
- *  @hw: pointer to hardware structure
- *  @offset: offset of  word in the EEPROM to write
- *  @words: number of word(s)
- *  @data: word(s) write to the EEPROM
+ * ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of  word in the EEPROM to write
+ * @words: number of word(s)
+ * @data: word(s) write to the EEPROM
  *
- *  Write a 16 bit word(s) to the EEPROM using the EEWR register.
+ * Write a 16 bit word(s) to the EEPROM using the EEWR register.
  **/
 s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
                                    u16 words, u16 *data)
@@ -1654,12 +1720,12 @@ out:
 }
 
 /**
- *  ixgbe_write_eewr_generic - Write EEPROM word using EEWR
- *  @hw: pointer to hardware structure
- *  @offset: offset of  word in the EEPROM to write
- *  @data: word write to the EEPROM
+ * ixgbe_write_eewr_generic - Write EEPROM word using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of  word in the EEPROM to write
+ * @data: word write to the EEPROM
  *
- *  Write a 16 bit word to the EEPROM using the EEWR register.
+ * Write a 16 bit word to the EEPROM using the EEWR register.
  **/
 s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
 {
@@ -1667,12 +1733,12 @@ s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
 }
 
 /**
- *  ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status
- *  @hw: pointer to hardware structure
- *  @ee_reg: EEPROM flag for polling
+ * ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status
+ * @hw: pointer to hardware structure
+ * @ee_reg: EEPROM flag for polling
  *
- *  Polls the status bit (bit 1) of the EERD or EEWR to determine when the
- *  read or write is done respectively.
+ * Polls the status bit (bit 1) of the EERD or EEWR to determine when the
+ * read or write is done respectively.
  **/
 s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
 {
@@ -1703,11 +1769,11 @@ s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
 }
 
 /**
- *  ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang
- *  @hw: pointer to hardware structure
+ * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang
+ * @hw: pointer to hardware structure
  *
- *  Prepares EEPROM for access using bit-bang method. This function should
- *  be called before issuing a command to the EEPROM.
+ * Prepares EEPROM for access using bit-bang method. This function should
+ * be called before issuing a command to the EEPROM.
  **/
 STATIC s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
 {
@@ -1758,10 +1824,10 @@ STATIC s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_get_eeprom_semaphore - Get hardware semaphore
- *  @hw: pointer to hardware structure
+ * ixgbe_get_eeprom_semaphore - Get hardware semaphore
+ * @hw: pointer to hardware structure
  *
- *  Sets the hardware semaphores so EEPROM access can occur for bit-bang method
+ * Sets the hardware semaphores so EEPROM access can occur for bit-bang method
  **/
 STATIC s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
 {
@@ -1849,10 +1915,10 @@ STATIC s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_release_eeprom_semaphore - Release hardware semaphore
- *  @hw: pointer to hardware structure
+ * ixgbe_release_eeprom_semaphore - Release hardware semaphore
+ * @hw: pointer to hardware structure
  *
- *  This function clears hardware semaphore bits.
+ * This function clears hardware semaphore bits.
  **/
 STATIC void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
 {
@@ -1869,8 +1935,8 @@ STATIC void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_ready_eeprom - Polls for EEPROM ready
- *  @hw: pointer to hardware structure
+ * ixgbe_ready_eeprom - Polls for EEPROM ready
+ * @hw: pointer to hardware structure
  **/
 STATIC s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
 {
@@ -1910,8 +1976,8 @@ STATIC s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_standby_eeprom - Returns EEPROM to a "standby" state
- *  @hw: pointer to hardware structure
+ * ixgbe_standby_eeprom - Returns EEPROM to a "standby" state
+ * @hw: pointer to hardware structure
  **/
 STATIC void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
 {
@@ -1933,10 +1999,10 @@ STATIC void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM.
- *  @hw: pointer to hardware structure
- *  @data: data to send to the EEPROM
- *  @count: number of bits to shift out
+ * ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM.
+ * @hw: pointer to hardware structure
+ * @data: data to send to the EEPROM
+ * @count: number of bits to shift out
  **/
 STATIC void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
                                        u16 count)
@@ -1990,8 +2056,9 @@ STATIC void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
 }
 
 /**
- *  ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM
- *  @hw: pointer to hardware structure
+ * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM
+ * @hw: pointer to hardware structure
+ * @count: number of bits to shift
  **/
 STATIC u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
 {
@@ -2029,9 +2096,9 @@ STATIC u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
 }
 
 /**
- *  ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input.
- *  @hw: pointer to hardware structure
- *  @eec: EEC register's current value
+ * ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input.
+ * @hw: pointer to hardware structure
+ * @eec: EEC register's current value
  **/
 STATIC void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
 {
@@ -2048,9 +2115,9 @@ STATIC void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
 }
 
 /**
- *  ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input.
- *  @hw: pointer to hardware structure
- *  @eecd: EECD's current value
+ * ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input.
+ * @hw: pointer to hardware structure
+ * @eec: EEC's current value
  **/
 STATIC void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
 {
@@ -2067,8 +2134,8 @@ STATIC void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
 }
 
 /**
- *  ixgbe_release_eeprom - Release EEPROM, release semaphores
- *  @hw: pointer to hardware structure
+ * ixgbe_release_eeprom - Release EEPROM, release semaphores
+ * @hw: pointer to hardware structure
  **/
 STATIC void ixgbe_release_eeprom(struct ixgbe_hw *hw)
 {
@@ -2097,10 +2164,10 @@ STATIC void ixgbe_release_eeprom(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum
- *  @hw: pointer to hardware structure
+ * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum
+ * @hw: pointer to hardware structure
  *
- *  Returns a negative error code on error, or the 16-bit checksum
+ * Returns a negative error code on error, or the 16-bit checksum
  **/
 s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
 {
@@ -2156,12 +2223,12 @@ s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum
- *  @hw: pointer to hardware structure
- *  @checksum_val: calculated checksum
+ * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum
+ * @hw: pointer to hardware structure
+ * @checksum_val: calculated checksum
  *
- *  Performs checksum calculation and validates the EEPROM checksum.  If the
- *  caller does not need checksum_val, the value can be NULL.
+ * Performs checksum calculation and validates the EEPROM checksum.  If the
+ * caller does not need checksum_val, the value can be NULL.
  **/
 s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
                                           u16 *checksum_val)
@@ -2208,8 +2275,8 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
 }
 
 /**
- *  ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum
- *  @hw: pointer to hardware structure
+ * ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum
+ * @hw: pointer to hardware structure
  **/
 s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
 {
@@ -2240,10 +2307,10 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_validate_mac_addr - Validate MAC address
- *  @mac_addr: pointer to MAC address.
+ * ixgbe_validate_mac_addr - Validate MAC address
+ * @mac_addr: pointer to MAC address.
  *
- *  Tests a MAC address to ensure it is a valid Individual Address.
+ * Tests a MAC address to ensure it is a valid Individual Address.
  **/
 s32 ixgbe_validate_mac_addr(u8 *mac_addr)
 {
@@ -2266,14 +2333,14 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr)
 }
 
 /**
- *  ixgbe_set_rar_generic - Set Rx address register
- *  @hw: pointer to hardware structure
- *  @index: Receive address register to write
- *  @addr: Address to put into receive address register
- *  @vmdq: VMDq "set" or "pool" index
- *  @enable_addr: set flag that address is active
+ * ixgbe_set_rar_generic - Set Rx address register
+ * @hw: pointer to hardware structure
+ * @index: Receive address register to write
+ * @addr: Address to put into receive address register
+ * @vmdq: VMDq "set" or "pool" index
+ * @enable_addr: set flag that address is active
  *
- *  Puts an ethernet address into a receive address register.
+ * Puts an ethernet address into a receive address register.
  **/
 s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
                          u32 enable_addr)
@@ -2320,11 +2387,11 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
 }
 
 /**
- *  ixgbe_clear_rar_generic - Remove Rx address register
- *  @hw: pointer to hardware structure
- *  @index: Receive address register to write
+ * ixgbe_clear_rar_generic - Remove Rx address register
+ * @hw: pointer to hardware structure
+ * @index: Receive address register to write
  *
- *  Clears an ethernet address from a receive address register.
+ * Clears an ethernet address from a receive address register.
  **/
 s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
 {
@@ -2358,12 +2425,12 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
 }
 
 /**
- *  ixgbe_init_rx_addrs_generic - Initializes receive address filters.
- *  @hw: pointer to hardware structure
+ * ixgbe_init_rx_addrs_generic - Initializes receive address filters.
+ * @hw: pointer to hardware structure
  *
- *  Places the MAC address in receive address register 0 and clears the rest
- *  of the receive address registers. Clears the multicast table. Assumes
- *  the receiver is in reset when the routine is called.
+ * Places the MAC address in receive address register 0 and clears the rest
+ * of the receive address registers. Clears the multicast table. Assumes
+ * the receiver is in reset when the routine is called.
  **/
 s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
 {
@@ -2397,10 +2464,11 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
                          hw->mac.addr[4], hw->mac.addr[5]);
 
                hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
-
-               /* clear VMDq pool/queue selection for RAR 0 */
-               hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
        }
+
+       /* clear VMDq pool/queue selection for RAR 0 */
+       hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
+
        hw->addr_ctrl.overflow_promisc = 0;
 
        hw->addr_ctrl.rar_used_count = 1;
@@ -2426,11 +2494,12 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_add_uc_addr - Adds a secondary unicast address.
- *  @hw: pointer to hardware structure
- *  @addr: new address
+ * ixgbe_add_uc_addr - Adds a secondary unicast address.
+ * @hw: pointer to hardware structure
+ * @addr: new address
+ * @vmdq: VMDq "set" or "pool" index
  *
- *  Adds it to unused receive address register or goes into promiscuous mode.
+ * Adds it to unused receive address register or goes into promiscuous mode.
  **/
 void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
 {
@@ -2459,18 +2528,18 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
 }
 
 /**
- *  ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
- *  @hw: pointer to hardware structure
- *  @addr_list: the list of new addresses
- *  @addr_count: number of addresses
- *  @next: iterator function to walk the address list
+ * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
+ * @hw: pointer to hardware structure
+ * @addr_list: the list of new addresses
+ * @addr_count: number of addresses
+ * @next: iterator function to walk the address list
  *
- *  The given list replaces any existing list.  Clears the secondary addrs from
- *  receive address registers.  Uses unused receive address registers for the
- *  first secondary addresses, and falls back to promiscuous mode as needed.
+ * The given list replaces any existing list.  Clears the secondary addrs from
+ * receive address registers.  Uses unused receive address registers for the
+ * first secondary addresses, and falls back to promiscuous mode as needed.
  *
- *  Drivers using secondary unicast addresses must set user_set_promisc when
- *  manually putting the device into promiscuous mode.
+ * Drivers using secondary unicast addresses must set user_set_promisc when
+ * manually putting the device into promiscuous mode.
  **/
 s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
                                      u32 addr_count, ixgbe_mc_addr_itr next)
@@ -2529,16 +2598,16 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
 }
 
 /**
- *  ixgbe_mta_vector - Determines bit-vector in multicast table to set
- *  @hw: pointer to hardware structure
- *  @mc_addr: the multicast address
+ * ixgbe_mta_vector - Determines bit-vector in multicast table to set
+ * @hw: pointer to hardware structure
+ * @mc_addr: the multicast address
  *
- *  Extracts the 12 bits, from a multicast address, to determine which
- *  bit-vector to set in the multicast table. The hardware uses 12 bits, from
- *  incoming rx multicast addresses, to determine the bit-vector to check in
- *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
- *  by the MO field of the MCSTCTRL. The MO field is set during initialization
- *  to mc_filter_type.
+ * Extracts the 12 bits, from a multicast address, to determine which
+ * bit-vector to set in the multicast table. The hardware uses 12 bits, from
+ * incoming rx multicast addresses, to determine the bit-vector to check in
+ * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
+ * by the MO field of the MCSTCTRL. The MO field is set during initialization
+ * to mc_filter_type.
  **/
 STATIC s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
 {
@@ -2571,11 +2640,11 @@ STATIC s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
 }
 
 /**
- *  ixgbe_set_mta - Set bit-vector in multicast table
- *  @hw: pointer to hardware structure
- *  @hash_value: Multicast address hash value
+ * ixgbe_set_mta - Set bit-vector in multicast table
+ * @hw: pointer to hardware structure
+ * @mc_addr: Multicast address
  *
- *  Sets the bit-vector in the multicast table.
+ * Sets the bit-vector in the multicast table.
  **/
 void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
 {
@@ -2605,15 +2674,15 @@ void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
 }
 
 /**
- *  ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
- *  @hw: pointer to hardware structure
- *  @mc_addr_list: the list of new multicast addresses
- *  @mc_addr_count: number of addresses
- *  @next: iterator function to walk the multicast address list
- *  @clear: flag, when set clears the table beforehand
+ * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
+ * @hw: pointer to hardware structure
+ * @mc_addr_list: the list of new multicast addresses
+ * @mc_addr_count: number of addresses
+ * @next: iterator function to walk the multicast address list
+ * @clear: flag, when set clears the table beforehand
  *
- *  When the clear flag is set, the given list replaces any existing list.
- *  Hashes the given addresses into the multicast table.
+ * When the clear flag is set, the given list replaces any existing list.
+ * Hashes the given addresses into the multicast table.
  **/
 s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
                                      u32 mc_addr_count, ixgbe_mc_addr_itr next,
@@ -2657,10 +2726,10 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
 }
 
 /**
- *  ixgbe_enable_mc_generic - Enable multicast address in RAR
- *  @hw: pointer to hardware structure
+ * ixgbe_enable_mc_generic - Enable multicast address in RAR
+ * @hw: pointer to hardware structure
  *
- *  Enables multicast address in RAR and the use of the multicast hash table.
+ * Enables multicast address in RAR and the use of the multicast hash table.
  **/
 s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
 {
@@ -2676,10 +2745,10 @@ s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_disable_mc_generic - Disable multicast address in RAR
- *  @hw: pointer to hardware structure
+ * ixgbe_disable_mc_generic - Disable multicast address in RAR
+ * @hw: pointer to hardware structure
  *
- *  Disables multicast address in RAR and the use of the multicast hash table.
+ * Disables multicast address in RAR and the use of the multicast hash table.
  **/
 s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
 {
@@ -2694,10 +2763,10 @@ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_fc_enable_generic - Enable flow control
- *  @hw: pointer to hardware structure
+ * ixgbe_fc_enable_generic - Enable flow control
+ * @hw: pointer to hardware structure
  *
- *  Enable flow control according to the current settings.
+ * Enable flow control according to the current settings.
  **/
 s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
 {
@@ -2729,7 +2798,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
        }
 
        /* Negotiate the fc mode to use */
-       ixgbe_fc_autoneg(hw);
+       hw->mac.ops.fc_autoneg(hw);
 
        /* Disable any previous flow control settings */
        mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
@@ -2827,20 +2896,20 @@ out:
 }
 
 /**
- *  ixgbe_negotiate_fc - Negotiate flow control
- *  @hw: pointer to hardware structure
- *  @adv_reg: flow control advertised settings
- *  @lp_reg: link partner's flow control settings
- *  @adv_sym: symmetric pause bit in advertisement
- *  @adv_asm: asymmetric pause bit in advertisement
- *  @lp_sym: symmetric pause bit in link partner advertisement
- *  @lp_asm: asymmetric pause bit in link partner advertisement
+ * ixgbe_negotiate_fc - Negotiate flow control
+ * @hw: pointer to hardware structure
+ * @adv_reg: flow control advertised settings
+ * @lp_reg: link partner's flow control settings
+ * @adv_sym: symmetric pause bit in advertisement
+ * @adv_asm: asymmetric pause bit in advertisement
+ * @lp_sym: symmetric pause bit in link partner advertisement
+ * @lp_asm: asymmetric pause bit in link partner advertisement
  *
- *  Find the intersection between advertised settings and link partner's
- *  advertised settings
+ * Find the intersection between advertised settings and link partner's
+ * advertised settings
  **/
-STATIC s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
-                             u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
+s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
+                      u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
 {
        if ((!(adv_reg)) ||  (!(lp_reg))) {
                ERROR_REPORT3(IXGBE_ERROR_UNSUPPORTED,
@@ -2881,10 +2950,10 @@ STATIC s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
 }
 
 /**
- *  ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber
- *  @hw: pointer to hardware structure
+ * ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber
+ * @hw: pointer to hardware structure
  *
- *  Enable flow control according on 1 gig fiber.
+ * Enable flow control according on 1 gig fiber.
  **/
 STATIC s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
 {
@@ -2918,10 +2987,10 @@ out:
 }
 
 /**
- *  ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37
- *  @hw: pointer to hardware structure
+ * ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37
+ * @hw: pointer to hardware structure
  *
- *  Enable flow control according to IEEE clause 37.
+ * Enable flow control according to IEEE clause 37.
  **/
 STATIC s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
 {
@@ -2962,10 +3031,10 @@ out:
 }
 
 /**
- *  ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37
- *  @hw: pointer to hardware structure
+ * ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37
+ * @hw: pointer to hardware structure
  *
- *  Enable flow control according to IEEE clause 37.
+ * Enable flow control according to IEEE clause 37.
  **/
 STATIC s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw)
 {
@@ -2986,11 +3055,11 @@ STATIC s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_fc_autoneg - Configure flow control
- *  @hw: pointer to hardware structure
+ * ixgbe_fc_autoneg - Configure flow control
+ * @hw: pointer to hardware structure
  *
- *  Compares our advertised flow control capabilities to those advertised by
- *  our link partner, and determines the proper flow control mode to use.
+ * Compares our advertised flow control capabilities to those advertised by
+ * our link partner, and determines the proper flow control mode to use.
  **/
 void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
 {
@@ -3007,8 +3076,9 @@ void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
         * - link is not up.
         */
        if (hw->fc.disable_fc_autoneg) {
-               ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
-                            "Flow control autoneg is disabled");
+               /* TODO: This should be just an informative log */
+               ERROR_REPORT1(IXGBE_ERROR_CAUTION,
+                             "Flow control autoneg is disabled");
                goto out;
        }
 
@@ -3098,13 +3168,13 @@ STATIC u32 ixgbe_pcie_timeout_poll(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_disable_pcie_master - Disable PCI-express master access
- *  @hw: pointer to hardware structure
+ * ixgbe_disable_pcie_master - Disable PCI-express master access
+ * @hw: pointer to hardware structure
  *
- *  Disables PCI-Express master access and verifies there are no pending
- *  requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable
- *  bit hasn't caused the master requests to be disabled, else IXGBE_SUCCESS
- *  is returned signifying master requests disabled.
+ * Disables PCI-Express master access and verifies there are no pending
+ * requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable
+ * bit hasn't caused the master requests to be disabled, else IXGBE_SUCCESS
+ * is returned signifying master requests disabled.
  **/
 s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
 {
@@ -3166,12 +3236,12 @@ out:
 }
 
 /**
- *  ixgbe_acquire_swfw_sync - Acquire SWFW semaphore
- *  @hw: pointer to hardware structure
- *  @mask: Mask to specify which semaphore to acquire
+ * ixgbe_acquire_swfw_sync - Acquire SWFW semaphore
+ * @hw: pointer to hardware structure
+ * @mask: Mask to specify which semaphore to acquire
  *
- *  Acquires the SWFW semaphore through the GSSR register for the specified
- *  function (CSR, PHY0, PHY1, EEPROM, Flash)
+ * Acquires the SWFW semaphore through the GSSR register for the specified
+ * function (CSR, PHY0, PHY1, EEPROM, Flash)
  **/
 s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask)
 {
@@ -3213,12 +3283,12 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask)
 }
 
 /**
- *  ixgbe_release_swfw_sync - Release SWFW semaphore
- *  @hw: pointer to hardware structure
- *  @mask: Mask to specify which semaphore to release
+ * ixgbe_release_swfw_sync - Release SWFW semaphore
+ * @hw: pointer to hardware structure
+ * @mask: Mask to specify which semaphore to release
  *
- *  Releases the SWFW semaphore through the GSSR register for the specified
- *  function (CSR, PHY0, PHY1, EEPROM, Flash)
+ * Releases the SWFW semaphore through the GSSR register for the specified
+ * function (CSR, PHY0, PHY1, EEPROM, Flash)
  **/
 void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask)
 {
@@ -3237,15 +3307,15 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask)
 }
 
 /**
- *  ixgbe_disable_sec_rx_path_generic - Stops the receive data path
- *  @hw: pointer to hardware structure
+ * ixgbe_disable_sec_rx_path_generic - Stops the receive data path
+ * @hw: pointer to hardware structure
  *
- *  Stops the receive data path and waits for the HW to internally empty
- *  the Rx security block
+ * Stops the receive data path and waits for the HW to internally empty
+ * the Rx security block
  **/
 s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw)
 {
-#define IXGBE_MAX_SECRX_POLL 40
+#define IXGBE_MAX_SECRX_POLL 4000
 
        int i;
        int secrxreg;
@@ -3262,7 +3332,7 @@ s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw)
                        break;
                else
                        /* Use interrupt-safe sleep just in case */
-                       usec_delay(1000);
+                       usec_delay(10);
        }
 
        /* For informational purposes only */
@@ -3274,11 +3344,12 @@ s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  prot_autoc_read_generic - Hides MAC differences needed for AUTOC read
- *  @hw: pointer to hardware structure
- *  @reg_val: Value we read from AUTOC
+ * prot_autoc_read_generic - Hides MAC differences needed for AUTOC read
+ * @hw: pointer to hardware structure
+ * @locked: bool to indicate whether the SW/FW lock was taken
+ * @reg_val: Value we read from AUTOC
  *
- *  The default case requires no protection so just to the register read.
+ * The default case requires no protection so just to the register read.
  */
 s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *locked, u32 *reg_val)
 {
@@ -3292,7 +3363,7 @@ s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *locked, u32 *reg_val)
  * @hw: pointer to hardware structure
  * @reg_val: value to write to AUTOC
  * @locked: bool to indicate whether the SW/FW lock was already taken by
- *           previous read.
+ *          previous read.
  *
  * The default case requires no protection so just to the register write.
  */
@@ -3305,14 +3376,14 @@ s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked)
 }
 
 /**
- *  ixgbe_enable_sec_rx_path_generic - Enables the receive data path
- *  @hw: pointer to hardware structure
+ * ixgbe_enable_sec_rx_path_generic - Enables the receive data path
+ * @hw: pointer to hardware structure
  *
- *  Enables the receive data path.
+ * Enables the receive data path.
  **/
 s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw)
 {
-       int secrxreg;
+       u32 secrxreg;
 
        DEBUGFUNC("ixgbe_enable_sec_rx_path_generic");
 
@@ -3325,11 +3396,11 @@ s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
- *  @hw: pointer to hardware structure
- *  @regval: register value to write to RXCTRL
+ * ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
+ * @hw: pointer to hardware structure
+ * @regval: register value to write to RXCTRL
  *
- *  Enables the Rx DMA unit
+ * Enables the Rx DMA unit
  **/
 s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
 {
@@ -3344,9 +3415,9 @@ s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
 }
 
 /**
- *  ixgbe_blink_led_start_generic - Blink LED based on index.
- *  @hw: pointer to hardware structure
- *  @index: led number to blink
+ * ixgbe_blink_led_start_generic - Blink LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to blink
  **/
 s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
 {
@@ -3359,6 +3430,9 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
 
        DEBUGFUNC("ixgbe_blink_led_start_generic");
 
+       if (index > 3)
+               return IXGBE_ERR_PARAM;
+
        /*
         * Link must be up to auto-blink the LEDs;
         * Force it if link is down.
@@ -3391,9 +3465,9 @@ out:
 }
 
 /**
- *  ixgbe_blink_led_stop_generic - Stop blinking LED based on index.
- *  @hw: pointer to hardware structure
- *  @index: led number to stop blinking
+ * ixgbe_blink_led_stop_generic - Stop blinking LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to stop blinking
  **/
 s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
 {
@@ -3404,6 +3478,10 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
 
        DEBUGFUNC("ixgbe_blink_led_stop_generic");
 
+       if (index > 3)
+               return IXGBE_ERR_PARAM;
+
+
        ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
        if (ret_val != IXGBE_SUCCESS)
                goto out;
@@ -3426,13 +3504,13 @@ out:
 }
 
 /**
- *  ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM
- *  @hw: pointer to hardware structure
- *  @san_mac_offset: SAN MAC address offset
+ * ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM
+ * @hw: pointer to hardware structure
+ * @san_mac_offset: SAN MAC address offset
  *
- *  This function will read the EEPROM location for the SAN MAC address
- *  pointer, and returns the value at that location.  This is used in both
- *  get and set mac_addr routines.
+ * This function will read the EEPROM location for the SAN MAC address
+ * pointer, and returns the value at that location.  This is used in both
+ * get and set mac_addr routines.
  **/
 STATIC s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
                                         u16 *san_mac_offset)
@@ -3457,14 +3535,14 @@ STATIC s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
 }
 
 /**
- *  ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM
- *  @hw: pointer to hardware structure
- *  @san_mac_addr: SAN MAC address
+ * ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM
+ * @hw: pointer to hardware structure
+ * @san_mac_addr: SAN MAC address
  *
- *  Reads the SAN MAC address from the EEPROM, if it's available.  This is
- *  per-port, so set_lan_id() must be called before reading the addresses.
- *  set_lan_id() is called by identify_sfp(), but this cannot be relied
- *  upon for non-SFP connections, so we must call it here.
+ * Reads the SAN MAC address from the EEPROM, if it's available.  This is
+ * per-port, so set_lan_id() must be called before reading the addresses.
+ * set_lan_id() is called by identify_sfp(), but this cannot be relied
+ * upon for non-SFP connections, so we must call it here.
  **/
 s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
 {
@@ -3513,11 +3591,11 @@ san_mac_addr_out:
 }
 
 /**
- *  ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM
- *  @hw: pointer to hardware structure
- *  @san_mac_addr: SAN MAC address
+ * ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM
+ * @hw: pointer to hardware structure
+ * @san_mac_addr: SAN MAC address
  *
- *  Write a SAN MAC address to the EEPROM.
+ * Write a SAN MAC address to the EEPROM.
  **/
 s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
 {
@@ -3549,11 +3627,11 @@ s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
 }
 
 /**
- *  ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count
- *  @hw: pointer to hardware structure
+ * ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count
+ * @hw: pointer to hardware structure
  *
- *  Read PCIe configuration space, and get the MSI-X vector count from
- *  the capabilities table.
+ * Read PCIe configuration space, and get the MSI-X vector count from
+ * the capabilities table.
  **/
 u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
 {
@@ -3594,13 +3672,13 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_insert_mac_addr_generic - Find a RAR for this mac address
- *  @hw: pointer to hardware structure
- *  @addr: Address to put into receive address register
- *  @vmdq: VMDq pool to assign
+ * ixgbe_insert_mac_addr_generic - Find a RAR for this mac address
+ * @hw: pointer to hardware structure
+ * @addr: Address to put into receive address register
+ * @vmdq: VMDq pool to assign
  *
- *  Puts an ethernet address into a receive address register, or
- *  finds the rar that it is aleady in; adds to the pool list
+ * Puts an ethernet address into a receive address register, or
+ * finds the rar that it is already in; adds to the pool list
  **/
 s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
 {
@@ -3663,10 +3741,10 @@ s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
 }
 
 /**
- *  ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address
- *  @hw: pointer to hardware struct
- *  @rar: receive address register index to disassociate
- *  @vmdq: VMDq pool index to remove from the rar
+ * ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to disassociate
+ * @vmdq: VMDq pool index to remove from the rar
  **/
 s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
 {
@@ -3694,11 +3772,11 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
        if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
                if (mpsar_lo) {
                        IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
-                       mpsar_lo = 0;
+                       mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
                }
                if (mpsar_hi) {
                        IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
-                       mpsar_hi = 0;
+                       mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
                }
        } else if (vmdq < 32) {
                mpsar_lo &= ~(1 << vmdq);
@@ -3709,17 +3787,18 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
        }
 
        /* was that the last pool using this rar? */
-       if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0)
+       if (mpsar_lo == 0 && mpsar_hi == 0 &&
+           rar != 0 && rar != hw->mac.san_mac_rar_index)
                hw->mac.ops.clear_rar(hw, rar);
 done:
        return IXGBE_SUCCESS;
 }
 
 /**
- *  ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address
- *  @hw: pointer to hardware struct
- *  @rar: receive address register index to associate with a VMDq index
- *  @vmdq: VMDq pool index
+ * ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to associate with a VMDq index
+ * @vmdq: VMDq pool index
  **/
 s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
 {
@@ -3748,14 +3827,14 @@ s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
 }
 
 /**
- *  This function should only be involved in the IOV mode.
- *  In IOV mode, Default pool is next pool after the number of
- *  VFs advertized and not 0.
- *  MPSAR table needs to be updated for SAN_MAC RAR [hw->mac.san_mac_rar_index]
+ * This function should only be involved in the IOV mode.
+ * In IOV mode, Default pool is next pool after the number of
+ * VFs advertized and not 0.
+ * MPSAR table needs to be updated for SAN_MAC RAR [hw->mac.san_mac_rar_index]
  *
- *  ixgbe_set_vmdq_san_mac - Associate default VMDq pool index with a rx address
- *  @hw: pointer to hardware struct
- *  @vmdq: VMDq pool index
+ * ixgbe_set_vmdq_san_mac - Associate default VMDq pool index with a rx address
+ * @hw: pointer to hardware struct
+ * @vmdq: VMDq pool index
  **/
 s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq)
 {
@@ -3775,8 +3854,8 @@ s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq)
 }
 
 /**
- *  ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array
- *  @hw: pointer to hardware structure
+ * ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array
+ * @hw: pointer to hardware structure
  **/
 s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
 {
@@ -3792,75 +3871,75 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_find_vlvf_slot - find the vlanid or the first empty slot
- *  @hw: pointer to hardware structure
- *  @vlan: VLAN id to write to VLAN filter
+ * ixgbe_find_vlvf_slot - find the vlanid or the first empty slot
+ * @hw: pointer to hardware structure
+ * @vlan: VLAN id to write to VLAN filter
+ * @vlvf_bypass: true to find vlanid only, false returns first empty slot if
+ *               vlanid not found
  *
- *  return the VLVF index where this VLAN id should be placed
+ *
+ * return the VLVF index where this VLAN id should be placed
  *
  **/
-s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
+s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
 {
-       u32 bits = 0;
-       u32 first_empty_slot = 0;
-       s32 regindex;
+       s32 regindex, first_empty_slot;
+       u32 bits;
 
        /* short cut the special case */
        if (vlan == 0)
                return 0;
 
-       /*
-         * Search for the vlan id in the VLVF entries. Save off the first empty
-         * slot found along the way
-         */
-       for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
+       /* if vlvf_bypass is set we don't want to use an empty slot, we
+        * will simply bypass the VLVF if there are no entries present in the
+        * VLVF that contain our VLAN
+        */
+       first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0;
+
+       /* add VLAN enable bit for comparison */
+       vlan |= IXGBE_VLVF_VIEN;
+
+       /* Search for the vlan id in the VLVF entries. Save off the first empty
+        * slot found along the way.
+        *
+        * pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1
+        */
+       for (regindex = IXGBE_VLVF_ENTRIES; --regindex;) {
                bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
-               if (!bits && !(first_empty_slot))
+               if (bits == vlan)
+                       return regindex;
+               if (!first_empty_slot && !bits)
                        first_empty_slot = regindex;
-               else if ((bits & 0x0FFF) == vlan)
-                       break;
        }
 
-       /*
-         * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan
-         * in the VLVF. Else use the first empty VLVF register for this
-         * vlan id.
-         */
-       if (regindex >= IXGBE_VLVF_ENTRIES) {
-               if (first_empty_slot)
-                       regindex = first_empty_slot;
-               else {
-                       ERROR_REPORT1(IXGBE_ERROR_SOFTWARE,
-                                    "No space in VLVF.\n");
-                       regindex = IXGBE_ERR_NO_SPACE;
-               }
-       }
+       /* If we are here then we didn't find the VLAN.  Return first empty
+        * slot we found during our search, else error.
+        */
+       if (!first_empty_slot)
+               ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "No space in VLVF.\n");
 
-       return regindex;
+       return first_empty_slot ? first_empty_slot : IXGBE_ERR_NO_SPACE;
 }
 
 /**
- *  ixgbe_set_vfta_generic - Set VLAN filter table
- *  @hw: pointer to hardware structure
- *  @vlan: VLAN id to write to VLAN filter
- *  @vind: VMDq output index that maps queue to VLAN id in VFVFB
- *  @vlan_on: boolean flag to turn on/off VLAN in VFVF
+ * ixgbe_set_vfta_generic - Set VLAN filter table
+ * @hw: pointer to hardware structure
+ * @vlan: VLAN id to write to VLAN filter
+ * @vind: VMDq output index that maps queue to VLAN id in VLVFB
+ * @vlan_on: boolean flag to turn on/off VLAN
+ * @vlvf_bypass: boolean flag indicating updating default pool is okay
  *
- *  Turn on/off specified VLAN in the VLAN filter table.
+ * Turn on/off specified VLAN in the VLAN filter table.
  **/
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
-                          bool vlan_on)
+                          bool vlan_on, bool vlvf_bypass)
 {
-       s32 regindex;
-       u32 bitindex;
-       u32 vfta;
-       u32 targetbit;
-       s32 ret_val = IXGBE_SUCCESS;
-       bool vfta_changed = false;
+       u32 regidx, vfta_delta, vfta;
+       s32 ret_val;
 
        DEBUGFUNC("ixgbe_set_vfta_generic");
 
-       if (vlan > 4095)
+       if (vlan > 4095 || vind > 63)
                return IXGBE_ERR_PARAM;
 
        /*
@@ -3875,56 +3954,60 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
         *    bits[11-5]: which register
         *    bits[4-0]:  which bit in the register
         */
-       regindex = (vlan >> 5) & 0x7F;
-       bitindex = vlan & 0x1F;
-       targetbit = (1 << bitindex);
-       vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
-
-       if (vlan_on) {
-               if (!(vfta & targetbit)) {
-                       vfta |= targetbit;
-                       vfta_changed = true;
-               }
-       } else {
-               if ((vfta & targetbit)) {
-                       vfta &= ~targetbit;
-                       vfta_changed = true;
-               }
-       }
+       regidx = vlan / 32;
+       vfta_delta = 1 << (vlan % 32);
+       vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regidx));
+
+       /*
+        * vfta_delta represents the difference between the current value
+        * of vfta and the value we want in the register.  Since the diff
+        * is an XOR mask we can just update the vfta using an XOR
+        */
+       vfta_delta &= vlan_on ? ~vfta : vfta;
+       vfta ^= vfta_delta;
 
        /* Part 2
         * Call ixgbe_set_vlvf_generic to set VLVFB and VLVF
         */
-       ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on,
-                                        &vfta_changed);
-       if (ret_val != IXGBE_SUCCESS)
+       ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on, &vfta_delta,
+                                        vfta, vlvf_bypass);
+       if (ret_val != IXGBE_SUCCESS) {
+               if (vlvf_bypass)
+                       goto vfta_update;
                return ret_val;
+       }
 
-       if (vfta_changed)
-               IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta);
+vfta_update:
+       /* Update VFTA now that we are ready for traffic */
+       if (vfta_delta)
+               IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
 
        return IXGBE_SUCCESS;
 }
 
 /**
- *  ixgbe_set_vlvf_generic - Set VLAN Pool Filter
- *  @hw: pointer to hardware structure
- *  @vlan: VLAN id to write to VLAN filter
- *  @vind: VMDq output index that maps queue to VLAN id in VFVFB
- *  @vlan_on: boolean flag to turn on/off VLAN in VFVF
- *  @vfta_changed: pointer to boolean flag which indicates whether VFTA
- *                 should be changed
+ * ixgbe_set_vlvf_generic - Set VLAN Pool Filter
+ * @hw: pointer to hardware structure
+ * @vlan: VLAN id to write to VLAN filter
+ * @vind: VMDq output index that maps queue to VLAN id in VLVFB
+ * @vlan_on: boolean flag to turn on/off VLAN in VLVF
+ * @vfta_delta: pointer to the difference between the current value of VFTA
+ *              and the desired value
+ * @vfta: the desired value of the VFTA
+ * @vlvf_bypass: boolean flag indicating updating default pool is okay
  *
- *  Turn on/off specified bit in VLVF table.
+ * Turn on/off specified bit in VLVF table.
  **/
 s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
-                           bool vlan_on, bool *vfta_changed)
+                          bool vlan_on, u32 *vfta_delta, u32 vfta,
+                          bool vlvf_bypass)
 {
-       u32 vt;
+       u32 bits;
+       s32 vlvf_index;
 
        DEBUGFUNC("ixgbe_set_vlvf_generic");
 
-       if (vlan > 4095)
+       if (vlan > 4095 || vind > 63)
                return IXGBE_ERR_PARAM;
 
        /* If VT Mode is set
@@ -3934,91 +4017,68 @@ s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
         *   Or !vlan_on
         *     clear the pool bit and possibly the vind
         */
-       vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
-       if (vt & IXGBE_VT_CTL_VT_ENABLE) {
-               s32 vlvf_index;
-               u32 bits;
-
-               vlvf_index = ixgbe_find_vlvf_slot(hw, vlan);
-               if (vlvf_index < 0)
-                       return vlvf_index;
-
-               if (vlan_on) {
-                       /* set the pool bit */
-                       if (vind < 32) {
-                               bits = IXGBE_READ_REG(hw,
-                                               IXGBE_VLVFB(vlvf_index * 2));
-                               bits |= (1 << vind);
-                               IXGBE_WRITE_REG(hw,
-                                               IXGBE_VLVFB(vlvf_index * 2),
-                                               bits);
-                       } else {
-                               bits = IXGBE_READ_REG(hw,
-                                       IXGBE_VLVFB((vlvf_index * 2) + 1));
-                               bits |= (1 << (vind - 32));
-                               IXGBE_WRITE_REG(hw,
-                                       IXGBE_VLVFB((vlvf_index * 2) + 1),
-                                       bits);
-                       }
-               } else {
-                       /* clear the pool bit */
-                       if (vind < 32) {
-                               bits = IXGBE_READ_REG(hw,
-                                               IXGBE_VLVFB(vlvf_index * 2));
-                               bits &= ~(1 << vind);
-                               IXGBE_WRITE_REG(hw,
-                                               IXGBE_VLVFB(vlvf_index * 2),
-                                               bits);
-                               bits |= IXGBE_READ_REG(hw,
-                                       IXGBE_VLVFB((vlvf_index * 2) + 1));
-                       } else {
-                               bits = IXGBE_READ_REG(hw,
-                                       IXGBE_VLVFB((vlvf_index * 2) + 1));
-                               bits &= ~(1 << (vind - 32));
-                               IXGBE_WRITE_REG(hw,
-                                       IXGBE_VLVFB((vlvf_index * 2) + 1),
-                                       bits);
-                               bits |= IXGBE_READ_REG(hw,
-                                               IXGBE_VLVFB(vlvf_index * 2));
-                       }
-               }
+       if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE))
+               return IXGBE_SUCCESS;
 
-               /*
-                * If there are still bits set in the VLVFB registers
-                * for the VLAN ID indicated we need to see if the
-                * caller is requesting that we clear the VFTA entry bit.
-                * If the caller has requested that we clear the VFTA
-                * entry bit but there are still pools/VFs using this VLAN
-                * ID entry then ignore the request.  We're not worried
-                * about the case where we're turning the VFTA VLAN ID
-                * entry bit on, only when requested to turn it off as
-                * there may be multiple pools and/or VFs using the
-                * VLAN ID entry.  In that case we cannot clear the
-                * VFTA bit until all pools/VFs using that VLAN ID have also
-                * been cleared.  This will be indicated by "bits" being
-                * zero.
+       vlvf_index = ixgbe_find_vlvf_slot(hw, vlan, vlvf_bypass);
+       if (vlvf_index < 0)
+               return vlvf_index;
+
+       bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32));
+
+       /* set the pool bit */
+       bits |= 1 << (vind % 32);
+       if (vlan_on)
+               goto vlvf_update;
+
+       /* clear the pool bit */
+       bits ^= 1 << (vind % 32);
+
+       if (!bits &&
+           !IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + 1 - vind / 32))) {
+               /* Clear VFTA first, then disable VLVF.  Otherwise
+                * we run the risk of stray packets leaking into
+                * the PF via the default pool
                 */
-               if (bits) {
-                       IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
-                                       (IXGBE_VLVF_VIEN | vlan));
-                       if ((!vlan_on) && (vfta_changed != NULL)) {
-                               /* someone wants to clear the vfta entry
-                                * but some pools/VFs are still using it.
-                                * Ignore it. */
-                               *vfta_changed = false;
-                       }
-               } else
-                       IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
+               if (*vfta_delta)
+                       IXGBE_WRITE_REG(hw, IXGBE_VFTA(vlan / 32), vfta);
+
+               /* disable VLVF and clear remaining bit from pool */
+               IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
+               IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), 0);
+
+               return IXGBE_SUCCESS;
        }
 
+       /* If there are still bits set in the VLVFB registers
+        * for the VLAN ID indicated we need to see if the
+        * caller is requesting that we clear the VFTA entry bit.
+        * If the caller has requested that we clear the VFTA
+        * entry bit but there are still pools/VFs using this VLAN
+        * ID entry then ignore the request.  We're not worried
+        * about the case where we're turning the VFTA VLAN ID
+        * entry bit on, only when requested to turn it off as
+        * there may be multiple pools and/or VFs using the
+        * VLAN ID entry.  In that case we cannot clear the
+        * VFTA bit until all pools/VFs using that VLAN ID have also
+        * been cleared.  This will be indicated by "bits" being
+        * zero.
+        */
+       *vfta_delta = 0;
+
+vlvf_update:
+       /* record pool change and enable VLAN ID if not already enabled */
+       IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), bits);
+       IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_VLVF_VIEN | vlan);
+
        return IXGBE_SUCCESS;
 }
 
 /**
- *  ixgbe_clear_vfta_generic - Clear VLAN filter table
- *  @hw: pointer to hardware structure
+ * ixgbe_clear_vfta_generic - Clear VLAN filter table
+ * @hw: pointer to hardware structure
  *
- *  Clears the VLAN filer table, and the VMDq index associated with the filter
+ * Clears the VLAN filer table, and the VMDq index associated with the filter
  **/
 s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
 {
@@ -4032,20 +4092,46 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
        for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
                IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
                IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
-               IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0);
+               IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2 + 1), 0);
        }
 
        return IXGBE_SUCCESS;
 }
 
 /**
- *  ixgbe_check_mac_link_generic - Determine link and speed status
- *  @hw: pointer to hardware structure
- *  @speed: pointer to link speed
- *  @link_up: true when link is up
- *  @link_up_wait_to_complete: bool used to wait for link up or not
+ * ixgbe_need_crosstalk_fix - Determine if we need to do cross talk fix
+ * @hw: pointer to hardware structure
+ *
+ * Contains the logic to identify if we need to verify link for the
+ * crosstalk fix
+ **/
+static bool ixgbe_need_crosstalk_fix(struct ixgbe_hw *hw)
+{
+
+       /* Does FW say we need the fix */
+       if (!hw->need_crosstalk_fix)
+               return false;
+
+       /* Only consider SFP+ PHYs i.e. media type fiber */
+       switch (hw->mac.ops.get_media_type(hw)) {
+       case ixgbe_media_type_fiber:
+       case ixgbe_media_type_fiber_qsfp:
+               break;
+       default:
+               return false;
+       }
+
+       return true;
+}
+
+/**
+ * ixgbe_check_mac_link_generic - Determine link and speed status
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @link_up: true when link is up
+ * @link_up_wait_to_complete: bool used to wait for link up or not
  *
- *  Reads the links register to determine if link is up and the current speed
+ * Reads the links register to determine if link is up and the current speed
  **/
 s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
                                 bool *link_up, bool link_up_wait_to_complete)
@@ -4055,6 +4141,35 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
 
        DEBUGFUNC("ixgbe_check_mac_link_generic");
 
+       /* If Crosstalk fix enabled do the sanity check of making sure
+        * the SFP+ cage is full.
+        */
+       if (ixgbe_need_crosstalk_fix(hw)) {
+               u32 sfp_cage_full;
+
+               switch (hw->mac.type) {
+               case ixgbe_mac_82599EB:
+                       sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
+                                       IXGBE_ESDP_SDP2;
+                       break;
+               case ixgbe_mac_X550EM_x:
+               case ixgbe_mac_X550EM_a:
+                       sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
+                                       IXGBE_ESDP_SDP0;
+                       break;
+               default:
+                       /* sanity check - No SFP+ devices here */
+                       sfp_cage_full = false;
+                       break;
+               }
+
+               if (!sfp_cage_full) {
+                       *link_up = false;
+                       *speed = IXGBE_LINK_SPEED_UNKNOWN;
+                       return IXGBE_SUCCESS;
+               }
+       }
+
        /* clear the old state */
        links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS);
 
@@ -4096,11 +4211,17 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
                break;
        case IXGBE_LINKS_SPEED_100_82599:
                *speed = IXGBE_LINK_SPEED_100_FULL;
-               if (hw->mac.type >= ixgbe_mac_X550) {
+               if (hw->mac.type == ixgbe_mac_X550) {
                        if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
                                *speed = IXGBE_LINK_SPEED_5GB_FULL;
                }
                break;
+       case IXGBE_LINKS_SPEED_10_X550EM_A:
+               *speed = IXGBE_LINK_SPEED_UNKNOWN;
+               if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
+                   hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
+                       *speed = IXGBE_LINK_SPEED_10_FULL;
+               break;
        default:
                *speed = IXGBE_LINK_SPEED_UNKNOWN;
        }
@@ -4109,14 +4230,14 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
 }
 
 /**
- *  ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from
- *  the EEPROM
- *  @hw: pointer to hardware structure
- *  @wwnn_prefix: the alternative WWNN prefix
- *  @wwpn_prefix: the alternative WWPN prefix
+ * ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from
+ * the EEPROM
+ * @hw: pointer to hardware structure
+ * @wwnn_prefix: the alternative WWNN prefix
+ * @wwpn_prefix: the alternative WWPN prefix
  *
- *  This function will read the EEPROM from the alternative SAN MAC address
- *  block to check the support for the alternative WWNN/WWPN prefix support.
+ * This function will read the EEPROM from the alternative SAN MAC address
+ * block to check the support for the alternative WWNN/WWPN prefix support.
  **/
 s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
                                 u16 *wwpn_prefix)
@@ -4167,11 +4288,11 @@ wwn_prefix_err:
 }
 
 /**
- *  ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM
- *  @hw: pointer to hardware structure
- *  @bs: the fcoe boot status
+ * ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM
+ * @hw: pointer to hardware structure
+ * @bs: the fcoe boot status
  *
- *  This function will read the FCOE boot status from the iSCSI FCOE block
+ * This function will read the FCOE boot status from the iSCSI FCOE block
  **/
 s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs)
 {
@@ -4216,52 +4337,34 @@ out:
 }
 
 /**
- *  ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing
- *  @hw: pointer to hardware structure
- *  @enable: enable or disable switch for anti-spoofing
- *  @pf: Physical Function pool - do not enable anti-spoofing for the PF
+ * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing
+ * @hw: pointer to hardware structure
+ * @enable: enable or disable switch for MAC anti-spoofing
+ * @vf: Virtual Function pool - VF Pool to set for MAC anti-spoofing
  *
  **/
-void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf)
+void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
 {
-       int j;
-       int pf_target_reg = pf >> 3;
-       int pf_target_shift = pf % 8;
-       u32 pfvfspoof = 0;
+       int vf_target_reg = vf >> 3;
+       int vf_target_shift = vf % 8;
+       u32 pfvfspoof;
 
        if (hw->mac.type == ixgbe_mac_82598EB)
                return;
 
+       pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
        if (enable)
-               pfvfspoof = IXGBE_SPOOF_MACAS_MASK;
-
-       /*
-        * PFVFSPOOF register array is size 8 with 8 bits assigned to
-        * MAC anti-spoof enables in each register array element.
-        */
-       for (j = 0; j < pf_target_reg; j++)
-               IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof);
-
-       /*
-        * The PF should be allowed to spoof so that it can support
-        * emulation mode NICs.  Do not set the bits assigned to the PF
-        */
-       pfvfspoof &= (1 << pf_target_shift) - 1;
-       IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof);
-
-       /*
-        * Remaining pools belong to the PF so they do not need to have
-        * anti-spoofing enabled.
-        */
-       for (j++; j < IXGBE_PFVFSPOOF_REG_COUNT; j++)
-               IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), 0);
+               pfvfspoof |= (1 << vf_target_shift);
+       else
+               pfvfspoof &= ~(1 << vf_target_shift);
+       IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
 }
 
 /**
- *  ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing
- *  @hw: pointer to hardware structure
- *  @enable: enable or disable switch for VLAN anti-spoofing
- *  @vf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing
+ * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing
+ * @hw: pointer to hardware structure
+ * @enable: enable or disable switch for VLAN anti-spoofing
+ * @vf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing
  *
  **/
 void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
@@ -4282,12 +4385,12 @@ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
 }
 
 /**
- *  ixgbe_get_device_caps_generic - Get additional device capabilities
- *  @hw: pointer to hardware structure
- *  @device_caps: the EEPROM word with the extra device capabilities
+ * ixgbe_get_device_caps_generic - Get additional device capabilities
+ * @hw: pointer to hardware structure
+ * @device_caps: the EEPROM word with the extra device capabilities
  *
- *  This function will read the EEPROM location for the device capabilities,
- *  and return the word through device_caps.
+ * This function will read the EEPROM location for the device capabilities,
+ * and return the word through device_caps.
  **/
 s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps)
 {
@@ -4299,8 +4402,8 @@ s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps)
 }
 
 /**
- *  ixgbe_enable_relaxed_ordering_gen2 - Enable relaxed ordering
- *  @hw: pointer to hardware structure
+ * ixgbe_enable_relaxed_ordering_gen2 - Enable relaxed ordering
+ * @hw: pointer to hardware structure
  *
  **/
 void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw)
@@ -4327,11 +4430,11 @@ void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_calculate_checksum - Calculate checksum for buffer
- *  @buffer: pointer to EEPROM
- *  @length: size of EEPROM to calculate a checksum for
- *  Calculates the checksum for some buffer on a specified length.  The
- *  checksum calculated is returned.
+ * ixgbe_calculate_checksum - Calculate checksum for buffer
+ * @buffer: pointer to EEPROM
+ * @length: size of EEPROM to calculate a checksum for
+ * Calculates the checksum for some buffer on a specified length.  The
+ * checksum calculated is returned.
  **/
 u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
 {
@@ -4350,49 +4453,45 @@ u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
 }
 
 /**
- *  ixgbe_host_interface_command - Issue command to manageability block
- *  @hw: pointer to the HW structure
- *  @buffer: contains the command to write and where the return status will
- *   be placed
- *  @length: length of buffer, must be multiple of 4 bytes
- *  @timeout: time in ms to wait for command completion
- *  @return_data: read and return data from the buffer (true) or not (false)
- *   Needed because FW structures are big endian and decoding of
- *   these fields can be 8 bit or 16 bit based on command. Decoding
- *   is not easily understood without making a table of commands.
- *   So we will leave this up to the caller to read back the data
- *   in these cases.
+ * ixgbe_hic_unlocked - Issue command to manageability block unlocked
+ * @hw: pointer to the HW structure
+ * @buffer: command to write and where the return status will be placed
+ * @length: length of buffer, must be multiple of 4 bytes
+ * @timeout: time in ms to wait for command completion
+ *
+ * Communicates with the manageability block. On success return IXGBE_SUCCESS
+ * else returns semaphore error when encountering an error acquiring
+ * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
  *
- *  Communicates with the manageability block.  On success return IXGBE_SUCCESS
- *  else return IXGBE_ERR_HOST_INTERFACE_COMMAND.
+ * This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held
+ * by the caller.
  **/
-s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
-                                u32 length, u32 timeout, bool return_data)
+s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length,
+                      u32 timeout)
 {
-       u32 hicr, i, bi, fwsts;
-       u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
-       u16 buf_len;
+       u32 hicr, i, fwsts;
        u16 dword_len;
 
-       DEBUGFUNC("ixgbe_host_interface_command");
+       DEBUGFUNC("ixgbe_hic_unlocked");
 
-       if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
+       if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
                DEBUGOUT1("Buffer length failure buffersize=%d.\n", length);
                return IXGBE_ERR_HOST_INTERFACE_COMMAND;
        }
+
        /* Set bit 9 of FWSTS clearing FW reset indication */
        fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS);
        IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI);
 
        /* Check that the host interface is enabled. */
        hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
-       if ((hicr & IXGBE_HICR_EN) == 0) {
+       if (!(hicr & IXGBE_HICR_EN)) {
                DEBUGOUT("IXGBE_HOST_EN bit disabled.\n");
                return IXGBE_ERR_HOST_INTERFACE_COMMAND;
        }
 
        /* Calculate length in DWORDs. We must be DWORD aligned */
-       if ((length % (sizeof(u32))) != 0) {
+       if (length % sizeof(u32)) {
                DEBUGOUT("Buffer length failure, not aligned to dword");
                return IXGBE_ERR_INVALID_ARGUMENT;
        }
@@ -4416,16 +4515,70 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
                msec_delay(1);
        }
 
+       /* For each command except "Apply Update" perform
+        * status checks in the HICR registry.
+        */
+       if ((buffer[0] & IXGBE_HOST_INTERFACE_MASK_CMD) ==
+           IXGBE_HOST_INTERFACE_APPLY_UPDATE_CMD)
+               return IXGBE_SUCCESS;
+
        /* Check command completion */
-       if ((timeout != 0 && i == timeout) ||
+       if ((timeout && i == timeout) ||
            !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) {
                ERROR_REPORT1(IXGBE_ERROR_CAUTION,
-                            "Command has failed with no status valid.\n");
+                             "Command has failed with no status valid.\n");
                return IXGBE_ERR_HOST_INTERFACE_COMMAND;
        }
 
+       return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_host_interface_command - Issue command to manageability block
+ * @hw: pointer to the HW structure
+ * @buffer: contains the command to write and where the return status will
+ *  be placed
+ * @length: length of buffer, must be multiple of 4 bytes
+ * @timeout: time in ms to wait for command completion
+ * @return_data: read and return data from the buffer (true) or not (false)
+ *  Needed because FW structures are big endian and decoding of
+ *  these fields can be 8 bit or 16 bit based on command. Decoding
+ *  is not easily understood without making a table of commands.
+ *  So we will leave this up to the caller to read back the data
+ *  in these cases.
+ *
+ * Communicates with the manageability block. On success return IXGBE_SUCCESS
+ * else returns semaphore error when encountering an error acquiring
+ * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
+ **/
+s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
+                                u32 length, u32 timeout, bool return_data)
+{
+       u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
+       struct ixgbe_hic_hdr *resp = (struct ixgbe_hic_hdr *)buffer;
+       u16 buf_len;
+       s32 status;
+       u32 bi;
+       u32 dword_len;
+
+       DEBUGFUNC("ixgbe_host_interface_command");
+
+       if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
+               DEBUGOUT1("Buffer length failure buffersize=%d.\n", length);
+               return IXGBE_ERR_HOST_INTERFACE_COMMAND;
+       }
+
+       /* Take management host interface semaphore */
+       status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
+       if (status)
+               return status;
+
+       status = ixgbe_hic_unlocked(hw, buffer, length, timeout);
+       if (status)
+               goto rel_out;
+
        if (!return_data)
-               return 0;
+               goto rel_out;
 
        /* Calculate length in DWORDs */
        dword_len = hdr_size >> 2;
@@ -4433,17 +4586,34 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
        /* first pull in the header so we know the buffer length */
        for (bi = 0; bi < dword_len; bi++) {
                buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
-               IXGBE_LE32_TO_CPUS(&buffer[bi]);
+               IXGBE_LE32_TO_CPUS((uintptr_t)&buffer[bi]);
        }
 
-       /* If there is any thing in data position pull it in */
-       buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len;
-       if (buf_len == 0)
-               return 0;
+       /*
+        * If there is any thing in data position pull it in
+        * Read Flash command requires reading buffer length from
+        * two byes instead of one byte
+        */
+       if (resp->cmd == IXGBE_HOST_INTERFACE_FLASH_READ_CMD ||
+           resp->cmd == IXGBE_HOST_INTERFACE_SHADOW_RAM_READ_CMD) {
+               for (; bi < dword_len + 2; bi++) {
+                       buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
+                                                         bi);
+                       IXGBE_LE32_TO_CPUS(&buffer[bi]);
+               }
+               buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3)
+                                 & 0xF00) | resp->buf_len;
+               hdr_size += (2 << 2);
+       } else {
+               buf_len = resp->buf_len;
+       }
+       if (!buf_len)
+               goto rel_out;
 
        if (length < buf_len + hdr_size) {
                DEBUGOUT("Buffer not large enough for reply message.\n");
-               return IXGBE_ERR_HOST_INTERFACE_COMMAND;
+               status = IXGBE_ERR_HOST_INTERFACE_COMMAND;
+               goto rel_out;
        }
 
        /* Calculate length in DWORDs, add 3 for odd lengths */
@@ -4452,39 +4622,40 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
        /* Pull in the rest of the buffer (bi is where we left off) */
        for (; bi <= dword_len; bi++) {
                buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
-               IXGBE_LE32_TO_CPUS(&buffer[bi]);
+               IXGBE_LE32_TO_CPUS((uintptr_t)&buffer[bi]);
        }
 
-       return 0;
+rel_out:
+       hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
+
+       return status;
 }
 
 /**
- *  ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware
- *  @hw: pointer to the HW structure
- *  @maj: driver version major number
- *  @min: driver version minor number
- *  @build: driver version build number
- *  @sub: driver version sub build number
+ * ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware
+ * @hw: pointer to the HW structure
+ * @maj: driver version major number
+ * @min: driver version minor number
+ * @build: driver version build number
+ * @sub: driver version sub build number
+ * @len: unused
+ * @driver_ver: unused
  *
- *  Sends driver version number to firmware through the manageability
- *  block.  On success return IXGBE_SUCCESS
- *  else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
- *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
+ * Sends driver version number to firmware through the manageability
+ * block.  On success return IXGBE_SUCCESS
+ * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
+ * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
  **/
 s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
-                                u8 build, u8 sub)
+                                u8 build, u8 sub, u16 len,
+                                const char *driver_ver)
 {
        struct ixgbe_hic_drv_info fw_cmd;
        int i;
        s32 ret_val = IXGBE_SUCCESS;
 
        DEBUGFUNC("ixgbe_set_fw_drv_ver_generic");
-
-       if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM)
-           != IXGBE_SUCCESS) {
-               ret_val = IXGBE_ERR_SWFW_SYNC;
-               goto out;
-       }
+       UNREFERENCED_2PARAMETER(len, driver_ver);
 
        fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
        fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN;
@@ -4495,10 +4666,10 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
        fw_cmd.ver_build = build;
        fw_cmd.ver_sub = sub;
        fw_cmd.hdr.checksum = 0;
-       fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
-                               (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
        fw_cmd.pad = 0;
        fw_cmd.pad2 = 0;
+       fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
+                               (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
 
        for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
                ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
@@ -4517,8 +4688,6 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
                break;
        }
 
-       hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
-out:
        return ret_val;
 }
 
@@ -4555,7 +4724,7 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom,
                rxpktsize <<= IXGBE_RXPBSIZE_SHIFT;
                for (; i < (num_pb / 2); i++)
                        IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
-               /* Fall through to configure remaining packet buffers */
+               /* fall through - configure remaining packet buffers */
        case PBA_STRATEGY_EQUAL:
                rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT;
                for (; i < num_pb; i++)
@@ -4656,11 +4825,10 @@ STATIC const u8 ixgbe_emc_therm_limit[4] = {
 };
 
 /**
- *  ixgbe_get_thermal_sensor_data - Gathers thermal sensor data
- *  @hw: pointer to hardware structure
- *  @data: pointer to the thermal sensor data structure
+ * ixgbe_get_thermal_sensor_data - Gathers thermal sensor data
+ * @hw: pointer to hardware structure
  *
- *  Returns the thermal sensor data structure
+ * Returns the thermal sensor data structure
  **/
 s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw)
 {
@@ -4731,11 +4899,11 @@ out:
 }
 
 /**
- *  ixgbe_init_thermal_sensor_thresh_generic - Inits thermal sensor thresholds
- *  @hw: pointer to hardware structure
+ * ixgbe_init_thermal_sensor_thresh_generic - Inits thermal sensor thresholds
+ * @hw: pointer to hardware structure
  *
- *  Inits the thermal sensor thresholds according to the NVM map
- *  and save off the threshold and location values into mac.thermal_sensor_data
+ * Inits the thermal sensor thresholds according to the NVM map
+ * and save off the threshold and location values into mac.thermal_sensor_data
  **/
 s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw)
 {
@@ -4811,6 +4979,117 @@ eeprom_err:
        return IXGBE_NOT_IMPLEMENTED;
 }
 
+/**
+ * ixgbe_get_orom_version - Return option ROM from EEPROM
+ *
+ * @hw: pointer to hardware structure
+ * @nvm_ver: pointer to output structure
+ *
+ * if valid option ROM version, nvm_ver->or_valid set to true
+ * else nvm_ver->or_valid is false.
+ **/
+void ixgbe_get_orom_version(struct ixgbe_hw *hw,
+                           struct ixgbe_nvm_version *nvm_ver)
+{
+       u16 offset, eeprom_cfg_blkh, eeprom_cfg_blkl;
+
+       nvm_ver->or_valid = false;
+       /* Option Rom may or may not be present.  Start with pointer */
+       hw->eeprom.ops.read(hw, NVM_OROM_OFFSET, &offset);
+
+       /* make sure offset is valid */
+       if ((offset == 0x0) || (offset == NVM_INVALID_PTR))
+               return;
+
+       hw->eeprom.ops.read(hw, offset + NVM_OROM_BLK_HI, &eeprom_cfg_blkh);
+       hw->eeprom.ops.read(hw, offset + NVM_OROM_BLK_LOW, &eeprom_cfg_blkl);
+
+       /* option rom exists and is valid */
+       if ((eeprom_cfg_blkl | eeprom_cfg_blkh) == 0x0 ||
+           eeprom_cfg_blkl == NVM_VER_INVALID ||
+           eeprom_cfg_blkh == NVM_VER_INVALID)
+               return;
+
+       nvm_ver->or_valid = true;
+       nvm_ver->or_major = eeprom_cfg_blkl >> NVM_OROM_SHIFT;
+       nvm_ver->or_build = (eeprom_cfg_blkl << NVM_OROM_SHIFT) |
+                           (eeprom_cfg_blkh >> NVM_OROM_SHIFT);
+       nvm_ver->or_patch = eeprom_cfg_blkh & NVM_OROM_PATCH_MASK;
+}
+
+/**
+ * ixgbe_get_oem_prod_version - Return OEM Product version
+ *
+ * @hw: pointer to hardware structure
+ * @nvm_ver: pointer to output structure
+ *
+ * if valid OEM product version, nvm_ver->oem_valid set to true
+ * else nvm_ver->oem_valid is false.
+ **/
+void ixgbe_get_oem_prod_version(struct ixgbe_hw *hw,
+                               struct ixgbe_nvm_version *nvm_ver)
+{
+       u16 rel_num, prod_ver, mod_len, cap, offset;
+
+       nvm_ver->oem_valid = false;
+       hw->eeprom.ops.read(hw, NVM_OEM_PROD_VER_PTR, &offset);
+
+       /* Return is offset to OEM Product Version block is invalid */
+       if (offset == 0x0 || offset == NVM_INVALID_PTR)
+               return;
+
+       /* Read product version block */
+       hw->eeprom.ops.read(hw, offset, &mod_len);
+       hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_CAP_OFF, &cap);
+
+       /* Return if OEM product version block is invalid */
+       if (mod_len != NVM_OEM_PROD_VER_MOD_LEN ||
+           (cap & NVM_OEM_PROD_VER_CAP_MASK) != 0x0)
+               return;
+
+       hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_OFF_L, &prod_ver);
+       hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_OFF_H, &rel_num);
+
+       /* Return if version is invalid */
+       if ((rel_num | prod_ver) == 0x0 ||
+           rel_num == NVM_VER_INVALID || prod_ver == NVM_VER_INVALID)
+               return;
+
+       nvm_ver->oem_major = prod_ver >> NVM_VER_SHIFT;
+       nvm_ver->oem_minor = prod_ver & NVM_VER_MASK;
+       nvm_ver->oem_release = rel_num;
+       nvm_ver->oem_valid = true;
+}
+
+/**
+ * ixgbe_get_etk_id - Return Etrack ID from EEPROM
+ *
+ * @hw: pointer to hardware structure
+ * @nvm_ver: pointer to output structure
+ *
+ * word read errors will return 0xFFFF
+ **/
+void ixgbe_get_etk_id(struct ixgbe_hw *hw, struct ixgbe_nvm_version *nvm_ver)
+{
+       u16 etk_id_l, etk_id_h;
+
+       if (hw->eeprom.ops.read(hw, NVM_ETK_OFF_LOW, &etk_id_l))
+               etk_id_l = NVM_VER_INVALID;
+       if (hw->eeprom.ops.read(hw, NVM_ETK_OFF_HI, &etk_id_h))
+               etk_id_h = NVM_VER_INVALID;
+
+       /* The word order for the version format is determined by high order
+        * word bit 15.
+        */
+       if ((etk_id_h & NVM_ETK_VALID) == 0) {
+               nvm_ver->etk_id = etk_id_h;
+               nvm_ver->etk_id |= (etk_id_l << NVM_ETK_SHIFT);
+       } else {
+               nvm_ver->etk_id = etk_id_l;
+               nvm_ver->etk_id |= (etk_id_h << NVM_ETK_SHIFT);
+       }
+}
+
 
 /**
  * ixgbe_dcb_get_rtrup2tc_generic - read rtrup2tc reg
@@ -4882,8 +5161,8 @@ bool ixgbe_mng_present(struct ixgbe_hw *hw)
                return false;
 
        fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw));
-       fwsm &= IXGBE_FWSM_MODE_MASK;
-       return fwsm == IXGBE_FWSM_FW_MODE_PT;
+
+       return !!(fwsm & IXGBE_FWSM_FW_MODE_PT);
 }
 
 /**
@@ -4914,12 +5193,12 @@ bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
- *  @hw: pointer to hardware structure
- *  @speed: new link speed
- *  @autoneg_wait_to_complete: true when waiting for completion is needed
+ * ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
  *
- *  Set the link speed in the MAC and/or PHY register and restarts link.
+ * Set the link speed in the MAC and/or PHY register and restarts link.
  **/
 s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                                          ixgbe_link_speed speed,
@@ -4948,14 +5227,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                speedcnt++;
                highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
 
-               /* If we already have link at this speed, just jump out */
-               status = ixgbe_check_link(hw, &link_speed, &link_up, false);
-               if (status != IXGBE_SUCCESS)
-                       return status;
-
-               if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
-                       goto out;
-
                /* Set the module link speed */
                switch (hw->phy.media_type) {
                case ixgbe_media_type_fiber:
@@ -4983,10 +5254,10 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                ixgbe_flap_tx_laser(hw);
 
                /* Wait for the controller to acquire link.  Per IEEE 802.3ap,
-                * Section 73.10.2, we may have to wait up to 500ms if KR is
+                * Section 73.10.2, we may have to wait up to 1000ms if KR is
                 * attempted.  82599 uses the same timing for 10g SFI.
                 */
-               for (i = 0; i < 5; i++) {
+               for (i = 0; i < 10; i++) {
                        /* Wait for the link partner to also set speed */
                        msec_delay(100);
 
@@ -5006,14 +5277,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
                        highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
 
-               /* If we already have link at this speed, just jump out */
-               status = ixgbe_check_link(hw, &link_speed, &link_up, false);
-               if (status != IXGBE_SUCCESS)
-                       return status;
-
-               if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
-                       goto out;
-
                /* Set the module link speed */
                switch (hw->phy.media_type) {
                case ixgbe_media_type_fiber:
@@ -5075,11 +5338,11 @@ out:
 }
 
 /**
- *  ixgbe_set_soft_rate_select_speed - Set module link speed
- *  @hw: pointer to hardware structure
- *  @speed: link speed to set
+ * ixgbe_set_soft_rate_select_speed - Set module link speed
+ * @hw: pointer to hardware structure
+ * @speed: link speed to set
  *
- *  Set module link speed via the soft rate select.
+ * Set module link speed via the soft rate select.
  */
 void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw,
                                        ixgbe_link_speed speed)