slave.c (bfcb813203e619a8960a819bf533ad2a108d8105) | slave.c (bff33f7e2ae2e805a4b0af597b58422185c68900) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * net/dsa/slave.c - Slave device handling 4 * Copyright (c) 2008-2009 Marvell Semiconductor 5 */ 6 7#include <linux/list.h> 8#include <linux/etherdevice.h> --- 1204 unchanged lines hidden (view full) --- 1213 } 1214 1215 /* Do not deprogram the CPU port as it may be shared with other user 1216 * ports which can be members of this VLAN as well. 1217 */ 1218 return dsa_port_vid_del(dp, vid); 1219} 1220 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * net/dsa/slave.c - Slave device handling 4 * Copyright (c) 2008-2009 Marvell Semiconductor 5 */ 6 7#include <linux/list.h> 8#include <linux/etherdevice.h> --- 1204 unchanged lines hidden (view full) --- 1213 } 1214 1215 /* Do not deprogram the CPU port as it may be shared with other user 1216 * ports which can be members of this VLAN as well. 1217 */ 1218 return dsa_port_vid_del(dp, vid); 1219} 1220 |
1221struct dsa_hw_port { 1222 struct list_head list; 1223 struct net_device *dev; 1224 int old_mtu; 1225}; 1226 1227static int dsa_hw_port_list_set_mtu(struct list_head *hw_port_list, int mtu) 1228{ 1229 const struct dsa_hw_port *p; 1230 int err; 1231 1232 list_for_each_entry(p, hw_port_list, list) { 1233 if (p->dev->mtu == mtu) 1234 continue; 1235 1236 err = dev_set_mtu(p->dev, mtu); 1237 if (err) 1238 goto rollback; 1239 } 1240 1241 return 0; 1242 1243rollback: 1244 list_for_each_entry_continue_reverse(p, hw_port_list, list) { 1245 if (p->dev->mtu == p->old_mtu) 1246 continue; 1247 1248 if (dev_set_mtu(p->dev, p->old_mtu)) 1249 netdev_err(p->dev, "Failed to restore MTU\n"); 1250 } 1251 1252 return err; 1253} 1254 1255static void dsa_hw_port_list_free(struct list_head *hw_port_list) 1256{ 1257 struct dsa_hw_port *p, *n; 1258 1259 list_for_each_entry_safe(p, n, hw_port_list, list) 1260 kfree(p); 1261} 1262 1263/* Make the hardware datapath to/from @dev limited to a common MTU */ 1264void dsa_bridge_mtu_normalization(struct dsa_port *dp) 1265{ 1266 struct list_head hw_port_list; 1267 struct dsa_switch_tree *dst; 1268 int min_mtu = ETH_MAX_MTU; 1269 struct dsa_port *other_dp; 1270 int err; 1271 1272 if (!dp->ds->mtu_enforcement_ingress) 1273 return; 1274 1275 if (!dp->bridge_dev) 1276 return; 1277 1278 INIT_LIST_HEAD(&hw_port_list); 1279 1280 /* Populate the list of ports that are part of the same bridge 1281 * as the newly added/modified port 1282 */ 1283 list_for_each_entry(dst, &dsa_tree_list, list) { 1284 list_for_each_entry(other_dp, &dst->ports, list) { 1285 struct dsa_hw_port *hw_port; 1286 struct net_device *slave; 1287 1288 if (other_dp->type != DSA_PORT_TYPE_USER) 1289 continue; 1290 1291 if (other_dp->bridge_dev != dp->bridge_dev) 1292 continue; 1293 1294 if (!other_dp->ds->mtu_enforcement_ingress) 1295 continue; 1296 1297 slave = other_dp->slave; 1298 1299 if (min_mtu > slave->mtu) 1300 min_mtu = slave->mtu; 1301 1302 hw_port = kzalloc(sizeof(*hw_port), GFP_KERNEL); 1303 if (!hw_port) 1304 goto out; 1305 1306 hw_port->dev = slave; 1307 hw_port->old_mtu = slave->mtu; 1308 1309 list_add(&hw_port->list, &hw_port_list); 1310 } 1311 } 1312 1313 /* Attempt to configure the entire hardware bridge to the newly added 1314 * interface's MTU first, regardless of whether the intention of the 1315 * user was to raise or lower it. 1316 */ 1317 err = dsa_hw_port_list_set_mtu(&hw_port_list, dp->slave->mtu); 1318 if (!err) 1319 goto out; 1320 1321 /* Clearly that didn't work out so well, so just set the minimum MTU on 1322 * all hardware bridge ports now. If this fails too, then all ports will 1323 * still have their old MTU rolled back anyway. 1324 */ 1325 dsa_hw_port_list_set_mtu(&hw_port_list, min_mtu); 1326 1327out: 1328 dsa_hw_port_list_free(&hw_port_list); 1329} 1330 |
|
1221static int dsa_slave_change_mtu(struct net_device *dev, int new_mtu) 1222{ 1223 struct net_device *master = dsa_slave_to_master(dev); 1224 struct dsa_port *dp = dsa_slave_to_port(dev); 1225 struct dsa_slave_priv *p = netdev_priv(dev); 1226 struct dsa_switch *ds = p->dp->ds; 1227 struct dsa_port *cpu_dp; 1228 int port = p->dp->index; --- 60 unchanged lines hidden (view full) --- 1289 } 1290 1291 err = dsa_port_mtu_change(dp, new_mtu, false); 1292 if (err) 1293 goto out_port_failed; 1294 1295 dev->mtu = new_mtu; 1296 | 1331static int dsa_slave_change_mtu(struct net_device *dev, int new_mtu) 1332{ 1333 struct net_device *master = dsa_slave_to_master(dev); 1334 struct dsa_port *dp = dsa_slave_to_port(dev); 1335 struct dsa_slave_priv *p = netdev_priv(dev); 1336 struct dsa_switch *ds = p->dp->ds; 1337 struct dsa_port *cpu_dp; 1338 int port = p->dp->index; --- 60 unchanged lines hidden (view full) --- 1399 } 1400 1401 err = dsa_port_mtu_change(dp, new_mtu, false); 1402 if (err) 1403 goto out_port_failed; 1404 1405 dev->mtu = new_mtu; 1406 |
1407 dsa_bridge_mtu_normalization(dp); 1408 |
|
1297 return 0; 1298 1299out_port_failed: 1300 if (new_master_mtu != old_master_mtu) 1301 dsa_port_mtu_change(cpu_dp, old_master_mtu - 1302 cpu_dp->tag_ops->overhead, 1303 true); 1304out_cpu_failed: --- 338 unchanged lines hidden (view full) --- 1643 struct netdev_notifier_changeupper_info *info) 1644{ 1645 struct dsa_port *dp = dsa_slave_to_port(dev); 1646 int err = NOTIFY_DONE; 1647 1648 if (netif_is_bridge_master(info->upper_dev)) { 1649 if (info->linking) { 1650 err = dsa_port_bridge_join(dp, info->upper_dev); | 1409 return 0; 1410 1411out_port_failed: 1412 if (new_master_mtu != old_master_mtu) 1413 dsa_port_mtu_change(cpu_dp, old_master_mtu - 1414 cpu_dp->tag_ops->overhead, 1415 true); 1416out_cpu_failed: --- 338 unchanged lines hidden (view full) --- 1755 struct netdev_notifier_changeupper_info *info) 1756{ 1757 struct dsa_port *dp = dsa_slave_to_port(dev); 1758 int err = NOTIFY_DONE; 1759 1760 if (netif_is_bridge_master(info->upper_dev)) { 1761 if (info->linking) { 1762 err = dsa_port_bridge_join(dp, info->upper_dev); |
1763 if (!err) 1764 dsa_bridge_mtu_normalization(dp); |
|
1651 err = notifier_from_errno(err); 1652 } else { 1653 dsa_port_bridge_leave(dp, info->upper_dev); 1654 err = NOTIFY_OK; 1655 } 1656 } 1657 1658 return err; --- 248 unchanged lines hidden --- | 1765 err = notifier_from_errno(err); 1766 } else { 1767 dsa_port_bridge_leave(dp, info->upper_dev); 1768 err = NOTIFY_OK; 1769 } 1770 } 1771 1772 return err; --- 248 unchanged lines hidden --- |