ixgbe/base: use another log macro
[dpdk.git] / lib / librte_pmd_ixgbe / ixgbe / ixgbe_common.c
index e612f6a..38a5a2a 100644 (file)
@@ -1,72 +1,63 @@
-/******************************************************************************
-
-  Copyright (c) 2001-2010, 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.
-
-******************************************************************************/
-/*$FreeBSD$*/
+/*******************************************************************************
+
+Copyright (c) 2001-2014, Intel Corporation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
 
 #include "ixgbe_common.h"
 #include "ixgbe_phy.h"
+#include "ixgbe_dcb.h"
+#include "ixgbe_dcb_82599.h"
 #include "ixgbe_api.h"
 
-static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw);
-static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw);
-static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw);
-static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw);
-static void ixgbe_standby_eeprom(struct ixgbe_hw *hw);
-static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
-                                        u16 count);
-static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count);
-static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
-static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
-static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
-
-static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
-static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
-                                        u16 *san_mac_offset);
-static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw);
-static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw);
-static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw);
-static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
-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);
-static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
-static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
-                                             u16 words, u16 *data);
-static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
-                                              u16 words, u16 *data);
-static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
-                                                 u16 offset);
-
-
-s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan);
+STATIC s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw);
+STATIC s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw);
+STATIC void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw);
+STATIC s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw);
+STATIC void ixgbe_standby_eeprom(struct ixgbe_hw *hw);
+STATIC void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
+                                       u16 count);
+STATIC u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count);
+STATIC void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
+STATIC void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
+STATIC void ixgbe_release_eeprom(struct ixgbe_hw *hw);
+
+STATIC s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
+STATIC s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
+                                        u16 *san_mac_offset);
+STATIC s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+                                            u16 words, u16 *data);
+STATIC s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+                                             u16 words, u16 *data);
+STATIC s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
+                                                u16 offset);
 
 /**
  *  ixgbe_init_ops_generic - Inits function ptrs
@@ -83,70 +74,286 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
        DEBUGFUNC("ixgbe_init_ops_generic");
 
        /* EEPROM */
-       eeprom->ops.init_params = &ixgbe_init_eeprom_params_generic;
+       eeprom->ops.init_params = ixgbe_init_eeprom_params_generic;
        /* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */
        if (eec & IXGBE_EEC_PRES) {
-               eeprom->ops.read = &ixgbe_read_eerd_generic;
-               eeprom->ops.read_buffer = &ixgbe_read_eerd_buffer_generic;
+               eeprom->ops.read = ixgbe_read_eerd_generic;
+               eeprom->ops.read_buffer = ixgbe_read_eerd_buffer_generic;
        } else {
-               eeprom->ops.read = &ixgbe_read_eeprom_bit_bang_generic;
+               eeprom->ops.read = ixgbe_read_eeprom_bit_bang_generic;
                eeprom->ops.read_buffer =
-                                &ixgbe_read_eeprom_buffer_bit_bang_generic;
+                                ixgbe_read_eeprom_buffer_bit_bang_generic;
        }
-       eeprom->ops.write = &ixgbe_write_eeprom_generic;
-       eeprom->ops.write_buffer = &ixgbe_write_eeprom_buffer_bit_bang_generic;
+       eeprom->ops.write = ixgbe_write_eeprom_generic;
+       eeprom->ops.write_buffer = ixgbe_write_eeprom_buffer_bit_bang_generic;
        eeprom->ops.validate_checksum =
-                                     &ixgbe_validate_eeprom_checksum_generic;
-       eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_generic;
-       eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_generic;
+                                     ixgbe_validate_eeprom_checksum_generic;
+       eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_generic;
+       eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_generic;
 
        /* MAC */
-       mac->ops.init_hw = &ixgbe_init_hw_generic;
+       mac->ops.init_hw = ixgbe_init_hw_generic;
        mac->ops.reset_hw = NULL;
-       mac->ops.start_hw = &ixgbe_start_hw_generic;
-       mac->ops.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic;
+       mac->ops.start_hw = ixgbe_start_hw_generic;
+       mac->ops.clear_hw_cntrs = ixgbe_clear_hw_cntrs_generic;
        mac->ops.get_media_type = NULL;
        mac->ops.get_supported_physical_layer = NULL;
-       mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_generic;
-       mac->ops.get_mac_addr = &ixgbe_get_mac_addr_generic;
-       mac->ops.stop_adapter = &ixgbe_stop_adapter_generic;
-       mac->ops.get_bus_info = &ixgbe_get_bus_info_generic;
-       mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie;
-       mac->ops.acquire_swfw_sync = &ixgbe_acquire_swfw_sync;
-       mac->ops.release_swfw_sync = &ixgbe_release_swfw_sync;
+       mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_generic;
+       mac->ops.get_mac_addr = ixgbe_get_mac_addr_generic;
+       mac->ops.stop_adapter = ixgbe_stop_adapter_generic;
+       mac->ops.get_bus_info = ixgbe_get_bus_info_generic;
+       mac->ops.set_lan_id = ixgbe_set_lan_id_multi_port_pcie;
+       mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync;
+       mac->ops.release_swfw_sync = ixgbe_release_swfw_sync;
+       mac->ops.prot_autoc_read = prot_autoc_read_generic;
+       mac->ops.prot_autoc_write = prot_autoc_write_generic;
 
        /* LEDs */
-       mac->ops.led_on = &ixgbe_led_on_generic;
-       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.led_on = ixgbe_led_on_generic;
+       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;
 
        /* RAR, Multicast, VLAN */
-       mac->ops.set_rar = &ixgbe_set_rar_generic;
-       mac->ops.clear_rar = &ixgbe_clear_rar_generic;
+       mac->ops.set_rar = ixgbe_set_rar_generic;
+       mac->ops.clear_rar = ixgbe_clear_rar_generic;
        mac->ops.insert_mac_addr = NULL;
        mac->ops.set_vmdq = NULL;
        mac->ops.clear_vmdq = NULL;
-       mac->ops.init_rx_addrs = &ixgbe_init_rx_addrs_generic;
-       mac->ops.update_uc_addr_list = &ixgbe_update_uc_addr_list_generic;
-       mac->ops.update_mc_addr_list = &ixgbe_update_mc_addr_list_generic;
-       mac->ops.enable_mc = &ixgbe_enable_mc_generic;
-       mac->ops.disable_mc = &ixgbe_disable_mc_generic;
+       mac->ops.init_rx_addrs = ixgbe_init_rx_addrs_generic;
+       mac->ops.update_uc_addr_list = ixgbe_update_uc_addr_list_generic;
+       mac->ops.update_mc_addr_list = ixgbe_update_mc_addr_list_generic;
+       mac->ops.enable_mc = ixgbe_enable_mc_generic;
+       mac->ops.disable_mc = ixgbe_disable_mc_generic;
        mac->ops.clear_vfta = NULL;
        mac->ops.set_vfta = NULL;
+       mac->ops.set_vlvf = NULL;
        mac->ops.init_uta_tables = NULL;
+       mac->ops.enable_rx = ixgbe_enable_rx_generic;
+       mac->ops.disable_rx = ixgbe_disable_rx_generic;
 
        /* Flow Control */
-       mac->ops.fc_enable = &ixgbe_fc_enable_generic;
+       mac->ops.fc_enable = ixgbe_fc_enable_generic;
 
        /* Link */
        mac->ops.get_link_capabilities = NULL;
        mac->ops.setup_link = NULL;
        mac->ops.check_link = NULL;
+       mac->ops.dmac_config = NULL;
+       mac->ops.dmac_update_tcs = NULL;
+       mac->ops.dmac_config_tcs = NULL;
 
        return IXGBE_SUCCESS;
 }
 
+/**
+ * ixgbe_device_supports_autoneg_fc - Check if device supports autonegotiation
+ * of flow control
+ * @hw: pointer to hardware structure
+ *
+ * This function returns true if the device supports flow control
+ * autonegotiation, and false if it does not.
+ *
+ **/
+bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
+{
+       bool supported = false;
+       ixgbe_link_speed speed;
+       bool link_up;
+
+       DEBUGFUNC("ixgbe_device_supports_autoneg_fc");
+
+       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 ?
+                               true : false;
+               else
+                       supported = true;
+               break;
+       case ixgbe_media_type_backplane:
+               supported = true;
+               break;
+       case ixgbe_media_type_copper:
+               /* only some copper devices support flow control autoneg */
+               switch (hw->device_id) {
+               case IXGBE_DEV_ID_82599_T3_LOM:
+               case IXGBE_DEV_ID_X540T:
+               case IXGBE_DEV_ID_X540T1:
+               case IXGBE_DEV_ID_X550T:
+                       supported = true;
+                       break;
+               default:
+                       supported = false;
+               }
+       default:
+               break;
+       }
+
+       ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED,
+                     "Device %x does not support flow control autoneg",
+                     hw->device_id);
+       return supported;
+}
+
+/**
+ *  ixgbe_setup_fc - Set up flow control
+ *  @hw: pointer to hardware structure
+ *
+ *  Called at init time to set up flow control.
+ **/
+STATIC s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
+{
+       s32 ret_val = IXGBE_SUCCESS;
+       u32 reg = 0, reg_bp = 0;
+       u16 reg_cu = 0;
+       bool locked = false;
+
+       DEBUGFUNC("ixgbe_setup_fc");
+
+       /* Validate the requested mode */
+       if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
+               ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
+                          "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
+               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+               goto out;
+       }
+
+       /*
+        * 10gig parts do not have a word in the EEPROM to determine the
+        * default flow control setting, so we explicitly set it to full.
+        */
+       if (hw->fc.requested_mode == ixgbe_fc_default)
+               hw->fc.requested_mode = ixgbe_fc_full;
+
+       /*
+        * Set up the 1G and 10G flow control advertisement registers so the
+        * HW will be able to do fc autoneg once the cable is plugged in.  If
+        * we link at 10G, the 1G advertisement is harmless and vice versa.
+        */
+       switch (hw->phy.media_type) {
+       case ixgbe_media_type_backplane:
+               /* some MAC's need RMW protection on AUTOC */
+               ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &reg_bp);
+               if (ret_val != IXGBE_SUCCESS)
+                       goto out;
+
+               /* only backplane uses autoc so fall though */
+       case ixgbe_media_type_fiber_qsfp:
+       case ixgbe_media_type_fiber:
+               reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+
+               break;
+       case ixgbe_media_type_copper:
+               hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
+                                    IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg_cu);
+               break;
+       default:
+               break;
+       }
+
+       /*
+        * The possible values of fc.requested_mode are:
+        * 0: Flow control is completely disabled
+        * 1: Rx flow control is enabled (we can receive pause frames,
+        *    but not send pause frames).
+        * 2: Tx flow control is enabled (we can send pause frames but
+        *    we do not support receiving pause frames).
+        * 3: Both Rx and Tx flow control (symmetric) are enabled.
+        * other: Invalid.
+        */
+       switch (hw->fc.requested_mode) {
+       case ixgbe_fc_none:
+               /* Flow control completely disabled by software override. */
+               reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+               if (hw->phy.media_type == ixgbe_media_type_backplane)
+                       reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE |
+                                   IXGBE_AUTOC_ASM_PAUSE);
+               else if (hw->phy.media_type == ixgbe_media_type_copper)
+                       reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
+               break;
+       case ixgbe_fc_tx_pause:
+               /*
+                * Tx Flow control is enabled, and Rx Flow control is
+                * disabled by software override.
+                */
+               reg |= IXGBE_PCS1GANA_ASM_PAUSE;
+               reg &= ~IXGBE_PCS1GANA_SYM_PAUSE;
+               if (hw->phy.media_type == ixgbe_media_type_backplane) {
+                       reg_bp |= IXGBE_AUTOC_ASM_PAUSE;
+                       reg_bp &= ~IXGBE_AUTOC_SYM_PAUSE;
+               } else if (hw->phy.media_type == ixgbe_media_type_copper) {
+                       reg_cu |= IXGBE_TAF_ASM_PAUSE;
+                       reg_cu &= ~IXGBE_TAF_SYM_PAUSE;
+               }
+               break;
+       case ixgbe_fc_rx_pause:
+               /*
+                * Rx Flow control is enabled and Tx Flow control is
+                * disabled by software override. Since there really
+                * isn't a way to advertise that we are capable of RX
+                * Pause ONLY, we will advertise that we support both
+                * symmetric and asymmetric Rx PAUSE, as such we fall
+                * through to the fc_full statement.  Later, we will
+                * disable the adapter's ability to send PAUSE frames.
+                */
+       case ixgbe_fc_full:
+               /* Flow control (both Rx and Tx) is enabled by SW override. */
+               reg |= IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE;
+               if (hw->phy.media_type == ixgbe_media_type_backplane)
+                       reg_bp |= IXGBE_AUTOC_SYM_PAUSE |
+                                 IXGBE_AUTOC_ASM_PAUSE;
+               else if (hw->phy.media_type == ixgbe_media_type_copper)
+                       reg_cu |= IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE;
+               break;
+       default:
+               ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
+                            "Flow control param set incorrectly\n");
+               ret_val = IXGBE_ERR_CONFIG;
+               goto out;
+               break;
+       }
+
+       if (hw->mac.type < ixgbe_mac_X540) {
+               /*
+                * Enable auto-negotiation between the MAC & PHY;
+                * the MAC will advertise clause 37 flow control.
+                */
+               IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
+               reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
+
+               /* Disable AN timeout */
+               if (hw->fc.strict_ieee)
+                       reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
+
+               IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
+               DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg);
+       }
+
+       /*
+        * AUTOC restart handles negotiation of 1G and 10G on backplane
+        * and copper. There is no need to set the PCS1GCTL register.
+        *
+        */
+       if (hw->phy.media_type == ixgbe_media_type_backplane) {
+               reg_bp |= IXGBE_AUTOC_AN_RESTART;
+               ret_val = hw->mac.ops.prot_autoc_write(hw, reg_bp, locked);
+               if (ret_val)
+                       goto out;
+       } else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
+                   (ixgbe_device_supports_autoneg_fc(hw))) {
+               hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
+                                     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu);
+       }
+
+       DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg);
+out:
+       return ret_val;
+}
+
 /**
  *  ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
  *  @hw: pointer to hardware structure
@@ -158,6 +365,7 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
  **/
 s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
 {
+       s32 ret_val;
        u32 ctrl_ext;
 
        DEBUGFUNC("ixgbe_start_hw_generic");
@@ -180,12 +388,15 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
        IXGBE_WRITE_FLUSH(hw);
 
        /* Setup flow control */
-       ixgbe_setup_fc(hw, 0);
+       ret_val = ixgbe_setup_fc(hw);
+       if (ret_val != IXGBE_SUCCESS)
+               goto out;
 
        /* Clear adapter stopped flag */
-       hw->adapter_stopped = FALSE;
+       hw->adapter_stopped = false;
 
-       return IXGBE_SUCCESS;
+out:
+       return ret_val;
 }
 
 /**
@@ -213,14 +424,14 @@ s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
        /* Disable relaxed ordering */
        for (i = 0; i < hw->mac.max_tx_queues; i++) {
                regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
-               regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+               regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
                IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
        }
 
        for (i = 0; i < hw->mac.max_rx_queues; i++) {
                regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
-               regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
-                                       IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+               regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
+                           IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
                IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
        }
 
