ixgbe/base: support X550
authorOuyang Changchun <changchun.ouyang@intel.com>
Mon, 29 Sep 2014 07:16:25 +0000 (15:16 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Tue, 7 Oct 2014 15:00:52 +0000 (17:00 +0200)
Add new file to support controller X550, therefore update the Makefile
and README file. It also updates the API functions, DCB related functions,
mailbox related functions, etc to support X550.
In addition, some new macros used by X550 are added.

Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>
[Thomas: merge dependent patches]

15 files changed:
lib/librte_pmd_ixgbe/Makefile
lib/librte_pmd_ixgbe/ixgbe/README
lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h
lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_dcb.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_mbx.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_osdep.h
lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h
lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h
lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h
lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.c [new file with mode: 0644]
lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.h [new file with mode: 0644]

index 00ccedb..0b647bd 100644 (file)
@@ -64,6 +64,7 @@ CFLAGS_BASE_DRIVER += -Wno-strict-aliasing -Wno-format-extra-args
 
 ifeq ($(shell test $(GCC_MAJOR_VERSION) -ge 4 -a $(GCC_MINOR_VERSION) -ge 6 && echo 1), 1)
 CFLAGS_ixgbe_common.o += -Wno-unused-but-set-variable
+CFLAGS_ixgbe_x550.o += -Wno-unused-but-set-variable -Wno-maybe-uninitialized
 endif
 endif
 
@@ -83,6 +84,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_common.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82598.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_x540.c
+SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_x550.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_phy.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_api.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_vf.c
index fc71e85..e0e5f0d 100644 (file)
@@ -34,7 +34,7 @@ Intel® IXGBE driver
 ===================
 
 This directory contains source code of FreeBSD ixgbe driver of version
-cid-10g-shared-code.2014.03.13 released by LAD. The sub-directory of lad/
+cid-10g-shared-code.2014.09.04 released by LAD. The sub-directory of lad/
 contains the original source package.
 This driver is valid for the product(s) listed below
 
@@ -50,6 +50,7 @@ This driver is valid for the product(s) listed below
 * Intel® Ethernet Controller X540-AT2
 * Intel® Ethernet Server Adapter X520 Series
 * Intel® Ethernet Server Adapter X520-T2
+* Intel® Ethernet Controller X550-BT2
 
 Updating driver
 ===============
index 2b74374..a06b57c 100644 (file)
@@ -1918,6 +1918,15 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
        /* write both the same so that UDP and TCP use the same mask */
        IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm);
        IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm);
+       /* also use it for SCTP */
+       switch (hw->mac.type) {
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, ~fdirtcpm);
+               break;
+       default:
+               break;
+       }
 
        /* store source and destination IP masks (big-endian) */
        IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M,
index b3e89c5..1802760 100644 (file)
@@ -81,8 +81,16 @@ s32 ixgbe_init_shared_code(struct ixgbe_hw *hw)
        case ixgbe_mac_X540:
                status = ixgbe_init_ops_X540(hw);
                break;
+       case ixgbe_mac_X550:
+               status = ixgbe_init_ops_X550(hw);
+               break;
+       case ixgbe_mac_X550EM_x:
+               status = ixgbe_init_ops_X550EM(hw);
+               break;
        case ixgbe_mac_82599_vf:
        case ixgbe_mac_X540_vf:
+       case ixgbe_mac_X550_vf:
+       case ixgbe_mac_X550EM_x_vf:
                status = ixgbe_init_ops_vf(hw);
                break;
        default:
@@ -157,6 +165,23 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw)
        case IXGBE_DEV_ID_X540T1:
                hw->mac.type = ixgbe_mac_X540;
                break;
+       case IXGBE_DEV_ID_X550T:
+               hw->mac.type = ixgbe_mac_X550;
+               break;
+       case IXGBE_DEV_ID_X550EM_X:
+       case IXGBE_DEV_ID_X550EM_X_KX4:
+       case IXGBE_DEV_ID_X550EM_X_KR:
+       case IXGBE_DEV_ID_X550EM_X_SFP:
+               hw->mac.type = ixgbe_mac_X550EM_x;
+               break;
+       case IXGBE_DEV_ID_X550_VF:
+       case IXGBE_DEV_ID_X550_VF_HV:
+               hw->mac.type = ixgbe_mac_X550_vf;
+               break;
+       case IXGBE_DEV_ID_X550EM_X_VF:
+       case IXGBE_DEV_ID_X550EM_X_VF_HV:
+               hw->mac.type = ixgbe_mac_X550EM_x_vf;
+               break;
        default:
                ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
                ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED,
index c63664a..1c12ff6 100644 (file)
@@ -44,6 +44,8 @@ s32 ixgbe_init_shared_code(struct ixgbe_hw *hw);
 extern s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw);
 extern s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw);
 extern s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw);
+extern s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw);
+extern s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw);
 extern s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw);
 
 s32 ixgbe_set_mac_type(struct ixgbe_hw *hw);
index a799b40..37e5bae 100644 (file)
@@ -184,6 +184,7 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
                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:
@@ -563,7 +564,7 @@ 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, IXGBE_PCRC8ECL,
@@ -3567,6 +3568,8 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
                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;
@@ -4080,8 +4083,13 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
        }
 
        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)
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
index 1c2459b..2245f27 100644 (file)
@@ -394,6 +394,8 @@ s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
                break;
        default:
@@ -420,6 +422,8 @@ s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
                break;
        default:
@@ -457,6 +461,8 @@ s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw,
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid,
                                                        tsa, map);
                break;
@@ -494,6 +500,8 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw,
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
                                                             bwgid, tsa);
                break;
@@ -533,6 +541,8 @@ s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw,
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
                                                             bwgid, tsa,
                                                             map);
@@ -566,6 +576,8 @@ s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw,
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
                break;
        default:
@@ -590,6 +602,8 @@ s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL);
                break;
        default:
@@ -630,6 +644,8 @@ s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw,
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                ixgbe_dcb_config_82599(hw, dcb_config);
                ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed,
                                                refill, max, bwgid,
@@ -660,6 +676,8 @@ s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
                break;
        default:
@@ -681,6 +699,8 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max,
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id,
                                                  tsa, map);
                ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id,
index 9389861..c00c2f7 100644 (file)
@@ -615,6 +615,8 @@ STATIC s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
        case ixgbe_mac_82599EB:
                vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
                break;
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
        case ixgbe_mac_X540:
                vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
                break;
@@ -761,6 +763,8 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
        struct ixgbe_mbx_info *mbx = &hw->mbx;
 
        if (hw->mac.type != ixgbe_mac_82599EB &&
+           hw->mac.type != ixgbe_mac_X550 &&
+           hw->mac.type != ixgbe_mac_X550EM_x &&
            hw->mac.type != ixgbe_mac_X540)
                return;
 
index ab13d64..2d40bfd 100644 (file)
@@ -97,6 +97,8 @@ enum {
 #define IXGBE_NTOHS(_i)        rte_be_to_cpu_16(_i)
 #define IXGBE_CPU_TO_LE32(_i)  rte_cpu_to_le_32(_i)
 #define IXGBE_LE32_TO_CPUS(_i) rte_le_to_cpu_32(_i)
+#define IXGBE_CPU_TO_BE16(_i)  rte_cpu_to_be_16(_i)
+#define IXGBE_CPU_TO_BE32(_i)  rte_cpu_to_be_32(_i)
 
 typedef uint8_t                u8;
 typedef int8_t         s8;
index ca83f0c..2305448 100644 (file)
@@ -46,7 +46,7 @@ STATIC s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
 STATIC void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
 STATIC void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
 STATIC s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
-STATIC bool ixgbe_get_i2c_data(u32 *i2cctl);
+STATIC bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl);
 STATIC s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
                                          u8 *sff8472_data);
 
@@ -428,6 +428,7 @@ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
        case TN1010_PHY_ID:
                phy_type = ixgbe_phy_tn;
                break;
+       case X550_PHY_ID:
        case X540_PHY_ID:
                phy_type = ixgbe_phy_aq;
                break;
@@ -2033,7 +2034,7 @@ write_byte_out:
  **/
 STATIC void ixgbe_i2c_start(struct ixgbe_hw *hw)
 {
-       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
 
        DEBUGFUNC("ixgbe_i2c_start");
 
@@ -2064,7 +2065,7 @@ STATIC void ixgbe_i2c_start(struct ixgbe_hw *hw)
  **/
 STATIC void ixgbe_i2c_stop(struct ixgbe_hw *hw)
 {
-       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
 
        DEBUGFUNC("ixgbe_i2c_stop");
 
@@ -2128,9 +2129,9 @@ STATIC s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
        }
 
        /* Release SDA line (set high) */
-       i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
-       i2cctl |= IXGBE_I2C_DATA_OUT;
-       IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, i2cctl);
+       i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
+       i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw);
+       IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl);
        IXGBE_WRITE_FLUSH(hw);
 
        return status;
@@ -2146,7 +2147,7 @@ STATIC s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
 {
        s32 status = IXGBE_SUCCESS;
        u32 i = 0;
-       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
        u32 timeout = 10;
        bool ack = 1;
 
@@ -2161,17 +2162,16 @@ STATIC s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
        /* Poll for ACK.  Note that ACK in I2C spec is
         * transition from 1 to 0 */
        for (i = 0; i < timeout; i++) {
-               i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
-               ack = ixgbe_get_i2c_data(&i2cctl);
+               i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
+               ack = ixgbe_get_i2c_data(hw, &i2cctl);
 
                usec_delay(1);
                if (!ack)
                        break;
        }
 
-       if (ack == 1) {
-               ERROR_REPORT1(IXGBE_ERROR_POLLING,
-                            "I2C ack was not received.\n");
+       if (ack) {
+               DEBUGOUT("I2C ack was not received.\n");
                status = IXGBE_ERR_I2C;
        }
 
@@ -2192,7 +2192,7 @@ STATIC s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
  **/
 STATIC s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
 {
-       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
 
        DEBUGFUNC("ixgbe_clock_in_i2c_bit");
 
@@ -2201,8 +2201,8 @@ STATIC s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
        /* Minimum high period of clock is 4us */
        usec_delay(IXGBE_I2C_T_HIGH);
 
-       i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
-       *data = ixgbe_get_i2c_data(&i2cctl);
+       i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
+       *data = ixgbe_get_i2c_data(hw, &i2cctl);
 
        ixgbe_lower_i2c_clk(hw, &i2cctl);
 
@@ -2222,7 +2222,7 @@ STATIC s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
 STATIC s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
 {
        s32 status;
-       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
 
        DEBUGFUNC("ixgbe_clock_out_i2c_bit");
 
@@ -2264,15 +2264,15 @@ STATIC void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
        DEBUGFUNC("ixgbe_raise_i2c_clk");
 
        for (i = 0; i < timeout; i++) {
-               *i2cctl |= IXGBE_I2C_CLK_OUT;
+               *i2cctl |= IXGBE_I2C_CLK_OUT_BY_MAC(hw);
 
-               IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+               IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
                IXGBE_WRITE_FLUSH(hw);
                /* SCL rise time (1000ns) */
                usec_delay(IXGBE_I2C_T_RISE);
 
-               i2cctl_r = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
-               if (i2cctl_r & IXGBE_I2C_CLK_IN)
+               i2cctl_r = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
+               if (i2cctl_r & IXGBE_I2C_CLK_IN_BY_MAC(hw))
                        break;
        }
 }
@@ -2289,9 +2289,9 @@ STATIC void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
 
        DEBUGFUNC("ixgbe_lower_i2c_clk");
 
-       *i2cctl &= ~IXGBE_I2C_CLK_OUT;
+       *i2cctl &= ~(IXGBE_I2C_CLK_OUT_BY_MAC(hw));
 
-       IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+       IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
        IXGBE_WRITE_FLUSH(hw);
 
        /* SCL fall time (300ns) */
@@ -2313,19 +2313,19 @@ STATIC s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
        DEBUGFUNC("ixgbe_set_i2c_data");
 
        if (data)
-               *i2cctl |= IXGBE_I2C_DATA_OUT;
+               *i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw);
        else
-               *i2cctl &= ~IXGBE_I2C_DATA_OUT;
+               *i2cctl &= ~(IXGBE_I2C_DATA_OUT_BY_MAC(hw));
 
-       IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+       IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
        IXGBE_WRITE_FLUSH(hw);
 
        /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
        usec_delay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
 
        /* Verify data was set correctly */
-       *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
-       if (data != ixgbe_get_i2c_data(i2cctl)) {
+       *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
+       if (data != ixgbe_get_i2c_data(hw, i2cctl)) {
                status = IXGBE_ERR_I2C;
                ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
                             "Error - I2C data was not set to %X.\n",
@@ -2342,13 +2342,14 @@ STATIC s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
  *
  *  Returns the I2C data bit value
  **/
-STATIC bool ixgbe_get_i2c_data(u32 *i2cctl)
+STATIC bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl)
 {
        bool data;
+       UNREFERENCED_1PARAMETER(hw);
 
        DEBUGFUNC("ixgbe_get_i2c_data");
 
-       if (*i2cctl & IXGBE_I2C_DATA_IN)
+       if (*i2cctl & IXGBE_I2C_DATA_IN_BY_MAC(hw))
                data = 1;
        else
                data = 0;
@@ -2365,7 +2366,7 @@ STATIC bool ixgbe_get_i2c_data(u32 *i2cctl)
  **/
 void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
 {
-       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
        u32 i;
 
        DEBUGFUNC("ixgbe_i2c_bus_clear");
index c47812b..e262cc4 100644 (file)
@@ -82,6 +82,11 @@ POSSIBILITY OF SUCH DAMAGE.
 #define IXGBE_I2C_EEPROM_STATUS_FAIL   0x2
 #define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS    0x3
 
+#define IXGBE_CS4227                   0x9E    /* CS4227 address */
+#define IXGBE_CS4227_SPARE24_LSB       0x12B0  /* Reg to program EDC */
+#define IXGBE_CS4227_EDC_MODE_CX1      0x0002
+#define IXGBE_CS4227_EDC_MODE_SR       0x0004
+
 /* Flow control defines */
 #define IXGBE_TAF_SYM_PAUSE            0x400
 #define IXGBE_TAF_ASM_PAUSE            0x800
index b56cdab..c67d462 100644 (file)
@@ -126,6 +126,15 @@ POSSIBILITY OF SUCH DAMAGE.
 #define IXGBE_DEV_ID_X540_VF                   0x1515
 #define IXGBE_DEV_ID_X540_VF_HV                        0x1530
 #define IXGBE_DEV_ID_X540T1                    0x1560
+#define IXGBE_DEV_ID_X550EM_X                  0x15A7
+#define IXGBE_DEV_ID_X550EM_X_SFP              0x15AC
+#define IXGBE_DEV_ID_X550T                     0x1563
+#define IXGBE_DEV_ID_X550EM_X_KX4              0x15AA
+#define IXGBE_DEV_ID_X550EM_X_KR               0x15AB
+#define IXGBE_DEV_ID_X550_VF_HV                        0x1564
+#define IXGBE_DEV_ID_X550_VF                   0x1565
+#define IXGBE_DEV_ID_X550EM_X_VF               0x15A8
+#define IXGBE_DEV_ID_X550EM_X_VF_HV            0x15A9
 
 /* General Registers */
 #define IXGBE_CTRL             0x00000
@@ -133,7 +142,10 @@ POSSIBILITY OF SUCH DAMAGE.
 #define IXGBE_CTRL_EXT         0x00018
 #define IXGBE_ESDP             0x00020
 #define IXGBE_EODSDP           0x00028
-#define IXGBE_I2CCTL           0x00028
+#define IXGBE_I2CCTL_82599     0x00028
+#define IXGBE_I2CCTL_X550      0x15F5C
+#define IXGBE_I2CCTL_BY_MAC(_hw) ((((_hw)->mac.type >= ixgbe_mac_X550) ? \
+                                IXGBE_I2CCTL_X550 : IXGBE_I2CCTL_82599))
 #define IXGBE_PHY_GPIO         0x00028
 #define IXGBE_MAC_GPIO         0x00030
 #define IXGBE_PHYINT_STATUS0   0x00100
@@ -168,10 +180,14 @@ POSSIBILITY OF SUCH DAMAGE.
 #define IXGBE_VPDDIAG1 0x10208
 
 /* I2CCTL Bit Masks */
-#define IXGBE_I2C_CLK_IN       0x00000001
-#define IXGBE_I2C_CLK_OUT      0x00000002
-#define IXGBE_I2C_DATA_IN      0x00000004
-#define IXGBE_I2C_DATA_OUT     0x00000008
+#define IXGBE_I2C_CLK_IN_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \
+                                       0x00004000 : 0x00000001)
+#define IXGBE_I2C_CLK_OUT_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \
+                                       0x00000200 : 0x00000002)
+#define IXGBE_I2C_DATA_IN_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \
+                                       0x00001000 : 0x00000004)
+#define IXGBE_I2C_DATA_OUT_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \
+                                       0x00000400 : 0x00000008)
 #define IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT     500
 
 #define IXGBE_I2C_THERMAL_SENSOR_ADDR  0xF8
