aboutsummaryrefslogtreecommitdiffstats
path: root/net/dsa/slave.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dsa/slave.c')
-rw-r--r--net/dsa/slave.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index d8c3c0f00cf3..061a49c29cef 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -27,6 +27,17 @@
27 27
28static bool dsa_slave_dev_check(struct net_device *dev); 28static bool dsa_slave_dev_check(struct net_device *dev);
29 29
30static int dsa_slave_notify(struct net_device *dev, unsigned long e, void *v)
31{
32 struct dsa_slave_priv *p = netdev_priv(dev);
33 struct raw_notifier_head *nh = &p->dp->ds->dst->nh;
34 int err;
35
36 err = raw_notifier_call_chain(nh, e, v);
37
38 return notifier_to_errno(err);
39}
40
30/* slave mii_bus handling ***************************************************/ 41/* slave mii_bus handling ***************************************************/
31static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg) 42static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg)
32{ 43{
@@ -562,39 +573,46 @@ static int dsa_slave_bridge_port_join(struct net_device *dev,
562 struct net_device *br) 573 struct net_device *br)
563{ 574{
564 struct dsa_slave_priv *p = netdev_priv(dev); 575 struct dsa_slave_priv *p = netdev_priv(dev);
565 struct dsa_switch *ds = p->dp->ds; 576 struct dsa_notifier_bridge_info info = {
566 int ret = -EOPNOTSUPP; 577 .sw_index = p->dp->ds->index,
578 .port = p->dp->index,
579 .br = br,
580 };
581 int err;
567 582
568 /* Here the port is already bridged. Reflect the current configuration 583 /* Here the port is already bridged. Reflect the current configuration
569 * so that drivers can program their chips accordingly. 584 * so that drivers can program their chips accordingly.
570 */ 585 */
571 p->dp->bridge_dev = br; 586 p->dp->bridge_dev = br;
572 587
573 if (ds->ops->port_bridge_join) 588 err = dsa_slave_notify(dev, DSA_NOTIFIER_BRIDGE_JOIN, &info);
574 ret = ds->ops->port_bridge_join(ds, p->dp->index, br);
575 589
576 /* The bridging is rolled back on error */ 590 /* The bridging is rolled back on error */
577 if (ret && ret != -EOPNOTSUPP) { 591 if (err)
578 p->dp->bridge_dev = NULL; 592 p->dp->bridge_dev = NULL;
579 return ret;
580 }
581 593
582 return 0; 594 return err;
583} 595}
584 596
585static void dsa_slave_bridge_port_leave(struct net_device *dev, 597static void dsa_slave_bridge_port_leave(struct net_device *dev,
586 struct net_device *br) 598 struct net_device *br)
587{ 599{
588 struct dsa_slave_priv *p = netdev_priv(dev); 600 struct dsa_slave_priv *p = netdev_priv(dev);
589 struct dsa_switch *ds = p->dp->ds; 601 struct dsa_notifier_bridge_info info = {
602 .sw_index = p->dp->ds->index,
603 .port = p->dp->index,
604 .br = br,
605 };
606 int err;
590 607
591 /* Here the port is already unbridged. Reflect the current configuration 608 /* Here the port is already unbridged. Reflect the current configuration
592 * so that drivers can program their chips accordingly. 609 * so that drivers can program their chips accordingly.
593 */ 610 */
594 p->dp->bridge_dev = NULL; 611 p->dp->bridge_dev = NULL;
595 612
596 if (ds->ops->port_bridge_leave) 613 err = dsa_slave_notify(dev, DSA_NOTIFIER_BRIDGE_LEAVE, &info);
597 ds->ops->port_bridge_leave(ds, p->dp->index, br); 614 if (err)
615 netdev_err(dev, "failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n");
598 616
599 /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer, 617 /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
600 * so allow it to be in BR_STATE_FORWARDING to be kept functional 618 * so allow it to be in BR_STATE_FORWARDING to be kept functional