@@ -352,13 +563,17 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
                }
        }
 
-       if (hw->mac.type == ixgbe_mac_X540) {
+       if (hw->mac.type == ixgbe_mac_X550 || hw->mac.type == ixgbe_mac_X540) {
                if (hw->phy.id == 0)
                        ixgbe_identify_phy(hw);
-               hw->phy.ops.read_reg(hw, 0x3, IXGBE_PCRC8ECL, &i);
-               hw->phy.ops.read_reg(hw, 0x3, IXGBE_PCRC8ECH, &i);
-               hw->phy.ops.read_reg(hw, 0x3, IXGBE_LDPCECL, &i);
-               hw->phy.ops.read_reg(hw, 0x3, IXGBE_LDPCECH, &i);
+               hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECL,
+                                    IXGBE_MDIO_PCS_DEV_TYPE, &i);
+               hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECH,
+                                    IXGBE_MDIO_PCS_DEV_TYPE, &i);
+               hw->phy.ops.read_reg(hw, IXGBE_LDPCECL,
+                                    IXGBE_MDIO_PCS_DEV_TYPE, &i);
+               hw->phy.ops.read_reg(hw, IXGBE_LDPCECH,
+                                    IXGBE_MDIO_PCS_DEV_TYPE, &i);
        }
 
        return IXGBE_SUCCESS;
@@ -373,7 +588,7 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
  *  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)
+                                 u32 pba_num_size)
 {
        s32 ret_val;
        u16 data;
@@ -509,6 +724,195 @@ s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
        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
+ *
+ *  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,
+                      u32 eeprom_buf_size, u16 max_pba_block_size,
+                      struct ixgbe_pba *pba)
+{
+       s32 ret_val;
+       u16 pba_block_size;
+
+       if (pba == NULL)
+               return IXGBE_ERR_PARAM;
+
+       if (eeprom_buf == NULL) {
+               ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2,
+                                                    &pba->word[0]);
+               if (ret_val)
+                       return ret_val;
+       } else {
+               if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
+                       pba->word[0] = eeprom_buf[IXGBE_PBANUM0_PTR];
+                       pba->word[1] = eeprom_buf[IXGBE_PBANUM1_PTR];
+               } else {
+                       return IXGBE_ERR_PARAM;
+               }
+       }
+
+       if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) {
+               if (pba->pba_block == NULL)
+                       return IXGBE_ERR_PARAM;
+
+               ret_val = ixgbe_get_pba_block_size(hw, eeprom_buf,
+                                                  eeprom_buf_size,
+                                                  &pba_block_size);
+               if (ret_val)
+                       return ret_val;
+
+               if (pba_block_size > max_pba_block_size)
+                       return IXGBE_ERR_PARAM;
+
+               if (eeprom_buf == NULL) {
+                       ret_val = hw->eeprom.ops.read_buffer(hw, pba->word[1],
+                                                            pba_block_size,
+                                                            pba->pba_block);
+                       if (ret_val)
+                               return ret_val;
+               } else {
+                       if (eeprom_buf_size > (u32)(pba->word[1] +
+                                             pba_block_size)) {
+                               memcpy(pba->pba_block,
+                                      &eeprom_buf[pba->word[1]],
+                                      pba_block_size * sizeof(u16));
+                       } else {
+                               return IXGBE_ERR_PARAM;
+                       }
+               }
+       }
+
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  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.
+ *
+ **/
+s32 ixgbe_write_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
+                       u32 eeprom_buf_size, struct ixgbe_pba *pba)
+{
+       s32 ret_val;
+
+       if (pba == NULL)
+               return IXGBE_ERR_PARAM;
+
+       if (eeprom_buf == NULL) {
+               ret_val = hw->eeprom.ops.write_buffer(hw, IXGBE_PBANUM0_PTR, 2,
+                                                     &pba->word[0]);
+               if (ret_val)
+                       return ret_val;
+       } else {
+               if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
+                       eeprom_buf[IXGBE_PBANUM0_PTR] = pba->word[0];
+                       eeprom_buf[IXGBE_PBANUM1_PTR] = pba->word[1];
+               } else {
+                       return IXGBE_ERR_PARAM;
+               }
+       }
+
+       if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) {
+               if (pba->pba_block == NULL)
+                       return IXGBE_ERR_PARAM;
+
+               if (eeprom_buf == NULL) {
+                       ret_val = hw->eeprom.ops.write_buffer(hw, pba->word[1],
+                                                             pba->pba_block[0],
+                                                             pba->pba_block);
+                       if (ret_val)
+                               return ret_val;
+               } else {
+                       if (eeprom_buf_size > (u32)(pba->word[1] +
+                                             pba->pba_block[0])) {
+                               memcpy(&eeprom_buf[pba->word[1]],
+                                      pba->pba_block,
+                                      pba->pba_block[0] * sizeof(u16));
+                       } else {
+                               return IXGBE_ERR_PARAM;
+                       }
+               }
+       }
+
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  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.
+ *
+ **/
+s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf,
+                            u32 eeprom_buf_size, u16 *pba_block_size)
+{
+       s32 ret_val;
+       u16 pba_word[2];
+       u16 length;
+
+       DEBUGFUNC("ixgbe_get_pba_block_size");
+
+       if (eeprom_buf == NULL) {
+               ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2,
+                                                    &pba_word[0]);
+               if (ret_val)
+                       return ret_val;
+       } else {
+               if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
+                       pba_word[0] = eeprom_buf[IXGBE_PBANUM0_PTR];
+                       pba_word[1] = eeprom_buf[IXGBE_PBANUM1_PTR];
+               } else {
+                       return IXGBE_ERR_PARAM;
+               }
+       }
+
+       if (pba_word[0] == IXGBE_PBANUM_PTR_GUARD) {
+               if (eeprom_buf == NULL) {
+                       ret_val = hw->eeprom.ops.read(hw, pba_word[1] + 0,
+                                                     &length);
+                       if (ret_val)
+                               return ret_val;
+               } else {
+                       if (eeprom_buf_size > pba_word[1])
+                               length = eeprom_buf[pba_word[1] + 0];
+                       else
+                               return IXGBE_ERR_PARAM;
+               }
+
+               if (length == 0xFFFF || length == 0)
+                       return IXGBE_ERR_PBA_SECTION;
+       } else {
+               /* PBA number in legacy format, there is no PBA Block. */
+               length = 0;
+       }
+
+       if (pba_block_size != NULL)
+               *pba_block_size = length;
+
+       return IXGBE_SUCCESS;
+}
+
 /**
  *  ixgbe_get_mac_addr_generic - Generic get MAC address
  *  @hw: pointer to hardware structure
@@ -539,23 +943,18 @@ s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
 }
 
 /**
- *  ixgbe_get_bus_info_generic - Generic set PCI bus info
+ *  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
  *
- *  Sets 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
  **/
-s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
+void ixgbe_set_pci_config_data_generic(struct ixgbe_hw *hw, u16 link_status)
 {
        struct ixgbe_mac_info *mac = &hw->mac;
-       u16 link_status;
-
-       DEBUGFUNC("ixgbe_get_bus_info_generic");
 
        hw->bus.type = ixgbe_bus_type_pci_express;
 
-       /* Get the negotiated link width and speed from PCI config space */
-       link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS);
-
        switch (link_status & IXGBE_PCI_LINK_WIDTH) {
        case IXGBE_PCI_LINK_WIDTH_1:
                hw->bus.width = ixgbe_bus_width_pcie_x1;
@@ -581,14 +980,36 @@ s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
        case IXGBE_PCI_LINK_SPEED_5000:
                hw->bus.speed = ixgbe_bus_speed_5000;
                break;
+       case IXGBE_PCI_LINK_SPEED_8000:
+               hw->bus.speed = ixgbe_bus_speed_8000;
+               break;
        default:
                hw->bus.speed = ixgbe_bus_speed_unknown;
                break;
        }
 
        mac->ops.set_lan_id(hw);
-
-       return IXGBE_SUCCESS;
+}
+
+/**
+ *  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.
+ **/
+s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
+{
+       u16 link_status;
+
+       DEBUGFUNC("ixgbe_get_bus_info_generic");
+
+       /* Get the negotiated link width and speed from PCI config space */
+       link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS);
+
+       ixgbe_set_pci_config_data_generic(hw, link_status);
+
+       return IXGBE_SUCCESS;
 }
 
 /**
@@ -635,10 +1056,10 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
         * Set the adapter_stopped flag so other driver functions stop touching
         * the hardware
         */
-       hw->adapter_stopped = TRUE;
+       hw->adapter_stopped = true;
 
        /* Disable the receive unit */
-       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, 0);
+       ixgbe_disable_rx(hw);
 
        /* Clear interrupt mask to stop interrupts from being generated */
        IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
@@ -745,9 +1166,9 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
                         * change if a future EEPROM is not SPI.
                         */
                        eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
-                                           IXGBE_EEC_SIZE_SHIFT);
+                                           IXGBE_EEC_SIZE_SHIFT);
                        eeprom->word_size = 1 << (eeprom_size +
-                                            IXGBE_EEPROM_WORD_SIZE_SHIFT);
+                                            IXGBE_EEPROM_WORD_SIZE_SHIFT);
                }
 
                if (eec & IXGBE_EEC_ADDR_SIZE)
@@ -755,8 +1176,8 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
                else
                        eeprom->address_bits = 8;
                DEBUGOUT3("Eeprom params: type = %d, size = %d, address bits: "
-                         "%d\n", eeprom->type, eeprom->word_size,
-                         eeprom->address_bits);
+                         "%d\n", eeprom->type, eeprom->word_size,
+                         eeprom->address_bits);
        }
 
        return IXGBE_SUCCESS;
@@ -772,7 +1193,7 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
  *  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)
+                                              u16 words, u16 *data)
 {
        s32 status = IXGBE_SUCCESS;
        u16 i, count;
@@ -806,7 +1227,7 @@ s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
         */
        for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
                count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
-                       IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
+                       IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
                status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset + i,
                                                            count, &data[i]);
 
@@ -828,8 +1249,8 @@ out:
  *  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)
+STATIC s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+                                             u16 words, u16 *data)
 {
        s32 status;
        u16 word;
@@ -855,8 +1276,8 @@ static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
 
                        /*  Send the WRITE ENABLE command (8 bit opcode )  */
                        ixgbe_shift_out_eeprom_bits(hw,
-                                                  IXGBE_EEPROM_WREN_OPCODE_SPI,
-                                                  IXGBE_EEPROM_OPCODE_BITS);
+                                                  IXGBE_EEPROM_WREN_OPCODE_SPI,
+                                                  IXGBE_EEPROM_OPCODE_BITS);
 
                        ixgbe_standby_eeprom(hw);
 
