Skip to content

Commit

Permalink
net: dsa: hellcreek: Offload bridge port flags
Browse files Browse the repository at this point in the history
The switch implements unicast and multicast filtering per port.
Add support for it. By default filtering is disabled.

Signed-off-by: Kurt Kanzenbach <kurt@kmk-computers.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Kurt Kanzenbach authored and David S. Miller committed Mar 15, 2021
1 parent 2117fce commit db7284a
Showing 1 changed file with 104 additions and 25 deletions.
129 changes: 104 additions & 25 deletions drivers/net/dsa/hirschmann/hellcreek.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,83 @@ static void hellcreek_setup_vlan_membership(struct dsa_switch *ds, int port,
hellcreek_unapply_vlan(hellcreek, upstream, vid);
}

static void hellcreek_port_set_ucast_flood(struct hellcreek *hellcreek,
int port, bool enable)
{
struct hellcreek_port *hellcreek_port;
u16 val;

hellcreek_port = &hellcreek->ports[port];

dev_dbg(hellcreek->dev, "%s unicast flooding on port %d\n",
enable ? "Enable" : "Disable", port);

mutex_lock(&hellcreek->reg_lock);

hellcreek_select_port(hellcreek, port);
val = hellcreek_port->ptcfg;
if (enable)
val &= ~HR_PTCFG_UUC_FLT;
else
val |= HR_PTCFG_UUC_FLT;
hellcreek_write(hellcreek, val, HR_PTCFG);
hellcreek_port->ptcfg = val;

mutex_unlock(&hellcreek->reg_lock);
}

static void hellcreek_port_set_mcast_flood(struct hellcreek *hellcreek,
int port, bool enable)
{
struct hellcreek_port *hellcreek_port;
u16 val;

hellcreek_port = &hellcreek->ports[port];

dev_dbg(hellcreek->dev, "%s multicast flooding on port %d\n",
enable ? "Enable" : "Disable", port);

mutex_lock(&hellcreek->reg_lock);

hellcreek_select_port(hellcreek, port);
val = hellcreek_port->ptcfg;
if (enable)
val &= ~HR_PTCFG_UMC_FLT;
else
val |= HR_PTCFG_UMC_FLT;
hellcreek_write(hellcreek, val, HR_PTCFG);
hellcreek_port->ptcfg = val;

mutex_unlock(&hellcreek->reg_lock);
}

static int hellcreek_pre_bridge_flags(struct dsa_switch *ds, int port,
struct switchdev_brport_flags flags,
struct netlink_ext_ack *extack)
{
if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD))
return -EINVAL;

return 0;
}

static int hellcreek_bridge_flags(struct dsa_switch *ds, int port,
struct switchdev_brport_flags flags,
struct netlink_ext_ack *extack)
{
struct hellcreek *hellcreek = ds->priv;

if (flags.mask & BR_FLOOD)
hellcreek_port_set_ucast_flood(hellcreek, port,
!!(flags.val & BR_FLOOD));

if (flags.mask & BR_MCAST_FLOOD)
hellcreek_port_set_mcast_flood(hellcreek, port,
!!(flags.val & BR_MCAST_FLOOD));

return 0;
}

static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port,
struct net_device *br)
{
Expand Down Expand Up @@ -1655,31 +1732,33 @@ static int hellcreek_port_setup_tc(struct dsa_switch *ds, int port,
}

static const struct dsa_switch_ops hellcreek_ds_ops = {
.get_ethtool_stats = hellcreek_get_ethtool_stats,
.get_sset_count = hellcreek_get_sset_count,
.get_strings = hellcreek_get_strings,
.get_tag_protocol = hellcreek_get_tag_protocol,
.get_ts_info = hellcreek_get_ts_info,
.phylink_validate = hellcreek_phylink_validate,
.port_bridge_join = hellcreek_port_bridge_join,
.port_bridge_leave = hellcreek_port_bridge_leave,
.port_disable = hellcreek_port_disable,
.port_enable = hellcreek_port_enable,
.port_fdb_add = hellcreek_fdb_add,
.port_fdb_del = hellcreek_fdb_del,
.port_fdb_dump = hellcreek_fdb_dump,
.port_hwtstamp_set = hellcreek_port_hwtstamp_set,
.port_hwtstamp_get = hellcreek_port_hwtstamp_get,
.port_prechangeupper = hellcreek_port_prechangeupper,
.port_rxtstamp = hellcreek_port_rxtstamp,
.port_setup_tc = hellcreek_port_setup_tc,
.port_stp_state_set = hellcreek_port_stp_state_set,
.port_txtstamp = hellcreek_port_txtstamp,
.port_vlan_add = hellcreek_vlan_add,
.port_vlan_del = hellcreek_vlan_del,
.port_vlan_filtering = hellcreek_vlan_filtering,
.setup = hellcreek_setup,
.teardown = hellcreek_teardown,
.get_ethtool_stats = hellcreek_get_ethtool_stats,
.get_sset_count = hellcreek_get_sset_count,
.get_strings = hellcreek_get_strings,
.get_tag_protocol = hellcreek_get_tag_protocol,
.get_ts_info = hellcreek_get_ts_info,
.phylink_validate = hellcreek_phylink_validate,
.port_bridge_flags = hellcreek_bridge_flags,
.port_bridge_join = hellcreek_port_bridge_join,
.port_bridge_leave = hellcreek_port_bridge_leave,
.port_disable = hellcreek_port_disable,
.port_enable = hellcreek_port_enable,
.port_fdb_add = hellcreek_fdb_add,
.port_fdb_del = hellcreek_fdb_del,
.port_fdb_dump = hellcreek_fdb_dump,
.port_hwtstamp_set = hellcreek_port_hwtstamp_set,
.port_hwtstamp_get = hellcreek_port_hwtstamp_get,
.port_pre_bridge_flags = hellcreek_pre_bridge_flags,
.port_prechangeupper = hellcreek_port_prechangeupper,
.port_rxtstamp = hellcreek_port_rxtstamp,
.port_setup_tc = hellcreek_port_setup_tc,
.port_stp_state_set = hellcreek_port_stp_state_set,
.port_txtstamp = hellcreek_port_txtstamp,
.port_vlan_add = hellcreek_vlan_add,
.port_vlan_del = hellcreek_vlan_del,
.port_vlan_filtering = hellcreek_vlan_filtering,
.setup = hellcreek_setup,
.teardown = hellcreek_teardown,
};

static int hellcreek_probe(struct platform_device *pdev)
Expand Down

0 comments on commit db7284a

Please sign in to comment.