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.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index aec78f5aca72..a3fcc1d01615 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1050,8 +1050,6 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
1050static const struct switchdev_ops dsa_slave_switchdev_ops = { 1050static const struct switchdev_ops dsa_slave_switchdev_ops = {
1051 .switchdev_port_attr_get = dsa_slave_port_attr_get, 1051 .switchdev_port_attr_get = dsa_slave_port_attr_get,
1052 .switchdev_port_attr_set = dsa_slave_port_attr_set, 1052 .switchdev_port_attr_set = dsa_slave_port_attr_set,
1053 .switchdev_port_obj_add = dsa_slave_port_obj_add,
1054 .switchdev_port_obj_del = dsa_slave_port_obj_del,
1055}; 1053};
1056 1054
1057static struct device_type dsa_type = { 1055static struct device_type dsa_type = {
@@ -1529,6 +1527,44 @@ err_fdb_work_init:
1529 return NOTIFY_BAD; 1527 return NOTIFY_BAD;
1530} 1528}
1531 1529
1530static int
1531dsa_slave_switchdev_port_obj_event(unsigned long event,
1532 struct net_device *netdev,
1533 struct switchdev_notifier_port_obj_info *port_obj_info)
1534{
1535 int err = -EOPNOTSUPP;
1536
1537 switch (event) {
1538 case SWITCHDEV_PORT_OBJ_ADD:
1539 err = dsa_slave_port_obj_add(netdev, port_obj_info->obj,
1540 port_obj_info->trans);
1541 break;
1542 case SWITCHDEV_PORT_OBJ_DEL:
1543 err = dsa_slave_port_obj_del(netdev, port_obj_info->obj);
1544 break;
1545 }
1546
1547 port_obj_info->handled = true;
1548 return notifier_from_errno(err);
1549}
1550
1551static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
1552 unsigned long event, void *ptr)
1553{
1554 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1555
1556 if (!dsa_slave_dev_check(dev))
1557 return NOTIFY_DONE;
1558
1559 switch (event) {
1560 case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
1561 case SWITCHDEV_PORT_OBJ_DEL:
1562 return dsa_slave_switchdev_port_obj_event(event, dev, ptr);
1563 }
1564
1565 return NOTIFY_DONE;
1566}
1567
1532static struct notifier_block dsa_slave_nb __read_mostly = { 1568static struct notifier_block dsa_slave_nb __read_mostly = {
1533 .notifier_call = dsa_slave_netdevice_event, 1569 .notifier_call = dsa_slave_netdevice_event,
1534}; 1570};
@@ -1537,8 +1573,13 @@ static struct notifier_block dsa_slave_switchdev_notifier = {
1537 .notifier_call = dsa_slave_switchdev_event, 1573 .notifier_call = dsa_slave_switchdev_event,
1538}; 1574};
1539 1575
1576static struct notifier_block dsa_slave_switchdev_blocking_notifier = {
1577 .notifier_call = dsa_slave_switchdev_blocking_event,
1578};
1579
1540int dsa_slave_register_notifier(void) 1580int dsa_slave_register_notifier(void)
1541{ 1581{
1582 struct notifier_block *nb;
1542 int err; 1583 int err;
1543 1584
1544 err = register_netdevice_notifier(&dsa_slave_nb); 1585 err = register_netdevice_notifier(&dsa_slave_nb);
@@ -1549,8 +1590,15 @@ int dsa_slave_register_notifier(void)
1549 if (err) 1590 if (err)
1550 goto err_switchdev_nb; 1591 goto err_switchdev_nb;
1551 1592
1593 nb = &dsa_slave_switchdev_blocking_notifier;
1594 err = register_switchdev_blocking_notifier(nb);
1595 if (err)
1596 goto err_switchdev_blocking_nb;
1597
1552 return 0; 1598 return 0;
1553 1599
1600err_switchdev_blocking_nb:
1601 unregister_switchdev_notifier(&dsa_slave_switchdev_notifier);
1554err_switchdev_nb: 1602err_switchdev_nb:
1555 unregister_netdevice_notifier(&dsa_slave_nb); 1603 unregister_netdevice_notifier(&dsa_slave_nb);
1556 return err; 1604 return err;
@@ -1558,8 +1606,14 @@ err_switchdev_nb:
1558 1606
1559void dsa_slave_unregister_notifier(void) 1607void dsa_slave_unregister_notifier(void)
1560{ 1608{
1609 struct notifier_block *nb;
1561 int err; 1610 int err;
1562 1611
1612 nb = &dsa_slave_switchdev_blocking_notifier;
1613 err = unregister_switchdev_blocking_notifier(nb);
1614 if (err)
1615 pr_err("DSA: failed to unregister switchdev blocking notifier (%d)\n", err);
1616
1563 err = unregister_switchdev_notifier(&dsa_slave_switchdev_notifier); 1617 err = unregister_switchdev_notifier(&dsa_slave_switchdev_notifier);
1564 if (err) 1618 if (err)
1565 pr_err("DSA: failed to unregister switchdev notifier (%d)\n", err); 1619 pr_err("DSA: failed to unregister switchdev notifier (%d)\n", err);