diff options
author | Felix Fietkau <nbd@openwrt.org> | 2015-01-24 19:41:55 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2015-01-24 19:41:55 +0000 |
commit | f04feb379921c826b6034c831e8a5aed01525f9e (patch) | |
tree | 8dade0795aabb572c965a58e5d08693395a26ae6 /target/linux | |
parent | ae7769af49f1e104e701ff96e51b4c3a655ba2b6 (diff) | |
download | upstream-f04feb379921c826b6034c831e8a5aed01525f9e.tar.gz upstream-f04feb379921c826b6034c831e8a5aed01525f9e.tar.bz2 upstream-f04feb379921c826b6034c831e8a5aed01525f9e.zip |
ar8216: add link change detection for switch ports
Check for switch port link changes and
- flush ATU in case of a change
- report link change via syslog
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@44102 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/ar8216.c | 35 | ||||
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/ar8216.h | 1 |
2 files changed, 36 insertions, 0 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index 370f1acc89..130ebf7126 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -1707,12 +1707,47 @@ ar8xxx_phy_config_init(struct phy_device *phydev) return 0; } +static bool +ar8xxx_check_link_states(struct ar8xxx_priv *priv) +{ + bool link_new, changed = false; + u32 status; + int i; + + mutex_lock(&priv->reg_mutex); + + for (i = 0; i < priv->dev.ports; i++) { + status = priv->chip->read_port_status(priv, i); + link_new = !!(status & AR8216_PORT_STATUS_LINK_UP); + if (link_new == priv->link_up[i]) + continue; + + priv->link_up[i] = link_new; + changed = true; + dev_info(&priv->phy->dev, "Port %d is %s\n", + i, link_new ? "up" : "down"); + } + + if (changed) + priv->chip->atu_flush(priv); + + mutex_unlock(&priv->reg_mutex); + + return changed; +} + static int ar8xxx_phy_read_status(struct phy_device *phydev) { struct ar8xxx_priv *priv = phydev->priv; struct switch_port_link link; + /* check for link changes and flush ATU + * if a change was detected + */ + if (phydev->state == PHY_CHANGELINK) + ar8xxx_check_link_states(priv); + if (phydev->addr != 0) return genphy_read_status(phydev); diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.h b/target/linux/generic/files/drivers/net/phy/ar8216.h index 8487c3ea49..2d025ae835 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.h +++ b/target/linux/generic/files/drivers/net/phy/ar8216.h @@ -396,6 +396,7 @@ struct ar8xxx_priv { bool initialized; bool port4_phy; char buf[2048]; + bool link_up[AR8X16_MAX_PORTS]; bool init; |