aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/team
diff options
context:
space:
mode:
authorJiri Pirko <jiri@resnulli.us>2012-09-20 21:51:59 -0400
committerDavid S. Miller <davem@davemloft.net>2012-09-21 15:01:21 -0400
commit10f3f51d56648f4eaf5c9f7aee27c418b833c3c0 (patch)
treee831e437d98b28efd63881397365ab7ce17e9cbf /drivers/net/team
parent5e953778a2aab04929a5e7b69f53dc26e39b079e (diff)
team: send port changed when added
On some hw, link is not up during adding iface to team. That causes event not being sent to userspace and that may cause confusion. Fix this bug by sending port changed event once it's added to team. Signed-off-by: Jiri Pirko <jiri@resnulli.us> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/team')
-rw-r--r--drivers/net/team/team.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 266af7b38ebc..9ce0c51a04d5 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -966,7 +966,8 @@ static struct netpoll_info *team_netpoll_info(struct team *team)
966} 966}
967#endif 967#endif
968 968
969static void __team_port_change_check(struct team_port *port, bool linkup); 969static void __team_port_change_port_added(struct team_port *port, bool linkup);
970
970static int team_dev_type_check_change(struct net_device *dev, 971static int team_dev_type_check_change(struct net_device *dev,
971 struct net_device *port_dev); 972 struct net_device *port_dev);
972 973
@@ -1079,7 +1080,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
1079 team_port_enable(team, port); 1080 team_port_enable(team, port);
1080 list_add_tail_rcu(&port->list, &team->port_list); 1081 list_add_tail_rcu(&port->list, &team->port_list);
1081 __team_compute_features(team); 1082 __team_compute_features(team);
1082 __team_port_change_check(port, !!netif_carrier_ok(port_dev)); 1083 __team_port_change_port_added(port, !!netif_carrier_ok(port_dev));
1083 __team_options_change_check(team); 1084 __team_options_change_check(team);
1084 1085
1085 netdev_info(dev, "Port device %s added\n", portname); 1086 netdev_info(dev, "Port device %s added\n", portname);
@@ -1114,6 +1115,8 @@ err_set_mtu:
1114 return err; 1115 return err;
1115} 1116}
1116 1117
1118static void __team_port_change_port_removed(struct team_port *port);
1119
1117static int team_port_del(struct team *team, struct net_device *port_dev) 1120static int team_port_del(struct team *team, struct net_device *port_dev)
1118{ 1121{
1119 struct net_device *dev = team->dev; 1122 struct net_device *dev = team->dev;
@@ -1130,8 +1133,7 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
1130 __team_option_inst_mark_removed_port(team, port); 1133 __team_option_inst_mark_removed_port(team, port);
1131 __team_options_change_check(team); 1134 __team_options_change_check(team);
1132 __team_option_inst_del_port(team, port); 1135 __team_option_inst_del_port(team, port);
1133 port->removed = true; 1136 __team_port_change_port_removed(port);
1134 __team_port_change_check(port, false);
1135 team_port_disable(team, port); 1137 team_port_disable(team, port);
1136 list_del_rcu(&port->list); 1138 list_del_rcu(&port->list);
1137 netdev_rx_handler_unregister(port_dev); 1139 netdev_rx_handler_unregister(port_dev);
@@ -2499,13 +2501,11 @@ static void __team_options_change_check(struct team *team)
2499} 2501}
2500 2502
2501/* rtnl lock is held */ 2503/* rtnl lock is held */
2502static void __team_port_change_check(struct team_port *port, bool linkup) 2504
2505static void __team_port_change_send(struct team_port *port, bool linkup)
2503{ 2506{
2504 int err; 2507 int err;
2505 2508
2506 if (!port->removed && port->state.linkup == linkup)
2507 return;
2508
2509 port->changed = true; 2509 port->changed = true;
2510 port->state.linkup = linkup; 2510 port->state.linkup = linkup;
2511 team_refresh_port_linkup(port); 2511 team_refresh_port_linkup(port);
@@ -2530,6 +2530,23 @@ send_event:
2530 2530
2531} 2531}
2532 2532
2533static void __team_port_change_check(struct team_port *port, bool linkup)
2534{
2535 if (port->state.linkup != linkup)
2536 __team_port_change_send(port, linkup);
2537}
2538
2539static void __team_port_change_port_added(struct team_port *port, bool linkup)
2540{
2541 __team_port_change_send(port, linkup);
2542}
2543
2544static void __team_port_change_port_removed(struct team_port *port)
2545{
2546 port->removed = true;
2547 __team_port_change_send(port, false);
2548}
2549
2533static void team_port_change_check(struct team_port *port, bool linkup) 2550static void team_port_change_check(struct team_port *port, bool linkup)
2534{ 2551{
2535 struct team *team = port->team; 2552 struct team *team = port->team;