switch.c (36cbf39b56908bb2e7e8e392e5f08895c3ca4326) switch.c (d3eed0e57d5d1bcbf1bd60f83a4adfe7d7b8dd9c)
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

--- 81 unchanged lines hidden (view full) ---

90{
91 struct dsa_switch_tree *dst = ds->dst;
92 int err;
93
94 if (dst->index == info->tree_index && ds->index == info->sw_index) {
95 if (!ds->ops->port_bridge_join)
96 return -EOPNOTSUPP;
97
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

--- 81 unchanged lines hidden (view full) ---

90{
91 struct dsa_switch_tree *dst = ds->dst;
92 int err;
93
94 if (dst->index == info->tree_index && ds->index == info->sw_index) {
95 if (!ds->ops->port_bridge_join)
96 return -EOPNOTSUPP;
97
98 err = ds->ops->port_bridge_join(ds, info->port, info->br);
98 err = ds->ops->port_bridge_join(ds, info->port, info->bridge);
99 if (err)
100 return err;
101 }
102
103 if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
104 ds->ops->crosschip_bridge_join) {
105 err = ds->ops->crosschip_bridge_join(ds, info->tree_index,
106 info->sw_index,
99 if (err)
100 return err;
101 }
102
103 if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
104 ds->ops->crosschip_bridge_join) {
105 err = ds->ops->crosschip_bridge_join(ds, info->tree_index,
106 info->sw_index,
107 info->port, info->br);
107 info->port, info->bridge);
108 if (err)
109 return err;
110 }
111
112 return dsa_tag_8021q_bridge_join(ds, info);
113}
114
115static int dsa_switch_bridge_leave(struct dsa_switch *ds,
116 struct dsa_notifier_bridge_info *info)
117{
118 struct dsa_switch_tree *dst = ds->dst;
119 struct netlink_ext_ack extack = {0};
120 bool change_vlan_filtering = false;
121 bool vlan_filtering;
122 struct dsa_port *dp;
123 int err;
124
125 if (dst->index == info->tree_index && ds->index == info->sw_index &&
126 ds->ops->port_bridge_leave)
108 if (err)
109 return err;
110 }
111
112 return dsa_tag_8021q_bridge_join(ds, info);
113}
114
115static int dsa_switch_bridge_leave(struct dsa_switch *ds,
116 struct dsa_notifier_bridge_info *info)
117{
118 struct dsa_switch_tree *dst = ds->dst;
119 struct netlink_ext_ack extack = {0};
120 bool change_vlan_filtering = false;
121 bool vlan_filtering;
122 struct dsa_port *dp;
123 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);
127 ds->ops->port_bridge_leave(ds, info->port, info->bridge);
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,
132 info->sw_index, info->port,
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,
132 info->sw_index, info->port,
133 info->br);
133 info->bridge);
134
134
135 if (ds->needs_standalone_vlan_filtering && !br_vlan_enabled(info->br)) {
135 if (ds->needs_standalone_vlan_filtering &&
136 !br_vlan_enabled(info->bridge.dev)) {
136 change_vlan_filtering = true;
137 vlan_filtering = true;
138 } else if (!ds->needs_standalone_vlan_filtering &&
137 change_vlan_filtering = true;
138 vlan_filtering = true;
139 } else if (!ds->needs_standalone_vlan_filtering &&
139 br_vlan_enabled(info->br)) {
140 br_vlan_enabled(info->bridge.dev)) {
140 change_vlan_filtering = true;
141 vlan_filtering = false;
142 }
143
144 /* If the bridge was vlan_filtering, the bridge core doesn't trigger an
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

--- 664 unchanged lines hidden ---
141 change_vlan_filtering = true;
142 vlan_filtering = false;
143 }
144
145 /* If the bridge was vlan_filtering, the bridge core doesn't trigger an
146 * event for changing vlan_filtering setting upon slave ports leaving
147 * it. That is a good thing, because that lets us handle it and also
148 * handle the case where the switch's vlan_filtering setting is global

--- 664 unchanged lines hidden ---