@@ -1480,10 +1480,34 @@ static void mlxsw_sp_port_vport_destroy(struct mlxsw_sp_port *mlxsw_sp_vport)
1480
1480
kfree (mlxsw_sp_vport );
1481
1481
}
1482
1482
1483
+ static struct mlxsw_sp_port_vlan *
1484
+ mlxsw_sp_port_vlan_create (struct mlxsw_sp_port * mlxsw_sp_port , u16 vid )
1485
+ {
1486
+ struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan ;
1487
+
1488
+ mlxsw_sp_port_vlan = kzalloc (sizeof (* mlxsw_sp_port_vlan ), GFP_KERNEL );
1489
+ if (!mlxsw_sp_port_vlan )
1490
+ return ERR_PTR (- ENOMEM );
1491
+
1492
+ mlxsw_sp_port_vlan -> mlxsw_sp_port = mlxsw_sp_port ;
1493
+ mlxsw_sp_port_vlan -> vid = vid ;
1494
+ list_add (& mlxsw_sp_port_vlan -> list , & mlxsw_sp_port -> vlans_list );
1495
+
1496
+ return mlxsw_sp_port_vlan ;
1497
+ }
1498
+
1499
+ static void
1500
+ mlxsw_sp_port_vlan_destroy (struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan )
1501
+ {
1502
+ list_del (& mlxsw_sp_port_vlan -> list );
1503
+ kfree (mlxsw_sp_port_vlan );
1504
+ }
1505
+
1483
1506
static int mlxsw_sp_port_add_vid (struct net_device * dev ,
1484
1507
__be16 __always_unused proto , u16 vid )
1485
1508
{
1486
1509
struct mlxsw_sp_port * mlxsw_sp_port = netdev_priv (dev );
1510
+ struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan ;
1487
1511
struct mlxsw_sp_port * mlxsw_sp_vport ;
1488
1512
bool untagged = vid == 1 ;
1489
1513
int err ;
@@ -1494,12 +1518,19 @@ static int mlxsw_sp_port_add_vid(struct net_device *dev,
1494
1518
if (!vid )
1495
1519
return 0 ;
1496
1520
1497
- if (mlxsw_sp_port_vport_find (mlxsw_sp_port , vid ))
1521
+ mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid (mlxsw_sp_port , vid );
1522
+ if (mlxsw_sp_port_vlan )
1498
1523
return 0 ;
1499
1524
1525
+ mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_create (mlxsw_sp_port , vid );
1526
+ if (IS_ERR (mlxsw_sp_port_vlan ))
1527
+ return PTR_ERR (mlxsw_sp_port_vlan );
1528
+
1500
1529
mlxsw_sp_vport = mlxsw_sp_port_vport_create (mlxsw_sp_port , vid );
1501
- if (!mlxsw_sp_vport )
1502
- return - ENOMEM ;
1530
+ if (!mlxsw_sp_vport ) {
1531
+ err = - ENOMEM ;
1532
+ goto err_port_vport_create ;
1533
+ }
1503
1534
1504
1535
err = mlxsw_sp_port_vlan_set (mlxsw_sp_vport , vid , vid , true, untagged );
1505
1536
if (err )
@@ -1509,13 +1540,16 @@ static int mlxsw_sp_port_add_vid(struct net_device *dev,
1509
1540
1510
1541
err_port_add_vid :
1511
1542
mlxsw_sp_port_vport_destroy (mlxsw_sp_vport );
1543
+ err_port_vport_create :
1544
+ mlxsw_sp_port_vlan_destroy (mlxsw_sp_port_vlan );
1512
1545
return err ;
1513
1546
}
1514
1547
1515
1548
static int mlxsw_sp_port_kill_vid (struct net_device * dev ,
1516
1549
__be16 __always_unused proto , u16 vid )
1517
1550
{
1518
1551
struct mlxsw_sp_port * mlxsw_sp_port = netdev_priv (dev );
1552
+ struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan ;
1519
1553
struct mlxsw_sp_port * mlxsw_sp_vport ;
1520
1554
struct mlxsw_sp_fid * f ;
1521
1555
@@ -1525,6 +1559,10 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
1525
1559
if (!vid )
1526
1560
return 0 ;
1527
1561
1562
+ mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid (mlxsw_sp_port , vid );
1563
+ if (WARN_ON (!mlxsw_sp_port_vlan ))
1564
+ return 0 ;
1565
+
1528
1566
mlxsw_sp_vport = mlxsw_sp_port_vport_find (mlxsw_sp_port , vid );
1529
1567
if (WARN_ON (!mlxsw_sp_vport ))
1530
1568
return 0 ;
@@ -1540,6 +1578,8 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
1540
1578
1541
1579
mlxsw_sp_port_vport_destroy (mlxsw_sp_vport );
1542
1580
1581
+ mlxsw_sp_port_vlan_destroy (mlxsw_sp_port_vlan );
1582
+
1543
1583
return 0 ;
1544
1584
}
1545
1585
@@ -2720,6 +2760,7 @@ static int __mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2720
2760
err = - ENOMEM ;
2721
2761
goto err_port_untagged_vlans_alloc ;
2722
2762
}
2763
+ INIT_LIST_HEAD (& mlxsw_sp_port -> vlans_list );
2723
2764
INIT_LIST_HEAD (& mlxsw_sp_port -> vports_list );
2724
2765
INIT_LIST_HEAD (& mlxsw_sp_port -> mall_tc_list );
2725
2766
@@ -2926,6 +2967,7 @@ static void __mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
2926
2967
kfree (mlxsw_sp_port -> untagged_vlans );
2927
2968
kfree (mlxsw_sp_port -> active_vlans );
2928
2969
WARN_ON_ONCE (!list_empty (& mlxsw_sp_port -> vports_list ));
2970
+ WARN_ON_ONCE (!list_empty (& mlxsw_sp_port -> vlans_list ));
2929
2971
free_netdev (mlxsw_sp_port -> dev );
2930
2972
}
2931
2973
0 commit comments