@@ -870,9 +1291,9 @@ static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
 
                        /* Send the Write command (8-bit opcode + addr) */
                        ixgbe_shift_out_eeprom_bits(hw, write_opcode,
-                                                   IXGBE_EEPROM_OPCODE_BITS);
+                                                   IXGBE_EEPROM_OPCODE_BITS);
                        ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
-                                                   hw->eeprom.address_bits);
+                                                   hw->eeprom.address_bits);
 
                        page_size = hw->eeprom.word_page_size;
 
@@ -939,7 +1360,7 @@ out:
  *  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)
+                                             u16 words, u16 *data)
 {
        s32 status = IXGBE_SUCCESS;
        u16 i, count;
@@ -965,10 +1386,10 @@ s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
         */
        for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
                count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
-                       IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
+                       IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
 
                status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i,
-                                                          count, &data[i]);
+                                                          count, &data[i]);
 
                if (status != IXGBE_SUCCESS)
                        break;
@@ -987,8 +1408,8 @@ out:
  *
  *  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)
+STATIC s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+                                            u16 words, u16 *data)
 {
        s32 status;
        u16 word_in;
@@ -1020,9 +1441,9 @@ static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
 
                        /* Send the READ command (opcode + addr) */
                        ixgbe_shift_out_eeprom_bits(hw, read_opcode,
-                                                   IXGBE_EEPROM_OPCODE_BITS);
+                                                   IXGBE_EEPROM_OPCODE_BITS);
                        ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
-                                                   hw->eeprom.address_bits);
+                                                   hw->eeprom.address_bits);
 
                        /* Read the data. */
                        word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
@@ -1045,7 +1466,7 @@ static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
  *  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)
+                                      u16 *data)
 {
        s32 status;
 
@@ -1074,7 +1495,7 @@ out:
  *  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)
+                                  u16 words, u16 *data)
 {
        u32 eerd;
        s32 status = IXGBE_SUCCESS;
@@ -1086,16 +1507,18 @@ s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
 
        if (words == 0) {
                status = IXGBE_ERR_INVALID_ARGUMENT;
+               ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words");
                goto out;
        }
 
        if (offset >= hw->eeprom.word_size) {
                status = IXGBE_ERR_EEPROM;
+               ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset");
                goto out;
        }
 
        for (i = 0; i < words; i++) {
-               eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) +
+               eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
                       IXGBE_EEPROM_RW_REG_START;
 
                IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
@@ -1103,7 +1526,7 @@ s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
 
                if (status == IXGBE_SUCCESS) {
                        data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
-                                IXGBE_EEPROM_RW_REG_DATA);
+                                  IXGBE_EEPROM_RW_REG_DATA);
                } else {
                        DEBUGOUT("Eeprom read timed out\n");
                        goto out;
@@ -1122,8 +1545,8 @@ out:
  *  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)
+STATIC s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
+                                                u16 offset)
 {
        u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX];
        s32 status = IXGBE_SUCCESS;
@@ -1136,7 +1559,7 @@ static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
 
        hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX;
        status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset,
-                                            IXGBE_EEPROM_PAGE_SIZE_MAX, data);
+                                            IXGBE_EEPROM_PAGE_SIZE_MAX, data);
        hw->eeprom.word_page_size = 0;
        if (status != IXGBE_SUCCESS)
                goto out;
@@ -1152,7 +1575,7 @@ static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
        hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
 
        DEBUGOUT1("Detected EEPROM page size = %d words.",
-                 hw->eeprom.word_page_size);
+                 hw->eeprom.word_page_size);
 out:
        return status;
 }
@@ -1180,7 +1603,7 @@ s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
  *  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)
+                                   u16 words, u16 *data)
 {
        u32 eewr;
        s32 status = IXGBE_SUCCESS;
@@ -1192,18 +1615,20 @@ s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
 
        if (words == 0) {
                status = IXGBE_ERR_INVALID_ARGUMENT;
+               ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words");
                goto out;
        }
 
        if (offset >= hw->eeprom.word_size) {
                status = IXGBE_ERR_EEPROM;
+               ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset");
                goto out;
        }
 
        for (i = 0; i < words; i++) {
                eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
-                      (data[i] << IXGBE_EEPROM_RW_REG_DATA) |
-                      IXGBE_EEPROM_RW_REG_START;
+                       (data[i] << IXGBE_EEPROM_RW_REG_DATA) |
+                       IXGBE_EEPROM_RW_REG_START;
 
                status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
                if (status != IXGBE_SUCCESS) {
@@ -1265,6 +1690,11 @@ s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
                }
                usec_delay(5);
        }
+
+       if (i == IXGBE_EERD_EEWR_ATTEMPTS)
+               ERROR_REPORT1(IXGBE_ERROR_POLLING,
+                            "EEPROM read/write done polling timed out");
+
        return status;
 }
 
@@ -1275,7 +1705,7 @@ s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
  *  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)
+STATIC s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
 {
        s32 status = IXGBE_SUCCESS;
        u32 eec;
@@ -1329,7 +1759,7 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
  *
  *  Sets the hardware semaphores so EEPROM access can occur for bit-bang method
  **/
-static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
+STATIC s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
 {
        s32 status = IXGBE_ERR_EEPROM;
        u32 timeout = 2000;
@@ -1355,7 +1785,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
 
        if (i == timeout) {
                DEBUGOUT("Driver can't access the Eeprom - SMBI Semaphore "
-                        "not granted.\n");
+                        "not granted.\n");
                /*
                 * this release is particularly important because our attempts
                 * above to get the semaphore may have succeeded, and if there
@@ -1400,14 +1830,15 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
                 * was not granted because we don't have access to the EEPROM
                 */
                if (i >= timeout) {
-                       DEBUGOUT("SWESMBI Software EEPROM semaphore "
-                                "not granted.\n");
+                       ERROR_REPORT1(IXGBE_ERROR_POLLING,
+                           "SWESMBI Software EEPROM semaphore not granted.\n");
                        ixgbe_release_eeprom_semaphore(hw);
                        status = IXGBE_ERR_EEPROM;
                }
        } else {
-               DEBUGOUT("Software semaphore SMBI between device drivers "
-                        "not granted.\n");
+               ERROR_REPORT1(IXGBE_ERROR_POLLING,
+                            "Software semaphore SMBI between device drivers "
+                            "not granted.\n");
        }
 
        return status;
@@ -1419,7 +1850,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
  *
  *  This function clears hardware semaphore bits.
  **/
-static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
+STATIC void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
 {
        u32 swsm;
 
@@ -1437,7 +1868,7 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
  *  ixgbe_ready_eeprom - Polls for EEPROM ready
  *  @hw: pointer to hardware structure
  **/
-static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
+STATIC s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
 {
        s32 status = IXGBE_SUCCESS;
        u16 i;
@@ -1453,7 +1884,7 @@ static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
         */
        for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) {
                ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI,
-                                           IXGBE_EEPROM_OPCODE_BITS);
+                                           IXGBE_EEPROM_OPCODE_BITS);
                spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8);
                if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI))
                        break;
@@ -1478,7 +1909,7 @@ static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
  *  ixgbe_standby_eeprom - Returns EEPROM to a "standby" state
  *  @hw: pointer to hardware structure
  **/
-static void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
+STATIC void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
 {
        u32 eec;
 
@@ -1503,8 +1934,8 @@ static void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
  *  @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)
+STATIC void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
+                                       u16 count)
 {
        u32 eec;
        u32 mask;
@@ -1558,7 +1989,7 @@ 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
  **/
-static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
+STATIC u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
 {
        u32 eec;
        u32 i;
@@ -1598,7 +2029,7 @@ static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
  *  @hw: pointer to hardware structure
  *  @eec: EEC register's current value
  **/
-static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
+STATIC void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
 {
        DEBUGFUNC("ixgbe_raise_eeprom_clk");
 
@@ -1617,7 +2048,7 @@ static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
  *  @hw: pointer to hardware structure
  *  @eecd: EECD's current value
  **/
-static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
+STATIC void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
 {
        DEBUGFUNC("ixgbe_lower_eeprom_clk");
 
@@ -1635,7 +2066,7 @@ static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
  *  ixgbe_release_eeprom - Release EEPROM, release semaphores
  *  @hw: pointer to hardware structure
  **/
-static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
+STATIC void ixgbe_release_eeprom(struct ixgbe_hw *hw)
 {
        u32 eec;
 
@@ -1664,8 +2095,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
+ *
+ *  Returns a negative error code on error, or the 16-bit checksum
  **/
-u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
+s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
 {
        u16 i;
        u16 j;
@@ -1678,33 +2111,44 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
 
        /* Include 0x0-0x3F in the checksum */
        for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
-               if (hw->eeprom.ops.read(hw, i, &word) != IXGBE_SUCCESS) {
+               if (hw->eeprom.ops.read(hw, i, &word)) {
                        DEBUGOUT("EEPROM read failed\n");
-                       break;
+                       return IXGBE_ERR_EEPROM;
                }
                checksum += word;
        }
 
        /* Include all data from pointers except for the fw pointer */
        for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
-               hw->eeprom.ops.read(hw, i, &pointer);
+               if (hw->eeprom.ops.read(hw, i, &pointer)) {
+                       DEBUGOUT("EEPROM read failed\n");
+                       return IXGBE_ERR_EEPROM;
+               }
 
-               /* Make sure the pointer seems valid */
-               if (pointer != 0xFFFF && pointer != 0) {
-                       hw->eeprom.ops.read(hw, pointer, &length);
+               /* If the pointer seems invalid */
+               if (pointer == 0xFFFF || pointer == 0)
+                       continue;
+
+               if (hw->eeprom.ops.read(hw, pointer, &length)) {
+                       DEBUGOUT("EEPROM read failed\n");
+                       return IXGBE_ERR_EEPROM;
+               }
 
-                       if (length != 0xFFFF && length != 0) {
-                               for (j = pointer+1; j <= pointer+length; j++) {
-                                       hw->eeprom.ops.read(hw, j, &word);
-                                       checksum += word;
-                               }
+               if (length == 0xFFFF || length == 0)
+                       continue;
+
+               for (j = pointer + 1; j <= pointer + length; j++) {
+                       if (hw->eeprom.ops.read(hw, j, &word)) {
+                               DEBUGOUT("EEPROM read failed\n");
+                               return IXGBE_ERR_EEPROM;
                        }
+                       checksum += word;
                }
        }
 
        checksum = (u16)IXGBE_EEPROM_SUM - checksum;
 
-       return checksum;
+       return (s32)checksum;
 }
 
 /**
@@ -1716,7 +2160,7 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
  *  caller does not need checksum_val, the value can be NULL.
  **/
 s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
-                                           u16 *checksum_val)
+                                          u16 *checksum_val)
 {
        s32 status;
        u16 checksum;
@@ -1724,32 +2168,38 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
 
        DEBUGFUNC("ixgbe_validate_eeprom_checksum_generic");
 
-       /*
-        * Read the first word from the EEPROM. If this times out or fails, do
+       /* Read the first word from the EEPROM. If this times out or fails, do
         * not continue or we could be in for a very long wait while every
         * EEPROM read fails
         */
        status = hw->eeprom.ops.read(hw, 0, &checksum);
+       if (status) {
+               DEBUGOUT("EEPROM read failed\n");
+               return status;
+       }
 
-       if (status == IXGBE_SUCCESS) {
-               checksum = hw->eeprom.ops.calc_checksum(hw);
-
-               hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
+       status = hw->eeprom.ops.calc_checksum(hw);
+       if (status < 0)
+               return status;
 
-               /*
-                * Verify read checksum from EEPROM is the same as
-                * calculated checksum
-                */
-               if (read_checksum != checksum)
-                       status = IXGBE_ERR_EEPROM_CHECKSUM;
+       checksum = (u16)(status & 0xffff);
 
-               /* If the user cares, return the calculated checksum */
-               if (checksum_val)
-                       *checksum_val = checksum;
-       } else {
+       status = hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
+       if (status) {
                DEBUGOUT("EEPROM read failed\n");
+               return status;
        }
 
+       /* Verify read checksum from EEPROM is the same as
+        * calculated checksum
+        */
+       if (read_checksum != checksum)
+               status = IXGBE_ERR_EEPROM_CHECKSUM;
+
+       /* If the user cares, return the calculated checksum */
+       if (checksum_val)
+               *checksum_val = checksum;
+
        return status;
 }
 
@@ -1764,21 +2214,24 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
 
        DEBUGFUNC("ixgbe_update_eeprom_checksum_generic");
 
-       /*
-        * Read the first word from the EEPROM. If this times out or fails, do
+       /* Read the first word from the EEPROM. If this times out or fails, do
         * not continue or we could be in for a very long wait while every
         * EEPROM read fails
         */
        status = hw->eeprom.ops.read(hw, 0, &checksum);
-
-       if (status == IXGBE_SUCCESS) {
-               checksum = hw->eeprom.ops.calc_checksum(hw);
-               status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
-                                             checksum);
-       } else {
+       if (status) {
                DEBUGOUT("EEPROM read failed\n");
+               return status;
        }
 
+       status = hw->eeprom.ops.calc_checksum(hw);
+       if (status < 0)
+               return status;
+
+       checksum = (u16)(status & 0xffff);
+
+       status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum);
+
        return status;
 }
 
@@ -1804,7 +2257,7 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr)
                status = IXGBE_ERR_INVALID_MAC_ADDR;
        /* Reject the zero address */
        } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
-                  mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
+                  mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
                DEBUGOUT("MAC address is all zeros\n");
                status = IXGBE_ERR_INVALID_MAC_ADDR;
        }
