ixgbe: Add support for x550em_a 10G MAC type
authorMark Rustad <mark.d.rustad@intel.com>
Fri, 1 Apr 2016 19:18:09 +0000 (12:18 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 7 Apr 2016 23:15:35 +0000 (16:15 -0700)
Add support for x550em_a 10G MAC type to the ixgbe driver. The new
MAC includes new firmware commands that need to be used to control
PHY and IOSF access, so that support is also added. The interface
supported is a native SFP+ interface.

Signed-off-by: Mark Rustad <mark.d.rustad@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c

index 4590fabdedf0e065d8ac7b84134b9024b85ee8aa..d10ed62993c105da40a2335220b4bec3356e0e7c 100644 (file)
@@ -817,6 +817,7 @@ static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
                return IXGBE_MAX_RSS_INDICES;
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                return IXGBE_MAX_RSS_INDICES_X550;
        default:
                return 0;
@@ -860,6 +861,7 @@ enum ixgbe_boards {
        board_X540,
        board_X550,
        board_X550EM_x,
+       board_x550em_a,
 };
 
 extern const struct ixgbe_info ixgbe_82598_info;
@@ -867,6 +869,7 @@ extern const struct ixgbe_info ixgbe_82599_info;
 extern const struct ixgbe_info ixgbe_X540_info;
 extern const struct ixgbe_info ixgbe_X550_info;
 extern const struct ixgbe_info ixgbe_X550EM_x_info;
+extern const struct ixgbe_info ixgbe_x550em_a_info;
 #ifdef CONFIG_IXGBE_DCB
 extern const struct dcbnl_rtnl_ops dcbnl_ops;
 #endif
index 4bb6b685263be15514a1d78124d5630c0cb1bdd1..01519787324aeeebdbc223314008f6a2639f3667 100644 (file)
@@ -1633,6 +1633,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
        switch (hw->mac.type) {
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, ~fdirtcpm);
                break;
        default:
index 8c560da29d23b5d00a5de7ee968218506861167e..11450bd8ec9c26f8088dbefbf416355f018bddff 100644 (file)
@@ -2855,6 +2855,7 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS;
                max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599;
                break;
index 02c7333a9c83c1c0e9bb8fe826687e4eb144c85b..f8fb2acc2632d0a433c943301627606706024e81 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2014 Intel Corporation.
+  Copyright(c) 1999 - 2016 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -293,6 +293,7 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                return ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max,
                                                 bwgid, ptype, prio_tc);
        default:
@@ -311,6 +312,7 @@ s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                return ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc);
        default:
                break;
@@ -368,6 +370,7 @@ s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw,
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max,
                                                  bwg_id, prio_type, prio_tc);
                ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
@@ -398,6 +401,7 @@ void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                ixgbe_dcb_read_rtrup2tc_82599(hw, map);
                break;
        default:
index b3530e1e3ce125cca2e56930bdc700b4d4c801f2..9f76be1431b1ebf9840a6b7d075e1f218d617c76 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2014 Intel Corporation.
+  Copyright(c) 1999 - 2016 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -547,6 +547,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
                case ixgbe_mac_X540:
                case ixgbe_mac_X550:
                case ixgbe_mac_X550EM_x:
+               case ixgbe_mac_x550em_a:
                        regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL_82599(i));
                        regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH_82599(i));
                        break;
@@ -660,6 +661,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
                regs_buff[832] = IXGBE_READ_REG(hw, IXGBE_RTRPCS);
                for (i = 0; i < 8; i++)
@@ -1443,6 +1445,7 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                toggle = 0x7FFFF30F;
                test = reg_test_82599;
                break;
@@ -1681,6 +1684,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
                reg_ctl &= ~IXGBE_DMATXCTL_TE;
                IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl);
@@ -1720,6 +1724,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL);
                reg_data |= IXGBE_DMATXCTL_TE;
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data);
@@ -1780,6 +1785,7 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                reg_data = IXGBE_READ_REG(hw, IXGBE_MACC);
                reg_data |= IXGBE_MACC_FLU;
                IXGBE_WRITE_REG(hw, IXGBE_MACC, reg_data);
