mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-24 11:25:43 +00:00
net: lan966x: Add support for multiple bridge flags
This patch series extends the current supported bridge flags with the following flags: BR_FLOOD, BR_BCAST_FLOOD and BR_LEARNING. Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
963178a063
commit
2e49761e4f
4 changed files with 82 additions and 2 deletions
|
@ -715,8 +715,10 @@ static void lan966x_init(struct lan966x *lan966x)
|
|||
/* There are 8 priorities */
|
||||
for (i = 0; i < 8; ++i)
|
||||
lan_rmw(ANA_FLOODING_FLD_MULTICAST_SET(PGID_MC) |
|
||||
ANA_FLOODING_FLD_UNICAST_SET(PGID_UC) |
|
||||
ANA_FLOODING_FLD_BROADCAST_SET(PGID_BC),
|
||||
ANA_FLOODING_FLD_MULTICAST |
|
||||
ANA_FLOODING_FLD_UNICAST |
|
||||
ANA_FLOODING_FLD_BROADCAST,
|
||||
lan966x, ANA_FLOODING(i));
|
||||
|
||||
|
@ -768,6 +770,11 @@ static void lan966x_init(struct lan966x *lan966x)
|
|||
ANA_PGID_PGID,
|
||||
lan966x, ANA_PGID(PGID_MCIPV4));
|
||||
|
||||
/* Unicast to all other ports */
|
||||
lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0),
|
||||
ANA_PGID_PGID,
|
||||
lan966x, ANA_PGID(PGID_UC));
|
||||
|
||||
/* Broadcast to the CPU port and to other ports */
|
||||
lan_rmw(ANA_PGID_PGID_SET(BIT(CPU_PORT) | GENMASK(lan966x->num_phys_ports - 1, 0)),
|
||||
ANA_PGID_PGID,
|
||||
|
|
|
@ -126,6 +126,8 @@ struct lan966x_port {
|
|||
u16 vid;
|
||||
bool vlan_aware;
|
||||
|
||||
bool learn_ena;
|
||||
|
||||
struct phylink_config phylink_config;
|
||||
struct phylink_pcs phylink_pcs;
|
||||
struct lan966x_port_config config;
|
||||
|
|
|
@ -91,6 +91,12 @@ enum lan966x_target {
|
|||
/* ANA:ANA:FLOODING */
|
||||
#define ANA_FLOODING(r) __REG(TARGET_ANA, 0, 1, 29824, 0, 1, 244, 68, r, 8, 4)
|
||||
|
||||
#define ANA_FLOODING_FLD_UNICAST GENMASK(17, 12)
|
||||
#define ANA_FLOODING_FLD_UNICAST_SET(x)\
|
||||
FIELD_PREP(ANA_FLOODING_FLD_UNICAST, x)
|
||||
#define ANA_FLOODING_FLD_UNICAST_GET(x)\
|
||||
FIELD_GET(ANA_FLOODING_FLD_UNICAST, x)
|
||||
|
||||
#define ANA_FLOODING_FLD_BROADCAST GENMASK(11, 6)
|
||||
#define ANA_FLOODING_FLD_BROADCAST_SET(x)\
|
||||
FIELD_PREP(ANA_FLOODING_FLD_BROADCAST, x)
|
||||
|
|
|
@ -25,18 +25,72 @@ static void lan966x_port_set_mcast_flood(struct lan966x_port *port,
|
|||
port->lan966x, ANA_PGID(PGID_MC));
|
||||
}
|
||||
|
||||
static void lan966x_port_set_ucast_flood(struct lan966x_port *port,
|
||||
bool enabled)
|
||||
{
|
||||
u32 val = lan_rd(port->lan966x, ANA_PGID(PGID_UC));
|
||||
|
||||
val = ANA_PGID_PGID_GET(val);
|
||||
if (enabled)
|
||||
val |= BIT(port->chip_port);
|
||||
else
|
||||
val &= ~BIT(port->chip_port);
|
||||
|
||||
lan_rmw(ANA_PGID_PGID_SET(val),
|
||||
ANA_PGID_PGID,
|
||||
port->lan966x, ANA_PGID(PGID_UC));
|
||||
}
|
||||
|
||||
static void lan966x_port_set_bcast_flood(struct lan966x_port *port,
|
||||
bool enabled)
|
||||
{
|
||||
u32 val = lan_rd(port->lan966x, ANA_PGID(PGID_BC));
|
||||
|
||||
val = ANA_PGID_PGID_GET(val);
|
||||
if (enabled)
|
||||
val |= BIT(port->chip_port);
|
||||
else
|
||||
val &= ~BIT(port->chip_port);
|
||||
|
||||
lan_rmw(ANA_PGID_PGID_SET(val),
|
||||
ANA_PGID_PGID,
|
||||
port->lan966x, ANA_PGID(PGID_BC));
|
||||
}
|
||||
|
||||
static void lan966x_port_set_learning(struct lan966x_port *port, bool enabled)
|
||||
{
|
||||
lan_rmw(ANA_PORT_CFG_LEARN_ENA_SET(enabled),
|
||||
ANA_PORT_CFG_LEARN_ENA,
|
||||
port->lan966x, ANA_PORT_CFG(port->chip_port));
|
||||
|
||||
port->learn_ena = enabled;
|
||||
}
|
||||
|
||||
static void lan966x_port_bridge_flags(struct lan966x_port *port,
|
||||
struct switchdev_brport_flags flags)
|
||||
{
|
||||
if (flags.mask & BR_MCAST_FLOOD)
|
||||
lan966x_port_set_mcast_flood(port,
|
||||
!!(flags.val & BR_MCAST_FLOOD));
|
||||
|
||||
if (flags.mask & BR_FLOOD)
|
||||
lan966x_port_set_ucast_flood(port,
|
||||
!!(flags.val & BR_FLOOD));
|
||||
|
||||
if (flags.mask & BR_BCAST_FLOOD)
|
||||
lan966x_port_set_bcast_flood(port,
|
||||
!!(flags.val & BR_BCAST_FLOOD));
|
||||
|
||||
if (flags.mask & BR_LEARNING)
|
||||
lan966x_port_set_learning(port,
|
||||
!!(flags.val & BR_LEARNING));
|
||||
}
|
||||
|
||||
static int lan966x_port_pre_bridge_flags(struct lan966x_port *port,
|
||||
struct switchdev_brport_flags flags)
|
||||
{
|
||||
if (flags.mask & ~BR_MCAST_FLOOD)
|
||||
if (flags.mask & ~(BR_MCAST_FLOOD | BR_FLOOD | BR_BCAST_FLOOD |
|
||||
BR_LEARNING))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
@ -65,7 +119,8 @@ static void lan966x_port_stp_state_set(struct lan966x_port *port, u8 state)
|
|||
struct lan966x *lan966x = port->lan966x;
|
||||
bool learn_ena = false;
|
||||
|
||||
if (state == BR_STATE_FORWARDING || state == BR_STATE_LEARNING)
|
||||
if ((state == BR_STATE_FORWARDING || state == BR_STATE_LEARNING) &&
|
||||
port->learn_ena)
|
||||
learn_ena = true;
|
||||
|
||||
if (state == BR_STATE_FORWARDING)
|
||||
|
@ -128,6 +183,7 @@ static int lan966x_port_bridge_join(struct lan966x_port *port,
|
|||
struct net_device *bridge,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct switchdev_brport_flags flags = {0};
|
||||
struct lan966x *lan966x = port->lan966x;
|
||||
struct net_device *dev = port->dev;
|
||||
int err;
|
||||
|
@ -150,14 +206,23 @@ static int lan966x_port_bridge_join(struct lan966x_port *port,
|
|||
|
||||
lan966x->bridge_mask |= BIT(port->chip_port);
|
||||
|
||||
flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
|
||||
flags.val = flags.mask;
|
||||
lan966x_port_bridge_flags(port, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lan966x_port_bridge_leave(struct lan966x_port *port,
|
||||
struct net_device *bridge)
|
||||
{
|
||||
struct switchdev_brport_flags flags = {0};
|
||||
struct lan966x *lan966x = port->lan966x;
|
||||
|
||||
flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
|
||||
flags.val = flags.mask & ~BR_LEARNING;
|
||||
lan966x_port_bridge_flags(port, flags);
|
||||
|
||||
lan966x->bridge_mask &= ~BIT(port->chip_port);
|
||||
|
||||
if (!lan966x->bridge_mask)
|
||||
|
|
Loading…
Reference in a new issue