Skip to content

Commit 0d37f83

Browse files
clementlegerdavem330
authored andcommitted
net: dsa: rzn1-a5psw: add support for .port_bridge_flags
When running vlan test (bridge_vlan_aware/unaware.sh), there were some failure due to the lack .port_bridge_flag function to disable port flooding. Implement this operation for BR_LEARNING, BR_FLOOD, BR_MCAST_FLOOD and BR_BCAST_FLOOD. Since .port_bridge_flags affects the bits disabling learning for a port, ensure that any other modification on the same register done by a5psw_port_stp_state_set is in sync by using the port learning state to enable/disable learning on the port. Signed-off-by: Clément Léger <clement.leger@bootlin.com> Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 6cf30fd commit 0d37f83

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

drivers/net/dsa/rzn1_a5psw.c

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,63 @@ static void a5psw_port_bridge_leave(struct dsa_switch *ds, int port,
380380
a5psw->br_dev = NULL;
381381
}
382382

383+
static int a5psw_port_pre_bridge_flags(struct dsa_switch *ds, int port,
384+
struct switchdev_brport_flags flags,
385+
struct netlink_ext_ack *extack)
386+
{
387+
if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
388+
BR_BCAST_FLOOD))
389+
return -EINVAL;
390+
391+
return 0;
392+
}
393+
394+
static int
395+
a5psw_port_bridge_flags(struct dsa_switch *ds, int port,
396+
struct switchdev_brport_flags flags,
397+
struct netlink_ext_ack *extack)
398+
{
399+
struct a5psw *a5psw = ds->priv;
400+
u32 val;
401+
402+
/* If a port is set as standalone, we do not want to be able to
403+
* configure flooding nor learning which would result in joining the
404+
* unique bridge. This can happen when a port leaves the bridge, in
405+
* which case the DSA core will try to "clear" all flags for the
406+
* standalone port (ie enable flooding, disable learning). In that case
407+
* do not fail but do not apply the flags.
408+
*/
409+
if (!(a5psw->bridged_ports & BIT(port)))
410+
return 0;
411+
412+
if (flags.mask & BR_LEARNING) {
413+
val = flags.val & BR_LEARNING ? 0 : A5PSW_INPUT_LEARN_DIS(port);
414+
a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN,
415+
A5PSW_INPUT_LEARN_DIS(port), val);
416+
}
417+
418+
if (flags.mask & BR_FLOOD) {
419+
val = flags.val & BR_FLOOD ? BIT(port) : 0;
420+
a5psw_reg_rmw(a5psw, A5PSW_UCAST_DEF_MASK, BIT(port), val);
421+
}
422+
423+
if (flags.mask & BR_MCAST_FLOOD) {
424+
val = flags.val & BR_MCAST_FLOOD ? BIT(port) : 0;
425+
a5psw_reg_rmw(a5psw, A5PSW_MCAST_DEF_MASK, BIT(port), val);
426+
}
427+
428+
if (flags.mask & BR_BCAST_FLOOD) {
429+
val = flags.val & BR_BCAST_FLOOD ? BIT(port) : 0;
430+
a5psw_reg_rmw(a5psw, A5PSW_BCAST_DEF_MASK, BIT(port), val);
431+
}
432+
433+
return 0;
434+
}
435+
383436
static void a5psw_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
384437
{
385438
bool learning_enabled, rx_enabled, tx_enabled;
439+
struct dsa_port *dp = dsa_to_port(ds, port);
386440
struct a5psw *a5psw = ds->priv;
387441

388442
switch (state) {
@@ -396,12 +450,12 @@ static void a5psw_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
396450
case BR_STATE_LEARNING:
397451
rx_enabled = false;
398452
tx_enabled = false;
399-
learning_enabled = true;
453+
learning_enabled = dp->learning;
400454
break;
401455
case BR_STATE_FORWARDING:
402456
rx_enabled = true;
403457
tx_enabled = true;
404-
learning_enabled = true;
458+
learning_enabled = dp->learning;
405459
break;
406460
default:
407461
dev_err(ds->dev, "invalid STP state: %d\n", state);
@@ -801,6 +855,8 @@ static const struct dsa_switch_ops a5psw_switch_ops = {
801855
.set_ageing_time = a5psw_set_ageing_time,
802856
.port_bridge_join = a5psw_port_bridge_join,
803857
.port_bridge_leave = a5psw_port_bridge_leave,
858+
.port_pre_bridge_flags = a5psw_port_pre_bridge_flags,
859+
.port_bridge_flags = a5psw_port_bridge_flags,
804860
.port_stp_state_set = a5psw_port_stp_state_set,
805861
.port_fast_age = a5psw_port_fast_age,
806862
.port_fdb_add = a5psw_port_fdb_add,

0 commit comments

Comments
 (0)