Commit d6fce514 authored by Steen Hegelund's avatar Steen Hegelund Committed by David S. Miller
Browse files

net: sparx5: add switching support



This adds SwitchDev support by hardware offloading the
software bridge.

Signed-off-by: default avatarSteen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: default avatarBjarni Jonasson <bjarni.jonasson@microchip.com>
Signed-off-by: default avatarLars Povlsen <lars.povlsen@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 78eab33b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -6,4 +6,5 @@
obj-$(CONFIG_SPARX5_SWITCH) += sparx5-switch.o

sparx5-switch-objs  := sparx5_main.o sparx5_packet.o \
 sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o
 sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o \
 sparx5_switchdev.o
+3 −0
Original line number Diff line number Diff line
@@ -371,6 +371,9 @@ static void sparx5_mact_handle_entry(struct sparx5 *sparx5,
	if (port >= SPX5_PORTS)
		return;

	if (!test_bit(port, sparx5->bridge_mask))
		return;

	mutex_lock(&sparx5->mact_lock);
	list_for_each_entry(mact_entry, &sparx5->mact_entries, list) {
		if (mact_entry->vid == vid &&
+4 −0
Original line number Diff line number Diff line
@@ -623,6 +623,7 @@ static int sparx5_start(struct sparx5 *sparx5)
		return err;

	sparx5_board_init(sparx5);
	err = sparx5_register_notifier_blocks(sparx5);

	/* Start register based INJ/XTR */
	err = -ENXIO;
@@ -812,6 +813,9 @@ static int mchp_sparx5_remove(struct platform_device *pdev)
		sparx5->xtr_irq = -ENXIO;
	}
	sparx5_cleanup_ports(sparx5);
	/* Unregister netdevs */
	sparx5_unregister_notifier_blocks(sparx5);

	return 0;
}

+11 −0
Original line number Diff line number Diff line
@@ -135,9 +135,16 @@ struct sparx5 {
	/* port structures are in net device */
	struct sparx5_port *ports[SPX5_PORTS];
	enum sparx5_core_clockfreq coreclock;
	/* Notifiers */
	struct notifier_block netdevice_nb;
	struct notifier_block switchdev_nb;
	struct notifier_block switchdev_blocking_nb;
	/* Switch state */
	u8 base_mac[ETH_ALEN];
	/* Associated bridge device (when bridged) */
	struct net_device *hw_bridge_dev;
	/* Bridged interfaces */
	DECLARE_BITMAP(bridge_mask, SPX5_PORTS);
	DECLARE_BITMAP(bridge_fwd_mask, SPX5_PORTS);
	DECLARE_BITMAP(bridge_lrn_mask, SPX5_PORTS);
	DECLARE_BITMAP(vlan_mask[VLAN_N_VID], SPX5_PORTS);
@@ -153,6 +160,10 @@ struct sparx5 {
	int xtr_irq;
};

/* sparx5_switchdev.c */
int sparx5_register_notifier_blocks(struct sparx5 *sparx5);
void sparx5_unregister_notifier_blocks(struct sparx5 *sparx5);

/* sparx5_packet.c */
irqreturn_t sparx5_xtr_handler(int irq, void *_priv);
int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev);
+10 −0
Original line number Diff line number Diff line
@@ -117,6 +117,15 @@ static int sparx5_port_stop(struct net_device *ndev)
	return 0;
}

static void sparx5_set_rx_mode(struct net_device *dev)
{
	struct sparx5_port *port = netdev_priv(dev);
	struct sparx5 *sparx5 = port->sparx5;

	if (!test_bit(port->portno, sparx5->bridge_mask))
		__dev_mc_sync(dev, sparx5_mc_sync, sparx5_mc_unsync);
}

static int sparx5_port_get_phys_port_name(struct net_device *dev,
					  char *buf, size_t len)
{
@@ -167,6 +176,7 @@ static const struct net_device_ops sparx5_port_netdev_ops = {
	.ndo_open               = sparx5_port_open,
	.ndo_stop               = sparx5_port_stop,
	.ndo_start_xmit         = sparx5_port_xmit_impl,
	.ndo_set_rx_mode        = sparx5_set_rx_mode,
	.ndo_get_phys_port_name = sparx5_port_get_phys_port_name,
	.ndo_set_mac_address    = sparx5_set_mac_address,
	.ndo_validate_addr      = eth_validate_addr,
Loading