@@ -1822,7 +2275,7 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr)
  *  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)
+                         u32 enable_addr)
 {
        u32 rar_low, rar_high;
        u32 rar_entries = hw->mac.num_rar_entries;
@@ -1831,7 +2284,8 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
 
        /* Make sure we are using a valid rar index range */
        if (index >= rar_entries) {
-               DEBUGOUT1("RAR index %d is out of range.\n", index);
+               ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
+                            "RAR index %d is out of range.\n", index);
                return IXGBE_ERR_INVALID_ARGUMENT;
        }
 
@@ -1843,9 +2297,9 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
         * order from network order (big endian) to little endian
         */
        rar_low = ((u32)addr[0] |
-                  ((u32)addr[1] << 8) |
-                  ((u32)addr[2] << 16) |
-                  ((u32)addr[3] << 24));
+                  ((u32)addr[1] << 8) |
+                  ((u32)addr[2] << 16) |
+                  ((u32)addr[3] << 24));
        /*
         * Some parts put the VMDq setting in the extra RAH bits,
         * so save everything except the lower 16 bits that hold part
@@ -1880,7 +2334,8 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
 
        /* Make sure we are using a valid rar index range */
        if (index >= rar_entries) {
-               DEBUGOUT1("RAR index %d is out of range.\n", index);
+               ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
+                            "RAR index %d is out of range.\n", index);
                return IXGBE_ERR_INVALID_ARGUMENT;
        }
 
@@ -1927,18 +2382,18 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
                hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
 
                DEBUGOUT3(" Keeping Current RAR0 Addr =%.2X %.2X %.2X ",
-                         hw->mac.addr[0], hw->mac.addr[1],
-                         hw->mac.addr[2]);
+                         hw->mac.addr[0], hw->mac.addr[1],
+                         hw->mac.addr[2]);
                DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3],
-                         hw->mac.addr[4], hw->mac.addr[5]);
+                         hw->mac.addr[4], hw->mac.addr[5]);
        } else {
                /* Setup the receive address. */
                DEBUGOUT("Overriding MAC Address in RAR[0]\n");
                DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ",
-                         hw->mac.addr[0], hw->mac.addr[1],
-                         hw->mac.addr[2]);
+                         hw->mac.addr[0], hw->mac.addr[1],
+                         hw->mac.addr[2]);
                DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3],
-                         hw->mac.addr[4], hw->mac.addr[5]);
+                         hw->mac.addr[4], hw->mac.addr[5]);
 
                hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
 
@@ -1984,7 +2439,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
        DEBUGFUNC("ixgbe_add_uc_addr");
 
        DEBUGOUT6(" UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n",
-                 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+                 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
 
        /*
         * Place this address in the RAR if there is room,
@@ -2017,7 +2472,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
  *  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)
+                                     u32 addr_count, ixgbe_mc_addr_itr next)
 {
        u8 *addr;
        u32 i;
@@ -2084,7 +2539,7 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
  *  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)
+STATIC s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
 {
        u32 vector = 0;
 
@@ -2160,8 +2615,8 @@ void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
  *  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,
-                                      bool clear)
+                                     u32 mc_addr_count, ixgbe_mc_addr_itr next,
+                                     bool clear)
 {
        u32 i;
        u32 vmdq;
@@ -2194,7 +2649,7 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
 
        if (hw->addr_ctrl.mta_in_use > 0)
                IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL,
-                               IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
+                               IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
 
        DEBUGOUT("ixgbe_update_mc_addr_list_generic Complete\n");
        return IXGBE_SUCCESS;
@@ -2214,7 +2669,7 @@ s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
 
        if (a->mta_in_use > 0)
                IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
-                               hw->mac.mc_filter_type);
+                               hw->mac.mc_filter_type);
 
        return IXGBE_SUCCESS;
 }
@@ -2240,27 +2695,44 @@ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
 /**
  *  ixgbe_fc_enable_generic - Enable flow control
  *  @hw: pointer to hardware structure
- *  @packetbuf_num: packet buffer number (0-7)
  *
  *  Enable flow control according to the current settings.
  **/
-s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
+s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
 {
        s32 ret_val = IXGBE_SUCCESS;
        u32 mflcn_reg, fccfg_reg;
        u32 reg;
        u32 fcrtl, fcrth;
+       int i;
 
        DEBUGFUNC("ixgbe_fc_enable_generic");
 
-       /* Negotiate the fc mode to use */
-       ret_val = ixgbe_fc_autoneg(hw);
-       if (ret_val == IXGBE_ERR_FLOW_CONTROL)
+       /* Validate the water mark configuration */
+       if (!hw->fc.pause_time) {
+               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
                goto out;
+       }
+
+       /* Low water mark of zero causes XOFF floods */
+       for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
+               if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
+                   hw->fc.high_water[i]) {
+                       if (!hw->fc.low_water[i] ||
+                           hw->fc.low_water[i] >= hw->fc.high_water[i]) {
+                               DEBUGOUT("Invalid water mark configuration\n");
+                               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+                               goto out;
+                       }
+               }
+       }
+
+       /* Negotiate the fc mode to use */
+       ixgbe_fc_autoneg(hw);
 
        /* Disable any previous flow control settings */
        mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
-       mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE);
+       mflcn_reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE);
 
        fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
        fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
@@ -2306,7 +2778,8 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
                fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
                break;
        default:
-               DEBUGOUT("Flow control param set incorrectly\n");
+               ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
+                            "Flow control param set incorrectly\n");
                ret_val = IXGBE_ERR_CONFIG;
                goto out;
                break;
@@ -2317,95 +2790,93 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
        IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
        IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
 
-       fcrth = hw->fc.high_water[packetbuf_num] << 10;
-       fcrtl = hw->fc.low_water << 10;
 
-       if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
-               fcrth |= IXGBE_FCRTH_FCEN;
-               if (hw->fc.send_xon)
-                       fcrtl |= IXGBE_FCRTL_XONE;
-       }
+       /* Set up and enable Rx high/low water mark thresholds, enable XON. */
+       for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
+               if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
+                   hw->fc.high_water[i]) {
+                       fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
+                       IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
+                       fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
+               } else {
+                       IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
+                       /*
+                        * In order to prevent Tx hangs when the internal Tx
+                        * switch is enabled we must set the high water mark
+                        * to the Rx packet buffer size - 24KB.  This allows
+                        * the Tx switch to function even under heavy Rx
+                        * workloads.
+                        */
+                       fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576;
+               }
 
-       IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), fcrth);
-       IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), fcrtl);
+               IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), fcrth);
+       }
 
        /* Configure pause time (2 TCs per register) */
-       reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2));
-       if ((packetbuf_num & 1) == 0)
-               reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
-       else
-               reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
-       IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
+       reg = hw->fc.pause_time * 0x00010001;
+       for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
+               IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
 
-       IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+       /* Configure flow control refresh threshold value */
+       IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
 
 out:
        return ret_val;
 }
 
 /**
- *  ixgbe_fc_autoneg - Configure flow control
+ *  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
  *
- *  Compares our advertised flow control capabilities to those advertised by
- *  our link partner, and determines the proper flow control mode to use.
+ *  Find the intersection between advertised settings and link partner's
+ *  advertised settings
  **/
-s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
+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 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
-       ixgbe_link_speed speed;
-       bool link_up;
-
-       DEBUGFUNC("ixgbe_fc_autoneg");
-
-       if (hw->fc.disable_fc_autoneg)
-               goto out;
-
-       /*
-        * AN should have completed when the cable was plugged in.
-        * Look for reasons to bail out.  Bail out if:
-        * - FC autoneg is disabled, or if
-        * - link is not up.
-        *
-        * Since we're being called from an LSC, link is already known to be up.
-        * So use link_up_wait_to_complete=FALSE.
-        */
-       hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
-       if (!link_up) {
-               ret_val = IXGBE_ERR_FLOW_CONTROL;
-               goto out;
-       }
-
-       switch (hw->phy.media_type) {
-       /* Autoneg flow control on fiber adapters */
-       case ixgbe_media_type_fiber:
-               if (speed == IXGBE_LINK_SPEED_1GB_FULL)
-                       ret_val = ixgbe_fc_autoneg_fiber(hw);
-               break;
-
-       /* Autoneg flow control on backplane adapters */
-       case ixgbe_media_type_backplane:
-               ret_val = ixgbe_fc_autoneg_backplane(hw);
-               break;
-
-       /* Autoneg flow control on copper adapters */
-       case ixgbe_media_type_copper:
-               if (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS)
-                       ret_val = ixgbe_fc_autoneg_copper(hw);
-               break;
-
-       default:
-               break;
+       if ((!(adv_reg)) ||  (!(lp_reg))) {
+               ERROR_REPORT3(IXGBE_ERROR_UNSUPPORTED,
+                            "Local or link partner's advertised flow control "
+                            "settings are NULL. Local: %x, link partner: %x\n",
+                            adv_reg, lp_reg);
+               return IXGBE_ERR_FC_NOT_NEGOTIATED;
        }
 
-out:
-       if (ret_val == IXGBE_SUCCESS) {
-               hw->fc.fc_was_autonegged = TRUE;
+       if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) {
+               /*
+                * Now we need to check if the user selected Rx ONLY
+                * of pause frames.  In this case, we had to advertise
+                * FULL flow control because we could not advertise RX
+                * ONLY. Hence, we must now check to see if we need to
+                * turn OFF the TRANSMISSION of PAUSE frames.
+                */
+               if (hw->fc.requested_mode == ixgbe_fc_full) {
+                       hw->fc.current_mode = ixgbe_fc_full;
+                       DEBUGOUT("Flow Control = FULL.\n");
+               } else {
+                       hw->fc.current_mode = ixgbe_fc_rx_pause;
+                       DEBUGOUT("Flow Control=RX PAUSE frames only\n");
+               }
+       } else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) &&
+                  (lp_reg & lp_sym) && (lp_reg & lp_asm)) {
+               hw->fc.current_mode = ixgbe_fc_tx_pause;
+               DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
+       } else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) &&
+                  !(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
+               hw->fc.current_mode = ixgbe_fc_rx_pause;
+               DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
        } else {
-               hw->fc.fc_was_autonegged = FALSE;
-               hw->fc.current_mode = hw->fc.requested_mode;
+               hw->fc.current_mode = ixgbe_fc_none;
+               DEBUGOUT("Flow Control = NONE.\n");
        }
-       return ret_val;
+       return IXGBE_SUCCESS;
 }
 
 /**
@@ -2414,10 +2885,10 @@ out:
  *
  *  Enable flow control according on 1 gig fiber.
  **/
-static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
+STATIC s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
 {
        u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
-       s32 ret_val;
+       s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
 
        /*
         * On multispeed fiber at 1g, bail out if
@@ -2428,7 +2899,7 @@ static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
        linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
        if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
            (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
-               ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
+               DEBUGOUT("Auto-Negotiation did not complete or timed out\n");
                goto out;
        }
 
@@ -2436,10 +2907,10 @@ static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
        pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
 
        ret_val =  ixgbe_negotiate_fc(hw, pcs_anadv_reg,
-                              pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE,
-                              IXGBE_PCS1GANA_ASM_PAUSE,
-                              IXGBE_PCS1GANA_SYM_PAUSE,
-                              IXGBE_PCS1GANA_ASM_PAUSE);
+                                     pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE,
+                                     IXGBE_PCS1GANA_ASM_PAUSE,
+                                     IXGBE_PCS1GANA_SYM_PAUSE,
+                                     IXGBE_PCS1GANA_ASM_PAUSE);
 
 out:
        return ret_val;
@@ -2451,10 +2922,10 @@ out:
  *
  *  Enable flow control according to IEEE clause 37.
  **/
-static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
+STATIC s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
 {
        u32 links2, anlp1_reg, autoc_reg, links;
-       s32 ret_val;
+       s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
 
        /*
         * On backplane, bail out if
@@ -2463,18 +2934,14 @@ static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
         */
        links = IXGBE_READ_REG(hw, IXGBE_LINKS);
        if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) {
-               hw->fc.fc_was_autonegged = FALSE;
-               hw->fc.current_mode = hw->fc.requested_mode;
-               ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
+               DEBUGOUT("Auto-Negotiation did not complete\n");
                goto out;
        }
 
        if (hw->mac.type == ixgbe_mac_82599EB) {
                links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
                if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) {
-                       hw->fc.fc_was_autonegged = FALSE;
-                       hw->fc.current_mode = hw->fc.requested_mode;
-                       ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
+                       DEBUGOUT("Link partner is not AN enabled\n");
                        goto out;
                }
        }