@@ -326,6 +342,8 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4))  /* 64 of these (0-63) */
 #define IXGBE_VLVFB(_i)        (0x0F200 + ((_i) * 4))  /* 128 of these (0-127) */
 #define IXGBE_VMVIR(_i)        (0x08000 + ((_i) * 4))  /* 64 of these (0-63) */
+#define IXGBE_PFFLPL           0x050B0
+#define IXGBE_PFFLPH           0x050B4
 #define IXGBE_VT_CTL           0x051B0
 #define IXGBE_PFMAILBOX(_i)    (0x04B00 + (4 * (_i))) /* 64 total */
 /* 64 Mailboxes, 16 DW each */
@@ -342,6 +360,12 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_MRCTL(_i)                (0x0F600 + ((_i) * 4))
 #define IXGBE_VMRVLAN(_i)      (0x0F610 + ((_i) * 4))
 #define IXGBE_VMRVM(_i)                (0x0F630 + ((_i) * 4))
+#define IXGBE_LVMMC_RX         0x2FA8
+#define IXGBE_LVMMC_TX         0x8108
+#define IXGBE_LMVM_RX          0x2FA4
+#define IXGBE_LMVM_TX          0x8124
+#define IXGBE_WQBR_RX(_i)      (0x2FB0 + ((_i) * 4)) /* 4 total */
+#define IXGBE_WQBR_TX(_i)      (0x8130 + ((_i) * 4)) /* 4 total */
 #define IXGBE_L34T_IMIR(_i)    (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
 #define IXGBE_RXFECCERR0       0x051B8
 #define IXGBE_LLITHRESH                0x0EC90
@@ -350,8 +374,16 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_IMIRVP           0x05AC0
 #define IXGBE_VMD_CTL          0x0581C
 #define IXGBE_RETA(_i)         (0x05C00 + ((_i) * 4))  /* 32 of these (0-31) */
+#define IXGBE_ERETA(_i)                (0x0EE80 + ((_i) * 4))  /* 96 of these (0-95) */
 #define IXGBE_RSSRK(_i)                (0x05C80 + ((_i) * 4))  /* 10 of these (0-9) */
 
+/* Registers for setting up RSS on X550 with SRIOV
+ * _p - pool number (0..63)
+ * _i - index (0..10 for PFVFRSSRK, 0..15 for PFVFRETA)
+ */
+#define IXGBE_PFVFMRQC(_p)     (0x03400 + ((_p) * 4))
+#define IXGBE_PFVFRSSRK(_i, _p)        (0x018000 + ((_i) * 4) + ((_p) * 0x40))
+#define IXGBE_PFVFRETA(_i, _p) (0x019000 + ((_i) * 4) + ((_p) * 0x40))
 
 /* Flow Director registers */
 #define IXGBE_FDIRCTRL 0x0EE00
@@ -405,6 +437,8 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_DMATXCTL_TE      0x1 /* Transmit Enable */
 #define IXGBE_DMATXCTL_NS      0x2 /* No Snoop LSO hdr buffer */
 #define IXGBE_DMATXCTL_GDV     0x8 /* Global Double VLAN */
+#define IXGBE_DMATXCTL_MDP_EN  0x20 /* Bit 5 */
+#define IXGBE_DMATXCTL_MBINTEN 0x40 /* Bit 6 */
 #define IXGBE_DMATXCTL_VT_SHIFT        16  /* VLAN EtherType */
 
 #define IXGBE_PFDTXGSWC_VT_LBEN        0x1 /* Local L2 VT switch enable */
