@@ -4036,6 +4036,56 @@ static void mlxsw_sp_port_vlan_unlink(struct mlxsw_sp_port *mlxsw_sp_port,
40364036 mlxsw_sp_vport -> dev = mlxsw_sp_port -> dev ;
40374037}
40384038
4039+ static int mlxsw_sp_port_stp_set (struct mlxsw_sp_port * mlxsw_sp_port ,
4040+ bool enable )
4041+ {
4042+ struct mlxsw_sp * mlxsw_sp = mlxsw_sp_port -> mlxsw_sp ;
4043+ enum mlxsw_reg_spms_state spms_state ;
4044+ char * spms_pl ;
4045+ u16 vid ;
4046+ int err ;
4047+
4048+ spms_state = enable ? MLXSW_REG_SPMS_STATE_FORWARDING :
4049+ MLXSW_REG_SPMS_STATE_DISCARDING ;
4050+
4051+ spms_pl = kmalloc (MLXSW_REG_SPMS_LEN , GFP_KERNEL );
4052+ if (!spms_pl )
4053+ return - ENOMEM ;
4054+ mlxsw_reg_spms_pack (spms_pl , mlxsw_sp_port -> local_port );
4055+
4056+ for (vid = 0 ; vid < VLAN_N_VID ; vid ++ )
4057+ mlxsw_reg_spms_vid_pack (spms_pl , vid , spms_state );
4058+
4059+ err = mlxsw_reg_write (mlxsw_sp -> core , MLXSW_REG (spms ), spms_pl );
4060+ kfree (spms_pl );
4061+ return err ;
4062+ }
4063+
4064+ static int mlxsw_sp_port_ovs_join (struct mlxsw_sp_port * mlxsw_sp_port )
4065+ {
4066+ int err ;
4067+
4068+ err = mlxsw_sp_port_stp_set (mlxsw_sp_port , true);
4069+ if (err )
4070+ return err ;
4071+ err = mlxsw_sp_port_vlan_set (mlxsw_sp_port , 2 , VLAN_N_VID - 1 ,
4072+ true, false);
4073+ if (err )
4074+ goto err_port_vlan_set ;
4075+ return 0 ;
4076+
4077+ err_port_vlan_set :
4078+ mlxsw_sp_port_stp_set (mlxsw_sp_port , false);
4079+ return err ;
4080+ }
4081+
4082+ static void mlxsw_sp_port_ovs_leave (struct mlxsw_sp_port * mlxsw_sp_port )
4083+ {
4084+ mlxsw_sp_port_vlan_set (mlxsw_sp_port , 2 , VLAN_N_VID - 1 ,
4085+ false, false);
4086+ mlxsw_sp_port_stp_set (mlxsw_sp_port , false);
4087+ }
4088+
40394089static int mlxsw_sp_netdevice_port_upper_event (struct net_device * dev ,
40404090 unsigned long event , void * ptr )
40414091{
@@ -4055,7 +4105,8 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
40554105 if (!is_vlan_dev (upper_dev ) &&
40564106 !netif_is_lag_master (upper_dev ) &&
40574107 !netif_is_bridge_master (upper_dev ) &&
4058- !netif_is_l3_master (upper_dev ))
4108+ !netif_is_l3_master (upper_dev ) &&
4109+ !netif_is_ovs_master (upper_dev ))
40594110 return - EINVAL ;
40604111 if (!info -> linking )
40614112 break ;
@@ -4072,6 +4123,10 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
40724123 if (netif_is_lag_port (dev ) && is_vlan_dev (upper_dev ) &&
40734124 !netif_is_lag_master (vlan_dev_real_dev (upper_dev )))
40744125 return - EINVAL ;
4126+ if (netif_is_ovs_master (upper_dev ) && vlan_uses_dev (dev ))
4127+ return - EINVAL ;
4128+ if (netif_is_ovs_port (dev ) && is_vlan_dev (upper_dev ))
4129+ return - EINVAL ;
40754130 break ;
40764131 case NETDEV_CHANGEUPPER :
40774132 upper_dev = info -> upper_dev ;
@@ -4100,6 +4155,11 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
41004155 err = mlxsw_sp_port_vrf_join (mlxsw_sp_port );
41014156 else
41024157 mlxsw_sp_port_vrf_leave (mlxsw_sp_port );
4158+ } else if (netif_is_ovs_master (upper_dev )) {
4159+ if (info -> linking )
4160+ err = mlxsw_sp_port_ovs_join (mlxsw_sp_port );
4161+ else
4162+ mlxsw_sp_port_ovs_leave (mlxsw_sp_port );
41034163 } else {
41044164 err = - EINVAL ;
41054165 WARN_ON (1 );
0 commit comments