@@ -2499,7 +2966,7 @@ out:
  *
  *  Enable flow control according to IEEE clause 37.
  **/
-static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw)
+STATIC s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw)
 {
        u16 technology_ability_reg = 0;
        u16 lp_technology_ability_reg = 0;
@@ -2518,227 +2985,115 @@ static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw)
 }
 
 /**
- *  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
- **/
-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)
-{
-       if ((!(adv_reg)) ||  (!(lp_reg)))
-               return IXGBE_ERR_FC_NOT_NEGOTIATED;
-
-       if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) {
-               /*
-                * Now we need to check if the user selected Rx ONLY
-                * of pause frames.  In this case, we had to advertise
-                * FULL flow control because we could not advertise RX
-                * ONLY. Hence, we must now check to see if we need to
-                * turn OFF the TRANSMISSION of PAUSE frames.
-                */
-               if (hw->fc.requested_mode == ixgbe_fc_full) {
-                       hw->fc.current_mode = ixgbe_fc_full;
-                       DEBUGOUT("Flow Control = FULL.\n");
-               } else {
-                       hw->fc.current_mode = ixgbe_fc_rx_pause;
-                       DEBUGOUT("Flow Control=RX PAUSE frames only\n");
-               }
-       } else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) &&
-                  (lp_reg & lp_sym) && (lp_reg & lp_asm)) {
-               hw->fc.current_mode = ixgbe_fc_tx_pause;
-               DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
-       } else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) &&
-                  !(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
-               hw->fc.current_mode = ixgbe_fc_rx_pause;
-               DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
-       } else {
-               hw->fc.current_mode = ixgbe_fc_none;
-               DEBUGOUT("Flow Control = NONE.\n");
-       }
-       return IXGBE_SUCCESS;
-}
-
-/**
- *  ixgbe_setup_fc - Set up flow control
+ *  ixgbe_fc_autoneg - Configure flow control
  *  @hw: pointer to hardware structure
  *
- *  Called at init time to set up flow control.
+ *  Compares our advertised flow control capabilities to those advertised by
+ *  our link partner, and determines the proper flow control mode to use.
  **/
-static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
+void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
 {
-       s32 ret_val = IXGBE_SUCCESS;
-       u32 reg = 0, reg_bp = 0;
-       u16 reg_cu = 0;
-
-       DEBUGFUNC("ixgbe_setup_fc");
+       s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
+       ixgbe_link_speed speed;
+       bool link_up;
 
-       /* Validate the packetbuf configuration */
-       if (packetbuf_num < 0 || packetbuf_num > 7) {
-               DEBUGOUT1("Invalid packet buffer number [%d], expected range "
-                         "is 0-7\n", packetbuf_num);
-               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
-               goto out;
-       }
+       DEBUGFUNC("ixgbe_fc_autoneg");
 
        /*
-        * Validate the water mark configuration.  Zero water marks are invalid
-        * because it causes the controller to just blast out fc packets.
+        * AN should have completed when the cable was plugged in.
+        * Look for reasons to bail out.  Bail out if:
+        * - FC autoneg is disabled, or if
+        * - link is not up.
         */
-       if (!hw->fc.low_water ||
-           !hw->fc.high_water[packetbuf_num] ||
-           !hw->fc.pause_time) {
-               DEBUGOUT("Invalid water mark configuration\n");
-               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+       if (hw->fc.disable_fc_autoneg) {
+               ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
+                            "Flow control autoneg is disabled");
                goto out;
        }
 
-       /*
-        * Validate the requested mode.  Strict IEEE mode does not allow
-        * ixgbe_fc_rx_pause because it will cause us to fail at UNH.
-        */
-       if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
-               DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
-               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+       hw->mac.ops.check_link(hw, &speed, &link_up, false);
+       if (!link_up) {
+               ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
                goto out;
        }
 
-       /*
-        * 10gig parts do not have a word in the EEPROM to determine the
-        * default flow control setting, so we explicitly set it to full.
-        */
-       if (hw->fc.requested_mode == ixgbe_fc_default)
-               hw->fc.requested_mode = ixgbe_fc_full;
-
-       /*
-        * Set up the 1G and 10G flow control advertisement registers so the
-        * HW will be able to do fc autoneg once the cable is plugged in.  If
-        * we link at 10G, the 1G advertisement is harmless and vice versa.
-        */
-
        switch (hw->phy.media_type) {
+       /* Autoneg flow control on fiber adapters */
+       case ixgbe_media_type_fiber_qsfp:
        case ixgbe_media_type_fiber:
+               if (speed == IXGBE_LINK_SPEED_1GB_FULL)
+                       ret_val = ixgbe_fc_autoneg_fiber(hw);
+               break;
+
+       /* Autoneg flow control on backplane adapters */
        case ixgbe_media_type_backplane:
-               reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
-               reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+               ret_val = ixgbe_fc_autoneg_backplane(hw);
                break;
 
+       /* Autoneg flow control on copper adapters */
        case ixgbe_media_type_copper:
-               hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
-                                       IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg_cu);
+               if (ixgbe_device_supports_autoneg_fc(hw))
+                       ret_val = ixgbe_fc_autoneg_copper(hw);
                break;
 
        default:
-               ;
+               break;
        }
 
-       /*
-        * The possible values of fc.requested_mode are:
-        * 0: Flow control is completely disabled
-        * 1: Rx flow control is enabled (we can receive pause frames,
-        *    but not send pause frames).
-        * 2: Tx flow control is enabled (we can send pause frames but
-        *    we do not support receiving pause frames).
-        * 3: Both Rx and Tx flow control (symmetric) are enabled.
-        * other: Invalid.
-        */
-       switch (hw->fc.requested_mode) {
-       case ixgbe_fc_none:
-               /* Flow control completely disabled by software override. */
-               reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
-               if (hw->phy.media_type == ixgbe_media_type_backplane)
-                       reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE |
-                                   IXGBE_AUTOC_ASM_PAUSE);
-               else if (hw->phy.media_type == ixgbe_media_type_copper)
-                       reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
+out:
+       if (ret_val == IXGBE_SUCCESS) {
+               hw->fc.fc_was_autonegged = true;
+       } else {
+               hw->fc.fc_was_autonegged = false;
+               hw->fc.current_mode = hw->fc.requested_mode;
+       }
+}
+
+/*
+ * ixgbe_pcie_timeout_poll - Return number of times to poll for completion
+ * @hw: pointer to hardware structure
+ *
+ * System-wide timeout range is encoded in PCIe Device Control2 register.
+ *
+ * Add 10% to specified maximum and return the number of times to poll for
+ * completion timeout, in units of 100 microsec.  Never return less than
+ * 800 = 80 millisec.
+ */
+STATIC u32 ixgbe_pcie_timeout_poll(struct ixgbe_hw *hw)
+{
+       s16 devctl2;
+       u32 pollcnt;
+
+       devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2);
+       devctl2 &= IXGBE_PCIDEVCTRL2_TIMEO_MASK;
+
+       switch (devctl2) {
+       case IXGBE_PCIDEVCTRL2_65_130ms:
+               pollcnt = 1300;         /* 130 millisec */
                break;
-       case ixgbe_fc_rx_pause:
-               /*
-                * Rx Flow control is enabled and Tx Flow control is
-                * disabled by software override. Since there really
-                * isn't a way to advertise that we are capable of RX
-                * Pause ONLY, we will advertise that we support both
-                * symmetric and asymmetric Rx PAUSE.  Later, we will
-                * disable the adapter's ability to send PAUSE frames.
-                */
-               reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
-               if (hw->phy.media_type == ixgbe_media_type_backplane)
-                       reg_bp |= (IXGBE_AUTOC_SYM_PAUSE |
-                                  IXGBE_AUTOC_ASM_PAUSE);
-               else if (hw->phy.media_type == ixgbe_media_type_copper)
-                       reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
+       case IXGBE_PCIDEVCTRL2_260_520ms:
+               pollcnt = 5200;         /* 520 millisec */
                break;
-       case ixgbe_fc_tx_pause:
-               /*
-                * Tx Flow control is enabled, and Rx Flow control is
-                * disabled by software override.
-                */
-               reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
-               reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
-               if (hw->phy.media_type == ixgbe_media_type_backplane) {
-                       reg_bp |= (IXGBE_AUTOC_ASM_PAUSE);
-                       reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE);
-               } else if (hw->phy.media_type == ixgbe_media_type_copper) {
-                       reg_cu |= (IXGBE_TAF_ASM_PAUSE);
-                       reg_cu &= ~(IXGBE_TAF_SYM_PAUSE);
-               }
+       case IXGBE_PCIDEVCTRL2_1_2s:
+               pollcnt = 20000;        /* 2 sec */
                break;
-       case ixgbe_fc_full:
-               /* Flow control (both Rx and Tx) is enabled by SW override. */
-               reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
-               if (hw->phy.media_type == ixgbe_media_type_backplane)
-                       reg_bp |= (IXGBE_AUTOC_SYM_PAUSE |
-                                  IXGBE_AUTOC_ASM_PAUSE);
-               else if (hw->phy.media_type == ixgbe_media_type_copper)
-                       reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
+       case IXGBE_PCIDEVCTRL2_4_8s:
+               pollcnt = 80000;        /* 8 sec */
+               break;
+       case IXGBE_PCIDEVCTRL2_17_34s:
+               pollcnt = 34000;        /* 34 sec */
                break;
+       case IXGBE_PCIDEVCTRL2_50_100us:        /* 100 microsecs */
+       case IXGBE_PCIDEVCTRL2_1_2ms:           /* 2 millisecs */
+       case IXGBE_PCIDEVCTRL2_16_32ms:         /* 32 millisec */
+       case IXGBE_PCIDEVCTRL2_16_32ms_def:     /* 32 millisec default */
        default:
-               DEBUGOUT("Flow control param set incorrectly\n");
-               ret_val = IXGBE_ERR_CONFIG;
-               goto out;
+               pollcnt = 800;          /* 80 millisec minimum */
                break;
        }
 
-       if (hw->mac.type != ixgbe_mac_X540) {
-               /*
-                * Enable auto-negotiation between the MAC & PHY;
-                * the MAC will advertise clause 37 flow control.
-                */
-               IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
-               reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
-
-               /* Disable AN timeout */
-               if (hw->fc.strict_ieee)
-                       reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
-
-               IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
-               DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg);
-       }
-
-       /*
-        * AUTOC restart handles negotiation of 1G and 10G on backplane
-        * and copper. There is no need to set the PCS1GCTL register.
-        *
-        */
-       if (hw->phy.media_type == ixgbe_media_type_backplane) {
-               reg_bp |= IXGBE_AUTOC_AN_RESTART;
-               IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp);
-       } else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
-                   (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS)) {
-               hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
-                                     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu);
-       }
-
-       DEBUGOUT1("Set up FC; IXGBE_AUTOC = 0x%08X\n", reg);
-out:
-       return ret_val;
+       /* add 10% to spec maximum */
+       return (pollcnt * 11) / 10;
 }
 
 /**
@@ -2753,15 +3108,17 @@ out:
 s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
 {
        s32 status = IXGBE_SUCCESS;
-       u32 i;
+       u32 i, poll;
+       u16 value;
 
        DEBUGFUNC("ixgbe_disable_pcie_master");
 
        /* Always set this bit to ensure any future transactions are blocked */
        IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS);
 
-       /* Exit if master requets are blocked */
-       if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
+       /* Exit if master requests are blocked */
+       if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) ||
+           IXGBE_REMOVED(hw->hw_addr))
                goto out;
 
        /* Poll for master request bit to clear */
@@ -2786,14 +3143,18 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
         * Before proceeding, make sure that the PCIe block does not have
         * transactions pending.
         */
-       for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
+       poll = ixgbe_pcie_timeout_poll(hw);
+       for (i = 0; i < poll; i++) {
                usec_delay(100);
-               if (!(IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS) &
-                       IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
+               value = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS);
+               if (IXGBE_REMOVED(hw->hw_addr))
+                       goto out;
+               if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
                        goto out;
        }
 
-       DEBUGOUT("PCIe transaction pending bit also did not clear.\n");
+       ERROR_REPORT1(IXGBE_ERROR_POLLING,
+                    "PCIe transaction pending bit also did not clear.\n");
        status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
 
 out:
@@ -2808,70 +3169,155 @@ out:
  *  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, u16 mask)
