diff options
author | David S. Miller <davem@davemloft.net> | 2017-01-09 21:39:11 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-01-09 21:39:11 +0100 |
commit | bb1d3034449ed08e2ffbf5813a5ad9fa30475359 (patch) | |
tree | a48cc17fc4683b5fdc1656ac71639540bd8852e2 /drivers/net/phy | |
parent | Merge branch 'dwmac-dwc-qos-eth' (diff) | |
parent | phy state machine: failsafe leave invalid RUNNING state (diff) | |
download | linux-bb1d3034449ed08e2ffbf5813a5ad9fa30475359.tar.xz linux-bb1d3034449ed08e2ffbf5813a5ad9fa30475359.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/dp83867.c | 10 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 9 |
2 files changed, 19 insertions, 0 deletions
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index 1b639242f9e2..e84ae084e259 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -29,6 +29,7 @@ #define MII_DP83867_MICR 0x12 #define MII_DP83867_ISR 0x13 #define DP83867_CTRL 0x1f +#define DP83867_CFG3 0x1e /* Extended Registers */ #define DP83867_RGMIICTL 0x0032 @@ -98,6 +99,8 @@ static int dp83867_config_intr(struct phy_device *phydev) micr_status |= (MII_DP83867_MICR_AN_ERR_INT_EN | MII_DP83867_MICR_SPEED_CHNG_INT_EN | + MII_DP83867_MICR_AUTONEG_COMP_INT_EN | + MII_DP83867_MICR_LINK_STS_CHNG_INT_EN | MII_DP83867_MICR_DUP_MODE_CHNG_INT_EN | MII_DP83867_MICR_SLEEP_MODE_CHNG_INT_EN); @@ -214,6 +217,13 @@ static int dp83867_config_init(struct phy_device *phydev) } } + /* Enable Interrupt output INT_OE in CFG3 register */ + if (phy_interrupt_is_valid(phydev)) { + val = phy_read(phydev, DP83867_CFG3); + val |= BIT(7); + phy_write(phydev, DP83867_CFG3, val); + } + return 0; } diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 25f93a98863b..48da6e93c3f7 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1065,6 +1065,15 @@ void phy_state_machine(struct work_struct *work) if (old_link != phydev->link) phydev->state = PHY_CHANGELINK; } + /* + * Failsafe: check that nobody set phydev->link=0 between two + * poll cycles, otherwise we won't leave RUNNING state as long + * as link remains down. + */ + if (!phydev->link && phydev->state == PHY_RUNNING) { + phydev->state = PHY_CHANGELINK; + phydev_err(phydev, "no link in PHY_RUNNING\n"); + } break; case PHY_CHANGELINK: err = phy_read_status(phydev); |