diff options
Diffstat (limited to 'drivers/net/team/team.c')
-rw-r--r-- | drivers/net/team/team.c | 44 |
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 | ||
1018 | err_port_enter: | 1017 | err_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 | ||
1075 | static 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 | |||
1087 | static 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 | |||
1078 | static void __team_port_change_port_added(struct team_port *port, bool linkup); | 1094 | static void __team_port_change_port_added(struct team_port *port, bool linkup); |
1079 | static int team_dev_type_check_change(struct net_device *dev, | 1095 | static 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 | ||
1197 | err_option_port_add: | 1213 | err_option_port_add: |
1214 | team_upper_dev_unlink(dev, port_dev); | ||
1215 | |||
1216 | err_set_upper_link: | ||
1198 | netdev_rx_handler_unregister(port_dev); | 1217 | netdev_rx_handler_unregister(port_dev); |
1199 | 1218 | ||
1200 | err_handler_register: | 1219 | err_handler_register: |
1201 | netdev_upper_dev_unlink(port_dev, dev); | ||
1202 | |||
1203 | err_set_upper_link: | ||
1204 | team_port_disable_netpoll(port); | 1220 | team_port_disable_netpoll(port); |
1205 | 1221 | ||
1206 | err_enable_netpoll: | 1222 | err_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); |