+s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask)
 {
-       u32 gssr;
+       u32 gssr = 0;
        u32 swmask = mask;
        u32 fwmask = mask << 5;
-       s32 timeout = 200;
+       u32 timeout = 200;
+       u32 i;
 
        DEBUGFUNC("ixgbe_acquire_swfw_sync");
 
-       while (timeout) {
+       for (i = 0; i < timeout; i++) {
                /*
-                * SW EEPROM semaphore bit is used for access to all
-                * SW_FW_SYNC/GSSR bits (not just EEPROM)
+                * SW NVM semaphore bit is used for access to all
+                * SW_FW_SYNC bits (not just NVM)
                 */
                if (ixgbe_get_eeprom_semaphore(hw))
                        return IXGBE_ERR_SWFW_SYNC;
 
                gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
-               if (!(gssr & (fwmask | swmask)))
-                       break;
-
-               /*
-                * Firmware currently using resource (fwmask) or other software
-                * thread currently using resource (swmask)
-                */
-               ixgbe_release_eeprom_semaphore(hw);
-               msec_delay(5);
-               timeout--;
+               if (!(gssr & (fwmask | swmask))) {
+                       gssr |= swmask;
+                       IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
+                       ixgbe_release_eeprom_semaphore(hw);
+                       return IXGBE_SUCCESS;
+               } else {
+                       /* Resource is currently in use by FW or SW */
+                       ixgbe_release_eeprom_semaphore(hw);
+                       msec_delay(5);
+               }
        }
 
-       if (!timeout) {
-               DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
-               return IXGBE_ERR_SWFW_SYNC;
+       /* If time expired clear the bits holding the lock and retry */
+       if (gssr & (fwmask | swmask))
+               ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask));
+
+       msec_delay(5);
+       return IXGBE_ERR_SWFW_SYNC;
+}
+
+/**
+ *  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)
+ **/
+void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask)
+{
+       u32 gssr;
+       u32 swmask = mask;
+
+       DEBUGFUNC("ixgbe_release_swfw_sync");
+
+       ixgbe_get_eeprom_semaphore(hw);
+
+       gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
+       gssr &= ~swmask;
+       IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
+
+       ixgbe_release_eeprom_semaphore(hw);
+}
+
+/**
+ *  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
+ **/
+s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw)
+{
+#define IXGBE_MAX_SECRX_POLL 40
+
+       int i;
+       int secrxreg;
+
+       DEBUGFUNC("ixgbe_disable_sec_rx_path_generic");
+
+
+       secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+       secrxreg |= IXGBE_SECRXCTRL_RX_DIS;
+       IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
+       for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) {
+               secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);
+               if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY)
+                       break;
+               else
+                       /* Use interrupt-safe sleep just in case */
+                       usec_delay(1000);
        }
 
-       gssr |= swmask;
-       IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
+       /* For informational purposes only */
+       if (i >= IXGBE_MAX_SECRX_POLL)
+               DEBUGOUT("Rx unit being enabled before security "
+                        "path fully disabled.  Continuing with init.\n");
+
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  prot_autoc_read_generic - Hides MAC differences needed for AUTOC read
+ *  @hw: pointer to hardware structure
+ *  @reg_val: Value we read from AUTOC
+ *
+ *  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)
+{
+       *locked = false;
+       *reg_val = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       return IXGBE_SUCCESS;
+}
+
+/**
+ * prot_autoc_write_generic - Hides MAC differences needed for AUTOC write
+ * @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.
+ *
+ * The default case requires no protection so just to the register write.
+ */
+s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked)
+{
+       UNREFERENCED_1PARAMETER(locked);
 
-       ixgbe_release_eeprom_semaphore(hw);
+       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_val);
        return IXGBE_SUCCESS;
 }
 
 /**
- *  ixgbe_release_swfw_sync - Release SWFW semaphore
+ *  ixgbe_enable_sec_rx_path_generic - Enables the receive data path
  *  @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)
+ *  Enables the receive data path.
  **/
-void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
+s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw)
 {
-       u32 gssr;
-       u32 swmask = mask;
-
-       DEBUGFUNC("ixgbe_release_swfw_sync");
+       int secrxreg;
 
-       ixgbe_get_eeprom_semaphore(hw);
+       DEBUGFUNC("ixgbe_enable_sec_rx_path_generic");
 
-       gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
-       gssr &= ~swmask;
-       IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
+       secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+       secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS;
+       IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
+       IXGBE_WRITE_FLUSH(hw);
 
-       ixgbe_release_eeprom_semaphore(hw);
+       return IXGBE_SUCCESS;
 }
 
 /**
@@ -2885,7 +3331,10 @@ s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
 {
        DEBUGFUNC("ixgbe_enable_rx_dma_generic");
 
-       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+       if (regval & IXGBE_RXCTRL_RXEN)
+               ixgbe_enable_rx(hw);
+       else
+               ixgbe_disable_rx(hw);
 
        return IXGBE_SUCCESS;
 }
@@ -2899,8 +3348,10 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
 {
        ixgbe_link_speed speed = 0;
        bool link_up = 0;
-       u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 autoc_reg = 0;
        u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+       s32 ret_val = IXGBE_SUCCESS;
+       bool locked = false;
 
        DEBUGFUNC("ixgbe_blink_led_start_generic");
 
@@ -2908,12 +3359,20 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
         * Link must be up to auto-blink the LEDs;
         * Force it if link is down.
         */
-       hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
+       hw->mac.ops.check_link(hw, &speed, &link_up, false);
 
        if (!link_up) {
+               ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
+               if (ret_val != IXGBE_SUCCESS)
+                       goto out;
+
                autoc_reg |= IXGBE_AUTOC_AN_RESTART;
                autoc_reg |= IXGBE_AUTOC_FLU;
-               IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+               ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked);
+               if (ret_val != IXGBE_SUCCESS)
+                       goto out;
+
                IXGBE_WRITE_FLUSH(hw);
                msec_delay(10);
        }
@@ -2923,7 +3382,8 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
        IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
        IXGBE_WRITE_FLUSH(hw);
 
-       return IXGBE_SUCCESS;
+out:
+       return ret_val;
 }
 
 /**
@@ -2933,15 +3393,23 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
  **/
 s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
 {
-       u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 autoc_reg = 0;
        u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+       s32 ret_val = IXGBE_SUCCESS;
+       bool locked = false;
 
        DEBUGFUNC("ixgbe_blink_led_stop_generic");
 
+       ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
+       if (ret_val != IXGBE_SUCCESS)
+               goto out;
 
        autoc_reg &= ~IXGBE_AUTOC_FLU;
        autoc_reg |= IXGBE_AUTOC_AN_RESTART;
-       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+       ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked);
+       if (ret_val != IXGBE_SUCCESS)
+               goto out;
 
        led_reg &= ~IXGBE_LED_MODE_MASK(index);
        led_reg &= ~IXGBE_LED_BLINK(index);
@@ -2949,7 +3417,8 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
        IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
        IXGBE_WRITE_FLUSH(hw);
 
-       return IXGBE_SUCCESS;
+out:
+       return ret_val;
 }
 
 /**
@@ -2961,18 +3430,26 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
  *  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)
+STATIC s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
+                                        u16 *san_mac_offset)
 {
+       s32 ret_val;
+
        DEBUGFUNC("ixgbe_get_san_mac_addr_offset");
 
        /*
         * First read the EEPROM pointer to see if the MAC addresses are
         * available.
         */
-       hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset);
+       ret_val = hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR,
+                                     san_mac_offset);
+       if (ret_val) {
+               ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
+                             "eeprom at offset %d failed",
+                             IXGBE_SAN_MAC_ADDR_PTR);
+       }
 
-       return IXGBE_SUCCESS;
+       return ret_val;
 }
 
 /**
@@ -2989,6 +3466,7 @@ s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
 {
        u16 san_mac_data, san_mac_offset;
        u8 i;
+       s32 ret_val;
 
        DEBUGFUNC("ixgbe_get_san_mac_addr_generic");
 
@@ -2996,32 +3474,37 @@ s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
         * First read the EEPROM pointer to see if the MAC addresses are
         * available.  If they're not, no point in calling set_lan_id() here.
         */
-       ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
-
-       if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) {
-               /*
-                * No addresses available in this EEPROM.  It's not an
-                * error though, so just wipe the local address and return.
-                */
-               for (i = 0; i < 6; i++)
-                       san_mac_addr[i] = 0xFF;
-
+       ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
+       if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF)
                goto san_mac_addr_out;
-       }
 
        /* make sure we know which port we need to program */
        hw->mac.ops.set_lan_id(hw);
        /* apply the port offset to the address offset */
        (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
-                        (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
+                        (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
        for (i = 0; i < 3; i++) {
-               hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data);
+               ret_val = hw->eeprom.ops.read(hw, san_mac_offset,
+                                             &san_mac_data);
+               if (ret_val) {
+                       ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
+                                     "eeprom read at offset %d failed",
+                                     san_mac_offset);
+                       goto san_mac_addr_out;
+               }
                san_mac_addr[i * 2] = (u8)(san_mac_data);
                san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8);
                san_mac_offset++;
        }
+       return IXGBE_SUCCESS;
 
 san_mac_addr_out:
+       /*
+        * No addresses available in this EEPROM.  It's not an
+        * error though, so just wipe the local address and return.
+        */
+       for (i = 0; i < 6; i++)
+               san_mac_addr[i] = 0xFF;
        return IXGBE_SUCCESS;
 }
 
@@ -3034,25 +3517,22 @@ san_mac_addr_out:
  **/
 s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
 {
-       s32 status = IXGBE_SUCCESS;
+       s32 ret_val;
        u16 san_mac_data, san_mac_offset;
        u8 i;
 
        DEBUGFUNC("ixgbe_set_san_mac_addr_generic");
 
        /* Look for SAN mac address pointer.  If not defined, return */
-       ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
-
-       if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) {
-               status = IXGBE_ERR_NO_SAN_ADDR_PTR;
-               goto san_mac_addr_out;
-       }
+       ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
+       if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF)
+               return IXGBE_ERR_NO_SAN_ADDR_PTR;
 
        /* Make sure we know which port we need to write */
        hw->mac.ops.set_lan_id(hw);
        /* Apply the port offset to the address offset */
        (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
-                        (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
+                        (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
 
        for (i = 0; i < 3; i++) {
                san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8);
@@ -3061,8 +3541,7 @@ s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
                san_mac_offset++;
        }
 
-san_mac_addr_out:
-       return status;
+       return IXGBE_SUCCESS;
 }
 
 /**
@@ -3072,20 +3551,39 @@ san_mac_addr_out:
  *  Read PCIe configuration space, and get the MSI-X vector count from
  *  the capabilities table.
  **/
-u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
+u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
 {
-       u32 msix_count = 64;
+       u16 msix_count = 1;
+       u16 max_msix_count;
+       u16 pcie_offset;
+
+       switch (hw->mac.type) {
+       case ixgbe_mac_82598EB:
+               pcie_offset = IXGBE_PCIE_MSIX_82598_CAPS;
+               max_msix_count = IXGBE_MAX_MSIX_VECTORS_82598;
+               break;
+       case ixgbe_mac_82599EB:
+       case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
+               pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS;
+               max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599;
+               break;
+       default:
+               return msix_count;
+       }
 
        DEBUGFUNC("ixgbe_get_pcie_msix_count_generic");
-       if (hw->mac.msix_vectors_from_pcie) {
-               msix_count = IXGBE_READ_PCIE_WORD(hw,
-                                                 IXGBE_PCIE_MSIX_82599_CAPS);
-               msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
+       msix_count = IXGBE_READ_PCIE_WORD(hw, pcie_offset);
+       if (IXGBE_REMOVED(hw->hw_addr))
+               msix_count = 0;
+       msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
 
-               /* MSI-X count is zero-based in HW, so increment to give
-                * proper value */
-               msix_count++;
-       }
+       /* MSI-X count is zero-based in HW */
+       msix_count++;
+
+       if (msix_count > max_msix_count)
+               msix_count = max_msix_count;
 
        return msix_count;
 }
@@ -3174,13 +3672,17 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
 
        /* Make sure we are using a valid rar index range */
        if (rar >= rar_entries) {
-               DEBUGOUT1("RAR index %d is out of range.\n", rar);
+               ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
+                            "RAR index %d is out of range.\n", rar);
                return IXGBE_ERR_INVALID_ARGUMENT;
        }
 
        mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
        mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
 
+       if (IXGBE_REMOVED(hw->hw_addr))
+               goto done;
+
        if (!mpsar_lo && !mpsar_hi)
                goto done;
 
@@ -3223,7 +3725,8 @@ s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
 
        /* Make sure we are using a valid rar index range */
        if (rar >= rar_entries) {
-               DEBUGOUT1("RAR index %d is out of range.\n", rar);
+               ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
+                            "RAR index %d is out of range.\n", rar);
                return IXGBE_ERR_INVALID_ARGUMENT;
        }
 
@@ -3239,6 +3742,33 @@ s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
        return IXGBE_SUCCESS;
 }
 