@@ -2991,6 +2997,7 @@ static int ixgbe_get_ts_info(struct net_device *dev,
        switch (adapter->hw.mac.type) {
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
        case ixgbe_mac_X540:
        case ixgbe_mac_82599EB:
                info->so_timestamping =
index e771e764daa3ae9b9390e2a49ae45f8cf2bafa7d..bcdc88444cebeb2762f8634210556ce87a8c9961 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2013 Intel Corporation.
+  Copyright(c) 1999 - 2016 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -128,6 +128,7 @@ static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc,
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                if (num_tcs > 4) {
                        /*
                         * TCs    : TC0/1 TC2/3 TC4-7
index 9594438ffa07b96a0cbc327af69d32d6adb402d2..eb93319337a1a75d5cb3234ca2beb4b0d5413538 100644 (file)
@@ -73,7 +73,7 @@ static char ixgbe_default_device_descr[] =
 #define DRV_VERSION "4.2.1-k"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static const char ixgbe_copyright[] =
-                               "Copyright (c) 1999-2015 Intel Corporation.";
+                               "Copyright (c) 1999-2016 Intel Corporation.";
 
 static const char ixgbe_overheat_msg[] = "Network adapter has been stopped because it has over heated. Restart the computer. If the problem persists, power off the system and replace the adapter";
 
@@ -83,6 +83,7 @@ static const struct ixgbe_info *ixgbe_info_tbl[] = {
        [board_X540]            = &ixgbe_X540_info,
        [board_X550]            = &ixgbe_X550_info,
        [board_X550EM_x]        = &ixgbe_X550EM_x_info,
+       [board_x550em_a]        = &ixgbe_x550em_a_info,
 };
 
 /* ixgbe_pci_tbl - PCI Device ID Table
@@ -130,6 +131,7 @@ static const struct pci_device_id ixgbe_pci_tbl[] = {
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_KR), board_X550EM_x},
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_10G_T), board_X550EM_x},
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_SFP), board_X550EM_x},
+       {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_SFP_N), board_x550em_a },
        /* required last entry */
        {0, }
 };
@@ -861,6 +863,7 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                if (direction == -1) {
                        /* other causes */
                        msix_vector |= IXGBE_IVAR_ALLOC_VAL;
@@ -899,6 +902,7 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                mask = (qmask & 0xFFFFFFFF);
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask);
                mask = (qmask >> 32);
@@ -2245,6 +2249,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                ixgbe_set_ivar(adapter, -1, 1, v_idx);
                break;
        default:
@@ -2356,6 +2361,7 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                /*
                 * set the WDIS bit to not clear the timer bits and cause an
                 * immediate assertion of the interrupt
@@ -2517,6 +2523,7 @@ static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
                return false;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                switch (hw->mac.ops.get_media_type(hw)) {
                case ixgbe_media_type_fiber:
                case ixgbe_media_type_fiber_qsfp:
@@ -2591,6 +2598,7 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter,
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                mask = (qmask & 0xFFFFFFFF);
                if (mask)
                        IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask);
@@ -2619,6 +2627,7 @@ static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter,
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                mask = (qmask & 0xFFFFFFFF);
                if (mask)
                        IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask);
@@ -2654,6 +2663,7 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues,
                case ixgbe_mac_X540:
                case ixgbe_mac_X550:
                case ixgbe_mac_X550EM_x:
+               case ixgbe_mac_x550em_a:
                        mask |= IXGBE_EIMS_TS;
                        break;
                default:
@@ -2669,7 +2679,9 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues,
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
-               if (adapter->hw.device_id == IXGBE_DEV_ID_X550EM_X_SFP)
+       case ixgbe_mac_x550em_a:
+               if (adapter->hw.device_id == IXGBE_DEV_ID_X550EM_X_SFP ||
+                   adapter->hw.device_id == IXGBE_DEV_ID_X550EM_A_SFP_N)
                        mask |= IXGBE_EIMS_GPI_SDP0(&adapter->hw);
                if (adapter->hw.phy.type == ixgbe_phy_x550em_ext_t)
                        mask |= IXGBE_EICR_GPI_SDP0_X540;
@@ -2727,6 +2739,7 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                if (hw->phy.type == ixgbe_phy_x550em_ext_t &&
                    (eicr & IXGBE_EICR_GPI_SDP0_X540)) {
                        adapter->flags2 |= IXGBE_FLAG2_PHY_INTERRUPT;
@@ -2963,6 +2976,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                if (eicr & IXGBE_EICR_ECC) {
                        e_info(link, "Received ECC Err, initiating reset\n");
                        adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
@@ -3059,6 +3073,7 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000);
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0);
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
@@ -3858,6 +3873,7 @@ static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter)
                break;
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                if (adapter->num_vfs)
                        rdrxctl |= IXGBE_RDRXCTL_PSP;
                /* fall through for older HW */
@@ -4021,6 +4037,7 @@ static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                for (i = 0; i < adapter->num_rx_queues; i++) {
                        struct ixgbe_ring *ring = adapter->rx_ring[i];
 
@@ -4057,6 +4074,7 @@ static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                for (i = 0; i < adapter->num_rx_queues; i++) {
                        struct ixgbe_ring *ring = adapter->rx_ring[i];
 
@@ -4083,6 +4101,7 @@ static void ixgbe_vlan_promisc_enable(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
        default:
                if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
                        break;
@@ -4173,6 +4192,7 @@ static void ixgbe_vlan_promisc_disable(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
        default:
                if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
                        break;
@@ -4561,6 +4581,7 @@ static void ixgbe_clear_vxlan_port(struct ixgbe_adapter *adapter)
        switch (adapter->hw.mac.type) {
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_VXLANCTRL, 0);
                adapter->vxlan_port = 0;
                break;
@@ -4661,6 +4682,7 @@ static int ixgbe_hpbthresh(struct ixgbe_adapter *adapter, int pb)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                dv_id = IXGBE_DV_X540(link, tc);
                break;
        default:
@@ -4721,6 +4743,7 @@ static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter, int pb)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                dv_id = IXGBE_LOW_DV_X540(tc);
                break;
        default:
@@ -5137,6 +5160,7 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter)
                case ixgbe_mac_X540:
                case ixgbe_mac_X550:
                case ixgbe_mac_X550EM_x:
+               case ixgbe_mac_x550em_a:
                default:
                        IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(0), 0xFFFFFFFF);
                        IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(1), 0xFFFFFFFF);
@@ -5187,6 +5211,7 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter)
                gpie |= IXGBE_SDP1_GPIEN_8259X | IXGBE_SDP2_GPIEN_8259X;
                break;
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                gpie |= IXGBE_SDP0_GPIEN_X540;
                break;
        default:
@@ -5498,6 +5523,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
                                (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
                                 ~IXGBE_DMATXCTL_TE));
