aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2015-01-24 19:41:55 +0000
committerFelix Fietkau <nbd@openwrt.org>2015-01-24 19:41:55 +0000
commitf04feb379921c826b6034c831e8a5aed01525f9e (patch)
tree8dade0795aabb572c965a58e5d08693395a26ae6 /target/linux
parentae7769af49f1e104e701ff96e51b4c3a655ba2b6 (diff)
downloadupstream-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.c35
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8216.h1
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;