@@ -1398,7 +1398,7 @@ int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin,
1398
1398
return 0 ;
1399
1399
}
1400
1400
1401
- static int mlxsw_sp_port_vp_mode_trans (struct mlxsw_sp_port * mlxsw_sp_port )
1401
+ int mlxsw_sp_port_vp_mode_trans (struct mlxsw_sp_port * mlxsw_sp_port )
1402
1402
{
1403
1403
enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID ;
1404
1404
u16 vid , last_visited_vid ;
@@ -1428,7 +1428,7 @@ static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
1428
1428
return err ;
1429
1429
}
1430
1430
1431
- static int mlxsw_sp_port_vlan_mode_trans (struct mlxsw_sp_port * mlxsw_sp_port )
1431
+ int mlxsw_sp_port_vlan_mode_trans (struct mlxsw_sp_port * mlxsw_sp_port )
1432
1432
{
1433
1433
enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID ;
1434
1434
u16 vid ;
@@ -1501,26 +1501,13 @@ static int mlxsw_sp_port_add_vid(struct net_device *dev,
1501
1501
if (!mlxsw_sp_vport )
1502
1502
return - ENOMEM ;
1503
1503
1504
- /* When adding the first VLAN interface on a bridged port we need to
1505
- * transition all the active 802.1Q bridge VLANs to use explicit
1506
- * {Port, VID} to FID mappings and set the port's mode to Virtual mode.
1507
- */
1508
- if (list_is_singular (& mlxsw_sp_port -> vports_list )) {
1509
- err = mlxsw_sp_port_vp_mode_trans (mlxsw_sp_port );
1510
- if (err )
1511
- goto err_port_vp_mode_trans ;
1512
- }
1513
-
1514
1504
err = mlxsw_sp_port_vlan_set (mlxsw_sp_vport , vid , vid , true, untagged );
1515
1505
if (err )
1516
1506
goto err_port_add_vid ;
1517
1507
1518
1508
return 0 ;
1519
1509
1520
1510
err_port_add_vid :
1521
- if (list_is_singular (& mlxsw_sp_port -> vports_list ))
1522
- mlxsw_sp_port_vlan_mode_trans (mlxsw_sp_port );
1523
- err_port_vp_mode_trans :
1524
1511
mlxsw_sp_port_vport_destroy (mlxsw_sp_vport );
1525
1512
return err ;
1526
1513
}
@@ -1551,13 +1538,6 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
1551
1538
if (f && !WARN_ON (!f -> leave ))
1552
1539
f -> leave (mlxsw_sp_vport );
1553
1540
1554
- /* When removing the last VLAN interface on a bridged port we need to
1555
- * transition all active 802.1Q bridge VLANs to use VID to FID
1556
- * mappings and set port's mode to VLAN mode.
1557
- */
1558
- if (list_is_singular (& mlxsw_sp_port -> vports_list ))
1559
- mlxsw_sp_port_vlan_mode_trans (mlxsw_sp_port );
1560
-
1561
1541
mlxsw_sp_port_vport_destroy (mlxsw_sp_vport );
1562
1542
1563
1543
return 0 ;
@@ -4382,9 +4362,12 @@ static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port)
4382
4362
{
4383
4363
int err ;
4384
4364
4385
- err = mlxsw_sp_port_stp_set (mlxsw_sp_port , true);
4365
+ err = mlxsw_sp_port_vp_mode_set (mlxsw_sp_port , true);
4386
4366
if (err )
4387
4367
return err ;
4368
+ err = mlxsw_sp_port_stp_set (mlxsw_sp_port , true);
4369
+ if (err )
4370
+ goto err_port_stp_set ;
4388
4371
err = mlxsw_sp_port_vlan_set (mlxsw_sp_port , 2 , VLAN_N_VID - 1 ,
4389
4372
true, false);
4390
4373
if (err )
@@ -4393,6 +4376,8 @@ static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port)
4393
4376
4394
4377
err_port_vlan_set :
4395
4378
mlxsw_sp_port_stp_set (mlxsw_sp_port , false);
4379
+ err_port_stp_set :
4380
+ mlxsw_sp_port_vp_mode_set (mlxsw_sp_port , false);
4396
4381
return err ;
4397
4382
}
4398
4383
@@ -4401,6 +4386,7 @@ static void mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port *mlxsw_sp_port)
4401
4386
mlxsw_sp_port_vlan_set (mlxsw_sp_port , 2 , VLAN_N_VID - 1 ,
4402
4387
false, false);
4403
4388
mlxsw_sp_port_stp_set (mlxsw_sp_port , false);
4389
+ mlxsw_sp_port_vp_mode_set (mlxsw_sp_port , false);
4404
4390
}
4405
4391
4406
4392
static int mlxsw_sp_netdevice_port_upper_event (struct net_device * dev ,
@@ -4695,6 +4681,7 @@ static int mlxsw_sp_vport_fid_map(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid,
4695
4681
static int mlxsw_sp_vport_vfid_join (struct mlxsw_sp_port * mlxsw_sp_vport ,
4696
4682
struct net_device * br_dev )
4697
4683
{
4684
+ struct mlxsw_sp_port * mlxsw_sp_port ;
4698
4685
struct mlxsw_sp_fid * f ;
4699
4686
int err ;
4700
4687
@@ -4713,13 +4700,23 @@ static int mlxsw_sp_vport_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport,
4713
4700
if (err )
4714
4701
goto err_vport_fid_map ;
4715
4702
4703
+ mlxsw_sp_port = mlxsw_sp_vport_port (mlxsw_sp_vport );
4704
+ if (mlxsw_sp_port -> nr_port_vid_map ++ == 0 ) {
4705
+ err = mlxsw_sp_port_vp_mode_trans (mlxsw_sp_port );
4706
+ if (err )
4707
+ goto err_port_vp_mode_trans ;
4708
+ }
4709
+
4716
4710
mlxsw_sp_vport_fid_set (mlxsw_sp_vport , f );
4717
4711
f -> ref_count ++ ;
4718
4712
4719
4713
netdev_dbg (mlxsw_sp_vport -> dev , "Joined FID=%d\n" , f -> fid );
4720
4714
4721
4715
return 0 ;
4722
4716
4717
+ err_port_vp_mode_trans :
4718
+ mlxsw_sp_port -> nr_port_vid_map -- ;
4719
+ mlxsw_sp_vport_fid_map (mlxsw_sp_vport , f -> fid , false);
4723
4720
err_vport_fid_map :
4724
4721
mlxsw_sp_vport_flood_set (mlxsw_sp_vport , f -> fid , false);
4725
4722
err_vport_flood_set :
@@ -4731,17 +4728,25 @@ static int mlxsw_sp_vport_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport,
4731
4728
static void mlxsw_sp_vport_vfid_leave (struct mlxsw_sp_port * mlxsw_sp_vport )
4732
4729
{
4733
4730
struct mlxsw_sp_fid * f = mlxsw_sp_vport_fid_get (mlxsw_sp_vport );
4731
+ struct mlxsw_sp_port * mlxsw_sp_port ;
4734
4732
4735
4733
netdev_dbg (mlxsw_sp_vport -> dev , "Left FID=%d\n" , f -> fid );
4736
4734
4735
+ mlxsw_sp_vport_fid_set (mlxsw_sp_vport , NULL );
4736
+ f -> ref_count -- ;
4737
+
4738
+ mlxsw_sp_port = mlxsw_sp_vport_port (mlxsw_sp_vport );
4739
+ if (mlxsw_sp_port -> nr_port_vid_map == 1 )
4740
+ mlxsw_sp_port_vlan_mode_trans (mlxsw_sp_port );
4741
+ mlxsw_sp_port -> nr_port_vid_map -- ;
4742
+
4737
4743
mlxsw_sp_vport_fid_map (mlxsw_sp_vport , f -> fid , false);
4738
4744
4739
4745
mlxsw_sp_vport_flood_set (mlxsw_sp_vport , f -> fid , false);
4740
4746
4741
4747
mlxsw_sp_port_fdb_flush (mlxsw_sp_vport , f -> fid );
4742
4748
4743
- mlxsw_sp_vport_fid_set (mlxsw_sp_vport , NULL );
4744
- if (-- f -> ref_count == 0 )
4749
+ if (f -> ref_count == 0 )
4745
4750
mlxsw_sp_vfid_destroy (mlxsw_sp_vport -> mlxsw_sp , f );
4746
4751
}
4747
4752
0 commit comments