@@ -5616,6 +5642,7 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
                        adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
                break;
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
        case ixgbe_mac_X550:
 #ifdef CONFIG_IXGBE_DCA
                adapter->flags &= ~IXGBE_FLAG_DCA_CAPABLE;
@@ -5641,6 +5668,7 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                adapter->dcb_cfg.num_tcs.pg_tcs = X540_TRAFFIC_CLASS;
                adapter->dcb_cfg.num_tcs.pfc_tcs = X540_TRAFFIC_CLASS;
                break;
@@ -6248,6 +6276,7 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                pci_wake_from_d3(pdev, !!wufc);
                break;
        default:
@@ -6383,6 +6412,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
                case ixgbe_mac_X540:
                case ixgbe_mac_X550:
                case ixgbe_mac_X550EM_x:
+               case ixgbe_mac_x550em_a:
                        hwstats->pxonrxc[i] +=
                                IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
                        break;
@@ -6398,7 +6428,8 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
                if ((hw->mac.type == ixgbe_mac_82599EB) ||
                    (hw->mac.type == ixgbe_mac_X540) ||
                    (hw->mac.type == ixgbe_mac_X550) ||
-                   (hw->mac.type == ixgbe_mac_X550EM_x)) {
+                   (hw->mac.type == ixgbe_mac_X550EM_x) ||
+                   (hw->mac.type == ixgbe_mac_x550em_a)) {
                        hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
                        IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); /* to clear */
                        hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC_L(i));
