In conditions where none of the switch ports is connected during boot,
the priv->port[i].link != priv->port[i].phydev->link condition is false
since both link values are equal (false). The carrier of the switch
netdev is never set to off and the link state reported by ip is UNKNOWN.
Turn the carrier off if none of the switch ports has a link, regardless
whether something has been changed. Add a check for a carrier to
prevent unnecessary calls to netif_carrier_off() if the carrier is
already off.
Based on a patch send by Martin Schiller.
Signed-off-by: Mathias Kresin <dev@kresin.me>
+};
--- /dev/null
+++ b/drivers/net/ethernet/lantiq_xrx200.c
+};
--- /dev/null
+++ b/drivers/net/ethernet/lantiq_xrx200.c
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+static void xrx200_mdio_link(struct net_device *dev)
+{
+ struct xrx200_priv *priv = netdev_priv(dev);
+static void xrx200_mdio_link(struct net_device *dev)
+{
+ struct xrx200_priv *priv = netdev_priv(dev);
-+ bool changed = false, link = false;
+ int i;
+
+ for (i = 0; i < priv->num_port; i++) {
+ int i;
+
+ for (i = 0; i < priv->num_port; i++) {
+ link = true;
+
+ if (priv->port[i].link != priv->port[i].phydev->link) {
+ link = true;
+
+ if (priv->port[i].link != priv->port[i].phydev->link) {
+ xrx200_gmac_update(&priv->port[i]);
+ priv->port[i].link = priv->port[i].phydev->link;
+ netdev_info(dev, "port %d %s link\n",
+ xrx200_gmac_update(&priv->port[i]);
+ priv->port[i].link = priv->port[i].phydev->link;
+ netdev_info(dev, "port %d %s link\n",
+ (priv->port[i].link)?("got"):("lost"));
+ }
+ }
+ (priv->port[i].link)?("got"):("lost"));
+ }
+ }
++ if (netif_carrier_ok(dev) && !link)
+ netif_carrier_off(dev);
+}
+
+ netif_carrier_off(dev);
+}
+