ixgbe: add 1g PHY support for 82599
authorDon Skidmore <donald.c.skidmore@intel.com>
Tue, 29 Jun 2010 18:30:59 +0000 (18:30 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 30 Jun 2010 21:27:40 +0000 (14:27 -0700)
Add support for 1G SFP+ PHY's to 82599.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ixgbe/ixgbe_82599.c
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixgbe/ixgbe_phy.c
drivers/net/ixgbe/ixgbe_phy.h
drivers/net/ixgbe/ixgbe_type.h

index 976fd9e146c6b5479c63b43d835a4f0200e10353..0ee175a289ee2ca43bdf70d802d693b5bea8d3ff 100644 (file)
@@ -206,6 +206,14 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
        s32 status = 0;
        u32 autoc = 0;
 
+       /* Determine 1G link capabilities off of SFP+ type */
+       if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
+           hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1) {
+               *speed = IXGBE_LINK_SPEED_1GB_FULL;
+               *negotiation = true;
+               goto out;
+       }
+
        /*
         * Determine link capabilities based on the stored value of AUTOC,
         * which represents EEPROM defaults.  If AUTOC value has not been
@@ -2087,6 +2095,7 @@ static u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
        u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
        u16 ext_ability = 0;
        u8 comp_codes_10g = 0;
+       u8 comp_codes_1g = 0;
 
        hw->phy.ops.identify(hw);
 
@@ -2166,12 +2175,16 @@ sfp_check:
        case ixgbe_phy_sfp_ftl:
        case ixgbe_phy_sfp_intel:
        case ixgbe_phy_sfp_unknown:
+               hw->phy.ops.read_i2c_eeprom(hw,
+                     IXGBE_SFF_1GBE_COMP_CODES, &comp_codes_1g);
                hw->phy.ops.read_i2c_eeprom(hw,
                      IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
                if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
                        physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
                else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
                        physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+               else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
                break;
        default:
                break;
index 7d2e5ea2deba0bf2e0567076772f740d08a4365e..b50b5ea4cf83101ce7cf2be9c650ef762e3d13c6 100644 (file)
@@ -234,6 +234,13 @@ static int ixgbe_get_settings(struct net_device *netdev,
                case ixgbe_sfp_type_not_present:
                        ecmd->port = PORT_NONE;
                        break;
+               case ixgbe_sfp_type_1g_cu_core0:
+               case ixgbe_sfp_type_1g_cu_core1:
+                       ecmd->port = PORT_TP;
+                       ecmd->supported = SUPPORTED_TP;
+                       ecmd->advertising = (ADVERTISED_1000baseT_Full |
+                                            ADVERTISED_TP);
+                       break;
                case ixgbe_sfp_type_unknown:
                default:
                        ecmd->port = PORT_OTHER;
index 48325a5beff2054c59b2aa9f6b333bcdf4d3d0c8..6c0d42e33f21770092668b3c3405223c3e55d09b 100644 (file)
@@ -577,6 +577,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                 * 6    SFP_SR/LR_CORE1 - 82599-specific
                 * 7    SFP_act_lmt_DA_CORE0 - 82599-specific
                 * 8    SFP_act_lmt_DA_CORE1 - 82599-specific
+                * 9    SFP_1g_cu_CORE0 - 82599-specific
+                * 10   SFP_1g_cu_CORE1 - 82599-specific
                 */
                if (hw->mac.type == ixgbe_mac_82598EB) {
                        if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
@@ -625,6 +627,13 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                                else
                                        hw->phy.sfp_type =
                                                      ixgbe_sfp_type_srlr_core1;
+                       else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE)
+                               if (hw->bus.lan_id == 0)
+                                       hw->phy.sfp_type =
+                                               ixgbe_sfp_type_1g_cu_core0;
+                               else
+                                       hw->phy.sfp_type =
+                                               ixgbe_sfp_type_1g_cu_core1;
                        else
                                hw->phy.sfp_type = ixgbe_sfp_type_unknown;
                }
@@ -696,8 +705,10 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                        goto out;
                }
 
-               /* 1G SFP modules are not supported */
-               if (comp_codes_10g == 0) {
+               /* Verify supported 1G SFP modules */
+               if (comp_codes_10g == 0 &&
+                   !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
+                     hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0)) {
                        hw->phy.type = ixgbe_phy_sfp_unsupported;
                        status = IXGBE_ERR_SFP_NOT_SUPPORTED;
                        goto out;
@@ -711,7 +722,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
 
                /* This is guaranteed to be 82599, no need to check for NULL */
                hw->mac.ops.get_device_caps(hw, &enforce_sfp);
-               if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
+               if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
+                   !((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) ||
+                     (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1))) {
                        /* Make sure we're a supported PHY type */
                        if (hw->phy.type == ixgbe_phy_sfp_intel) {
                                status = 0;
@@ -742,6 +755,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
                                         u16 *data_offset)
 {
        u16 sfp_id;
+       u16 sfp_type = hw->phy.sfp_type;
 
        if (hw->phy.sfp_type == ixgbe_sfp_type_unknown)
                return IXGBE_ERR_SFP_NOT_SUPPORTED;
@@ -753,6 +767,17 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
            (hw->phy.sfp_type == ixgbe_sfp_type_da_cu))
                return IXGBE_ERR_SFP_NOT_SUPPORTED;
 
+       /*
+        * Limiting active cables and 1G Phys must be initialized as
+        * SR modules
+        */
+       if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 ||
+           sfp_type == ixgbe_sfp_type_1g_cu_core0)
+               sfp_type = ixgbe_sfp_type_srlr_core0;
+       else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 ||
+                sfp_type == ixgbe_sfp_type_1g_cu_core1)
+               sfp_type = ixgbe_sfp_type_srlr_core1;
+
        /* Read offset to PHY init contents */
        hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset);
 
@@ -769,7 +794,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
        hw->eeprom.ops.read(hw, *list_offset, &sfp_id);
 
        while (sfp_id != IXGBE_PHY_INIT_END_NL) {
-               if (sfp_id == hw->phy.sfp_type) {
+               if (sfp_id == sfp_type) {
                        (*list_offset)++;
                        hw->eeprom.ops.read(hw, *list_offset, data_offset);
                        if ((!*data_offset) || (*data_offset == 0xFFFF)) {
index ef4ba834c593e81220dfa78a9174646cb4289502..fb3898f12fc5519b1d01f2705323ef4271ef2730 100644 (file)
@@ -48,6 +48,7 @@
 #define IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING    0x4
 #define IXGBE_SFF_1GBASESX_CAPABLE           0x1
 #define IXGBE_SFF_1GBASELX_CAPABLE           0x2
+#define IXGBE_SFF_1GBASET_CAPABLE            0x8
 #define IXGBE_SFF_10GBASESR_CAPABLE          0x10
 #define IXGBE_SFF_10GBASELR_CAPABLE          0x20
 #define IXGBE_I2C_EEPROM_READ_MASK           0x100
index cdd1998f18c705348a618098f8e098edda8d7e98..9587d975d66c6eeb31e82f9233ab82f876036134 100644 (file)
@@ -2214,6 +2214,8 @@ enum ixgbe_sfp_type {
        ixgbe_sfp_type_srlr_core1 = 6,
        ixgbe_sfp_type_da_act_lmt_core0 = 7,
        ixgbe_sfp_type_da_act_lmt_core1 = 8,
+       ixgbe_sfp_type_1g_cu_core0 = 9,
+       ixgbe_sfp_type_1g_cu_core1 = 10,
        ixgbe_sfp_type_not_present = 0xFFFE,
        ixgbe_sfp_type_unknown = 0xFFFF
 };