@@ -6423,6 +6454,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                /* OS2BMC stats are X540 and later */
                hwstats->o2bgptc += IXGBE_READ_REG(hw, IXGBE_O2BGPTC);
                hwstats->o2bspc += IXGBE_READ_REG(hw, IXGBE_O2BSPC);
@@ -6693,6 +6725,7 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
        case ixgbe_mac_82599EB: {
                u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
                u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
@@ -9146,6 +9179,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
                break;
        default:
@@ -9578,6 +9612,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
                case ixgbe_mac_X550EM_x:
                        device_id = IXGBE_DEV_ID_X550EM_X_VF;
                        break;
+               case ixgbe_mac_x550em_a:
+                       device_id = IXGBE_DEV_ID_X550EM_A_VF;
+                       break;
                default:
                        device_id = 0;
                        break;
index 2837c94d6e356641f65c88a776cb6ce791e0b437..b2125e358f7b798302e4bff9ffb1dcc624e8a319 100644 (file)
@@ -307,6 +307,7 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
                break;
        default:
@@ -430,6 +431,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
        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_x550em_a &&
            hw->mac.type != ixgbe_mac_X540)
                return;
 
index ef1504d41890f69839c182e7ee99dc4d57917492..bdc8fdcc07a50c3b48261bc9a396acf9c12a158c 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2015 Intel Corporation.
+  Copyright(c) 1999 - 2016 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -333,6 +333,7 @@ static void ixgbe_ptp_convert_to_hwtstamp(struct ixgbe_adapter *adapter,
         */
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                /* Upper 32 bits represent billions of cycles, lower 32 bits
                 * represent cycles. However, we use timespec64_to_ns for the
                 * correct math even though the units haven't been corrected
@@ -921,6 +922,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
        switch (hw->mac.type) {
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                /* enable timestamping all packets only if at least some
                 * packets were requested. Otherwise, play nice and disable
                 * timestamping
@@ -1083,6 +1085,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
                        cc.shift = 2;
                }
                /* fallthrough */
+       case ixgbe_mac_x550em_a:
        case ixgbe_mac_X550:
                cc.read = ixgbe_ptp_read_X550;
 
@@ -1223,6 +1226,7 @@ static long ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)
                break;
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_x550em_a:
                snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name);
                adapter->ptp_caps.owner = THIS_MODULE;
                adapter->ptp_caps.max_adj = 30000000;
