diff options
Diffstat (limited to 'drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c')
| -rw-r--r-- | drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c | 24 | 
1 files changed, 21 insertions, 3 deletions
| diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c index a72e3b3b596e..649ca609884a 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c @@ -93,9 +93,12 @@ static int sparx5_port_attr_set(struct net_device *dev, const void *ctx,  }  static int sparx5_port_bridge_join(struct sparx5_port *port, -				   struct net_device *bridge) +				   struct net_device *bridge, +				   struct netlink_ext_ack *extack)  {  	struct sparx5 *sparx5 = port->sparx5; +	struct net_device *ndev = port->ndev; +	int err;  	if (bitmap_empty(sparx5->bridge_mask, SPX5_PORTS))  		/* First bridged port */ @@ -109,12 +112,21 @@ static int sparx5_port_bridge_join(struct sparx5_port *port,  	set_bit(port->portno, sparx5->bridge_mask); +	err = switchdev_bridge_port_offload(ndev, ndev, NULL, NULL, NULL, +					    false, extack); +	if (err) +		goto err_switchdev_offload; +  	/* Port enters in bridge mode therefor don't need to copy to CPU  	 * frames for multicast in case the bridge is not requesting them  	 */ -	__dev_mc_unsync(port->ndev, sparx5_mc_unsync); +	__dev_mc_unsync(ndev, sparx5_mc_unsync);  	return 0; + +err_switchdev_offload: +	clear_bit(port->portno, sparx5->bridge_mask); +	return err;  }  static void sparx5_port_bridge_leave(struct sparx5_port *port, @@ -122,6 +134,8 @@ static void sparx5_port_bridge_leave(struct sparx5_port *port,  {  	struct sparx5 *sparx5 = port->sparx5; +	switchdev_bridge_port_unoffload(port->ndev, NULL, NULL, NULL); +  	clear_bit(port->portno, sparx5->bridge_mask);  	if (bitmap_empty(sparx5->bridge_mask, SPX5_PORTS))  		sparx5->hw_bridge_dev = NULL; @@ -139,11 +153,15 @@ static int sparx5_port_changeupper(struct net_device *dev,  				   struct netdev_notifier_changeupper_info *info)  {  	struct sparx5_port *port = netdev_priv(dev); +	struct netlink_ext_ack *extack;  	int err = 0; +	extack = netdev_notifier_info_to_extack(&info->info); +  	if (netif_is_bridge_master(info->upper_dev)) {  		if (info->linking) -			err = sparx5_port_bridge_join(port, info->upper_dev); +			err = sparx5_port_bridge_join(port, info->upper_dev, +						      extack);  		else  			sparx5_port_bridge_leave(port, info->upper_dev); |