+/**
+ *  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
+ **/
+s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq)
+{
+       u32 rar = hw->mac.san_mac_rar_index;
+
+       DEBUGFUNC("ixgbe_set_vmdq_san_mac");
+
+       if (vmdq < 32) {
+               IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 1 << vmdq);
+               IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
+       } else {
+               IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
+               IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 1 << (vmdq - 32));
+       }
+
+       return IXGBE_SUCCESS;
+}
+
 /**
  *  ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array
  *  @hw: pointer to hardware structure
@@ -3295,7 +3825,8 @@ s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
                if (first_empty_slot)
                        regindex = first_empty_slot;
                else {
-                       DEBUGOUT("No space in VLVF.\n");
+                       ERROR_REPORT1(IXGBE_ERROR_SOFTWARE,
+                                    "No space in VLVF.\n");
                        regindex = IXGBE_ERR_NO_SPACE;
                }
        }
@@ -3313,15 +3844,14 @@ s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
  *  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)
 {
        s32 regindex;
        u32 bitindex;
        u32 vfta;
-       u32 bits;
-       u32 vt;
        u32 targetbit;
-       bool vfta_changed = FALSE;
+       s32 ret_val = IXGBE_SUCCESS;
+       bool vfta_changed = false;
 
        DEBUGFUNC("ixgbe_set_vfta_generic");
 
@@ -3348,17 +3878,51 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
        if (vlan_on) {
                if (!(vfta & targetbit)) {
                        vfta |= targetbit;
-                       vfta_changed = TRUE;
+                       vfta_changed = true;
                }
        } else {
                if ((vfta & targetbit)) {
                        vfta &= ~targetbit;
-                       vfta_changed = TRUE;
+                       vfta_changed = true;
                }
        }
 
        /* Part 2
-        * If VT Mode is set
+        * 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)
+               return ret_val;
+
+       if (vfta_changed)
+               IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), 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
+ *
+ *  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)
+{
+       u32 vt;
+
+       DEBUGFUNC("ixgbe_set_vlvf_generic");
+
+       if (vlan > 4095)
+               return IXGBE_ERR_PARAM;
+
+       /* If VT Mode is set
         *   Either vlan_on
         *     make sure the vlan is in VLVF
         *     set the vind bit in the matching VLVFB
@@ -3368,6 +3932,7 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 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)
@@ -3377,39 +3942,39 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
                        /* set the pool bit */
                        if (vind < 32) {
                                bits = IXGBE_READ_REG(hw,
-                                               IXGBE_VLVFB(vlvf_index*2));
+                                               IXGBE_VLVFB(vlvf_index * 2));
                                bits |= (1 << vind);
                                IXGBE_WRITE_REG(hw,
-                                               IXGBE_VLVFB(vlvf_index*2),
+                                               IXGBE_VLVFB(vlvf_index * 2),
                                                bits);
                        } else {
                                bits = IXGBE_READ_REG(hw,
-                                               IXGBE_VLVFB((vlvf_index*2)+1));
-                               bits |= (1 << (vind-32));
+                                       IXGBE_VLVFB((vlvf_index * 2) + 1));
+                               bits |= (1 << (vind - 32));
                                IXGBE_WRITE_REG(hw,
-                                               IXGBE_VLVFB((vlvf_index*2)+1),
-                                               bits);
+                                       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));
+                                               IXGBE_VLVFB(vlvf_index * 2));
                                bits &= ~(1 << vind);
                                IXGBE_WRITE_REG(hw,
-                                               IXGBE_VLVFB(vlvf_index*2),
+                                               IXGBE_VLVFB(vlvf_index * 2),
                                                bits);
                                bits |= IXGBE_READ_REG(hw,
-                                               IXGBE_VLVFB((vlvf_index*2)+1));
+                                       IXGBE_VLVFB((vlvf_index * 2) + 1));
                        } else {
                                bits = IXGBE_READ_REG(hw,
-                                               IXGBE_VLVFB((vlvf_index*2)+1));
-                               bits &= ~(1 << (vind-32));
+                                       IXGBE_VLVFB((vlvf_index * 2) + 1));
+                               bits &= ~(1 << (vind - 32));
                                IXGBE_WRITE_REG(hw,
-                                               IXGBE_VLVFB((vlvf_index*2)+1),
-                                               bits);
+                                       IXGBE_VLVFB((vlvf_index * 2) + 1),
+                                       bits);
                                bits |= IXGBE_READ_REG(hw,
-                                               IXGBE_VLVFB(vlvf_index*2));
+                                               IXGBE_VLVFB(vlvf_index * 2));
                        }
                }
 
@@ -3431,20 +3996,16 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
                if (bits) {
                        IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
                                        (IXGBE_VLVF_VIEN | vlan));
-                       if (!vlan_on) {
+                       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;
+                               *vfta_changed = false;
                        }
-               }
-               else
+               } else
                        IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
        }
 
-       if (vfta_changed)
-               IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta);
-
        return IXGBE_SUCCESS;
 }
 
@@ -3465,8 +4026,8 @@ 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), 0);
+               IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0);
        }
 
        return IXGBE_SUCCESS;
@@ -3476,13 +4037,13 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
  *  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: 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
  **/
 s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
-                                 bool *link_up, bool link_up_wait_to_complete)
+                                bool *link_up, bool link_up_wait_to_complete)
 {
        u32 links_reg, links_orig;
        u32 i;
@@ -3496,45 +4057,44 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
 
        if (links_orig != links_reg) {
                DEBUGOUT2("LINKS changed from %08X to %08X\n",
-                         links_orig, links_reg);
+                         links_orig, links_reg);
        }
 
        if (link_up_wait_to_complete) {
                for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
                        if (links_reg & IXGBE_LINKS_UP) {
-                               *link_up = TRUE;
+                               *link_up = true;
                                break;
                        } else {
-                               *link_up = FALSE;
+                               *link_up = false;
                        }
                        msec_delay(100);
                        links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
                }
        } else {
                if (links_reg & IXGBE_LINKS_UP)
-                       *link_up = TRUE;
+                       *link_up = true;
                else
-                       *link_up = FALSE;
+                       *link_up = false;
        }
 
        if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
-           IXGBE_LINKS_SPEED_10G_82599)
+           IXGBE_LINKS_SPEED_10G_82599) {
                *speed = IXGBE_LINK_SPEED_10GB_FULL;
+               if (hw->mac.type > ixgbe_mac_X550) {
+                       if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
+                               *speed = IXGBE_LINK_SPEED_2_5GB_FULL;
+               }
+       }
        else if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
-                IXGBE_LINKS_SPEED_1G_82599)
+                IXGBE_LINKS_SPEED_1G_82599)
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
        else if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
-                IXGBE_LINKS_SPEED_100_82599)
+                IXGBE_LINKS_SPEED_100_82599)
                *speed = IXGBE_LINK_SPEED_100_FULL;
        else
                *speed = IXGBE_LINK_SPEED_UNKNOWN;
 
-       /* if link is down, zero out the current_mode */
-       if (*link_up == FALSE) {
-               hw->fc.current_mode = ixgbe_fc_none;
-               hw->fc.fc_was_autonegged = FALSE;
-       }
-
        return IXGBE_SUCCESS;
 }
 
@@ -3549,7 +4109,7 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
  *  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)
+                                u16 *wwpn_prefix)
 {
        u16 offset, caps;
        u16 alt_san_mac_blk_offset;
@@ -3561,8 +4121,9 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
        *wwpn_prefix = 0xFFFF;
 
        /* check if alternative SAN MAC is supported */
-       hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR,
-                           &alt_san_mac_blk_offset);
+       offset = IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR;
+       if (hw->eeprom.ops.read(hw, offset, &alt_san_mac_blk_offset))
+               goto wwn_prefix_err;
 
        if ((alt_san_mac_blk_offset == 0) ||
            (alt_san_mac_blk_offset == 0xFFFF))
@@ -3570,19 +4131,29 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
 
        /* check capability in alternative san mac address block */
        offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
-       hw->eeprom.ops.read(hw, offset, &caps);
+       if (hw->eeprom.ops.read(hw, offset, &caps))
+               goto wwn_prefix_err;
        if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
                goto wwn_prefix_out;
 
        /* get the corresponding prefix for WWNN/WWPN */
        offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
-       hw->eeprom.ops.read(hw, offset, wwnn_prefix);
+       if (hw->eeprom.ops.read(hw, offset, wwnn_prefix)) {
+               ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
+                             "eeprom read at offset %d failed", offset);
+       }
 
        offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET;
-       hw->eeprom.ops.read(hw, offset, wwpn_prefix);
+       if (hw->eeprom.ops.read(hw, offset, wwpn_prefix))
+               goto wwn_prefix_err;
 
 wwn_prefix_out:
        return IXGBE_SUCCESS;
+
+wwn_prefix_err:
+       ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
+                     "eeprom read at offset %d failed", offset);
+       return IXGBE_SUCCESS;
 }
 
 /**
@@ -3634,30 +4205,6 @@ out:
        return status;
 }
 
-/**
- *  ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow
- *  control
- *  @hw: pointer to hardware structure
- *
- *  There are several phys that do not support autoneg flow control. This
- *  function check the device id to see if the associated phy supports
- *  autoneg flow control.
- **/
-static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
-{
-
-       DEBUGFUNC("ixgbe_device_supports_autoneg_fc");
-
-       switch (hw->device_id) {
-       case IXGBE_DEV_ID_X540T:
-               return IXGBE_SUCCESS;
-       case IXGBE_DEV_ID_82599_T3_LOM:
-               return IXGBE_SUCCESS;
-       default:
-               return IXGBE_ERR_FC_NOT_SUPPORTED;
-       }
-}
-
 /**
  *  ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing
  *  @hw: pointer to hardware structure
@@ -3682,27 +4229,29 @@ void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf)
         * PFVFSPOOF register array is size 8 with 8 bits assigned to
         * MAC anti-spoof enables in each register array element.
         */
-       for (j = 0; j < IXGBE_PFVFSPOOF_REG_COUNT; j++)
+       for (j = 0; j < pf_target_reg; j++)
                IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof);
 
-       /* If not enabling anti-spoofing then done */
-       if (!enable)
-               return;
-
        /*
         * The PF should be allowed to spoof so that it can support
-        * emulation mode NICs.  Reset the bit assigned to the PF
+        * 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.
         */
-       pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg));
-       pfvfspoof ^= (1 << pf_target_shift);
-       IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg), pfvfspoof);
+       for (j++; j < IXGBE_PFVFSPOOF_REG_COUNT; j++)
+               IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), 0);
 }
 
 /**
  *  ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing
  *  @hw: pointer to hardware structure
  *  @enable: enable or disable switch for VLAN anti-spoofing
- *  @pf: Virtual Function pool - VF Pool to set 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)
@@ -3754,14 +4303,14 @@ void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw)
        /* Enable relaxed ordering */
        for (i = 0; i < hw->mac.max_tx_queues; i++) {
                regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
-               regval |= IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+               regval |= IXGBE_DCA_TXCTRL_DESC_WRO_EN;
                IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
        }
 
        for (i = 0; i < hw->mac.max_rx_queues; i++) {
                regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
-               regval |= (IXGBE_DCA_RXCTRL_DESC_WRO_EN |
-                          IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+               regval |= IXGBE_DCA_RXCTRL_DATA_WRO_EN |
+                         IXGBE_DCA_RXCTRL_HEAD_WRO_EN;
                IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
        }
 
@@ -3774,7 +4323,7 @@ void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw)
  *  Calculates the checksum for some buffer on a specified length.  The
  *  checksum calculated is returned.
  **/
-static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
+u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
 {
        u32 i;
        u8 sum = 0;
@@ -3794,48 +4343,57 @@ static 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
- *  @lenght: lenght of buffer, must be multiple of 4 bytes
+ *   be placed
+ *  @length: length of buffer, must be multiple of 4 bytes
+ *  @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 return IXGBE_ERR_HOST_INTERFACE_COMMAND.
  **/
-static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u8 *buffer,
-                                        u32 length)
+s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
+                                u32 length, bool return_data)
 {
-       u32 hicr, i;
+       u32 hicr, i, bi, fwsts;
        u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
-       u8 buf_len, dword_len;
-
-       s32 ret_val = IXGBE_SUCCESS;
+       u16 buf_len;
+       u8 dword_len;
 
        DEBUGFUNC("ixgbe_host_interface_command");
 
-       if (length == 0 || length & 0x3 ||
-           length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
-               DEBUGOUT("Buffer length failure.\n");
-               ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
-               goto out;
+       if (length == 0 || 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) {
                DEBUGOUT("IXGBE_HOST_EN bit disabled.\n");
-               ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
-               goto out;
+               return IXGBE_ERR_HOST_INTERFACE_COMMAND;
+       }
+
+       /* Calculate length in DWORDs. We must be DWORD aligned */
+       if ((length % (sizeof(u32))) != 0) {
+               DEBUGOUT("Buffer length failure, not aligned to dword");
+               return IXGBE_ERR_INVALID_ARGUMENT;
        }
 
-       /* Calculate length in DWORDs */
        dword_len = length >> 2;
 
-       /*
-        * The device driver writes the relevant command block
+       /* The device driver writes the relevant command block
         * into the ram area.
         */
        for (i = 0; i < dword_len; i++)
                IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG,
-                                     i, *((u32 *)buffer + i));
+                                     i, IXGBE_CPU_TO_LE32(buffer[i]));
 
        /* Setting this bit tells the ARC that a new command is pending. */
        IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C);
@@ -3847,43 +4405,46 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u8 *buffer,
                msec_delay(1);
        }
 
