switch.c (60dd57c7479418e2bc902143eb46a2fdcfeecbbb) | switch.c (d0004a020bb50263de0e3e775c7b7c7a003e0e0c) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Handling of a single switch chip, part of a switch fabric 4 * 5 * Copyright (c) 2017 Savoir-faire Linux Inc. 6 * Vivien Didelot <vivien.didelot@savoirfairelinux.com> 7 */ 8 9#include <linux/if_bridge.h> 10#include <linux/netdevice.h> 11#include <linux/notifier.h> 12#include <linux/if_vlan.h> 13#include <net/switchdev.h> 14 15#include "dsa_priv.h" 16 17static unsigned int dsa_switch_fastest_ageing_time(struct dsa_switch *ds, 18 unsigned int ageing_time) 19{ | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Handling of a single switch chip, part of a switch fabric 4 * 5 * Copyright (c) 2017 Savoir-faire Linux Inc. 6 * Vivien Didelot <vivien.didelot@savoirfairelinux.com> 7 */ 8 9#include <linux/if_bridge.h> 10#include <linux/netdevice.h> 11#include <linux/notifier.h> 12#include <linux/if_vlan.h> 13#include <net/switchdev.h> 14 15#include "dsa_priv.h" 16 17static unsigned int dsa_switch_fastest_ageing_time(struct dsa_switch *ds, 18 unsigned int ageing_time) 19{ |
20 int i; | 20 struct dsa_port *dp; |
21 | 21 |
22 for (i = 0; i < ds->num_ports; ++i) { 23 struct dsa_port *dp = dsa_to_port(ds, i); 24 | 22 dsa_switch_for_each_port(dp, ds) |
25 if (dp->ageing_time && dp->ageing_time < ageing_time) 26 ageing_time = dp->ageing_time; | 23 if (dp->ageing_time && dp->ageing_time < ageing_time) 24 ageing_time = dp->ageing_time; |
27 } | |
28 29 return ageing_time; 30} 31 32static int dsa_switch_ageing_time(struct dsa_switch *ds, 33 struct dsa_notifier_ageing_time_info *info) 34{ 35 unsigned int ageing_time = info->ageing_time; --- 79 unchanged lines hidden (view full) --- 115 116static int dsa_switch_bridge_leave(struct dsa_switch *ds, 117 struct dsa_notifier_bridge_info *info) 118{ 119 struct dsa_switch_tree *dst = ds->dst; 120 struct netlink_ext_ack extack = {0}; 121 bool change_vlan_filtering = false; 122 bool vlan_filtering; | 25 26 return ageing_time; 27} 28 29static int dsa_switch_ageing_time(struct dsa_switch *ds, 30 struct dsa_notifier_ageing_time_info *info) 31{ 32 unsigned int ageing_time = info->ageing_time; --- 79 unchanged lines hidden (view full) --- 112 113static int dsa_switch_bridge_leave(struct dsa_switch *ds, 114 struct dsa_notifier_bridge_info *info) 115{ 116 struct dsa_switch_tree *dst = ds->dst; 117 struct netlink_ext_ack extack = {0}; 118 bool change_vlan_filtering = false; 119 bool vlan_filtering; |
123 int err, port; | 120 struct dsa_port *dp; 121 int err; |
124 125 if (dst->index == info->tree_index && ds->index == info->sw_index && 126 ds->ops->port_bridge_leave) 127 ds->ops->port_bridge_leave(ds, info->port, info->br); 128 129 if ((dst->index != info->tree_index || ds->index != info->sw_index) && 130 ds->ops->crosschip_bridge_leave) 131 ds->ops->crosschip_bridge_leave(ds, info->tree_index, --- 13 unchanged lines hidden (view full) --- 145 * event for changing vlan_filtering setting upon slave ports leaving 146 * it. That is a good thing, because that lets us handle it and also 147 * handle the case where the switch's vlan_filtering setting is global 148 * (not per port). When that happens, the correct moment to trigger the 149 * vlan_filtering callback is only when the last port leaves the last 150 * VLAN-aware bridge. 151 */ 152 if (change_vlan_filtering && ds->vlan_filtering_is_global) { | 122 123 if (dst->index == info->tree_index && ds->index == info->sw_index && 124 ds->ops->port_bridge_leave) 125 ds->ops->port_bridge_leave(ds, info->port, info->br); 126 127 if ((dst->index != info->tree_index || ds->index != info->sw_index) && 128 ds->ops->crosschip_bridge_leave) 129 ds->ops->crosschip_bridge_leave(ds, info->tree_index, --- 13 unchanged lines hidden (view full) --- 143 * event for changing vlan_filtering setting upon slave ports leaving 144 * it. That is a good thing, because that lets us handle it and also 145 * handle the case where the switch's vlan_filtering setting is global 146 * (not per port). When that happens, the correct moment to trigger the 147 * vlan_filtering callback is only when the last port leaves the last 148 * VLAN-aware bridge. 149 */ 150 if (change_vlan_filtering && ds->vlan_filtering_is_global) { |
153 for (port = 0; port < ds->num_ports; port++) { | 151 dsa_switch_for_each_port(dp, ds) { |
154 struct net_device *bridge_dev; 155 | 152 struct net_device *bridge_dev; 153 |
156 bridge_dev = dsa_to_port(ds, port)->bridge_dev; | 154 bridge_dev = dp->bridge_dev; |
157 158 if (bridge_dev && br_vlan_enabled(bridge_dev)) { 159 change_vlan_filtering = false; 160 break; 161 } 162 } 163 } 164 --- 409 unchanged lines hidden (view full) --- 574 */ 575 return 0; 576} 577 578static int dsa_switch_change_tag_proto(struct dsa_switch *ds, 579 struct dsa_notifier_tag_proto_info *info) 580{ 581 const struct dsa_device_ops *tag_ops = info->tag_ops; | 155 156 if (bridge_dev && br_vlan_enabled(bridge_dev)) { 157 change_vlan_filtering = false; 158 break; 159 } 160 } 161 } 162 --- 409 unchanged lines hidden (view full) --- 572 */ 573 return 0; 574} 575 576static int dsa_switch_change_tag_proto(struct dsa_switch *ds, 577 struct dsa_notifier_tag_proto_info *info) 578{ 579 const struct dsa_device_ops *tag_ops = info->tag_ops; |
582 int port, err; | 580 struct dsa_port *dp, *cpu_dp; 581 int err; |
583 584 if (!ds->ops->change_tag_protocol) 585 return -EOPNOTSUPP; 586 587 ASSERT_RTNL(); 588 | 582 583 if (!ds->ops->change_tag_protocol) 584 return -EOPNOTSUPP; 585 586 ASSERT_RTNL(); 587 |
589 for (port = 0; port < ds->num_ports; port++) { 590 if (!dsa_is_cpu_port(ds, port)) 591 continue; 592 593 err = ds->ops->change_tag_protocol(ds, port, tag_ops->proto); | 588 dsa_switch_for_each_cpu_port(cpu_dp, ds) { 589 err = ds->ops->change_tag_protocol(ds, cpu_dp->index, 590 tag_ops->proto); |
594 if (err) 595 return err; 596 | 591 if (err) 592 return err; 593 |
597 dsa_port_set_tag_protocol(dsa_to_port(ds, port), tag_ops); | 594 dsa_port_set_tag_protocol(cpu_dp, tag_ops); |
598 } 599 600 /* Now that changing the tag protocol can no longer fail, let's update 601 * the remaining bits which are "duplicated for faster access", and the 602 * bits that depend on the tagger, such as the MTU. 603 */ | 595 } 596 597 /* Now that changing the tag protocol can no longer fail, let's update 598 * the remaining bits which are "duplicated for faster access", and the 599 * bits that depend on the tagger, such as the MTU. 600 */ |
604 for (port = 0; port < ds->num_ports; port++) { 605 if (dsa_is_user_port(ds, port)) { 606 struct net_device *slave; | 601 dsa_switch_for_each_user_port(dp, ds) { 602 struct net_device *slave = dp->slave; |
607 | 603 |
608 slave = dsa_to_port(ds, port)->slave; 609 dsa_slave_setup_tagger(slave); | 604 dsa_slave_setup_tagger(slave); |
610 | 605 |
611 /* rtnl_mutex is held in dsa_tree_change_tag_proto */ 612 dsa_slave_change_mtu(slave, slave->mtu); 613 } | 606 /* rtnl_mutex is held in dsa_tree_change_tag_proto */ 607 dsa_slave_change_mtu(slave, slave->mtu); |
614 } 615 616 return 0; 617} 618 619static int dsa_switch_mrp_add(struct dsa_switch *ds, 620 struct dsa_notifier_mrp_info *info) 621{ --- 161 unchanged lines hidden --- | 608 } 609 610 return 0; 611} 612 613static int dsa_switch_mrp_add(struct dsa_switch *ds, 614 struct dsa_notifier_mrp_info *info) 615{ --- 161 unchanged lines hidden --- |