Commit dea80774 authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-cross-chip-notifiers'

Vladimir Oltean says:

====================
Improvements to the DSA tag_8021q cross-chip notifiers

This series improves cross-chip notifier error messages and addresses a
benign error message seen during reboot on a system with disjoint DSA
trees.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0de6fd5f 724395f4
...@@ -49,6 +49,9 @@ int dsa_tree_notify(struct dsa_switch_tree *dst, unsigned long e, void *v) ...@@ -49,6 +49,9 @@ int dsa_tree_notify(struct dsa_switch_tree *dst, unsigned long e, void *v)
* Can be used to notify the switching fabric of events such as cross-chip * Can be used to notify the switching fabric of events such as cross-chip
* bridging between disjoint trees (such as islands of tagger-compatible * bridging between disjoint trees (such as islands of tagger-compatible
* switches bridged by an incompatible middle switch). * switches bridged by an incompatible middle switch).
*
* WARNING: this function is not reliable during probe time, because probing
* between trees is asynchronous and not all DSA trees might have probed.
*/ */
int dsa_broadcast(unsigned long e, void *v) int dsa_broadcast(unsigned long e, void *v)
{ {
......
...@@ -261,8 +261,8 @@ int dsa_port_link_register_of(struct dsa_port *dp); ...@@ -261,8 +261,8 @@ int dsa_port_link_register_of(struct dsa_port *dp);
void dsa_port_link_unregister_of(struct dsa_port *dp); void dsa_port_link_unregister_of(struct dsa_port *dp);
int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr); int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr);
void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr); void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr);
int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid); int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast);
void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid); void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast);
extern const struct phylink_mac_ops dsa_port_phylink_mac_ops; extern const struct phylink_mac_ops dsa_port_phylink_mac_ops;
static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp, static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp,
......
...@@ -426,7 +426,9 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) ...@@ -426,7 +426,9 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
err = dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info); err = dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info);
if (err) if (err)
pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n"); dev_err(dp->ds->dev,
"port %d failed to notify DSA_NOTIFIER_BRIDGE_LEAVE: %pe\n",
dp->index, ERR_PTR(err));
dsa_port_switchdev_unsync_attrs(dp); dsa_port_switchdev_unsync_attrs(dp);
} }
...@@ -525,8 +527,9 @@ void dsa_port_lag_leave(struct dsa_port *dp, struct net_device *lag) ...@@ -525,8 +527,9 @@ void dsa_port_lag_leave(struct dsa_port *dp, struct net_device *lag)
err = dsa_port_notify(dp, DSA_NOTIFIER_LAG_LEAVE, &info); err = dsa_port_notify(dp, DSA_NOTIFIER_LAG_LEAVE, &info);
if (err) if (err)
pr_err("DSA: failed to notify DSA_NOTIFIER_LAG_LEAVE: %d\n", dev_err(dp->ds->dev,
err); "port %d failed to notify DSA_NOTIFIER_LAG_LEAVE: %pe\n",
dp->index, ERR_PTR(err));
dsa_lag_unmap(dp->ds->dst, lag); dsa_lag_unmap(dp->ds->dst, lag);
} }
...@@ -1306,10 +1309,12 @@ void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr) ...@@ -1306,10 +1309,12 @@ void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr)
err = dsa_port_notify(dp, DSA_NOTIFIER_HSR_LEAVE, &info); err = dsa_port_notify(dp, DSA_NOTIFIER_HSR_LEAVE, &info);
if (err) if (err)
pr_err("DSA: failed to notify DSA_NOTIFIER_HSR_LEAVE\n"); dev_err(dp->ds->dev,
"port %d failed to notify DSA_NOTIFIER_HSR_LEAVE: %pe\n",
dp->index, ERR_PTR(err));
} }
int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid) int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast)
{ {
struct dsa_notifier_tag_8021q_vlan_info info = { struct dsa_notifier_tag_8021q_vlan_info info = {
.tree_index = dp->ds->dst->index, .tree_index = dp->ds->dst->index,
...@@ -1318,10 +1323,13 @@ int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid) ...@@ -1318,10 +1323,13 @@ int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid)
.vid = vid, .vid = vid,
}; };
if (broadcast)
return dsa_broadcast(DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info); return dsa_broadcast(DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info);
return dsa_port_notify(dp, DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info);
} }
void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid) void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast)
{ {
struct dsa_notifier_tag_8021q_vlan_info info = { struct dsa_notifier_tag_8021q_vlan_info info = {
.tree_index = dp->ds->dst->index, .tree_index = dp->ds->dst->index,
...@@ -1331,8 +1339,12 @@ void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid) ...@@ -1331,8 +1339,12 @@ void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid)
}; };
int err; int err;
if (broadcast)
err = dsa_broadcast(DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, &info); err = dsa_broadcast(DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, &info);
else
err = dsa_port_notify(dp, DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, &info);
if (err) if (err)
pr_err("DSA: failed to notify tag_8021q VLAN deletion: %pe\n", dev_err(dp->ds->dev,
ERR_PTR(err)); "port %d failed to notify tag_8021q VLAN %d deletion: %pe\n",
dp->index, vid, ERR_PTR(err));
} }
...@@ -362,12 +362,12 @@ int dsa_tag_8021q_bridge_join(struct dsa_switch *ds, ...@@ -362,12 +362,12 @@ int dsa_tag_8021q_bridge_join(struct dsa_switch *ds,
continue; continue;
/* Install the RX VID of the targeted port in our VLAN table */ /* Install the RX VID of the targeted port in our VLAN table */
err = dsa_port_tag_8021q_vlan_add(dp, targeted_rx_vid); err = dsa_port_tag_8021q_vlan_add(dp, targeted_rx_vid, false);
if (err) if (err)
return err; return err;
/* Install our RX VID into the targeted port's VLAN table */ /* Install our RX VID into the targeted port's VLAN table */
err = dsa_port_tag_8021q_vlan_add(targeted_dp, rx_vid); err = dsa_port_tag_8021q_vlan_add(targeted_dp, rx_vid, false);
if (err) if (err)
return err; return err;
} }
...@@ -398,10 +398,10 @@ int dsa_tag_8021q_bridge_leave(struct dsa_switch *ds, ...@@ -398,10 +398,10 @@ int dsa_tag_8021q_bridge_leave(struct dsa_switch *ds,
continue; continue;
/* Remove the RX VID of the targeted port from our VLAN table */ /* Remove the RX VID of the targeted port from our VLAN table */
dsa_port_tag_8021q_vlan_del(dp, targeted_rx_vid); dsa_port_tag_8021q_vlan_del(dp, targeted_rx_vid, true);
/* Remove our RX VID from the targeted port's VLAN table */ /* Remove our RX VID from the targeted port's VLAN table */
dsa_port_tag_8021q_vlan_del(targeted_dp, rx_vid); dsa_port_tag_8021q_vlan_del(targeted_dp, rx_vid, true);
} }
return 0; return 0;
...@@ -413,7 +413,8 @@ int dsa_tag_8021q_bridge_tx_fwd_offload(struct dsa_switch *ds, int port, ...@@ -413,7 +413,8 @@ int dsa_tag_8021q_bridge_tx_fwd_offload(struct dsa_switch *ds, int port,
{ {
u16 tx_vid = dsa_8021q_bridge_tx_fwd_offload_vid(bridge_num); u16 tx_vid = dsa_8021q_bridge_tx_fwd_offload_vid(bridge_num);
return dsa_port_tag_8021q_vlan_add(dsa_to_port(ds, port), tx_vid); return dsa_port_tag_8021q_vlan_add(dsa_to_port(ds, port), tx_vid,
true);
} }
EXPORT_SYMBOL_GPL(dsa_tag_8021q_bridge_tx_fwd_offload); EXPORT_SYMBOL_GPL(dsa_tag_8021q_bridge_tx_fwd_offload);
...@@ -423,7 +424,7 @@ void dsa_tag_8021q_bridge_tx_fwd_unoffload(struct dsa_switch *ds, int port, ...@@ -423,7 +424,7 @@ void dsa_tag_8021q_bridge_tx_fwd_unoffload(struct dsa_switch *ds, int port,
{ {
u16 tx_vid = dsa_8021q_bridge_tx_fwd_offload_vid(bridge_num); u16 tx_vid = dsa_8021q_bridge_tx_fwd_offload_vid(bridge_num);
dsa_port_tag_8021q_vlan_del(dsa_to_port(ds, port), tx_vid); dsa_port_tag_8021q_vlan_del(dsa_to_port(ds, port), tx_vid, true);
} }
EXPORT_SYMBOL_GPL(dsa_tag_8021q_bridge_tx_fwd_unoffload); EXPORT_SYMBOL_GPL(dsa_tag_8021q_bridge_tx_fwd_unoffload);
...@@ -450,7 +451,7 @@ static int dsa_tag_8021q_port_setup(struct dsa_switch *ds, int port) ...@@ -450,7 +451,7 @@ static int dsa_tag_8021q_port_setup(struct dsa_switch *ds, int port)
* L2 forwarding rules still take precedence when there are no VLAN * L2 forwarding rules still take precedence when there are no VLAN
* restrictions, so there are no concerns about leaking traffic. * restrictions, so there are no concerns about leaking traffic.
*/ */
err = dsa_port_tag_8021q_vlan_add(dp, rx_vid); err = dsa_port_tag_8021q_vlan_add(dp, rx_vid, true);
if (err) { if (err) {
dev_err(ds->dev, dev_err(ds->dev,
"Failed to apply RX VID %d to port %d: %pe\n", "Failed to apply RX VID %d to port %d: %pe\n",
...@@ -462,7 +463,7 @@ static int dsa_tag_8021q_port_setup(struct dsa_switch *ds, int port) ...@@ -462,7 +463,7 @@ static int dsa_tag_8021q_port_setup(struct dsa_switch *ds, int port)
vlan_vid_add(master, ctx->proto, rx_vid); vlan_vid_add(master, ctx->proto, rx_vid);
/* Finally apply the TX VID on this port and on the CPU port */ /* Finally apply the TX VID on this port and on the CPU port */
err = dsa_port_tag_8021q_vlan_add(dp, tx_vid); err = dsa_port_tag_8021q_vlan_add(dp, tx_vid, true);
if (err) { if (err) {
dev_err(ds->dev, dev_err(ds->dev,
"Failed to apply TX VID %d on port %d: %pe\n", "Failed to apply TX VID %d on port %d: %pe\n",
...@@ -489,11 +490,11 @@ static void dsa_tag_8021q_port_teardown(struct dsa_switch *ds, int port) ...@@ -489,11 +490,11 @@ static void dsa_tag_8021q_port_teardown(struct dsa_switch *ds, int port)
master = dp->cpu_dp->master; master = dp->cpu_dp->master;
dsa_port_tag_8021q_vlan_del(dp, rx_vid); dsa_port_tag_8021q_vlan_del(dp, rx_vid, false);
vlan_vid_del(master, ctx->proto, rx_vid); vlan_vid_del(master, ctx->proto, rx_vid);
dsa_port_tag_8021q_vlan_del(dp, tx_vid); dsa_port_tag_8021q_vlan_del(dp, tx_vid, false);
} }
static int dsa_tag_8021q_setup(struct dsa_switch *ds) static int dsa_tag_8021q_setup(struct dsa_switch *ds)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment