Skip to content

Commit d6fce51

Browse files
steen-hegelund-mchpdavem330
authored andcommitted
net: sparx5: add switching support
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>
1 parent 78eab33 commit d6fce51

File tree

7 files changed

+544
-1
lines changed

7 files changed

+544
-1
lines changed

drivers/net/ethernet/microchip/sparx5/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
obj-$(CONFIG_SPARX5_SWITCH) += sparx5-switch.o
77

88
sparx5-switch-objs := sparx5_main.o sparx5_packet.o \
9-
sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o
9+
sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o \
10+
sparx5_switchdev.o

drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,9 @@ static void sparx5_mact_handle_entry(struct sparx5 *sparx5,
371371
if (port >= SPX5_PORTS)
372372
return;
373373

374+
if (!test_bit(port, sparx5->bridge_mask))
375+
return;
376+
374377
mutex_lock(&sparx5->mact_lock);
375378
list_for_each_entry(mact_entry, &sparx5->mact_entries, list) {
376379
if (mact_entry->vid == vid &&

drivers/net/ethernet/microchip/sparx5/sparx5_main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,7 @@ static int sparx5_start(struct sparx5 *sparx5)
623623
return err;
624624

625625
sparx5_board_init(sparx5);
626+
err = sparx5_register_notifier_blocks(sparx5);
626627

627628
/* Start register based INJ/XTR */
628629
err = -ENXIO;
@@ -812,6 +813,9 @@ static int mchp_sparx5_remove(struct platform_device *pdev)
812813
sparx5->xtr_irq = -ENXIO;
813814
}
814815
sparx5_cleanup_ports(sparx5);
816+
/* Unregister netdevs */
817+
sparx5_unregister_notifier_blocks(sparx5);
818+
815819
return 0;
816820
}
817821

drivers/net/ethernet/microchip/sparx5/sparx5_main.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,16 @@ struct sparx5 {
135135
/* port structures are in net device */
136136
struct sparx5_port *ports[SPX5_PORTS];
137137
enum sparx5_core_clockfreq coreclock;
138+
/* Notifiers */
139+
struct notifier_block netdevice_nb;
140+
struct notifier_block switchdev_nb;
141+
struct notifier_block switchdev_blocking_nb;
138142
/* Switch state */
139143
u8 base_mac[ETH_ALEN];
144+
/* Associated bridge device (when bridged) */
145+
struct net_device *hw_bridge_dev;
140146
/* Bridged interfaces */
147+
DECLARE_BITMAP(bridge_mask, SPX5_PORTS);
141148
DECLARE_BITMAP(bridge_fwd_mask, SPX5_PORTS);
142149
DECLARE_BITMAP(bridge_lrn_mask, SPX5_PORTS);
143150
DECLARE_BITMAP(vlan_mask[VLAN_N_VID], SPX5_PORTS);
@@ -153,6 +160,10 @@ struct sparx5 {
153160
int xtr_irq;
154161
};
155162

163+
/* sparx5_switchdev.c */
164+
int sparx5_register_notifier_blocks(struct sparx5 *sparx5);
165+
void sparx5_unregister_notifier_blocks(struct sparx5 *sparx5);
166+
156167
/* sparx5_packet.c */
157168
irqreturn_t sparx5_xtr_handler(int irq, void *_priv);
158169
int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev);

drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ static int sparx5_port_stop(struct net_device *ndev)
117117
return 0;
118118
}
119119

120+
static void sparx5_set_rx_mode(struct net_device *dev)
121+
{
122+
struct sparx5_port *port = netdev_priv(dev);
123+
struct sparx5 *sparx5 = port->sparx5;
124+
125+
if (!test_bit(port->portno, sparx5->bridge_mask))
126+
__dev_mc_sync(dev, sparx5_mc_sync, sparx5_mc_unsync);
127+
}
128+
120129
static int sparx5_port_get_phys_port_name(struct net_device *dev,
121130
char *buf, size_t len)
122131
{
@@ -167,6 +176,7 @@ static const struct net_device_ops sparx5_port_netdev_ops = {
167176
.ndo_open = sparx5_port_open,
168177
.ndo_stop = sparx5_port_stop,
169178
.ndo_start_xmit = sparx5_port_xmit_impl,
179+
.ndo_set_rx_mode = sparx5_set_rx_mode,
170180
.ndo_get_phys_port_name = sparx5_port_get_phys_port_name,
171181
.ndo_set_mac_address = sparx5_set_mac_address,
172182
.ndo_validate_addr = eth_validate_addr,

drivers/net/ethernet/microchip/sparx5/sparx5_packet.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ static void sparx5_xtr_grp(struct sparx5 *sparx5, u8 grp, bool byte_swap)
139139
return;
140140
}
141141

142+
/* Everything we see on an interface that is in the HW bridge
143+
* has already been forwarded
144+
*/
145+
if (test_bit(port->portno, sparx5->bridge_mask))
146+
skb->offload_fwd_mark = 1;
147+
142148
/* Finish up skb */
143149
skb_put(skb, byte_cnt - ETH_FCS_LEN);
144150
eth_skb_pad(skb);

0 commit comments

Comments
 (0)