Skip to content

Commit

Permalink
net: sparx5: add switching support
Browse files Browse the repository at this point in the history
This adds SwitchDev support by hardware offloading the
software bridge.

Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Steen Hegelund authored and David S. Miller committed Jun 24, 2021
1 parent 78eab33 commit d6fce51
Show file tree
Hide file tree
Showing 7 changed files with 544 additions and 1 deletion.
3 changes: 2 additions & 1 deletion drivers/net/ethernet/microchip/sparx5/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 3 additions & 0 deletions drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/microchip/sparx5/sparx5_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
11 changes: 11 additions & 0 deletions drivers/net/ethernet/microchip/sparx5/sparx5_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ static void sparx5_xtr_grp(struct sparx5 *sparx5, u8 grp, bool byte_swap)
return;
}

/* Everything we see on an interface that is in the HW bridge
* has already been forwarded
*/
if (test_bit(port->portno, sparx5->bridge_mask))
skb->offload_fwd_mark = 1;

/* Finish up skb */
skb_put(skb, byte_cnt - ETH_FCS_LEN);
eth_skb_pad(skb);
Expand Down
Loading

0 comments on commit d6fce51

Please sign in to comment.