@@ -370,7 +370,8 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev,
370
370
return err ;
371
371
}
372
372
373
- static int mlxsw_sp_port_pvid_set (struct mlxsw_sp_port * mlxsw_sp_port , u16 vid )
373
+ static int __mlxsw_sp_port_pvid_set (struct mlxsw_sp_port * mlxsw_sp_port ,
374
+ u16 vid )
374
375
{
375
376
struct mlxsw_sp * mlxsw_sp = mlxsw_sp_port -> mlxsw_sp ;
376
377
char spvid_pl [MLXSW_REG_SPVID_LEN ];
@@ -379,6 +380,53 @@ static int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
379
380
return mlxsw_reg_write (mlxsw_sp -> core , MLXSW_REG (spvid ), spvid_pl );
380
381
}
381
382
383
+ static int mlxsw_sp_port_allow_untagged_set (struct mlxsw_sp_port * mlxsw_sp_port ,
384
+ bool allow )
385
+ {
386
+ struct mlxsw_sp * mlxsw_sp = mlxsw_sp_port -> mlxsw_sp ;
387
+ char spaft_pl [MLXSW_REG_SPAFT_LEN ];
388
+
389
+ mlxsw_reg_spaft_pack (spaft_pl , mlxsw_sp_port -> local_port , allow );
390
+ return mlxsw_reg_write (mlxsw_sp -> core , MLXSW_REG (spaft ), spaft_pl );
391
+ }
392
+
393
+ int mlxsw_sp_port_pvid_set (struct mlxsw_sp_port * mlxsw_sp_port , u16 vid )
394
+ {
395
+ struct net_device * dev = mlxsw_sp_port -> dev ;
396
+ int err ;
397
+
398
+ if (!vid ) {
399
+ err = mlxsw_sp_port_allow_untagged_set (mlxsw_sp_port , false);
400
+ if (err ) {
401
+ netdev_err (dev , "Failed to disallow untagged traffic\n" );
402
+ return err ;
403
+ }
404
+ } else {
405
+ err = __mlxsw_sp_port_pvid_set (mlxsw_sp_port , vid );
406
+ if (err ) {
407
+ netdev_err (dev , "Failed to set PVID\n" );
408
+ return err ;
409
+ }
410
+
411
+ /* Only allow if not already allowed. */
412
+ if (!mlxsw_sp_port -> pvid ) {
413
+ err = mlxsw_sp_port_allow_untagged_set (mlxsw_sp_port ,
414
+ true);
415
+ if (err ) {
416
+ netdev_err (dev , "Failed to allow untagged traffic\n" );
417
+ goto err_port_allow_untagged_set ;
418
+ }
419
+ }
420
+ }
421
+
422
+ mlxsw_sp_port -> pvid = vid ;
423
+ return 0 ;
424
+
425
+ err_port_allow_untagged_set :
426
+ __mlxsw_sp_port_pvid_set (mlxsw_sp_port , mlxsw_sp_port -> pvid );
427
+ return err ;
428
+ }
429
+
382
430
static int mlxsw_sp_fid_create (struct mlxsw_sp * mlxsw_sp , u16 fid )
383
431
{
384
432
char sfmr_pl [MLXSW_REG_SFMR_LEN ];
@@ -540,7 +588,12 @@ static int __mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port,
540
588
netdev_err (dev , "Unable to add PVID %d\n" , vid_begin );
541
589
goto err_port_pvid_set ;
542
590
}
543
- mlxsw_sp_port -> pvid = vid_begin ;
591
+ } else if (!flag_pvid && old_pvid >= vid_begin && old_pvid <= vid_end ) {
592
+ err = mlxsw_sp_port_pvid_set (mlxsw_sp_port , 0 );
593
+ if (err ) {
594
+ netdev_err (dev , "Unable to del PVID\n" );
595
+ goto err_port_pvid_set ;
596
+ }
544
597
}
545
598
546
599
/* Changing activity bits only if HW operation succeded */
@@ -892,20 +945,18 @@ static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
892
945
return err ;
893
946
}
894
947
948
+ if (init )
949
+ goto out ;
950
+
895
951
pvid = mlxsw_sp_port -> pvid ;
896
- if (pvid >= vid_begin && pvid <= vid_end && pvid != 1 ) {
897
- /* Default VLAN is always 1 */
898
- err = mlxsw_sp_port_pvid_set (mlxsw_sp_port , 1 );
952
+ if (pvid >= vid_begin && pvid <= vid_end ) {
953
+ err = mlxsw_sp_port_pvid_set (mlxsw_sp_port , 0 );
899
954
if (err ) {
900
955
netdev_err (dev , "Unable to del PVID %d\n" , pvid );
901
956
return err ;
902
957
}
903
- mlxsw_sp_port -> pvid = 1 ;
904
958
}
905
959
906
- if (init )
907
- goto out ;
908
-
909
960
err = __mlxsw_sp_port_flood_set (mlxsw_sp_port , vid_begin , vid_end ,
910
961
false, false);
911
962
if (err ) {
0 commit comments