Commit 36b20fcd authored by Murali Karicheri's avatar Murali Karicheri Committed by David S. Miller
Browse files

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: default avatarMurali Karicheri <m-karicheri2@ti.com>
Signed-off-by: default avatarRavi Gunasekaran <r-gunasekaran@ti.com>
Reviewed-by: default avatarWojciech Drewek <wojciech.drewek@intel.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 53475287
Loading
Loading
Loading
Loading
+66 −1
Original line number Diff line number Diff line
@@ -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 = {