aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2014-08-27 20:04:53 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-28 01:59:40 -0400
commitec9436baedb689668c409cfc8b69eb9573b0d661 (patch)
tree928b1885d12a73c353a6a7f1047d3790a3ee5ad6
parent5aed85cec29882d1c4b4b2a01cb75a99efdbe4ed (diff)
net: dsa: allow drivers to do link adjustment
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>
-rw-r--r--include/net/dsa.h7
-rw-r--r--net/dsa/slave.c4
2 files changed, 11 insertions, 0 deletions
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 1035f6452d79..2d3835924dd2 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -16,6 +16,7 @@
16#include <linux/timer.h> 16#include <linux/timer.h>
17#include <linux/workqueue.h> 17#include <linux/workqueue.h>
18#include <linux/of.h> 18#include <linux/of.h>
19#include <linux/phy.h>
19 20
20#define DSA_MAX_SWITCHES 4 21#define DSA_MAX_SWITCHES 4
21#define DSA_MAX_PORTS 12 22#define DSA_MAX_PORTS 12
@@ -182,6 +183,12 @@ struct dsa_switch_driver {
182 void (*poll_link)(struct dsa_switch *ds); 183 void (*poll_link)(struct dsa_switch *ds);
183 184
184 /* 185 /*
186 * Link state adjustment (called from libphy)
187 */
188 void (*adjust_link)(struct dsa_switch *ds, int port,
189 struct phy_device *phydev);
190
191 /*
185 * ethtool hardware statistics. 192 * ethtool hardware statistics.
186 */ 193 */
187 void (*get_strings)(struct dsa_switch *ds, int port, uint8_t *data); 194 void (*get_strings)(struct dsa_switch *ds, int port, uint8_t *data);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 241c2a1684cb..398d0663d3dd 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -333,6 +333,7 @@ static const struct dsa_device_ops notag_netdev_ops = {
333static void dsa_slave_adjust_link(struct net_device *dev) 333static void dsa_slave_adjust_link(struct net_device *dev)
334{ 334{
335 struct dsa_slave_priv *p = netdev_priv(dev); 335 struct dsa_slave_priv *p = netdev_priv(dev);
336 struct dsa_switch *ds = p->parent;
336 unsigned int status_changed = 0; 337 unsigned int status_changed = 0;
337 338
338 if (p->old_link != p->phy->link) { 339 if (p->old_link != p->phy->link) {
@@ -350,6 +351,9 @@ static void dsa_slave_adjust_link(struct net_device *dev)
350 p->old_pause = p->phy->pause; 351 p->old_pause = p->phy->pause;
351 } 352 }
352 353
354 if (ds->drv->adjust_link && status_changed)
355 ds->drv->adjust_link(ds, p->port, p->phy);
356
353 if (status_changed) 357 if (status_changed)
354 phy_print_status(p->phy); 358 phy_print_status(p->phy);
355} 359}