]> git.ipfire.org Git - people/ms/linux.git/commitdiff
net: dsa: allow drivers to do link adjustment
authorFlorian Fainelli <f.fainelli@gmail.com>
Thu, 28 Aug 2014 00:04:53 +0000 (17:04 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 28 Aug 2014 05:59:40 +0000 (22:59 -0700)
Whenever libphy determines that the link status of a given PHY/port has
changed, allow to call into the switch driver link adjustment callback
so proper actions can be taken care of by the switch driver upon link
notification.

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 1035f6452d7931ce8ca1e388f47b49137936721f..2d3835924dd23afa9141c88b5f778e8cea0610e3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 #include <linux/of.h>
+#include <linux/phy.h>
 
 #define DSA_MAX_SWITCHES       4
 #define DSA_MAX_PORTS          12
@@ -181,6 +182,12 @@ struct dsa_switch_driver {
         */
        void    (*poll_link)(struct dsa_switch *ds);
 
+       /*
+        * Link state adjustment (called from libphy)
+        */
+       void    (*adjust_link)(struct dsa_switch *ds, int port,
+                               struct phy_device *phydev);
+
        /*
         * ethtool hardware statistics.
         */
index 241c2a1684cbb120ac62ae6d96f084cc1a5654ff..398d0663d3ddf94052c1cd79553841abc5dcd918 100644 (file)
@@ -333,6 +333,7 @@ static const struct dsa_device_ops notag_netdev_ops = {
 static void dsa_slave_adjust_link(struct net_device *dev)
 {
        struct dsa_slave_priv *p = netdev_priv(dev);
+       struct dsa_switch *ds = p->parent;
        unsigned int status_changed = 0;
 
        if (p->old_link != p->phy->link) {
@@ -350,6 +351,9 @@ static void dsa_slave_adjust_link(struct net_device *dev)
                p->old_pause = p->phy->pause;
        }
 
+       if (ds->drv->adjust_link && status_changed)
+               ds->drv->adjust_link(ds, p->port, p->phy);
+
        if (status_changed)
                phy_print_status(p->phy);
 }