net: hsr: Add support for MC filtering at the slave device

When MC (multicast) list is updated by the networking layer due to a
user command and as well as when allmulti flag is set, it needs to be
passed to the enslaved Ethernet devices. This patch allows this
to happen by implementing ndo_change_rx_flags() and ndo_set_rx_mode()
API calls that in turns pass it to the slave devices using
existing API calls.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Ravi Gunasekaran <r-gunasekaran@ti.com>
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Murali Karicheri 2023-11-21 11:07:53 +05:30 committed by David S. Miller
parent 53475287da
commit 36b20fcdd9
1 changed files with 66 additions and 1 deletions

View File

@ -173,7 +173,24 @@ static int hsr_dev_open(struct net_device *dev)
static int hsr_dev_close(struct net_device *dev)
{
/* Nothing to do here. */
struct hsr_port *port;
struct hsr_priv *hsr;
hsr = netdev_priv(dev);
hsr_for_each_port(hsr, port) {
if (port->type == HSR_PT_MASTER)
continue;
switch (port->type) {
case HSR_PT_SLAVE_A:
case HSR_PT_SLAVE_B:
dev_uc_unsync(port->dev, dev);
dev_mc_unsync(port->dev, dev);
break;
default:
break;
}
}
return 0;
}
@ -404,12 +421,60 @@ void hsr_del_ports(struct hsr_priv *hsr)
hsr_del_port(port);
}
static void hsr_set_rx_mode(struct net_device *dev)
{
struct hsr_port *port;
struct hsr_priv *hsr;
hsr = netdev_priv(dev);
hsr_for_each_port(hsr, port) {
if (port->type == HSR_PT_MASTER)
continue;
switch (port->type) {
case HSR_PT_SLAVE_A:
case HSR_PT_SLAVE_B:
dev_mc_sync_multiple(port->dev, dev);
dev_uc_sync_multiple(port->dev, dev);
break;
default:
break;
}
}
}
static void hsr_change_rx_flags(struct net_device *dev, int change)
{
struct hsr_port *port;
struct hsr_priv *hsr;
hsr = netdev_priv(dev);
hsr_for_each_port(hsr, port) {
if (port->type == HSR_PT_MASTER)
continue;
switch (port->type) {
case HSR_PT_SLAVE_A:
case HSR_PT_SLAVE_B:
if (change & IFF_ALLMULTI)
dev_set_allmulti(port->dev,
dev->flags &
IFF_ALLMULTI ? 1 : -1);
break;
default:
break;
}
}
}
static const struct net_device_ops hsr_device_ops = {
.ndo_change_mtu = hsr_dev_change_mtu,
.ndo_open = hsr_dev_open,
.ndo_stop = hsr_dev_close,
.ndo_start_xmit = hsr_dev_xmit,
.ndo_change_rx_flags = hsr_change_rx_flags,
.ndo_fix_features = hsr_fix_features,
.ndo_set_rx_mode = hsr_set_rx_mode,
};
static struct device_type hsr_type = {