index fef2264ff5f034ebc85b9473333125f2e7c1df87..ced38c19436c820c6396b7952df718b81efaab42 100644 (file)
@@ -2627,6 +2627,20 @@ enum ixgbe_fdir_pballoc_type {
 #define FW_MAX_READ_BUFFER_SIZE                1024
 #define FW_DISABLE_RXEN_CMD            0xDE
 #define FW_DISABLE_RXEN_LEN            0x1
+#define FW_PHY_MGMT_REQ_CMD            0x20
+#define FW_PHY_TOKEN_REQ_CMD           0x0A
+#define FW_PHY_TOKEN_REQ_LEN           2
+#define FW_PHY_TOKEN_REQ               0
+#define FW_PHY_TOKEN_REL               1
+#define FW_PHY_TOKEN_OK                        1
+#define FW_PHY_TOKEN_RETRY             0x80
+#define FW_PHY_TOKEN_DELAY             5       /* milliseconds */
+#define FW_PHY_TOKEN_WAIT              5       /* seconds */
+#define FW_PHY_TOKEN_RETRIES ((FW_PHY_TOKEN_WAIT * 1000) / FW_PHY_TOKEN_DELAY)
+#define FW_INT_PHY_REQ_CMD             0xB
+#define FW_INT_PHY_REQ_LEN             10
+#define FW_INT_PHY_REQ_READ            0
+#define FW_INT_PHY_REQ_WRITE           1
 
 /* Host Interface Command Structures */
 struct ixgbe_hic_hdr {
@@ -2695,6 +2709,28 @@ struct ixgbe_hic_disable_rxen {
        u16 pad3;
 };
 
+struct ixgbe_hic_phy_token_req {
+       struct ixgbe_hic_hdr hdr;
+       u8 port_number;
+       u8 command_type;
+       u16 pad;
+};
+
+struct ixgbe_hic_internal_phy_req {
+       struct ixgbe_hic_hdr hdr;
+       u8 port_number;
+       u8 command_type;
+       __be16 address;
+       u16 rsv1;
+       __be32 write_data;
+       u16 pad;
+} __packed;
+
+struct ixgbe_hic_internal_phy_resp {
+       struct ixgbe_hic_hdr hdr;
+       __be32 read_data;
+};
+
 /* Transmit Descriptor - Advanced */
 union ixgbe_adv_tx_desc {
        struct {
@@ -3528,6 +3564,8 @@ struct ixgbe_info {
 #define IXGBE_ERR_INVALID_ARGUMENT              -32
 #define IXGBE_ERR_HOST_INTERFACE_COMMAND        -33
 #define IXGBE_ERR_FDIR_CMD_INCOMPLETE          -38
+#define IXGBE_ERR_FW_RESP_INVALID              -39
+#define IXGBE_ERR_TOKEN_RETRY                  -40
 #define IXGBE_NOT_IMPLEMENTED                   0x7FFFFFFF
 
 #define IXGBE_FUSES0_GROUP(_i)         (0x11158 + ((_i) * 4))
index 878ea1ed87b4892559c30cd72f89c73f8944c1f9..ba161b5077ebfd2884c23133f6eb20e43da95766 100644 (file)
@@ -278,6 +278,8 @@ static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
                hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
                ixgbe_setup_mux_ctl(hw);
                ixgbe_check_cs4227(hw);
+               /* Fallthrough */
+       case IXGBE_DEV_ID_X550EM_A_SFP_N:
                return ixgbe_identify_module_generic(hw);
        case IXGBE_DEV_ID_X550EM_X_KX4:
                hw->phy.type = ixgbe_phy_x550em_kx4;
@@ -413,6 +415,121 @@ out:
        return ret;
 }
 
+/**
+ * ixgbe_get_phy_token - Get the token for shared PHY access
+ * @hw: Pointer to hardware structure
+ */
+static s32 ixgbe_get_phy_token(struct ixgbe_hw *hw)
+{
+       struct ixgbe_hic_phy_token_req token_cmd;
+       s32 status;
+
+       token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
+       token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
+       token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
+       token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
+       token_cmd.port_number = hw->bus.lan_id;
+       token_cmd.command_type = FW_PHY_TOKEN_REQ;
+       token_cmd.pad = 0;
+       status = ixgbe_host_interface_command(hw, &token_cmd, sizeof(token_cmd),
+                                             IXGBE_HI_COMMAND_TIMEOUT,
+                                             true);
+       if (status)
+               return status;
+       if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
+               return 0;
+       if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY)
+               return IXGBE_ERR_FW_RESP_INVALID;
+
+       return IXGBE_ERR_TOKEN_RETRY;
+}
+
+/**
+ * ixgbe_put_phy_token - Put the token for shared PHY access
+ * @hw: Pointer to hardware structure
+ */
+static s32 ixgbe_put_phy_token(struct ixgbe_hw *hw)
+{
+       struct ixgbe_hic_phy_token_req token_cmd;
+       s32 status;
+
+       token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
+       token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
+       token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
+       token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
+       token_cmd.port_number = hw->bus.lan_id;
+       token_cmd.command_type = FW_PHY_TOKEN_REL;
+       token_cmd.pad = 0;
+       status = ixgbe_host_interface_command(hw, &token_cmd, sizeof(token_cmd),
+                                             IXGBE_HI_COMMAND_TIMEOUT,
+                                             true);
+       if (status)
+               return status;
+       if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
+               return 0;
+       return IXGBE_ERR_FW_RESP_INVALID;
+}
+
+/**
+ *  ixgbe_write_iosf_sb_reg_x550a - Write to IOSF PHY register
+ *  @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
+ **/
+static s32 ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
+                                        __always_unused u32 device_type,
+                                        u32 data)
+{
+       struct ixgbe_hic_internal_phy_req write_cmd;
+
+       memset(&write_cmd, 0, sizeof(write_cmd));
+       write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
+       write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
+       write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
+       write_cmd.port_number = hw->bus.lan_id;
+       write_cmd.command_type = FW_INT_PHY_REQ_WRITE;
+       write_cmd.address = cpu_to_be16(reg_addr);
+       write_cmd.write_data = cpu_to_be32(data);
+
+       return ixgbe_host_interface_command(hw, &write_cmd, sizeof(write_cmd),
+                                           IXGBE_HI_COMMAND_TIMEOUT, false);
+}
+
+/**
+ *  ixgbe_read_iosf_sb_reg_x550a - Read from IOSF PHY register
+ *  @hw: pointer to hardware structure
+ *  @reg_addr: 32 bit PHY register to write
+ *  @device_type: 3 bit device type
+ *  @data: Pointer to read data from the register
+ **/
+static s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
+                                       __always_unused u32 device_type,
+                                       u32 *data)
+{
+       union {
+               struct ixgbe_hic_internal_phy_req cmd;
+               struct ixgbe_hic_internal_phy_resp rsp;
+       } hic;
+       s32 status;
+
+       memset(&hic, 0, sizeof(hic));
+       hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
+       hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
+       hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
+       hic.cmd.port_number = hw->bus.lan_id;
+       hic.cmd.command_type = FW_INT_PHY_REQ_READ;
+       hic.cmd.address = cpu_to_be16(reg_addr);
+
+       status = ixgbe_host_interface_command(hw, &hic.cmd, sizeof(hic.cmd),
+                                             IXGBE_HI_COMMAND_TIMEOUT, true);
+
+       /* Extract the register value from the response. */
+       *data = be32_to_cpu(hic.rsp.read_data);
+
+       return status;
+}
+
 /** ixgbe_read_ee_hostif_data_X550 - Read EEPROM word using a host interface
  *  command assuming that the semaphore is already obtained.
  *  @hw: pointer to hardware structure
@@ -1339,9 +1456,9 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
                mac->ops.disable_tx_laser = NULL;
                mac->ops.enable_tx_laser = NULL;
                mac->ops.flap_tx_laser = NULL;
+               mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
                mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
                mac->ops.setup_fc = ixgbe_setup_fc_x550em;
-               mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
                mac->ops.set_rate_select_speed =
                                        ixgbe_set_soft_rate_select_speed;
                break;
@@ -1349,6 +1466,8 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
                mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
                mac->ops.setup_fc = ixgbe_setup_fc_generic;
                mac->ops.check_link = ixgbe_check_link_t_X550em;
+               return;
+       case ixgbe_media_type_backplane:
                break;
        default:
                mac->ops.setup_fc = ixgbe_setup_fc_x550em;
@@ -2107,11 +2226,12 @@ static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
                media_type = ixgbe_media_type_backplane;
                break;
        case IXGBE_DEV_ID_X550EM_X_SFP:
+       case IXGBE_DEV_ID_X550EM_A_SFP_N:
                media_type = ixgbe_media_type_fiber;
                break;
        case IXGBE_DEV_ID_X550EM_X_1G_T:
        case IXGBE_DEV_ID_X550EM_X_10G_T:
-                media_type = ixgbe_media_type_copper;
+               media_type = ixgbe_media_type_copper;
                break;
        default:
                media_type = ixgbe_media_type_unknown;
@@ -2375,6 +2495,59 @@ static void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
        ixgbe_release_swfw_sync_X540(hw, mask);
 }
 
+/**
+ * ixgbe_acquire_swfw_sync_x550em_a - Acquire SWFW semaphore
+ * @hw: pointer to hardware structure
+ * @mask: Mask to specify which semaphore to acquire
+ *
+ * Acquires the SWFW semaphore and get the shared PHY token as needed
+ */
+static s32 ixgbe_acquire_swfw_sync_x550em_a(struct ixgbe_hw *hw, u32 mask)
+{
+       u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
+       int retries = FW_PHY_TOKEN_RETRIES;
+       s32 status;
+
+       while (--retries) {
+               status = 0;
+               if (hmask)
+                       status = ixgbe_acquire_swfw_sync_X540(hw, hmask);
+               if (status)
+                       return status;
+               if (!(mask & IXGBE_GSSR_TOKEN_SM))
+                       return 0;
+
+               status = ixgbe_get_phy_token(hw);
+               if (!status)
+                       return 0;
+               if (hmask)
+                       ixgbe_release_swfw_sync_X540(hw, hmask);
+               if (status != IXGBE_ERR_TOKEN_RETRY)
+                       return status;
+               udelay(FW_PHY_TOKEN_DELAY * 1000);
+       }
+
+       return status;
+}
+
+/**
+ * ixgbe_release_swfw_sync_x550em_a - Release SWFW semaphore
+ * @hw: pointer to hardware structure
+ * @mask: Mask to specify which semaphore to release
+ *
+ * Release the SWFW semaphore and puts the shared PHY token as needed
+ */
+static void ixgbe_release_swfw_sync_x550em_a(struct ixgbe_hw *hw, u32 mask)
+{
+       u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
+
+       if (mask & IXGBE_GSSR_TOKEN_SM)
+               ixgbe_put_phy_token(hw);
+
+       if (hmask)
+               ixgbe_release_swfw_sync_X540(hw, hmask);
+}
+
 #define X550_COMMON_MAC \
        .init_hw                        = &ixgbe_init_hw_generic, \
        .start_hw                       = &ixgbe_start_hw_X540, \
@@ -2455,6 +2628,23 @@ static const struct ixgbe_mac_operations mac_ops_X550EM_x = {
        .write_iosf_sb_reg      = ixgbe_write_iosf_sb_reg_x550,
 };
 
+static struct ixgbe_mac_operations mac_ops_x550em_a = {
+       X550_COMMON_MAC
+       .reset_hw               = ixgbe_reset_hw_X550em,
+       .get_media_type         = ixgbe_get_media_type_X550em,
+       .get_san_mac_addr       = NULL,
+       .get_wwn_prefix         = NULL,
+       .setup_link             = NULL, /* defined later */
+       .get_link_capabilities  = ixgbe_get_link_capabilities_X550em,
+       .get_bus_info           = ixgbe_get_bus_info_X550em,
+       .setup_sfp              = ixgbe_setup_sfp_modules_X550em,
+       .acquire_swfw_sync      = ixgbe_acquire_swfw_sync_x550em_a,
+       .release_swfw_sync      = ixgbe_release_swfw_sync_x550em_a,
+       .setup_fc               = ixgbe_setup_fc_generic,
+       .read_iosf_sb_reg       = ixgbe_read_iosf_sb_reg_x550a,
+       .write_iosf_sb_reg      = ixgbe_write_iosf_sb_reg_x550a,
+};
+
 #define X550_COMMON_EEP \
        .read                   = &ixgbe_read_ee_hostif_X550, \
        .read_buffer            = &ixgbe_read_ee_hostif_buffer_X550, \
@@ -2515,6 +2705,10 @@ static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = {
        IXGBE_MVALS_INIT(X550EM_x)
 };
 
+static const u32 ixgbe_mvals_x550em_a[IXGBE_MVALS_IDX_LIMIT] = {
+       IXGBE_MVALS_INIT(X550EM_a)
+};
+
 const struct ixgbe_info ixgbe_X550_info = {
        .mac                    = ixgbe_mac_X550,
        .get_invariants         = &ixgbe_get_invariants_X540,
@@ -2534,3 +2728,13 @@ const struct ixgbe_info ixgbe_X550EM_x_info = {
        .mbx_ops                = &mbx_ops_generic,
        .mvals                  = ixgbe_mvals_X550EM_x,
 };
+
+const struct ixgbe_info ixgbe_x550em_a_info = {
+       .mac                    = ixgbe_mac_x550em_a,
+       .get_invariants         = &ixgbe_get_invariants_X550_x,
+       .mac_ops                = &mac_ops_x550em_a,
+       .eeprom_ops             = &eeprom_ops_X550EM_x,
+       .phy_ops                = &phy_ops_X550EM_x,
+       .mbx_ops                = &mbx_ops_generic,
+       .mvals                  = ixgbe_mvals_x550em_a,
+};