Module Name: src Committed By: msaitoh Date: Tue Nov 7 05:41:54 UTC 2017
Modified Files: src/sys/dev/pci/ixgbe: ixgbe_phy.c Log Message: Fix a bug that X550T(1) didn't linkup if it forces 100BaseTX-FDX. Popular switches and OSes don't use auto-negotiation if the media is 100BASE-TX (and 10BASE-T). Do the same thig. Another fix is required for Denverton's _T device which use firmware. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/sys/dev/pci/ixgbe/ixgbe_phy.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/ixgbe/ixgbe_phy.c diff -u src/sys/dev/pci/ixgbe/ixgbe_phy.c:1.12 src/sys/dev/pci/ixgbe/ixgbe_phy.c:1.13 --- src/sys/dev/pci/ixgbe/ixgbe_phy.c:1.12 Wed Aug 30 08:49:18 2017 +++ src/sys/dev/pci/ixgbe/ixgbe_phy.c Tue Nov 7 05:41:54 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ixgbe_phy.c,v 1.12 2017/08/30 08:49:18 msaitoh Exp $ */ +/* $NetBSD: ixgbe_phy.c,v 1.13 2017/11/07 05:41:54 msaitoh Exp $ */ /****************************************************************************** @@ -38,6 +38,8 @@ #include "ixgbe_common.h" #include "ixgbe_phy.h" +#include <dev/mii/mdio.h> + static void ixgbe_i2c_start(struct ixgbe_hw *hw); static void ixgbe_i2c_stop(struct ixgbe_hw *hw); static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data); @@ -855,18 +857,39 @@ s32 ixgbe_setup_phy_link_generic(struct IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); - /* Blocked by MNG FW so don't reset PHY */ - if (ixgbe_check_reset_blocked(hw)) - return status; + if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_100_FULL) { + u16 ctrl; - /* Restart PHY auto-negotiation. */ - hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, + /* Force 100Mbps */ + hw->phy.ops.read_reg(hw, MDIO_PMAPMD_CTRL1, MDIO_MMD_PMAPMD, + &ctrl); + ctrl &= ~PMAPMD_CTRL1_SPEED_MASK; + ctrl |= PMAPMD_CTRL1_SPEED_100; + hw->phy.ops.write_reg(hw, MDIO_PMAPMD_CTRL1,MDIO_MMD_PMAPMD, + ctrl); + + /* Don't use auto-nego for 100Mbps */ + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); - autoneg_reg |= IXGBE_MII_RESTART; + autoneg_reg &= ~AN_CTRL1_AUTOEN; - hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, + hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); + } else { + /* Blocked by MNG FW so don't reset PHY */ + if (ixgbe_check_reset_blocked(hw)) + return status; + + /* Restart PHY auto-negotiation. */ + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); + + autoneg_reg |= IXGBE_MII_RESTART | AN_CTRL1_AUTOEN; + + hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); + } return status; }