Author: smh
Date: Sun Jan 31 15:14:23 2016
New Revision: 295093
URL: https://svnweb.freebsd.org/changeset/base/295093

Log:
  Configure ixgbe phy & gbic power
  
  Setup phy and gbic power as per Linux 4.3.13 driver.
  
  This fixes link not detected on X540-AT2 after booting to Linux which turns
  the phy power off on detach.
  
  Reviewed by:  sbruno
  MFC after:    2 days
  Sponsored by: Multiplay
  Differential Revision:        https://reviews.freebsd.org/D5107

Modified:
  head/sys/dev/ixgbe/if_ix.c
  head/sys/dev/ixgbe/ixgbe_phy.c
  head/sys/dev/ixgbe/ixgbe_type.h
  head/sys/dev/ixgbe/ixgbe_x540.c
  head/sys/dev/ixgbe/ixgbe_x550.c

Modified: head/sys/dev/ixgbe/if_ix.c
==============================================================================
--- head/sys/dev/ixgbe/if_ix.c  Sun Jan 31 13:59:16 2016        (r295092)
+++ head/sys/dev/ixgbe/if_ix.c  Sun Jan 31 15:14:23 2016        (r295093)
@@ -592,6 +592,12 @@ ixgbe_attach(device_t dev)
        if (error) 
                goto err_late;
 
+       /* Enable the optics for 82599 SFP+ fiber */
+       ixgbe_enable_tx_laser(hw);
+
+       /* Enable power to the phy. */
+       ixgbe_set_phy_power(hw, TRUE);
+
        /* Setup OS specific network interface */
        if (ixgbe_setup_interface(dev, adapter) != 0)
                goto err_late;
@@ -1260,6 +1266,9 @@ ixgbe_init_locked(struct adapter *adapte
                        device_printf(dev, "Error setting up EEE: %d\n", err);
        }
 
+       /* Enable power to the phy. */
+       ixgbe_set_phy_power(hw, TRUE);
+
        /* Config/Enable Link */
        ixgbe_config_link(adapter);
 
@@ -3980,6 +3989,9 @@ ixgbe_setup_low_power_mode(struct adapte
 
        mtx_assert(&adapter->core_mtx, MA_OWNED);
 
+       if (!hw->wol_enabled)
+               ixgbe_set_phy_power(hw, FALSE);
+
        /* Limit power management flow to X550EM baseT */
        if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T
            && hw->phy.ops.enter_lplu) {

Modified: head/sys/dev/ixgbe/ixgbe_phy.c
==============================================================================
--- head/sys/dev/ixgbe/ixgbe_phy.c      Sun Jan 31 13:59:16 2016        
(r295092)
+++ head/sys/dev/ixgbe/ixgbe_phy.c      Sun Jan 31 15:14:23 2016        
(r295093)
@@ -2734,6 +2734,9 @@ s32 ixgbe_set_copper_phy_power(struct ix
        u32 status;
        u16 reg;
 
+       if (!on && ixgbe_mng_present(hw))
+               return 0;
+
        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
                                      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
                                      &reg);

Modified: head/sys/dev/ixgbe/ixgbe_type.h
==============================================================================
--- head/sys/dev/ixgbe/ixgbe_type.h     Sun Jan 31 13:59:16 2016        
(r295092)
+++ head/sys/dev/ixgbe/ixgbe_type.h     Sun Jan 31 15:14:23 2016        
(r295093)
@@ -1479,7 +1479,10 @@ struct ixgbe_dmac_config {
 #define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK    0xFF01 /* int chip-wide mask */
 #define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG    0xFC01 /* int chip-wide mask */
 #define IXGBE_MDIO_GLOBAL_ALARM_1              0xCC00 /* Global alarm 1 */
+#define IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT      0x0010 /* device fault */
 #define IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL    0x4000 /* high temp failure */
+#define IXGBE_MDIO_GLOBAL_FAULT_MSG            0xC850 /* Global Fault Message 
*/
+#define IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP     0x8007 /* high temp failure */
 #define IXGBE_MDIO_GLOBAL_INT_MASK             0xD400 /* Global int mask */
 #define IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN    0x1000 /* autoneg vendor alarm 
int enable */
 #define IXGBE_MDIO_GLOBAL_ALARM_1_INT          0x4 /* int in Global alarm 1 */

Modified: head/sys/dev/ixgbe/ixgbe_x540.c
==============================================================================
--- head/sys/dev/ixgbe/ixgbe_x540.c     Sun Jan 31 13:59:16 2016        
(r295092)
+++ head/sys/dev/ixgbe/ixgbe_x540.c     Sun Jan 31 15:14:23 2016        
(r295093)
@@ -82,8 +82,7 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw 
        /* PHY */
        phy->ops.init = ixgbe_init_phy_ops_generic;
        phy->ops.reset = NULL;
-       if (!ixgbe_mng_present(hw))
-               phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
+       phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
 
        /* MAC */
        mac->ops.reset_hw = ixgbe_reset_hw_X540;

Modified: head/sys/dev/ixgbe/ixgbe_x550.c
==============================================================================
--- head/sys/dev/ixgbe/ixgbe_x550.c     Sun Jan 31 13:59:16 2016        
(r295092)
+++ head/sys/dev/ixgbe/ixgbe_x550.c     Sun Jan 31 15:14:23 2016        
(r295093)
@@ -965,7 +965,7 @@ void ixgbe_restore_mdd_vf_X550(struct ix
                num_qs = 4;  /* 32 VFs / pools */
                bitmask = 0x0000000F;
                break;
-       default:            /* 64 VFs / pools */
+       default:            /* 64 VFs / pools */
                num_qs = 2;
                bitmask = 0x00000003;
                break;
@@ -1264,7 +1264,7 @@ static s32 ixgbe_get_lasi_ext_t_x550em(s
            IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
                return status;
 
-       /* High temperature failure alarm triggered */
+       /* Global alarm triggered */
        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
                                      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
                                      &reg);
@@ -1277,6 +1277,21 @@ static s32 ixgbe_get_lasi_ext_t_x550em(s
                /* power down the PHY in case the PHY FW didn't already */
                ixgbe_set_copper_phy_power(hw, FALSE);
                return IXGBE_ERR_OVERTEMP;
+       } else if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
+               /*  device fault alarm triggered */
+               status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
+                                         IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+                                         &reg);
+
+               if (status != IXGBE_SUCCESS)
+                       return status;
+
+               /* if device fault was due to high temp alarm handle and exit */
+               if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
+                       /* power down the PHY in case the PHY FW didn't */
+                       ixgbe_set_copper_phy_power(hw, FALSE);
+                       return IXGBE_ERR_OVERTEMP;
+               }
        }
 
        /* Vendor alarm 2 triggered */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to