@@ -436,16 +470,22 @@ struct ixgbe_thermal_sensor_data {
 
 #define IXGBE_WUPL     0x05900
 #define IXGBE_WUPM     0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
+#define IXGBE_PROXYS   0x05F60 /* Proxying Status Register */
+#define IXGBE_PROXYFC  0x05F64 /* Proxying Filter Control Register */
+#define IXGBE_VXLANCTRL        0x0000507C /* Rx filter VXLAN UDPPORT Register */
 
-#define IXGBE_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flex host filter table */
+#define IXGBE_FHFT(_n) (0x09000 + ((_n) * 0x100)) /* Flex host filter table */
 /* Ext Flexible Host Filter Table */
-#define IXGBE_FHFT_EXT(_n)     (0x09800 + (_n * 0x100))
+#define IXGBE_FHFT_EXT(_n)     (0x09800 + ((_n) * 0x100))
+#define IXGBE_FHFT_EXT_X550(_n)        (0x09600 + ((_n) * 0x100))
 
 /* Four Flexible Filters are supported */
 #define IXGBE_FLEXIBLE_FILTER_COUNT_MAX                4
 
 /* Six Flexible Filters are supported */
 #define IXGBE_FLEXIBLE_FILTER_COUNT_MAX_6      6
+/* Eight Flexible Filters are supported */
+#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX_8      8
 #define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX    2
 
 /* Each Flexible Filter is at most 128 (0x80) bytes in length */
@@ -478,10 +518,14 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_WUFC_FLX4        0x00100000 /* Flexible Filter 4 Enable */
 #define IXGBE_WUFC_FLX5        0x00200000 /* Flexible Filter 5 Enable */
 #define IXGBE_WUFC_FLX_FILTERS         0x000F0000 /* Mask for 4 flex filters */
+#define IXGBE_WUFC_FLX_FILTERS_6       0x003F0000 /* Mask for 6 flex filters */
+#define IXGBE_WUFC_FLX_FILTERS_8       0x00FF0000 /* Mask for 8 flex filters */
+#define IXGBE_WUFC_FW_RST_WK   0x80000000 /* Ena wake on FW reset assertion */
 /* Mask for Ext. flex filters */
 #define IXGBE_WUFC_EXT_FLX_FILTERS     0x00300000
 #define IXGBE_WUFC_ALL_FILTERS         0x000F00FF /* Mask all 4 flex filters */
 #define IXGBE_WUFC_ALL_FILTERS_6       0x003F00FF /* Mask all 6 flex filters */
+#define IXGBE_WUFC_ALL_FILTERS_8       0x00FF00FF /* Mask all 8 flex filters */
 #define IXGBE_WUFC_FLX_OFFSET  16 /* Offset to the Flexible Filters bits */
 
 /* Wake Up Status */
@@ -501,6 +545,23 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_WUS_FLX4         IXGBE_WUFC_FLX4
 #define IXGBE_WUS_FLX5         IXGBE_WUFC_FLX5
 #define IXGBE_WUS_FLX_FILTERS  IXGBE_WUFC_FLX_FILTERS
+#define IXGBE_WUS_FW_RST_WK    IXGBE_WUFC_FW_RST_WK
+/* Proxy Status */
+#define IXGBE_PROXYS_EX                0x00000004 /* Exact packet received */
+#define IXGBE_PROXYS_ARP_DIR   0x00000020 /* ARP w/filter match received */
+#define IXGBE_PROXYS_NS                0x00000200 /* IPV6 NS received */
+#define IXGBE_PROXYS_NS_DIR    0x00000400 /* IPV6 NS w/DA match received */
+#define IXGBE_PROXYS_ARP       0x00000800 /* ARP request packet received */
+#define IXGBE_PROXYS_MLD       0x00001000 /* IPv6 MLD packet received */
+
+/* Proxying Filter Control */
+#define IXGBE_PROXYFC_ENABLE   0x00000001 /* Port Proxying Enable */
+#define IXGBE_PROXYFC_EX       0x00000004 /* Directed Exact Proxy Enable */
+#define IXGBE_PROXYFC_ARP_DIR  0x00000020 /* Directed ARP Proxy Enable */
+#define IXGBE_PROXYFC_NS       0x00000200 /* IPv6 Neighbor Solicitation */
+#define IXGBE_PROXYFC_ARP      0x00000800 /* ARP Request Proxy Enable */
+#define IXGBE_PROXYFC_MLD      0x00000800 /* IPv6 MLD Proxy Enable */
+#define IXGBE_PROXYFC_NO_TCO   0x00008000 /* Ignore TCO packets */
 
 #define IXGBE_WUPL_LENGTH_MASK 0xFFFF
 
@@ -708,6 +769,8 @@ struct ixgbe_dmac_config {
 
 
 /* FCoE DMA Context Registers */
+/* FCoE Direct DMA Context */
+#define IXGBE_FCDDC(_i, _j)    (0x20000 + ((_i) * 0x4) + ((_j) * 0x10))
 #define IXGBE_FCPTRL           0x02410 /* FC User Desc. PTR Low */
 #define IXGBE_FCPTRH           0x02414 /* FC USer Desc. PTR High */
 #define IXGBE_FCBUFF           0x02418 /* FC Buffer Control */
@@ -731,6 +794,12 @@ struct ixgbe_dmac_config {
 #define IXGBE_REOFF            0x05158 /* Rx FC EOF */
 #define IXGBE_RSOFF            0x051F8 /* Rx FC SOF */
 /* FCoE Filter Context Registers */
+#define IXGBE_FCD_ID           0x05114 /* FCoE D_ID */
+#define IXGBE_FCSMAC           0x0510C /* FCoE Source MAC */
+#define IXGBE_FCFLTRW_SMAC_HIGH_SHIFT  16
+/* FCoE Direct Filter Context */
+#define IXGBE_FCDFC(_i, _j)    (0x28000 + ((_i) * 0x4) + ((_j) * 0x10))
+#define IXGBE_FCDFCD(_i)       (0x30000 + ((_i) * 0x4))
 #define IXGBE_FCFLT            0x05108 /* FC FLT Context */
 #define IXGBE_FCFLTRW          0x05110 /* FC Filter RW Control */
 #define IXGBE_FCPARAM          0x051d8 /* FC Offset Parameter */
@@ -761,6 +830,10 @@ struct ixgbe_dmac_config {
 #define IXGBE_FCRETASEL_ENA    0x2 /* FCoE FCRETASEL bit */
 #define IXGBE_FCRETA_SIZE      8 /* Max entries in FCRETA */
 #define IXGBE_FCRETA_ENTRY_MASK        0x0000007f /* 7 bits for the queue index */
+#define IXGBE_FCRETA_SIZE_X550 32 /* Max entries in FCRETA */
+/* Higher 7 bits for the queue index */
+#define IXGBE_FCRETA_ENTRY_HIGH_MASK   0x007F0000
+#define IXGBE_FCRETA_ENTRY_HIGH_SHIFT  16
 
 /* Stats registers */
 #define IXGBE_CRCERRS  0x04000
@@ -880,6 +953,7 @@ struct ixgbe_dmac_config {
 #define IXGBE_BMCIP_IPADDR_VALID       0x00000002
 
 /* Management Bit Fields and Masks */
+#define IXGBE_MANC_MPROXYE     0x40000000 /* Management Proxy Enable */
 #define IXGBE_MANC_RCV_TCO_EN  0x00020000 /* Rcv TCO packet enable */
 #define IXGBE_MANC_EN_BMC2OS   0x10000000 /* Ena BMC2OS and OS2BMC traffic */
 #define IXGBE_MANC_EN_BMC2OS_SHIFT     28
@@ -942,6 +1016,12 @@ struct ixgbe_dmac_config {
 #define IXGBE_PBACLR_82599     0x11068
 #define IXGBE_CIAA_82599       0x11088
 #define IXGBE_CIAD_82599       0x1108C
+#define IXGBE_CIAA_X550                0x11508
+#define IXGBE_CIAD_X550                0x11510
+#define IXGBE_CIAA_BY_MAC(_hw) ((((_hw)->mac.type >= ixgbe_mac_X550) ? \
+                                IXGBE_CIAA_X550 : IXGBE_CIAA_82599))
+#define IXGBE_CIAD_BY_MAC(_hw) ((((_hw)->mac.type >= ixgbe_mac_X550) ? \
+                                IXGBE_CIAD_X550 : IXGBE_CIAD_82599))
 #define IXGBE_PICAUSE          0x110B0
 #define IXGBE_PIENA            0x110B8
 #define IXGBE_CDQ_MBR_82599    0x110B4
@@ -978,6 +1058,7 @@ struct ixgbe_dmac_config {
 #define IXGBE_TXSTMPH  0x08C08 /* Tx timestamp value High - RO */
 #define IXGBE_SYSTIML  0x08C0C /* System time register Low - RO */
 #define IXGBE_SYSTIMH  0x08C10 /* System time register High - RO */
+#define IXGBE_SYSTIMR  0x08C58 /* System time register Residue - RO */
 #define IXGBE_TIMINCA  0x08C14 /* Increment attributes register - RW */
 #define IXGBE_TIMADJL  0x08C18 /* Time Adjustment Offset register Low - RW */
 #define IXGBE_TIMADJH  0x08C1C /* Time Adjustment Offset register High - RW */
@@ -994,6 +1075,9 @@ struct ixgbe_dmac_config {
 #define IXGBE_AUXSTMPH0        0x08C40 /* Auxiliary Time Stamp 0 register High - RO */
 #define IXGBE_AUXSTMPL1        0x08C44 /* Auxiliary Time Stamp 1 register Low - RO */
 #define IXGBE_AUXSTMPH1        0x08C48 /* Auxiliary Time Stamp 1 register High - RO */
+#define IXGBE_TSIM     0x08C68 /* TimeSync Interrupt Mask Register - RW */
+#define IXGBE_TSICR    0x08C60 /* TimeSync Interrupt Cause Register - WO */
+#define IXGBE_TSSDP    0x0003C /* TimeSync SDP Configuration Register - RW */
 
 /* Diagnostic Registers */
 #define IXGBE_RDSTATCTL                0x02C20
@@ -1150,6 +1234,7 @@ struct ixgbe_dmac_config {
 /* RDRXCTL Bit Masks */
 #define IXGBE_RDRXCTL_RDMTS_1_2                0x00000000 /* Rx Desc Min THLD Size */
 #define IXGBE_RDRXCTL_CRCSTRIP         0x00000002 /* CRC Strip */
+#define IXGBE_RDRXCTL_PSP              0x00000004 /* Pad Small Packet */
 #define IXGBE_RDRXCTL_MVMEN            0x00000020
 #define IXGBE_RDRXCTL_RSC_PUSH_DIS     0x00000020
 #define IXGBE_RDRXCTL_DMAIDONE         0x00000008 /* DMA init cycle done */
@@ -1159,6 +1244,8 @@ struct ixgbe_dmac_config {
 #define IXGBE_RDRXCTL_RSCLLIDIS                0x00800000 /* Disable RSC compl on LLI*/
 #define IXGBE_RDRXCTL_RSCACKC          0x02000000 /* must set 1 when RSC ena */
 #define IXGBE_RDRXCTL_FCOE_WRFIX       0x04000000 /* must set 1 when RSC ena */
+#define IXGBE_RDRXCTL_MBINTEN          0x10000000
+#define IXGBE_RDRXCTL_MDP_EN           0x20000000
 
 /* RQTC Bit Masks and Shifts */
 #define IXGBE_RQTC_SHIFT_TC(_i)        ((_i) * 4)
@@ -1337,6 +1424,7 @@ struct ixgbe_dmac_config {
 #define TN1010_PHY_ID  0x00A19410
 #define TNX_FW_REV     0xB
 #define X540_PHY_ID    0x01540200
+#define X550_PHY_ID    0x01540220
 #define AQ_FW_REV      0x20
 #define QT2022_PHY_ID  0x0043A400
 #define ATH_PHY_ID     0x03429050
@@ -1692,12 +1780,14 @@ enum {
  *     1588 (0x88f7):   Filter 3
  *     FIP  (0x8914):   Filter 4
  *     LLDP (0x88CC):   Filter 5
+ *     LACP (0x8809):   Filter 6
  */
 #define IXGBE_ETQF_FILTER_EAPOL                0
 #define IXGBE_ETQF_FILTER_FCOE         2
 #define IXGBE_ETQF_FILTER_1588         3
 #define IXGBE_ETQF_FILTER_FIP          4
 #define IXGBE_ETQF_FILTER_LLDP         5
+#define IXGBE_ETQF_FILTER_LACP         6
 /* VLAN Control Bit Masks */
 #define IXGBE_VLNCTRL_VET              0x0000FFFF  /* bits 0-15 */
 #define IXGBE_VLNCTRL_CFI              0x10000000  /* bit 28 */
@@ -1842,6 +1932,7 @@ enum {
 #define IXGBE_LINKS_TL_FAULT           0x00001000
 #define IXGBE_LINKS_SIGNAL             0x00000F00
 
+#define IXGBE_LINKS_SPEED_NON_STD      0x08000000
 #define IXGBE_LINKS_SPEED_82599                0x30000000
 #define IXGBE_LINKS_SPEED_10G_82599    0x30000000
 #define IXGBE_LINKS_SPEED_1G_82599     0x20000000
@@ -1922,6 +2013,9 @@ enum {
 #define IXGBE_EEPROM_WORD_SIZE_SHIFT   6
 #define IXGBE_EEPROM_OPCODE_BITS       8
 
+/* FLA Register */
+#define IXGBE_FLA_LOCKED       0x00000040
+
 /* Part Number String Length */
 #define IXGBE_PBANUM_LENGTH    11
 
@@ -1943,6 +2037,11 @@ enum {
 #define IXGBE_MAC1_PTR                 0x0C
 #define IXGBE_CSR0_CONFIG_PTR          0x0D
 #define IXGBE_CSR1_CONFIG_PTR          0x0E
+#define IXGBE_PCIE_ANALOG_PTR_X550     0x02
+#define IXGBE_SHADOW_RAM_SIZE_X550     0x4000
+#define IXGBE_IXGBE_PCIE_GENERAL_SIZE  0x24
+#define IXGBE_PCIE_CONFIG_SIZE         0x08
+#define IXGBE_EEPROM_LAST_WORD         0x41
 #define IXGBE_FW_PTR                   0x0F
 #define IXGBE_PBANUM0_PTR              0x15
 #define IXGBE_PBANUM1_PTR              0x16
@@ -2155,6 +2254,14 @@ enum {
 #define IXGBE_TSAUXC_EN_CLK            0x00000004
 #define IXGBE_TSAUXC_SYNCLK            0x00000008
 #define IXGBE_TSAUXC_SDP0_INT          0x00000040
+#define IXGBE_TSAUXC_EN_TT0            0x00000001
+#define IXGBE_TSAUXC_EN_TT1            0x00000002
+#define IXGBE_TSAUXC_ST0               0x00000010
+#define IXGBE_TSAUXC_DISABLE_SYSTIME   0x80000000
+
+#define IXGBE_TSSDP_TS_SDP0_SEL_MASK   0x000000C0
+#define IXGBE_TSSDP_TS_SDP0_CLK0       0x00000080
+#define IXGBE_TSSDP_TS_SDP0_EN         0x00000100
 
 #define IXGBE_TSYNCTXCTL_VALID         0x00000001 /* Tx timestamp valid */
 #define IXGBE_TSYNCTXCTL_ENABLED       0x00000010 /* Tx timestamping enabled */
@@ -2164,8 +2271,19 @@ enum {
 #define IXGBE_TSYNCRXCTL_TYPE_L2_V2    0x00
 #define IXGBE_TSYNCRXCTL_TYPE_L4_V1    0x02
 #define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
+#define IXGBE_TSYNCRXCTL_TYPE_ALL      0x08
 #define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
 #define IXGBE_TSYNCRXCTL_ENABLED       0x00000010 /* Rx Timestamping enabled */
+#define IXGBE_TSYNCRXCTL_TSIP_UT_EN    0x00800000 /* Rx Timestamp in Packet */
+#define IXGBE_TSYNCRXCTL_TSIP_UP_MASK  0xFF000000 /* Rx Timestamp UP Mask */
+
+#define IXGBE_TSIM_SYS_WRAP            0x00000001
+#define IXGBE_TSIM_TXTS                        0x00000002
+#define IXGBE_TSIM_TADJ                        0x00000080
+
+#define IXGBE_TSICR_SYS_WRAP           IXGBE_TSIM_SYS_WRAP
+#define IXGBE_TSICR_TXTS               IXGBE_TSIM_TXTS
+#define IXGBE_TSICR_TADJ               IXGBE_TSIM_TADJ
 
 #define IXGBE_RXMTRL_V1_CTRLT_MASK     0x000000FF
 #define IXGBE_RXMTRL_V1_SYNC_MSG       0x00
@@ -2224,10 +2342,12 @@ enum {
 #define IXGBE_MRQC_RSS_FIELD_IPV4_UDP  0x00400000
 #define IXGBE_MRQC_RSS_FIELD_IPV6_UDP  0x00800000
 #define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000
+#define IXGBE_MRQC_MULTIPLE_RSS                0x00002000
 #define IXGBE_MRQC_L3L4TXSWEN          0x00008000
 
 /* Queue Drop Enable */
 #define IXGBE_QDE_ENABLE       0x00000001
+#define IXGBE_QDE_HIDE_VLAN    0x00000002
 #define IXGBE_QDE_IDX_MASK     0x00007F00
 #define IXGBE_QDE_IDX_SHIFT    8
 #define IXGBE_QDE_WRITE                0x00010000
@@ -2269,10 +2389,12 @@ enum {
 #define IXGBE_RXD_STAT_IPCS    0x40 /* IP xsum calculated */
 #define IXGBE_RXD_STAT_PIF     0x80 /* passed in-exact filter */
 #define IXGBE_RXD_STAT_CRCV    0x100 /* Speculative CRC Valid */
+#define IXGBE_RXD_STAT_OUTERIPCS       0x100 /* Cloud IP xsum calculated */
 #define IXGBE_RXD_STAT_VEXT    0x200 /* 1st VLAN found */
 #define IXGBE_RXD_STAT_UDPV    0x400 /* Valid UDP checksum */
 #define IXGBE_RXD_STAT_DYNINT  0x800 /* Pkt caused INT via DYNINT */
 #define IXGBE_RXD_STAT_LLINT   0x800 /* Pkt caused Low Latency Interrupt */
+#define IXGBE_RXD_STAT_TSIP    0x08000 /* Time Stamp in packet buffer */
 #define IXGBE_RXD_STAT_TS      0x10000 /* Time Stamp */
 #define IXGBE_RXD_STAT_SECP    0x20000 /* Security Processing */
 #define IXGBE_RXD_STAT_LB      0x40000 /* Loopback Status */
@@ -2286,6 +2408,7 @@ enum {
 #define IXGBE_RXD_ERR_IPE      0x80 /* IP Checksum Error */
 #define IXGBE_RXDADV_ERR_MASK          0xfff00000 /* RDESC.ERRORS mask */
 #define IXGBE_RXDADV_ERR_SHIFT         20 /* RDESC.ERRORS shift */
+#define IXGBE_RXDADV_ERR_OUTERIPER     0x04000000 /* CRC IP Header error */
 #define IXGBE_RXDADV_ERR_RXE           0x20000000 /* Any MAC Error */
 #define IXGBE_RXDADV_ERR_FCEOFE                0x80000000 /* FCoEFe/IPE */
 #define IXGBE_RXDADV_ERR_FCERR         0x00700000 /* FCERR/FDIRERR */
@@ -2318,6 +2441,7 @@ enum {
 #define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP        0x00000020 /* 10: Recv. FCP_RSP */
 #define IXGBE_RXDADV_STAT_FCSTAT_DDP   0x00000030 /* 11: Ctxt w/ DDP */
 #define IXGBE_RXDADV_STAT_TS           0x00010000 /* IEEE1588 Time Stamp */
+#define IXGBE_RXDADV_STAT_TSIP         0x00008000 /* Time Stamp in packet buffer */
 
 /* PSRTYPE bit definitions */
 #define IXGBE_PSRTYPE_TCPHDR   0x00000010
@@ -2379,6 +2503,8 @@ enum {
 #define IXGBE_RXDADV_PKTTYPE_UDP       0x00000200 /* UDP hdr present */
 #define IXGBE_RXDADV_PKTTYPE_SCTP      0x00000400 /* SCTP hdr present */
 #define IXGBE_RXDADV_PKTTYPE_NFS       0x00000800 /* NFS hdr present */
+#define IXGBE_RXDADV_PKTTYPE_VXLAN     0x00000800 /* VXLAN hdr present */
+#define IXGBE_RXDADV_PKTTYPE_TUNNEL    0x00010000 /* Tunnel type */
 #define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */
 #define IXGBE_RXDADV_PKTTYPE_IPSEC_AH  0x00002000 /* IPSec AH */
 #define IXGBE_RXDADV_PKTTYPE_LINKSEC   0x00004000 /* LinkSec Encap */
@@ -2429,6 +2555,68 @@ enum {
 #define IXGBE_MBVFICR(_i)              (0x00710 + ((_i) * 4))
 #define IXGBE_VFLRE(_i)                        (((_i & 1) ? 0x001C0 : 0x00600))
 #define IXGBE_VFLREC(_i)                (0x00700 + ((_i) * 4))
+/* Translated register #defines */
+#define IXGBE_PVFCTRL(P)       (0x00300 + (4 * (P)))
+#define IXGBE_PVFSTATUS(P)     (0x00008 + (0 * (P)))
+#define IXGBE_PVFLINKS(P)      (0x042A4 + (0 * (P)))
+#define IXGBE_PVFRTIMER(P)     (0x00048 + (0 * (P)))
+#define IXGBE_PVFMAILBOX(P)    (0x04C00 + (4 * (P)))
+#define IXGBE_PVFRXMEMWRAP(P)  (0x03190 + (0 * (P)))
+#define IXGBE_PVTEICR(P)       (0x00B00 + (4 * (P)))
+#define IXGBE_PVTEICS(P)       (0x00C00 + (4 * (P)))
+#define IXGBE_PVTEIMS(P)       (0x00D00 + (4 * (P)))
+#define IXGBE_PVTEIMC(P)       (0x00E00 + (4 * (P)))
+#define IXGBE_PVTEIAC(P)       (0x00F00 + (4 * (P)))
+#define IXGBE_PVTEIAM(P)       (0x04D00 + (4 * (P)))
+#define IXGBE_PVTEITR(P)       (((P) < 24) ? (0x00820 + ((P) * 4)) : \
+                                (0x012300 + (((P) - 24) * 4)))
+#define IXGBE_PVTIVAR(P)       (0x12500 + (4 * (P)))
+#define IXGBE_PVTIVAR_MISC(P)  (0x04E00 + (4 * (P)))
+#define IXGBE_PVTRSCINT(P)     (0x12000 + (4 * (P)))
+#define IXGBE_VFPBACL(P)       (0x110C8 + (4 * (P)))
+#define IXGBE_PVFRDBAL(P)      ((P < 64) ? (0x01000 + (0x40 * (P))) \
+                                : (0x0D000 + (0x40 * ((P) - 64))))
+#define IXGBE_PVFRDBAH(P)      ((P < 64) ? (0x01004 + (0x40 * (P))) \
+                                : (0x0D004 + (0x40 * ((P) - 64))))
+#define IXGBE_PVFRDLEN(P)      ((P < 64) ? (0x01008 + (0x40 * (P))) \
+                                : (0x0D008 + (0x40 * ((P) - 64))))
+#define IXGBE_PVFRDH(P)                ((P < 64) ? (0x01010 + (0x40 * (P))) \
+                                : (0x0D010 + (0x40 * ((P) - 64))))
+#define IXGBE_PVFRDT(P)                ((P < 64) ? (0x01018 + (0x40 * (P))) \
+                                : (0x0D018 + (0x40 * ((P) - 64))))
+#define IXGBE_PVFRXDCTL(P)     ((P < 64) ? (0x01028 + (0x40 * (P))) \
+                                : (0x0D028 + (0x40 * ((P) - 64))))
+#define IXGBE_PVFSRRCTL(P)     ((P < 64) ? (0x01014 + (0x40 * (P))) \
+                                : (0x0D014 + (0x40 * ((P) - 64))))
+#define IXGBE_PVFPSRTYPE(P)    (0x0EA00 + (4 * (P)))
+#define IXGBE_PVFTDBAL(P)      (0x06000 + (0x40 * (P)))
+#define IXGBE_PVFTDBAH(P)      (0x06004 + (0x40 * (P)))
+#define IXGBE_PVFTTDLEN(P)     (0x06008 + (0x40 * (P)))
+#define IXGBE_PVFTDH(P)                (0x06010 + (0x40 * (P)))
+#define IXGBE_PVFTDT(P)                (0x06018 + (0x40 * (P)))
+#define IXGBE_PVFTXDCTL(P)     (0x06028 + (0x40 * (P)))
+#define IXGBE_PVFTDWBAL(P)     (0x06038 + (0x40 * (P)))
+#define IXGBE_PVFTDWBAH(P)     (0x0603C + (0x40 * (P)))
+#define IXGBE_PVFDCA_RXCTRL(P) (((P) < 64) ? (0x0100C + (0x40 * (P))) \
+                                : (0x0D00C + (0x40 * ((P) - 64))))
+#define IXGBE_PVFDCA_TXCTRL(P) (0x0600C + (0x40 * (P)))
+#define IXGBE_PVFGPRC(x)       (0x0101C + (0x40 * (x)))
+#define IXGBE_PVFGPTC(x)       (0x08300 + (0x04 * (x)))
+#define IXGBE_PVFGORC_LSB(x)   (0x01020 + (0x40 * (x)))
+#define IXGBE_PVFGORC_MSB(x)   (0x0D020 + (0x40 * (x)))
+#define IXGBE_PVFGOTC_LSB(x)   (0x08400 + (0x08 * (x)))
+#define IXGBE_PVFGOTC_MSB(x)   (0x08404 + (0x08 * (x)))
+#define IXGBE_PVFMPRC(x)       (0x0D01C + (0x40 * (x)))
+
+#define IXGBE_PVFTDWBALn(q_per_pool, vf_number, vf_q_index) \
+               (IXGBE_PVFTDWBAL((q_per_pool)*(vf_number) + (vf_q_index)))
+#define IXGBE_PVFTDWBAHn(q_per_pool, vf_number, vf_q_index) \
+               (IXGBE_PVFTDWBAH((q_per_pool)*(vf_number) + (vf_q_index)))
+
+#define IXGBE_PVFTDHn(q_per_pool, vf_number, vf_q_index) \
+               (IXGBE_PVFTDH((q_per_pool)*(vf_number) + (vf_q_index)))
+#define IXGBE_PVFTDTn(q_per_pool, vf_number, vf_q_index) \
+               (IXGBE_PVFTDT((q_per_pool)*(vf_number) + (vf_q_index)))
 
 /* Little Endian defines */
 #ifndef __le16
@@ -2552,7 +2740,17 @@ enum ixgbe_fdir_pballoc_type {
 #define FW_CEM_UNUSED_VER              0x0
 #define FW_CEM_MAX_RETRIES             3
 #define FW_CEM_RESP_STATUS_SUCCESS     0x1
-
+#define FW_READ_SHADOW_RAM_CMD         0x31
+#define FW_READ_SHADOW_RAM_LEN         0x6
+#define FW_WRITE_SHADOW_RAM_CMD                0x33
+#define FW_WRITE_SHADOW_RAM_LEN                0xA /* 8 plus 1 WORD to write */
+#define FW_SHADOW_RAM_DUMP_CMD         0x36
+#define FW_SHADOW_RAM_DUMP_LEN         0
+#define FW_DEFAULT_CHECKSUM            0xFF /* checksum always 0xFF */
+#define FW_NVM_DATA_OFFSET             3
+#define FW_MAX_READ_BUFFER_SIZE                1024
+#define FW_DISABLE_RXEN_CMD            0xDE
+#define FW_DISABLE_RXEN_LEN            0x1
 /* Host Interface Command Structures */
 
 struct ixgbe_hic_hdr {
@@ -2565,6 +2763,13 @@ struct ixgbe_hic_hdr {
        u8 checksum;
 };
 
+struct ixgbe_hic_hdr2 {
+       u8 cmd;
+       u8 buf_len1;
+       u8 buf_len2;
+       u8 checksum;
+};
+
 struct ixgbe_hic_drv_info {
        struct ixgbe_hic_hdr hdr;
        u8 port_num;
@@ -2576,6 +2781,33 @@ struct ixgbe_hic_drv_info {
        u16 pad2; /* end spacing to ensure length is mult. of dword2 */
 };
 
+/* These need to be dword aligned */
+struct ixgbe_hic_read_shadow_ram {
+       struct ixgbe_hic_hdr2 hdr;
+       u32 address;
+       u16 length;
+       u16 pad2;
+       u16 data;
+       u16 pad3;
+};
+
+struct ixgbe_hic_write_shadow_ram {
+       struct ixgbe_hic_hdr2 hdr;
+       u32 address;
+       u16 length;
+       u16 pad2;
+       u16 data;
+       u16 pad3;
+};
+
+struct ixgbe_hic_disable_rxen {
+       struct ixgbe_hic_hdr hdr;
+       u8  port_number;
+       u8  pad2;
+       u16 pad3;
+};
+
+
 /* Transmit Descriptor - Legacy */
 struct ixgbe_legacy_tx_desc {
        u64 buffer_addr; /* Address of the descriptor's data buffer */
@@ -2717,6 +2949,12 @@ struct ixgbe_adv_tx_context_desc {
 #define IXGBE_ADVTXD_L4LEN_SHIFT       8  /* Adv ctxt L4LEN shift */
 #define IXGBE_ADVTXD_MSS_SHIFT         16  /* Adv ctxt MSS shift */
 
+#define IXGBE_ADVTXD_OUTER_IPLEN       16 /* Adv ctxt OUTERIPLEN shift */
+#define IXGBE_ADVTXD_TUNNEL_LEN        24 /* Adv ctxt TUNNELLEN shift */
+#define IXGBE_ADVTXD_TUNNEL_TYPE_SHIFT 16 /* Adv Tx Desc Tunnel Type shift */
+#define IXGBE_ADVTXD_OUTERIPCS_SHIFT   17 /* Adv Tx Desc OUTERIPCS Shift */
+#define IXGBE_ADVTXD_TUNNEL_TYPE_NVGRE 1  /* Adv Tx Desc Tunnel Type NVGRE */
+
 /* Autonegotiation advertised speeds */
 typedef u32 ixgbe_autoneg_advertised;
 /* Link speed */
@@ -2724,6 +2962,7 @@ typedef u32 ixgbe_link_speed;
 #define IXGBE_LINK_SPEED_UNKNOWN       0
 #define IXGBE_LINK_SPEED_100_FULL      0x0008
 #define IXGBE_LINK_SPEED_1GB_FULL      0x0020
+#define IXGBE_LINK_SPEED_2_5GB_FULL    0x0040
 #define IXGBE_LINK_SPEED_10GB_FULL     0x0080
 #define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \
                                         IXGBE_LINK_SPEED_10GB_FULL)
@@ -2920,6 +3159,15 @@ enum ixgbe_mac_type {
        ixgbe_mac_82599_vf,
        ixgbe_mac_X540,
        ixgbe_mac_X540_vf,
+       /*
+        * X550EM MAC type decoder:
+        * ixgbe_mac_X550EM_x: "x" = Xeon
+        * ixgbe_mac_X550EM_a: "a" = Atom
+        */
+       ixgbe_mac_X550,
+       ixgbe_mac_X550EM_x,
+       ixgbe_mac_X550_vf,
+       ixgbe_mac_X550EM_x_vf,
        ixgbe_num_macs
 };
 
@@ -2928,6 +3176,8 @@ enum ixgbe_phy_type {
        ixgbe_phy_none,
        ixgbe_phy_tn,
        ixgbe_phy_aq,
+       ixgbe_phy_x550em_kr,
+       ixgbe_phy_x550em_kx4,
        ixgbe_phy_cu_unknown,
        ixgbe_phy_qt,
        ixgbe_phy_xaui,
@@ -3455,6 +3705,44 @@ struct ixgbe_hw {
 #define IXGBE_NOT_IMPLEMENTED                  0x7FFFFFFF
 
 
+#define IXGBE_KRM_PORT_CAR_GEN_CTRL(P) ((P == 0) ? (0x4010) : (0x8010))
+#define IXGBE_KRM_LINK_CTRL_1(P)       ((P == 0) ? (0x420C) : (0x820C))
+#define IXGBE_KRM_DSP_TXFFE_STATE_4(P) ((P == 0) ? (0x4634) : (0x8634))
+#define IXGBE_KRM_DSP_TXFFE_STATE_5(P) ((P == 0) ? (0x4638) : (0x8638))
+#define IXGBE_KRM_RX_TRN_LINKUP_CTRL(P)        ((P == 0) ? (0x4B00) : (0x8B00))
+#define IXGBE_KRM_PMD_DFX_BURNIN(P)    ((P == 0) ? (0x4E00) : (0x8E00))
+#define IXGBE_KRM_TX_COEFF_CTRL_1(P)   ((P == 0) ? (0x5520) : (0x9520))
+#define IXGBE_KRM_RX_ANA_CTL(P)                ((P == 0) ? (0x5A00) : (0x9A00))
+
+#define IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B           (1 << 9)
+#define IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS         (1 << 11)
+
+#define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK    (0x7 << 8)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G      (2 << 8)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G     (4 << 8)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ          (1 << 14)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC          (1 << 15)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX           (1 << 16)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR           (1 << 18)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX          (1 << 24)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR          (1 << 26)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE           (1 << 29)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART          (1 << 31)
+
+#define IXGBE_KRM_DSP_TXFFE_STATE_C0_EN                        (1 << 6)
+#define IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN           (1 << 15)
+#define IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN          (1 << 16)
+
+#define IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL  (1 << 4)
+#define IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS   (1 << 2)
+
+#define IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK      (0x3 << 16)
+
+#define IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN     (1 << 1)
+#define IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN      (1 << 2)
+#define IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN             (1 << 3)
+#define IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN             (1 << 31)
+
 #define IXGBE_SB_IOSF_INDIRECT_CTRL    0x00011144
 #define IXGBE_SB_IOSF_INDIRECT_DATA    0x00011148
 
index b84b4ba..3c1c168 100644 (file)
@@ -84,6 +84,9 @@ POSSIBILITY OF SUCH DAMAGE.
 #define IXGBE_VFGOTC_LSB       0x02020
 #define IXGBE_VFGOTC_MSB       0x02024
 #define IXGBE_VFMPRC           0x01034
+#define IXGBE_VFMRQC           0x3000
+#define IXGBE_VFRSSRK(x)       (0x3100 + ((x) * 4))
+#define IXGBE_VFRETA(x)        (0x3200 + ((x) * 4))
 
 
 struct ixgbevf_hw_stats {
diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.c
new file mode 100644 (file)
index 0000000..06d66dd
--- /dev/null
@@ -0,0 +1,1809 @@
+/*******************************************************************************
+
+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_x550.h"
+#include "ixgbe_x540.h"
+#include "ixgbe_type.h"
+#include "ixgbe_api.h"
+#include "ixgbe_common.h"
+#include "ixgbe_phy.h"
+
+/**
+ *  ixgbe_init_ops_X550 - Inits func ptrs and MAC type
+ *  @hw: pointer to hardware structure
+ *
+ *  Initialize the function pointers and assign the MAC type for X550.
+ *  Does not touch the hardware.
+ **/
+s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw)
+{
+       struct ixgbe_mac_info *mac = &hw->mac;
+       struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+       s32 ret_val;
+
+       DEBUGFUNC("ixgbe_init_ops_X550");
+
+       ret_val = ixgbe_init_ops_X540(hw);
+       mac->ops.dmac_config = &ixgbe_dmac_config_X550;
+       mac->ops.dmac_config_tcs = &ixgbe_dmac_config_tcs_X550;
+       mac->ops.dmac_update_tcs = &ixgbe_dmac_update_tcs_X550;
+       mac->ops.setup_eee = &ixgbe_setup_eee_X550;
+       mac->ops.set_source_address_pruning =
+                       &ixgbe_set_source_address_pruning_X550;
+       mac->ops.set_ethertype_anti_spoofing =
+                       &ixgbe_set_ethertype_anti_spoofing_X550;
+
+       mac->ops.get_rtrup2tc = &ixgbe_dcb_get_rtrup2tc_generic;
+       eeprom->ops.init_params = &ixgbe_init_eeprom_params_X550;
+       eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_X550;
+       eeprom->ops.read = &ixgbe_read_ee_hostif_X550;
+       eeprom->ops.read_buffer = &ixgbe_read_ee_hostif_buffer_X550;
+       eeprom->ops.write = &ixgbe_write_ee_hostif_X550;
+       eeprom->ops.write_buffer = &ixgbe_write_ee_hostif_buffer_X550;
+       eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_X550;
+       eeprom->ops.validate_checksum = &ixgbe_validate_eeprom_checksum_X550;
+
+       mac->ops.disable_mdd = &ixgbe_disable_mdd_X550;
+       mac->ops.enable_mdd = &ixgbe_enable_mdd_X550;
+       mac->ops.mdd_event = &ixgbe_mdd_event_X550;
+       mac->ops.restore_mdd_vf = &ixgbe_restore_mdd_vf_X550;
+       mac->ops.disable_rx = &ixgbe_disable_rx_x550;
+       return ret_val;
+}
+
+/**
+ * ixgbe_identify_phy_x550em - Get PHY type based on device id
+ * @hw: pointer to hardware structure
+ *
+ * Returns error code
+ */
+STATIC s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
+{
+       u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+       switch (hw->device_id) {
+       case IXGBE_DEV_ID_X550EM_X_SFP:
+               /* set up for CS4227 usage */
+               hw->phy.lan_id = IXGBE_READ_REG(hw, IXGBE_STATUS) &
+                                IXGBE_STATUS_LAN_ID_1;
+               hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
+               if (hw->phy.lan_id) {
+
+                       esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
+                       esdp |= IXGBE_ESDP_SDP1_DIR;
+               }
+               esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
+               IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+
+               return ixgbe_identify_module_generic(hw);
+               break;
+       case IXGBE_DEV_ID_X550EM_X_KX4:
+               hw->phy.type = ixgbe_phy_x550em_kx4;
+               break;
+       case IXGBE_DEV_ID_X550EM_X_KR:
+       case IXGBE_DEV_ID_X550EM_X:
+               hw->phy.type = ixgbe_phy_x550em_kr;
+               break;
+       default:
+               break;
+       }
+       return IXGBE_SUCCESS;
+}
+
+STATIC s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
+                                    u32 device_type, u16 *phy_data)
+{
+       UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data);
+       return IXGBE_NOT_IMPLEMENTED;
+}
+
+STATIC s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
+                                     u32 device_type, u16 phy_data)
+{
+       UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data);
+       return IXGBE_NOT_IMPLEMENTED;
+}
+
+/**
+*  ixgbe_init_ops_X550EM - Inits func ptrs and MAC type
+*  @hw: pointer to hardware structure
+*
+*  Initialize the function pointers and for MAC type X550EM.
+*  Does not touch the hardware.
+**/
+s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
+{
+       struct ixgbe_mac_info *mac = &hw->mac;
+       struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+       struct ixgbe_phy_info *phy = &hw->phy;
+       s32 ret_val;
+
+       DEBUGFUNC("ixgbe_init_ops_X550EM");
+
+       /* Similar to X550 so start there. */
+       ret_val = ixgbe_init_ops_X550(hw);
+
+       /* Since this function eventually calls
+        * ixgbe_init_ops_540 by design, we are setting
+        * the pointers to NULL explicitly here to overwrite
+        * the values being set in the x540 function.
+        */
+       /* Thermal sensor not supported in x550EM */
+       mac->ops.get_thermal_sensor_data = NULL;
+       mac->ops.init_thermal_sensor_thresh = NULL;
+       mac->thermal_sensor_enabled = false;
+
+       /* FCOE not supported in x550EM */
+       mac->ops.get_san_mac_addr = NULL;
+       mac->ops.set_san_mac_addr = NULL;
+       mac->ops.get_wwn_prefix = NULL;
+       mac->ops.get_fcoe_boot_status = NULL;
+
+       /* IPsec not supported in x550EM */
+       mac->ops.disable_sec_rx_path = NULL;
+       mac->ops.enable_sec_rx_path = NULL;
+
+       /* PCIe bus info not supported in X550EM */
+       mac->ops.get_bus_info = NULL;
+
+       mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
+       mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
+       mac->ops.get_media_type = &ixgbe_get_media_type_X550em;
+       mac->ops.setup_sfp = &ixgbe_setup_sfp_modules_X550em;
+       mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_X550em;
+       mac->ops.reset_hw = &ixgbe_reset_hw_X550em;
+       mac->ops.get_supported_physical_layer =
+                                   &ixgbe_get_supported_physical_layer_X550em;
+
+       /* PHY */
+       phy->ops.init = &ixgbe_init_phy_ops_X550em;
+       phy->ops.identify = &ixgbe_identify_phy_x550em;
+       phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
+       phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
+       phy->ops.setup_link = ixgbe_setup_kr_x550em;
+
+
+       /* EEPROM */
+       eeprom->ops.init_params = &ixgbe_init_eeprom_params_X540;
+       eeprom->ops.read = &ixgbe_read_ee_hostif_X550;
+       eeprom->ops.read_buffer = &ixgbe_read_ee_hostif_buffer_X550;
+       eeprom->ops.write = &ixgbe_write_ee_hostif_X550;
+       eeprom->ops.write_buffer = &ixgbe_write_ee_hostif_buffer_X550;
+       eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_X550;
+       eeprom->ops.validate_checksum = &ixgbe_validate_eeprom_checksum_X550;
+       eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_X550;
+
+       return ret_val;
+}
+
+/**
+ *  ixgbe_dmac_config_X550
+ *  @hw: pointer to hardware structure
+ *
+ *  Configure DMA coalescing. If enabling dmac, dmac is activated.
+ *  When disabling dmac, dmac enable dmac bit is cleared.
+ **/
+s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw)
+{
+       u32 reg, high_pri_tc;
+
+       DEBUGFUNC("ixgbe_dmac_config_X550");
+
+       /* Disable DMA coalescing before configuring */
+       reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
+       reg &= ~IXGBE_DMACR_DMAC_EN;
+       IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
+
+       /* Disable DMA Coalescing if the watchdog timer is 0 */
+       if (!hw->mac.dmac_config.watchdog_timer)
+               goto out;
+
+       ixgbe_dmac_config_tcs_X550(hw);
+
+       /* Configure DMA Coalescing Control Register */
+       reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
+
+       /* Set the watchdog timer in units of 40.96 usec */
+       reg &= ~IXGBE_DMACR_DMACWT_MASK;
+       reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096;
+
+       reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK;
+       /* If fcoe is enabled, set high priority traffic class */
+       if (hw->mac.dmac_config.fcoe_en) {
+               high_pri_tc = 1 << hw->mac.dmac_config.fcoe_tc;
+               reg |= ((high_pri_tc << IXGBE_DMACR_HIGH_PRI_TC_SHIFT) &
+                       IXGBE_DMACR_HIGH_PRI_TC_MASK);
+       }
+       reg |= IXGBE_DMACR_EN_MNG_IND;
+
+       /* Enable DMA coalescing after configuration */
+       reg |= IXGBE_DMACR_DMAC_EN;
+       IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
+
+out:
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  ixgbe_dmac_config_tcs_X550
+ *  @hw: pointer to hardware structure
+ *
+ *  Configure DMA coalescing threshold per TC. The dmac enable bit must
+ *  be cleared before configuring.
+ **/
+s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw)
+{
+       u32 tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb;
+
+       DEBUGFUNC("ixgbe_dmac_config_tcs_X550");
+
+       /* Configure DMA coalescing enabled */
+       switch (hw->mac.dmac_config.link_speed) {
+       case IXGBE_LINK_SPEED_100_FULL:
+               pb_headroom = IXGBE_DMACRXT_100M;
+               break;
+       case IXGBE_LINK_SPEED_1GB_FULL:
+               pb_headroom = IXGBE_DMACRXT_1G;
+               break;
+       default:
+               pb_headroom = IXGBE_DMACRXT_10G;
+               break;
+       }
+
+       maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >>
+                            IXGBE_MHADD_MFS_SHIFT) / 1024);
+
+       /* Set the per Rx packet buffer receive threshold */
+       for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
+               reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc));
+               reg &= ~IXGBE_DMCTH_DMACRXT_MASK;
+
+               if (tc < hw->mac.dmac_config.num_tcs) {
+                       /* Get Rx PB size */
+                       rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc));
+                       rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >>
+                               IXGBE_RXPBSIZE_SHIFT;
+
+                       /* Calculate receive buffer threshold in kilobytes */
+                       if (rx_pb_size > pb_headroom)
+                               rx_pb_size = rx_pb_size - pb_headroom;
+                       else
+                               rx_pb_size = 0;
+
+                       /* Minimum of MFS shall be set for DMCTH */
+                       reg |= (rx_pb_size > maxframe_size_kb) ?
+                               rx_pb_size : maxframe_size_kb;
+               }
+               IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg);
+       }
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  ixgbe_dmac_update_tcs_X550
+ *  @hw: pointer to hardware structure
+ *
+ *  Disables dmac, updates per TC settings, and then enables dmac.
+ **/
+s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw)
+{
+       u32 reg;
+
+       DEBUGFUNC("ixgbe_dmac_update_tcs_X550");
+
+       /* Disable DMA coalescing before configuring */
+       reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
+       reg &= ~IXGBE_DMACR_DMAC_EN;
+       IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
+
+       ixgbe_dmac_config_tcs_X550(hw);
+
+       /* Enable DMA coalescing after configuration */
+       reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
+       reg |= IXGBE_DMACR_DMAC_EN;
+       IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
+
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
+ *  @hw: pointer to hardware structure
+ *
+ *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
+ *  ixgbe_hw struct in order to set up EEPROM access.
+ **/
+s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
+{
+       struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+       u32 eec;
+       u16 eeprom_size;
+
+       DEBUGFUNC("ixgbe_init_eeprom_params_X550");
+
+       if (eeprom->type == ixgbe_eeprom_uninitialized) {
+               eeprom->semaphore_delay = 10;
+               eeprom->type = ixgbe_flash;
+
+               eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+               eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
+                                   IXGBE_EEC_SIZE_SHIFT);
+               eeprom->word_size = 1 << (eeprom_size +
+                                         IXGBE_EEPROM_WORD_SIZE_SHIFT);
+
+               DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
+                         eeprom->type, eeprom->word_size);
+       }
+
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  ixgbe_setup_eee_X550 - Enable/disable EEE support
+ *  @hw: pointer to the HW structure
+ *  @enable_eee: boolean flag to enable EEE
+ *
+ *  Enable/disable EEE based on enable_eee flag.
+ *  Auto-negotiation must be started after BASE-T EEE bits in PHY register 7.3C
+ *  are modified.
+ *
+ **/
+s32 ixgbe_setup_eee_X550(struct ixgbe_hw *hw, bool enable_eee)
+{
+       u32 eeer;
+       u16 autoneg_eee_reg;
+       u32 link_reg;
+       s32 status;
+
+       DEBUGFUNC("ixgbe_setup_eee_X550");
+
+       eeer = IXGBE_READ_REG(hw, IXGBE_EEER);
+       /* Enable or disable EEE per flag */
+       if (enable_eee) {
+               eeer |= (IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN);
+
+               if (hw->device_id == IXGBE_DEV_ID_X550T) {
+                       /* Advertise EEE capability */
+                       hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
+                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_eee_reg);
+
+                       autoneg_eee_reg |= (IXGBE_AUTO_NEG_10GBASE_EEE_ADVT |
+                               IXGBE_AUTO_NEG_1000BASE_EEE_ADVT |
+                               IXGBE_AUTO_NEG_100BASE_EEE_ADVT);
+
+                       hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
+                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_eee_reg);
+               } else if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR ||
+                          hw->device_id == IXGBE_DEV_ID_X550EM_X) {
+                       status = ixgbe_read_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg);
+                       if (status != IXGBE_SUCCESS)
+                               return status;
+
+                       link_reg |= IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR |
+                                   IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX;
+
+                       status = ixgbe_write_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg);
+                       if (status != IXGBE_SUCCESS)
+                               return status;
+               }
+       } else {
+               eeer &= ~(IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN);
+
+               if (hw->device_id == IXGBE_DEV_ID_X550T) {
+                       /* Disable advertised EEE capability */
+                       hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
+                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_eee_reg);
+
+                       autoneg_eee_reg &= ~(IXGBE_AUTO_NEG_10GBASE_EEE_ADVT |
+                               IXGBE_AUTO_NEG_1000BASE_EEE_ADVT |
+                               IXGBE_AUTO_NEG_100BASE_EEE_ADVT);
+
+                       hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
+                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_eee_reg);
+               } else if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR ||
+                          hw->device_id == IXGBE_DEV_ID_X550EM_X) {
+                       status = ixgbe_read_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg);
+                       if (status != IXGBE_SUCCESS)
+                               return status;
+
+                       link_reg &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR |
+                               IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX);
+
+                       status = ixgbe_write_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg);
+                       if (status != IXGBE_SUCCESS)
+                               return status;
+               }
+       }
+       IXGBE_WRITE_REG(hw, IXGBE_EEER, eeer);
+
+       return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address pruning
+ * @hw: pointer to hardware structure
+ * @enable: enable or disable source address pruning
+ * @pool: Rx pool to set source address pruning for
+ **/
+void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
+                                          unsigned int pool)
+{
+       u64 pfflp;
+
+       /* max rx pool is 63 */
+       if (pool > 63)
+               return;
+
+       pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
+       pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
+
+       if (enable)
+               pfflp |= (1ULL << pool);
+       else
+               pfflp &= ~(1ULL << pool);
+
+       IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
+       IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
+}
+
+/**
+ *  ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype anti-spoofing
+ *  @hw: pointer to hardware structure
+ *  @enable: enable or disable switch for Ethertype anti-spoofing
+ *  @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
+ *
+ **/
+void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
+               bool enable, int vf)
+{
+       int vf_target_reg = vf >> 3;
+       int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
+       u32 pfvfspoof;
+
+       DEBUGFUNC("ixgbe_set_ethertype_anti_spoofing_X550");
+
+       pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
+       if (enable)
+               pfvfspoof |= (1 << vf_target_shift);
+       else
+               pfvfspoof &= ~(1 << vf_target_shift);
+
+       IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
+}
+
+/**
+ *  ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register of the IOSF
+ *  device
+ *  @hw: pointer to hardware structure
+ *  @reg_addr: 32 bit PHY register to write
+ *  @device_type: 3 bit device type
+ *  @data: Data to write to the register
+ **/
+s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
+                           u32 device_type, u32 data)
+{
+       u32 i, command, error;
+
+       command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
+                  (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
+
+       /* Write IOSF control register */
+       IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
+
+       /* Write IOSF data register */
+       IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
+       /*
+        * Check every 10 usec to see if the address cycle completed.
+        * The SB IOSF BUSY bit will clear when the operation is
+        * complete
+        */
+       for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
+               usec_delay(10);
+
+               command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
+               if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
+                       break;
+       }
+
+       if ((command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) != 0) {
+               error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
+                        IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
+               ERROR_REPORT2(IXGBE_ERROR_POLLING,
+                             "Failed to write, error %x\n", error);
+               return IXGBE_ERR_PHY;
+       }
+
+       if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
+               ERROR_REPORT1(IXGBE_ERROR_POLLING, "Write timed out\n");
+               return IXGBE_ERR_PHY;
+       }
+
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  ixgbe_read_iosf_sb_reg_x550 - Writes a value to specified register of the IOSF
+ *  device
+ *  @hw: pointer to hardware structure
+ *  @reg_addr: 32 bit PHY register to write
+ *  @device_type: 3 bit device type
+ *  @phy_data: Pointer to read data from the register
+ **/
+s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
+                          u32 device_type, u32 *data)
+{
+       u32 i, command, error;
+
+       command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
+                  (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
+
+       /* Write IOSF control register */
+       IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
+
+       /*
+        * Check every 10 usec to see if the address cycle completed.
+        * The SB IOSF BUSY bit will clear when the operation is
+        * complete
+        */
+       for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
+               usec_delay(10);
+
+               command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
+               if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
+                       break;
+       }
+
+       if ((command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) != 0) {
+               error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
+                        IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
+               ERROR_REPORT2(IXGBE_ERROR_POLLING,
+                               "Failed to read, error %x\n", error);
+               return IXGBE_ERR_PHY;
+       }
+
+       if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
+               ERROR_REPORT1(IXGBE_ERROR_POLLING, "Read timed out\n");
+               return IXGBE_ERR_PHY;
+       }
+
+       *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
+
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  ixgbe_disable_mdd_X550
+ *  @hw: pointer to hardware structure
+ *
+ *  Disable malicious driver detection
+ **/
+void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw)
+{
+       u32 reg;
+
+       DEBUGFUNC("ixgbe_disable_mdd_X550");
+
+       /* Disable MDD for TX DMA and interrupt */
+       reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+       reg &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
+       IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
+
+       /* Disable MDD for RX and interrupt */
+       reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+       reg &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
+       IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
+}
+
+/**
+ *  ixgbe_enable_mdd_X550
+ *  @hw: pointer to hardware structure
+ *
+ *  Enable malicious driver detection
+ **/
+void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw)
+{
+       u32 reg;
+
+       DEBUGFUNC("ixgbe_enable_mdd_X550");
+
+       /* Enable MDD for TX DMA and interrupt */
+       reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+       reg |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
+       IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
+
+       /* Enable MDD for RX and interrupt */
+       reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+       reg |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
+       IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
+}
+
+/**
+ *  ixgbe_restore_mdd_vf_X550
+ *  @hw: pointer to hardware structure
+ *  @vf: vf index
+ *
+ *  Restore VF that was disabled during malicious driver detection event
+ **/
+void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf)
+{
+       u32 idx, reg, num_qs, start_q, bitmask;
+
+       DEBUGFUNC("ixgbe_restore_mdd_vf_X550");
+
+       /* Map VF to queues */
+       reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
+       switch (reg & IXGBE_MRQC_MRQE_MASK) {
+       case IXGBE_MRQC_VMDQRT8TCEN:
+               num_qs = 8;  /* 16 VFs / pools */
+               bitmask = 0x000000FF;
+               break;
+       case IXGBE_MRQC_VMDQRSS32EN:
+       case IXGBE_MRQC_VMDQRT4TCEN:
+               num_qs = 4;  /* 32 VFs / pools */
+               bitmask = 0x0000000F;
+               break;
+       default:            /* 64 VFs / pools */
+               num_qs = 2;
+               bitmask = 0x00000003;
+               break;
+       }
+       start_q = vf * num_qs;
+
+       /* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */
+       idx = start_q / 32;
+       reg = 0;
+       reg |= (bitmask << (start_q % 32));
+       IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), reg);
+       IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), reg);
+}
+
+/**
+ *  ixgbe_mdd_event_X550
+ *  @hw: pointer to hardware structure
+ *  @vf_bitmap: vf bitmap of malicious vfs
+ *
+ *  Handle malicious driver detection event.
+ **/
+void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap)
+{
+       u32 wqbr;
+       u32 i, j, reg, q, shift, vf, idx;
+
+       DEBUGFUNC("ixgbe_mdd_event_X550");
+
+       /* figure out pool size for mapping to vf's */
+       reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
+       switch (reg & IXGBE_MRQC_MRQE_MASK) {
+       case IXGBE_MRQC_VMDQRT8TCEN:
+               shift = 3;  /* 16 VFs / pools */
+               break;
+       case IXGBE_MRQC_VMDQRSS32EN:
+       case IXGBE_MRQC_VMDQRT4TCEN:
+               shift = 2;  /* 32 VFs / pools */
+               break;
+       default:
+               shift = 1;  /* 64 VFs / pools */
+               break;
+       }
+
+       /* Read WQBR_TX and WQBR_RX and check for malicious queues */
+       for (i = 0; i < 4; i++) {
+               wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i));
+               wqbr |= IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i));
+
+               if (!wqbr)
+                       continue;
+
+               /* Get malicious queue */
+               for (j = 0; j < 32 && wqbr; j++) {
+
+                       if (!(wqbr & (1 << j)))
+                               continue;
+
+                       /* Get queue from bitmask */
+                       q = j + (i * 32);
+
+                       /* Map queue to vf */
+                       vf = (q >> shift);
+
+                       /* Set vf bit in vf_bitmap */
+                       idx = vf / 32;
+                       vf_bitmap[idx] |= (1 << (vf % 32));
+                       wqbr &= ~(1 << j);
+               }
+       }
+}
+
+/**
+ *  ixgbe_get_media_type_X550em - Get media type
+ *  @hw: pointer to hardware structure
+ *
+ *  Returns the media type (fiber, copper, backplane)
+ */
+enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
+{
+       enum ixgbe_media_type media_type;
+
+       DEBUGFUNC("ixgbe_get_media_type_X550em");
+
+       /* Detect if there is a copper PHY attached. */
+       switch (hw->device_id) {
+       case IXGBE_DEV_ID_X550EM_X:
+       case IXGBE_DEV_ID_X550EM_X_KR:
+       case IXGBE_DEV_ID_X550EM_X_KX4:
+               media_type = ixgbe_media_type_backplane;
+               break;
+       case IXGBE_DEV_ID_X550EM_X_SFP:
+               media_type = ixgbe_media_type_fiber;
+               break;
+       default:
+               media_type = ixgbe_media_type_unknown;
+               break;
+       }
+       return media_type;
+}
+
+/**
+ *  ixgbe_setup_sfp_modules_X550em - Setup SFP module
+ *  @hw: pointer to hardware structure
+ */
+s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
+{
+       bool setup_linear;
+       u16 reg_slice, edc_mode;
+
+       DEBUGFUNC("ixgbe_setup_sfp_modules_X550em");
+
+       switch (hw->phy.sfp_type) {
+       case ixgbe_sfp_type_unknown:
+               return IXGBE_SUCCESS;
+       case ixgbe_sfp_type_not_present:
+               return IXGBE_ERR_SFP_NOT_PRESENT;
+       case ixgbe_sfp_type_da_cu_core0:
+       case ixgbe_sfp_type_da_cu_core1:
+               setup_linear = true;
+               break;
+       case ixgbe_sfp_type_srlr_core0:
+       case ixgbe_sfp_type_srlr_core1:
+       case ixgbe_sfp_type_da_act_lmt_core0:
+       case ixgbe_sfp_type_da_act_lmt_core1:
+       case ixgbe_sfp_type_1g_sx_core0:
+       case ixgbe_sfp_type_1g_sx_core1:
+       case ixgbe_sfp_type_1g_lx_core0:
+       case ixgbe_sfp_type_1g_lx_core1:
+               setup_linear = false;
+               break;
+       default:
+               return IXGBE_ERR_SFP_NOT_SUPPORTED;
+       }
+
+       ixgbe_init_mac_link_ops_X550em(hw);
+       hw->phy.ops.reset = NULL;
+
+       /* The CS4227 slice address is the base address + the port-pair reg
+        * offset. I.e. Slice 0 = 0x0000 and slice 1 = 0x1000.
+        */
+       reg_slice = IXGBE_CS4227_SPARE24_LSB + (hw->phy.lan_id << 12);
+
+       if (setup_linear)
+               edc_mode = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
+       else
+               edc_mode = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
+
+       /* Configure CS4227 for connection type. */
+       return hw->phy.ops.write_i2c_combined(hw, IXGBE_CS4227,
+                                             reg_slice, edc_mode);
+}
+
+/**
+ *  ixgbe_init_mac_link_ops_X550em - init mac link function pointers
+ *  @hw: pointer to hardware structure
+ */
+void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
+{
+       struct ixgbe_mac_info *mac = &hw->mac;
+
+       DEBUGFUNC("ixgbe_init_mac_link_ops_X550em");
+
+       /* CS4227 does not support autoneg, so disable the laser control
+        * functions for SFP+ fiber
+        */
+        if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) {
+               mac->ops.disable_tx_laser = NULL;
+               mac->ops.enable_tx_laser = NULL;
+               mac->ops.flap_tx_laser = NULL;
+        }
+}
+
+/**
+ *  ixgbe_get_link_capabilities_x550em - Determines link capabilities
+ *  @hw: pointer to hardware structure
+ *  @speed: pointer to link speed
+ *  @autoneg: true when autoneg or autotry is enabled
+ */
+s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
+                                      ixgbe_link_speed *speed,
+                                      bool *autoneg)
+{
+       DEBUGFUNC("ixgbe_get_link_capabilities_X550em");
+
+       /* SFP */
+       if (hw->phy.media_type == ixgbe_media_type_fiber) {
+
+               /* CS4227 SFP must not enable auto-negotiation */
+               *autoneg = false;
+
+               /* Check if 1G SFP module. */
+               if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
+                   hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1
+                   || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
+                   hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
+                       *speed = IXGBE_LINK_SPEED_1GB_FULL;
+                       return IXGBE_SUCCESS;
+               }
+
+               /* Link capabilities are based on SFP */
+               if (hw->phy.multispeed_fiber)
+                       *speed |= IXGBE_LINK_SPEED_10GB_FULL |
+                                 IXGBE_LINK_SPEED_1GB_FULL;
+               else
+                       *speed = IXGBE_LINK_SPEED_10GB_FULL;
+       } else {
+               *speed |= IXGBE_LINK_SPEED_10GB_FULL |
+                         IXGBE_LINK_SPEED_1GB_FULL;
+               *autoneg = true;
+       }
+
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  ixgbe_init_phy_ops_X550em - PHY/SFP specific init
+ *  @hw: pointer to hardware structure
+ *
+ *  Initialize any function pointers that were not able to be
+ *  set during init_shared_code because the PHY/SFP type was
+ *  not known.  Perform the SFP init if necessary.
+ */
+s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
+{
+       struct ixgbe_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u32 esdp;
+
+       DEBUGFUNC("ixgbe_init_phy_ops_X550em");
+
+       if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) {
+               esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+               phy->lan_id = IXGBE_READ_REG(hw, IXGBE_STATUS) &
+                             IXGBE_STATUS_LAN_ID_1;
+               phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
+               if (phy->lan_id) {
+                       esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
+                       esdp |= IXGBE_ESDP_SDP1_DIR;
+               }
+               esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
+               IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+       }
+
+       /* Identify the PHY or SFP module */
+       ret_val = phy->ops.identify(hw);
+       if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
+               return ret_val;
+
+       /* Setup function pointers based on detected SFP module and speeds */
+       ixgbe_init_mac_link_ops_X550em(hw);
+       if (phy->sfp_type != ixgbe_sfp_type_unknown)
+               phy->ops.reset = NULL;
+
+       /* Set functions pointers based on phy type */
+       switch (hw->phy.type) {
+       case ixgbe_phy_x550em_kr:
+               phy->ops.setup_link = ixgbe_setup_kr_x550em;
+               break;
+       default:
+               break;
+       }
+       return ret_val;
+}
+
+/**
+ *  ixgbe_reset_hw_X550em - Perform hardware reset
+ *  @hw: pointer to hardware structure
+ *
+ *  Resets the hardware by resetting the transmit and receive units, masks
+ *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
+ *  reset.
+ */
+s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
+{
+       ixgbe_link_speed link_speed;
+       s32 status;
+       u32 ctrl = 0;
+       u32 i;
+       bool link_up = false;
+
+       DEBUGFUNC("ixgbe_reset_hw_X550em");
+
+       /* Call adapter stop to disable Tx/Rx and clear interrupts */
+       status = hw->mac.ops.stop_adapter(hw);
+       if (status != IXGBE_SUCCESS)
+               return status;
+
+       /* flush pending Tx transactions */
+       ixgbe_clear_tx_pending(hw);
+
+       /* PHY ops must be identified and initialized prior to reset */
+
+       /* Identify PHY and related function pointers */
+       status = hw->phy.ops.init(hw);
+
+       if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+               return status;
+
+       /* Setup SFP module if there is one present. */
+       if (hw->phy.sfp_setup_needed) {
+               status = hw->mac.ops.setup_sfp(hw);
+               hw->phy.sfp_setup_needed = false;
+       }
+
+       if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+               return status;
+
+       /* Reset PHY */
+       if (!hw->phy.reset_disable && hw->phy.ops.reset)
+               hw->phy.ops.reset(hw);
+
+mac_reset_top:
+       /* Issue global reset to the MAC.  Needs to be SW reset if link is up.
+        * If link reset is used when link is up, it might reset the PHY when
+        * mng is using it.  If link is down or the flag to force full link
+        * reset is set, then perform link reset.
+        */
+       ctrl = IXGBE_CTRL_LNK_RST;
+       if (!hw->force_full_reset) {
+               hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+               if (link_up)
+                       ctrl = IXGBE_CTRL_RST;
+       }
+
+       ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
+       IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
+       IXGBE_WRITE_FLUSH(hw);
+
+       /* Poll for reset bit to self-clear meaning reset is complete */
+       for (i = 0; i < 10; i++) {
+               usec_delay(1);
+               ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+               if (!(ctrl & IXGBE_CTRL_RST_MASK))
+                       break;
+       }
+
+       if (ctrl & IXGBE_CTRL_RST_MASK) {
+               status = IXGBE_ERR_RESET_FAILED;
+               DEBUGOUT("Reset polling failed to complete.\n");
+       }
+
+       msec_delay(50);
+
+       /* Double resets are required for recovery from certain error
+        * conditions.  Between resets, it is necessary to stall to
+        * allow time for any pending HW events to complete.
+        */
+       if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
+               hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
+               goto mac_reset_top;
+       }
+
+       /* Store the permanent mac address */
+       hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+
+       /* Store MAC address from RAR0, clear receive address registers, and
+        * clear the multicast table.  Also reset num_rar_entries to 128,
+        * since we modify this value when programming the SAN MAC address.
+        */
+       hw->mac.num_rar_entries = 128;
+       hw->mac.ops.init_rx_addrs(hw);
+
+       return status;
+}
+
+/**
+ *  ixgbe_setup_kr_x550em - Configure the KR PHY.
+ *  @hw: pointer to hardware structure
+ *
+ *  Configures the integrated KR PHY.
+ **/
+s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
+{
+       s32 status;
+       u32 reg_val;
+
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+               IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+               IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+
+       reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
+       reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ;
+       reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC;
+       reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
+                    IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
+
+       /* Advertise 10G support. */
+       if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
+               reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
+
+       /* Advertise 1G support. */
+       if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
+               reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
+
+       /* Restart auto-negotiation. */
+       reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+               IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+
+       return status;
+}
+
+/**
+ *  ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI.
+ *  @hw: pointer to hardware structure
+ *
+ *  Configures the integrated KR PHY to use iXFI mode.
+ **/
+s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw)
+{
+       s32 status;
+       u32 reg_val;
+
+       /* Disable AN and force speed to 10G Serial. */
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+                                       IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+                                       IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
+       reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
+       reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+                                       IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+                                       IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+
+       /* Disable training protocol FSM. */
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+
+       /* Disable Flex from training TXFFE. */
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_DSP_TXFFE_STATE_4(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
+       reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
+       reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_DSP_TXFFE_STATE_4(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_DSP_TXFFE_STATE_5(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
+       reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
+       reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_DSP_TXFFE_STATE_5(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+
+       /* Enable override for coefficients. */
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_TX_COEFF_CTRL_1(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
+       reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
+       reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
+       reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+                               IXGBE_KRM_TX_COEFF_CTRL_1(hw->phy.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+
+       /* Toggle port SW reset by AN reset. */
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+                                       IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+                                       IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+                                       IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+                                       IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+
+       return status;
+}
+
+/**
+ *  ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback.
+ *  @hw: pointer to hardware structure
+ *
+ *  Configures the integrated KR PHY to use internal loopback mode.
+ **/
+s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw)
+{
+       s32 status;
+       u32 reg_val;
+
+       /* Disable AN and force speed to 10G Serial. */
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+               IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+               IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
+       reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
+       reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+               IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id),
+               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+
+       /* Set near-end loopback clocks. */
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+               IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->phy.lan_id),
+               IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B;
+       reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+               IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->phy.lan_id),
+               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+
+       /* Set loopback enable. */
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+               IXGBE_KRM_PMD_DFX_BURNIN(hw->phy.lan_id),
+               IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+               IXGBE_KRM_PMD_DFX_BURNIN(hw->phy.lan_id),
+               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+
+       /* Training bypass. */
+       status = ixgbe_read_iosf_sb_reg_x550(hw,
+               IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->phy.lan_id),
+               IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+       reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS;
+       status = ixgbe_write_iosf_sb_reg_x550(hw,
+               IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->phy.lan_id),
+               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+
+       return status;
+}
+
+/**
+ *  ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
+ *  assuming that the semaphore is already obtained.
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to read
+ *  @data: word read from the EEPROM
+ *
+ *  Reads a 16 bit word from the EEPROM using the hostif.
+ **/
+s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
+                                  u16 *data)
+{
+       s32 status;
+       struct ixgbe_hic_read_shadow_ram buffer;
+
+       DEBUGFUNC("ixgbe_read_ee_hostif_data_X550");
+       buffer.hdr.cmd = FW_READ_SHADOW_RAM_CMD;
+       buffer.hdr.buf_len1 = 0;
+       buffer.hdr.buf_len2 = FW_READ_SHADOW_RAM_LEN;
+       buffer.hdr.checksum = FW_DEFAULT_CHECKSUM;
+
+       /* convert offset from words to bytes */
+       buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
+       /* one word */
+       buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
+
+       status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
+                                             sizeof(buffer), false);
+
+       if (status)
+               return status;
+
+       *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
+                                         FW_NVM_DATA_OFFSET);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to read
+ *  @data: word read from the EEPROM
+ *
+ *  Reads a 16 bit word from the EEPROM using the hostif.
+ **/
+s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
+                             u16 *data)
+{
+       s32 status = IXGBE_SUCCESS;
+
+       DEBUGFUNC("ixgbe_read_ee_hostif_X550");
+
+       if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+           IXGBE_SUCCESS) {
+               status = ixgbe_read_ee_hostif_data_X550(hw, offset, data);
+               hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+       } else {
+               status = IXGBE_ERR_SWFW_SYNC;
+       }
+
+       return status;
+}
+
+/**
+ *  ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to read
+ *  @words: number of words
+ *  @data: word(s) read from the EEPROM
+ *
+ *  Reads a 16 bit word(s) from the EEPROM using the hostif.
+ **/
+s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
+                                    u16 offset, u16 words, u16 *data)
+{
+       struct ixgbe_hic_read_shadow_ram buffer;
+       u32 current_word = 0;
+       u16 words_to_read;
+       s32 status;
+       u32 i;
+
+       DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550");
+
+       /* Take semaphore for the entire operation. */
+       status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+       if (status) {
+               DEBUGOUT("EEPROM read buffer - semaphore failed\n");
+               return status;
+       }
+       while (words) {
+               if (words > FW_MAX_READ_BUFFER_SIZE / 2)
+                       words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
+               else
+                       words_to_read = words;
+
+               buffer.hdr.cmd = FW_READ_SHADOW_RAM_CMD;
+               buffer.hdr.buf_len1 = 0;
+               buffer.hdr.buf_len2 = FW_READ_SHADOW_RAM_LEN;
+               buffer.hdr.checksum = FW_DEFAULT_CHECKSUM;
+
+               /* convert offset from words to bytes */
+               buffer.address = IXGBE_CPU_TO_BE32((offset + current_word) * 2);
+               buffer.length = IXGBE_CPU_TO_BE16(words_to_read * 2);
+
+               status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
+                                                     sizeof(buffer), false);
+
+               if (status) {
+                       DEBUGOUT("Host interface command failed\n");
+                       goto out;
+               }
+
+               for (i = 0; i < words_to_read; i++) {
+                       u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
+                                 2 * i;
+                       u32 value = IXGBE_READ_REG(hw, reg);
+
+                       data[current_word] = (u16)(value & 0xffff);
+                       current_word++;
+                       i++;
+                       if (i < words_to_read) {
+                               value >>= 16;
+                               data[current_word] = (u16)(value & 0xffff);
+                               current_word++;
+                       }
+               }
+               words -= words_to_read;
+       }
+
+out:
+       hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+       return status;
+}
+
+/**
+ *  ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to write
+ *  @data: word write to the EEPROM
+ *
+ *  Write a 16 bit word to the EEPROM using the hostif.
+ **/
+s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
+                                   u16 data)
+{
+       s32 status;
+       struct ixgbe_hic_write_shadow_ram buffer;
+
+       DEBUGFUNC("ixgbe_write_ee_hostif_data_X550");
+
+       buffer.hdr.cmd = FW_WRITE_SHADOW_RAM_CMD;
+       buffer.hdr.buf_len1 = 0;
+       buffer.hdr.buf_len2 = FW_WRITE_SHADOW_RAM_LEN;
+       buffer.hdr.checksum = FW_DEFAULT_CHECKSUM;
+
+        /* one word */
+       buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
+       buffer.data = data;
+       buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
+
+       status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
+                                             sizeof(buffer), false);
+
+       return status;
+}
+
+/**
+ *  ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to write
+ *  @data: word write to the EEPROM
+ *
+ *  Write a 16 bit word to the EEPROM using the hostif.
+ **/
+s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
+                              u16 data)
+{
+       s32 status = IXGBE_SUCCESS;
+
+       DEBUGFUNC("ixgbe_write_ee_hostif_X550");
+
+       if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+           IXGBE_SUCCESS) {
+               status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
+               hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+       } else {
+               DEBUGOUT("write ee hostif failed to get semaphore");
+               status = IXGBE_ERR_SWFW_SYNC;
+       }
+
+       return status;
+}
+
+/**
+ *  ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to write
+ *  @words: number of words
+ *  @data: word(s) write to the EEPROM
+ *
+ *  Write a 16 bit word(s) to the EEPROM using the hostif.
+ **/
+s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
+                                     u16 offset, u16 words, u16 *data)
+{
+       s32 status = IXGBE_SUCCESS;
+       u32 i = 0;
+
+       DEBUGFUNC("ixgbe_write_ee_hostif_buffer_X550");
+
+       /* Take semaphore for the entire operation. */
+       status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+       if (status != IXGBE_SUCCESS) {
+               DEBUGOUT("EEPROM write buffer - semaphore failed\n");
+               goto out;
+       }
+
+       for (i = 0; i < words; i++) {
+               status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
+                                                        data[i]);
+
+               if (status != IXGBE_SUCCESS) {
+                       DEBUGOUT("Eeprom buffered write failed\n");
+                       break;
+               }
+       }
+
+       hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+out:
+
+       return status;
+}
+
+/**
+ * ixgbe_checksum_ptr_x550 - Checksum one pointer region
+ * @hw: pointer to hardware structure
+ * @ptr: pointer offset in eeprom
+ * @size: size of section pointed by ptr, if 0 first word will be used as size
+ * @csum: address of checksum to update
+ *
+ * Returns error status for any failure
+ */
+STATIC s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
+                                  u16 size, u16 *csum)
+{
+       u16 buf[256];
+       s32 status;
+       u16 length, bufsz, i, start;
+
+       bufsz = sizeof(buf) / sizeof(buf[0]);
+
+       /* Read a chunk at the pointer location */
+       status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
+       if (status) {
+               DEBUGOUT("Failed to read EEPROM image\n");
+               return status;
+       }
+
+       if (size) {
+               start = 0;
+               length = size;
+       } else {
+               start = 1;
+               length = buf[0];
+
+               /* Skip pointer section if length is invalid. */
+               if (length == 0xFFFF || length == 0 ||
+                   (ptr + length) >= hw->eeprom.word_size)
+                       return IXGBE_SUCCESS;
+       }
+
+       for (i = start; length; i++, length--) {
+               if (i == bufsz) {
+                       ptr += bufsz;
+                       i = 0;
+                       if (length < bufsz)
+                               bufsz = length;
+
+                       /* Read a chunk at the pointer location */
+                       status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
+                                                                 bufsz, buf);
+                       if (status) {
+                               DEBUGOUT("Failed to read EEPROM image\n");
+                               return status;
+                       }
+               }
+               *csum += buf[i];
+       }
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
+ *  @hw: pointer to hardware structure
+ *
+ *  Returns a negative error code on error, or the 16-bit checksum
+ **/
+s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
+{
+       u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
+       s32 status;
+       u16 checksum = 0;
+       u16 pointer, i, size;
+
+       DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550");
+
+       hw->eeprom.ops.init_params(hw);
+
+       /* Read pointer area */
+       status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
+                                                 IXGBE_EEPROM_LAST_WORD + 1,
+                                                 eeprom_ptrs);
+       if (status) {
+               DEBUGOUT("Failed to read EEPROM image\n");
+               return status;
+       }
+
+       /*
+        * For X550 hardware include 0x0-0x41 in the checksum, skip the
+        * checksum word itself
+        */
+       for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
+               if (i != IXGBE_EEPROM_CHECKSUM)
+                       checksum += eeprom_ptrs[i];
+
+       /*
+        * Include all data from pointers 0x3, 0x6-0xE.  This excludes the
+        * FW, PHY module, and PCIe Expansion/Option ROM pointers.
+        */
+       for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
+               if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
+                       continue;
+
+               pointer = eeprom_ptrs[i];
+
+               /* Skip pointer section if the pointer is invalid. */
+               if (pointer == 0xFFFF || pointer == 0 ||
+                   pointer >= hw->eeprom.word_size)
+                       continue;
+
+               switch (i) {
+               case IXGBE_PCIE_GENERAL_PTR:
+                       size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
+                       break;
+               case IXGBE_PCIE_CONFIG0_PTR:
+               case IXGBE_PCIE_CONFIG1_PTR:
+                       size = IXGBE_PCIE_CONFIG_SIZE;
+                       break;
+               default:
+                       size = 0;
+                       break;
+               }
+
+               status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum);
+               if (status)
+                       return status;
+       }
+
+       checksum = (u16)IXGBE_EEPROM_SUM - checksum;
+
+       return (s32)checksum;
+}
+
+/**
+ *  ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
+ *  @hw: pointer to hardware structure
+ *  @checksum_val: calculated checksum
+ *
+ *  Performs checksum calculation and validates the EEPROM checksum.  If the
+ *  caller does not need checksum_val, the value can be NULL.
+ **/
+s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw,
+                                       u16 *checksum_val)
+{
+       s32 status;
+       u16 checksum;
+       u16 read_checksum = 0;
+
+       DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550");
+
+       /* 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;
+       }
+
+       status = hw->eeprom.ops.calc_checksum(hw);
+       if (status < 0)
+               return status;
+
+       checksum = (u16)(status & 0xffff);
+
+       status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
+                                          &read_checksum);
+       if (status)
+               return status;
+
+       /* Verify read checksum from EEPROM is the same as
+        * calculated checksum
+        */
+       if (read_checksum != checksum) {
+               status = IXGBE_ERR_EEPROM_CHECKSUM;
+               ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
+                            "Invalid EEPROM checksum");
+       }
+
+       /* If the user cares, return the calculated checksum */
+       if (checksum_val)
+               *checksum_val = checksum;
+
+       return status;
+}
+
+/**
+ * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
+ * @hw: pointer to hardware structure
+ *
+ * After writing EEPROM to shadow RAM using EEWR register, software calculates
+ * checksum and updates the EEPROM and instructs the hardware to update
+ * the flash.
+ **/
+s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
+{
+       s32 status;
+       u16 checksum = 0;
+
+       DEBUGFUNC("ixgbe_update_eeprom_checksum_X550");
+
+       /* 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 = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
+       if (status) {
+               DEBUGOUT("EEPROM read failed\n");
+               return status;
+       }
+
+       status = ixgbe_calc_eeprom_checksum_X550(hw);
+       if (status < 0)
+               return status;
+
+       checksum = (u16)(status & 0xffff);
+
+       status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
+                                           checksum);
+       if (status)
+               return status;
+
+       status = ixgbe_update_flash_X550(hw);
+
+       return status;
+}
+
+/**
+ *  ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
+ *  @hw: pointer to hardware structure
+ *
+ *  Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
+ **/
+s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
+{
+       s32 status = IXGBE_SUCCESS;
+       struct ixgbe_hic_hdr2 buffer;
+
+       DEBUGFUNC("ixgbe_update_flash_X550");
+
+       buffer.cmd = FW_SHADOW_RAM_DUMP_CMD;
+       buffer.buf_len1 = 0;
+       buffer.buf_len2 = FW_SHADOW_RAM_DUMP_LEN;
+       buffer.checksum = FW_DEFAULT_CHECKSUM;
+
+       status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
+                                             sizeof(buffer), false);
+
+       return status;
+}
+
+/**
+ *  ixgbe_get_supported_physical_layer_X550em - Returns physical layer type
+ *  @hw: pointer to hardware structure
+ *
+ *  Determines physical layer capabilities of the current configuration.
+ **/
+u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw)
+{
+       u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+
+       DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em");
+
+       hw->phy.ops.identify(hw);
+
+       switch (hw->phy.type) {
+       case ixgbe_phy_x550em_kr:
+               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR |
+                                IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+               break;
+       case ixgbe_phy_x550em_kx4:
+               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
+                                IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+               break;
+       default:
+               break;
+       }
+
+       if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
+               physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
+
+       return physical_layer;
+}
+
+/**
+ * ixgbe_disable_rx_x550 - Disable RX unit
+ *
+ * Enables the Rx DMA unit for x550
+ **/
+void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
+{
+       u32 rxctrl, pfdtxgswc;
+       s32 status;
+       struct ixgbe_hic_disable_rxen fw_cmd;
+
+       DEBUGFUNC("ixgbe_enable_rx_dma_x550");
+
+       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+       if (rxctrl & IXGBE_RXCTRL_RXEN) {
+               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;
+               }
+
+               fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
+               fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
+               fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
+               fw_cmd.port_number = hw->phy.lan_id;
+
+               status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
+                                       sizeof(struct ixgbe_hic_disable_rxen),
+                                       true);
+
+               /* If we fail - disable RX using register write */
+               if (status) {
+                       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+                       if (rxctrl & IXGBE_RXCTRL_RXEN) {
+                               rxctrl &= ~IXGBE_RXCTRL_RXEN;
+                               IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
+                       }
+               }
+       }
+}
diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.h
new file mode 100644 (file)
index 0000000..e8de134
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************
+
+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.
+
+***************************************************************************/
+
+#ifndef _IXGBE_X550_H_
+#define _IXGBE_X550_H_
+
+#include "ixgbe_type.h"
+
+s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw);
+s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw);
+s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw);
+
+s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw);
+s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw);
+s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw);
+s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw,
+               u16 *checksum_val);
+s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw);
+s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
+                                     u16 offset, u16 words, u16 *data);
+s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
+                              u16 data);
+s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
+                                    u16 offset, u16 words, u16 *data);
+s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
+u16                            *data);
+s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
+                                  u16 *data);
+s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
+                                   u16 data);
+s32 ixgbe_set_eee_X550(struct ixgbe_hw *hw, bool enable_eee);
+s32 ixgbe_setup_eee_X550(struct ixgbe_hw *hw, bool enable_eee);
+void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
+                                          unsigned int pool);
+void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
+                                           bool enable, int vf);
+s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
+                                u32 device_type, u32 data);
+s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
+                               u32 device_type, u32 *data);
+void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw);
+void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw);
+void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap);
+void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf);
+enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
+                                      ixgbe_link_speed *speed, bool *autoneg);
+void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw);
+u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw);
+void ixgbe_disable_rx_x550(struct ixgbe_hw *hw);
+#endif /* _IXGBE_X550_H_ */
+