aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/team/team.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/team/team.c')
-rw-r--r--drivers/net/team/team.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index ef10302ec936..2277c3679a51 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1003,7 +1003,6 @@ static int team_port_enter(struct team *team, struct team_port *port)
1003 int err = 0; 1003 int err = 0;
1004 1004
1005 dev_hold(team->dev); 1005 dev_hold(team->dev);
1006 port->dev->priv_flags |= IFF_TEAM_PORT;
1007 if (team->ops.port_enter) { 1006 if (team->ops.port_enter) {
1008 err = team->ops.port_enter(team, port); 1007 err = team->ops.port_enter(team, port);
1009 if (err) { 1008 if (err) {
@@ -1016,7 +1015,6 @@ static int team_port_enter(struct team *team, struct team_port *port)
1016 return 0; 1015 return 0;
1017 1016
1018err_port_enter: 1017err_port_enter:
1019 port->dev->priv_flags &= ~IFF_TEAM_PORT;
1020 dev_put(team->dev); 1018 dev_put(team->dev);
1021 1019
1022 return err; 1020 return err;
@@ -1026,7 +1024,6 @@ static void team_port_leave(struct team *team, struct team_port *port)
1026{ 1024{
1027 if (team->ops.port_leave) 1025 if (team->ops.port_leave)
1028 team->ops.port_leave(team, port); 1026 team->ops.port_leave(team, port);
1029 port->dev->priv_flags &= ~IFF_TEAM_PORT;
1030 dev_put(team->dev); 1027 dev_put(team->dev);
1031} 1028}
1032 1029
@@ -1075,6 +1072,25 @@ static void team_port_disable_netpoll(struct team_port *port)
1075} 1072}
1076#endif 1073#endif
1077 1074
1075static int team_upper_dev_link(struct net_device *dev,
1076 struct net_device *port_dev)
1077{
1078 int err;
1079
1080 err = netdev_master_upper_dev_link(port_dev, dev);
1081 if (err)
1082 return err;
1083 port_dev->priv_flags |= IFF_TEAM_PORT;
1084 return 0;
1085}
1086
1087static void team_upper_dev_unlink(struct net_device *dev,
1088 struct net_device *port_dev)
1089{
1090 netdev_upper_dev_unlink(port_dev, dev);
1091 port_dev->priv_flags &= ~IFF_TEAM_PORT;
1092}
1093
1078static void __team_port_change_port_added(struct team_port *port, bool linkup); 1094static void __team_port_change_port_added(struct team_port *port, bool linkup);
1079static int team_dev_type_check_change(struct net_device *dev, 1095static int team_dev_type_check_change(struct net_device *dev,
1080 struct net_device *port_dev); 1096 struct net_device *port_dev);
@@ -1161,13 +1177,6 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
1161 goto err_enable_netpoll; 1177 goto err_enable_netpoll;
1162 } 1178 }
1163 1179
1164 err = netdev_master_upper_dev_link(port_dev, dev);
1165 if (err) {
1166 netdev_err(dev, "Device %s failed to set upper link\n",
1167 portname);
1168 goto err_set_upper_link;
1169 }
1170
1171 err = netdev_rx_handler_register(port_dev, team_handle_frame, 1180 err = netdev_rx_handler_register(port_dev, team_handle_frame,
1172 port); 1181 port);
1173 if (err) { 1182 if (err) {
@@ -1176,6 +1185,13 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
1176 goto err_handler_register; 1185 goto err_handler_register;
1177 } 1186 }
1178 1187
1188 err = team_upper_dev_link(dev, port_dev);
1189 if (err) {
1190 netdev_err(dev, "Device %s failed to set upper link\n",
1191 portname);
1192 goto err_set_upper_link;
1193 }
1194
1179 err = __team_option_inst_add_port(team, port); 1195 err = __team_option_inst_add_port(team, port);
1180 if (err) { 1196 if (err) {
1181 netdev_err(dev, "Device %s failed to add per-port options\n", 1197 netdev_err(dev, "Device %s failed to add per-port options\n",
@@ -1195,12 +1211,12 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
1195 return 0; 1211 return 0;
1196 1212
1197err_option_port_add: 1213err_option_port_add:
1214 team_upper_dev_unlink(dev, port_dev);
1215
1216err_set_upper_link:
1198 netdev_rx_handler_unregister(port_dev); 1217 netdev_rx_handler_unregister(port_dev);
1199 1218
1200err_handler_register: 1219err_handler_register:
1201 netdev_upper_dev_unlink(port_dev, dev);
1202
1203err_set_upper_link:
1204 team_port_disable_netpoll(port); 1220 team_port_disable_netpoll(port);
1205 1221
1206err_enable_netpoll: 1222err_enable_netpoll:
@@ -1239,8 +1255,8 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
1239 1255
1240 team_port_disable(team, port); 1256 team_port_disable(team, port);
1241 list_del_rcu(&port->list); 1257 list_del_rcu(&port->list);
1258 team_upper_dev_unlink(dev, port_dev);
1242 netdev_rx_handler_unregister(port_dev); 1259 netdev_rx_handler_unregister(port_dev);
1243 netdev_upper_dev_unlink(port_dev, dev);
1244 team_port_disable_netpoll(port); 1260 team_port_disable_netpoll(port);
1245 vlan_vids_del_by_dev(port_dev, dev); 1261 vlan_vids_del_by_dev(port_dev, dev);
1246 dev_uc_unsync(port_dev, dev); 1262 dev_uc_unsync(port_dev, dev);