-       /* Check command successful completion. */
+       /* Check command completion */
        if (i == IXGBE_HI_COMMAND_TIMEOUT ||
-           (!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) {
-               DEBUGOUT("Command has failed with no status valid.\n");
-               ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
-               goto out;
+           !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) {
+               ERROR_REPORT1(IXGBE_ERROR_CAUTION,
+                            "Command has failed with no status valid.\n");
+               return IXGBE_ERR_HOST_INTERFACE_COMMAND;
        }
 
+       if (!return_data)
+               return 0;
+
        /* Calculate length in DWORDs */
        dword_len = hdr_size >> 2;
 
        /* first pull in the header so we know the buffer length */
-       for (i = 0; i < dword_len; i++)
-               *((u32 *)buffer + i) =
-                       IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, i);
+       for (bi = 0; bi < dword_len; bi++) {
+               buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
+               IXGBE_LE32_TO_CPUS(&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)
-               goto out;
+               return 0;
 
-       if (length < (buf_len + hdr_size)) {
+       if (length < buf_len + hdr_size) {
                DEBUGOUT("Buffer not large enough for reply message.\n");
-               ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
-               goto out;
+               return IXGBE_ERR_HOST_INTERFACE_COMMAND;
        }
 
-       /* Calculate length in DWORDs, add one for odd lengths */
-       dword_len = (buf_len + 1) >> 2;
+       /* Calculate length in DWORDs, add 3 for odd lengths */
+       dword_len = (buf_len + 3) >> 2;
 
-       /* Pull in the rest of the buffer (i is where we left off)*/
-       for (; i < buf_len; i++)
-               *((u32 *)buffer + i) =
-                       IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, i);
+       /* 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]);
+       }
 
-out:
-       return ret_val;
+       return 0;
 }
 
 /**
@@ -3929,8 +4490,8 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
        fw_cmd.pad2 = 0;
 
        for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
-               ret_val = ixgbe_host_interface_command(hw, (u8 *)&fw_cmd,
-                                                      sizeof(fw_cmd));
+               ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
+                                                      sizeof(fw_cmd), true);
                if (ret_val != IXGBE_SUCCESS)
                        continue;
 
@@ -3956,7 +4517,7 @@ out:
  * @strategy: packet buffer allocation strategy
  **/
 void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom,
-                             int strategy)
+                            int strategy)
 {
        u32 pbsize = hw->mac.rx_pb_size;
        int i = 0;
@@ -3972,17 +4533,17 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom,
         * buffers requested using supplied strategy.
         */
        switch (strategy) {
-       case (PBA_STRATEGY_WEIGHTED):
-               /* pba_80_48 strategy weight first half of packet buffer with
-                * 5/8 of the packet buffer space.
+       case PBA_STRATEGY_WEIGHTED:
+               /* ixgbe_dcb_pba_80_48 strategy weight first half of packet
+                * buffer with 5/8 of the packet buffer space.
                 */
-               rxpktsize = (pbsize * 5 * 2) / (num_pb * 8);
+               rxpktsize = (pbsize * 5) / (num_pb * 4);
                pbsize -= rxpktsize * (num_pb / 2);
                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 */
-       case (PBA_STRATEGY_EQUAL):
+       case PBA_STRATEGY_EQUAL:
                rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT;
                for (; i < num_pb; i++)
                        IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
@@ -4037,7 +4598,7 @@ void ixgbe_clear_tx_pending(struct ixgbe_hw *hw)
        /* initiate cleaning flow for buffers in the PCIe transaction layer */
        gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
        IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT,
-                       gcr_ext | IXGBE_GCR_EXT_BUFFERS_CLEAR);
+                       gcr_ext | IXGBE_GCR_EXT_BUFFERS_CLEAR);
 
        /* Flush all writes and allow 20usec for all transactions to clear */
        IXGBE_WRITE_FLUSH(hw);
@@ -4047,3 +4608,258 @@ void ixgbe_clear_tx_pending(struct ixgbe_hw *hw)
        IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
        IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
 }
+
+STATIC const u8 ixgbe_emc_temp_data[4] = {
+       IXGBE_EMC_INTERNAL_DATA,
+       IXGBE_EMC_DIODE1_DATA,
+       IXGBE_EMC_DIODE2_DATA,
+       IXGBE_EMC_DIODE3_DATA
+};
+STATIC const u8 ixgbe_emc_therm_limit[4] = {
+       IXGBE_EMC_INTERNAL_THERM_LIMIT,
+       IXGBE_EMC_DIODE1_THERM_LIMIT,
+       IXGBE_EMC_DIODE2_THERM_LIMIT,
+       IXGBE_EMC_DIODE3_THERM_LIMIT
+};
+
+/**
+ *  ixgbe_get_thermal_sensor_data - Gathers thermal sensor data
+ *  @hw: pointer to hardware structure
+ *  @data: pointer to the thermal sensor data structure
+ *
+ *  Returns the thermal sensor data structure
+ **/
+s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw)
+{
+       s32 status = IXGBE_SUCCESS;
+       u16 ets_offset;
+       u16 ets_cfg;
+       u16 ets_sensor;
+       u8  num_sensors;
+       u8  sensor_index;
+       u8  sensor_location;
+       u8  i;
+       struct ixgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
+
+       DEBUGFUNC("ixgbe_get_thermal_sensor_data_generic");
+
+       /* Only support thermal sensors attached to 82599 physical port 0 */
+       if ((hw->mac.type != ixgbe_mac_82599EB) ||
+           (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) {
+               status = IXGBE_NOT_IMPLEMENTED;
+               goto out;
+       }
+
+       status = hw->eeprom.ops.read(hw, IXGBE_ETS_CFG, &ets_offset);
+       if (status)
+               goto out;
+
+       if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF)) {
+               status = IXGBE_NOT_IMPLEMENTED;
+               goto out;
+       }
+
+       status = hw->eeprom.ops.read(hw, ets_offset, &ets_cfg);
+       if (status)
+               goto out;
+
+       if (((ets_cfg & IXGBE_ETS_TYPE_MASK) >> IXGBE_ETS_TYPE_SHIFT)
+               != IXGBE_ETS_TYPE_EMC) {
+               status = IXGBE_NOT_IMPLEMENTED;
+               goto out;
+       }
+
+       num_sensors = (ets_cfg & IXGBE_ETS_NUM_SENSORS_MASK);
+       if (num_sensors > IXGBE_MAX_SENSORS)
+               num_sensors = IXGBE_MAX_SENSORS;
+
+       for (i = 0; i < num_sensors; i++) {
+               status = hw->eeprom.ops.read(hw, (ets_offset + 1 + i),
+                                            &ets_sensor);
+               if (status)
+                       goto out;
+
+               sensor_index = ((ets_sensor & IXGBE_ETS_DATA_INDEX_MASK) >>
+                               IXGBE_ETS_DATA_INDEX_SHIFT);
+               sensor_location = ((ets_sensor & IXGBE_ETS_DATA_LOC_MASK) >>
+                                  IXGBE_ETS_DATA_LOC_SHIFT);
+
+               if (sensor_location != 0) {
+                       status = hw->phy.ops.read_i2c_byte(hw,
+                                       ixgbe_emc_temp_data[sensor_index],
+                                       IXGBE_I2C_THERMAL_SENSOR_ADDR,
+                                       &data->sensor[i].temp);
+                       if (status)
+                               goto out;
+               }
+       }
+out:
+       return status;
+}
+
+/**
+ *  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
+ **/
+s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw)
+{
+       s32 status = IXGBE_SUCCESS;
+       u16 offset;
+       u16 ets_offset;
+       u16 ets_cfg;
+       u16 ets_sensor;
+       u8  low_thresh_delta;
+       u8  num_sensors;
+       u8  sensor_index;
+       u8  sensor_location;
+       u8  therm_limit;
+       u8  i;
+       struct ixgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
+
+       DEBUGFUNC("ixgbe_init_thermal_sensor_thresh_generic");
+
+       memset(data, 0, sizeof(struct ixgbe_thermal_sensor_data));
+
+       /* Only support thermal sensors attached to 82599 physical port 0 */
+       if ((hw->mac.type != ixgbe_mac_82599EB) ||
+           (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1))
+               return IXGBE_NOT_IMPLEMENTED;
+
+       offset = IXGBE_ETS_CFG;
+       if (hw->eeprom.ops.read(hw, offset, &ets_offset))
+               goto eeprom_err;
+       if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF))
+               return IXGBE_NOT_IMPLEMENTED;
+
+       offset = ets_offset;
+       if (hw->eeprom.ops.read(hw, offset, &ets_cfg))
+               goto eeprom_err;
+       if (((ets_cfg & IXGBE_ETS_TYPE_MASK) >> IXGBE_ETS_TYPE_SHIFT)
+               != IXGBE_ETS_TYPE_EMC)
+               return IXGBE_NOT_IMPLEMENTED;
+
+       low_thresh_delta = ((ets_cfg & IXGBE_ETS_LTHRES_DELTA_MASK) >>
+                            IXGBE_ETS_LTHRES_DELTA_SHIFT);
+       num_sensors = (ets_cfg & IXGBE_ETS_NUM_SENSORS_MASK);
+
+       for (i = 0; i < num_sensors; i++) {
+               offset = ets_offset + 1 + i;
+               if (hw->eeprom.ops.read(hw, offset, &ets_sensor)) {
+                       ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
+                                     "eeprom read at offset %d failed",
+                                     offset);
+                       continue;
+               }
+               sensor_index = ((ets_sensor & IXGBE_ETS_DATA_INDEX_MASK) >>
+                               IXGBE_ETS_DATA_INDEX_SHIFT);
+               sensor_location = ((ets_sensor & IXGBE_ETS_DATA_LOC_MASK) >>
+                                  IXGBE_ETS_DATA_LOC_SHIFT);
+               therm_limit = ets_sensor & IXGBE_ETS_DATA_HTHRESH_MASK;
+
+               hw->phy.ops.write_i2c_byte(hw,
+                       ixgbe_emc_therm_limit[sensor_index],
+                       IXGBE_I2C_THERMAL_SENSOR_ADDR, therm_limit);
+
+               if ((i < IXGBE_MAX_SENSORS) && (sensor_location != 0)) {
+                       data->sensor[i].location = sensor_location;
+                       data->sensor[i].caution_thresh = therm_limit;
+                       data->sensor[i].max_op_thresh = therm_limit -
+                                                       low_thresh_delta;
+               }
+       }
+       return status;
+
+eeprom_err:
+       ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
+                     "eeprom read at offset %d failed", offset);
+       return IXGBE_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * ixgbe_dcb_get_rtrup2tc_generic - read rtrup2tc reg
+ * @hw: pointer to hardware structure
+ * @map: pointer to u8 arr for returning map
+ *
+ * Read the rtrup2tc HW register and resolve its content into map
+ **/
+void ixgbe_dcb_get_rtrup2tc_generic(struct ixgbe_hw *hw, u8 *map)
+{
+       u32 reg, i;
+
+       reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC);
+       for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++)
+               map[i] = IXGBE_RTRUP2TC_UP_MASK &
+                       (reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT));
+       return;
+}
+
+void ixgbe_disable_rx_generic(struct ixgbe_hw *hw)
+{
+       u32 pfdtxgswc;
+       u32 rxctrl;
+
+       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+       if (rxctrl & IXGBE_RXCTRL_RXEN) {
+               if (hw->mac.type != ixgbe_mac_82598EB) {
+                       pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+                       if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
+                               pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+                               IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
+                               hw->mac.set_lben = true;
+                       } else {
+                               hw->mac.set_lben = false;
+                       }
+               }
+               rxctrl &= ~IXGBE_RXCTRL_RXEN;
+               IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
+       }
+}
+
+void ixgbe_enable_rx_generic(struct ixgbe_hw *hw)
+{
+       u32 pfdtxgswc;
+       u32 rxctrl;
+
+       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, (rxctrl | IXGBE_RXCTRL_RXEN));
+
+       if (hw->mac.type != ixgbe_mac_82598EB) {
+               if (hw->mac.set_lben) {
+                       pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+                       pfdtxgswc |= IXGBE_PFDTXGSWC_VT_LBEN;
+                       IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
+                       hw->mac.set_lben = false;
+               }
+       }
+}
+
+/**
+ * ixgbe_mng_enabled - Is the manageability engine enabled?
+ * @hw: pointer to hardware structure
+ *
+ * Returns true if the manageability engine is enabled.
+ **/
+bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
+{
+       u32 fwsm, manc, factps;
+
+       fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
+       if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT)
+               return false;
+
+       manc = IXGBE_READ_REG(hw, IXGBE_MANC);
+       if (!(manc & IXGBE_MANC_RCV_TCO_EN))
+               return false;
+
+       if (hw->mac.type <= ixgbe_mac_X540) {
+               factps = IXGBE_READ_REG(hw, IXGBE_FACTPS);
+               if (factps & IXGBE_FACTPS_MNGCG)
+                       return false;
+       }
+
+       return true;
+}