net: dsa: allow updating fixed PHY link information
authorFlorian Fainelli <f.fainelli@gmail.com>
Thu, 28 Aug 2014 00:04:54 +0000 (17:04 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 28 Aug 2014 05:59:40 +0000 (22:59 -0700)
Allow switch drivers to hook a PHY link update callback to perform
port-specific link work.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/dsa.h
net/dsa/slave.c

index 2d3835924dd23afa9141c88b5f778e8cea0610e3..2c9563f0b2f4905bddcdc127d5a16f44e36936fc 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/workqueue.h>
 #include <linux/of.h>
 #include <linux/phy.h>
+#include <linux/phy_fixed.h>
 
 #define DSA_MAX_SWITCHES       4
 #define DSA_MAX_PORTS          12
@@ -187,6 +188,8 @@ struct dsa_switch_driver {
         */
        void    (*adjust_link)(struct dsa_switch *ds, int port,
                                struct phy_device *phydev);
+       void    (*fixed_link_update)(struct dsa_switch *ds, int port,
+                               struct fixed_phy_status *st);
 
        /*
         * ethtool hardware statistics.
index 398d0663d3ddf94052c1cd79553841abc5dcd918..18ff53836fe3a10a4ae7aca9ad68121c90cbccd0 100644 (file)
@@ -358,6 +358,18 @@ static void dsa_slave_adjust_link(struct net_device *dev)
                phy_print_status(p->phy);
 }
 
+static int dsa_slave_fixed_link_update(struct net_device *dev,
+                                      struct fixed_phy_status *status)
+{
+       struct dsa_slave_priv *p = netdev_priv(dev);
+       struct dsa_switch *ds = p->parent;
+
+       if (ds->drv->fixed_link_update)
+               ds->drv->fixed_link_update(ds, p->port, status);
+
+       return 0;
+}
+
 /* slave device setup *******************************************************/
 static void dsa_slave_phy_setup(struct dsa_slave_priv *p,
                                struct net_device *slave_dev)
@@ -365,6 +377,7 @@ static void dsa_slave_phy_setup(struct dsa_slave_priv *p,
        struct dsa_switch *ds = p->parent;
        struct dsa_chip_data *cd = ds->pd;
        struct device_node *phy_dn, *port_dn;
+       bool phy_is_fixed = false;
        int ret;
 
        port_dn = cd->port_dn[p->port];
@@ -380,6 +393,7 @@ static void dsa_slave_phy_setup(struct dsa_slave_priv *p,
                        pr_err("failed to register fixed PHY\n");
                        return;
                }
+               phy_is_fixed = true;
                phy_dn = port_dn;
        }
 
@@ -388,6 +402,9 @@ static void dsa_slave_phy_setup(struct dsa_slave_priv *p,
                                        dsa_slave_adjust_link, 0,
                                        p->phy_interface);
 
+       if (p->phy && phy_is_fixed)
+               fixed_phy_set_link_update(p->phy, dsa_slave_fixed_link_update);
+
        /* We could not connect to a designated PHY, so use the switch internal
         * MDIO bus instead
         */