@@ -1198,6 +1198,12 @@ int mv88e6xxx_port_pvid_get(struct dsa_switch *ds, int port, u16 *pvid)
1198
1198
return 0 ;
1199
1199
}
1200
1200
1201
+ int mv88e6xxx_port_pvid_set (struct dsa_switch * ds , int port , u16 pvid )
1202
+ {
1203
+ return mv88e6xxx_reg_write (ds , REG_PORT (port ), PORT_DEFAULT_VLAN ,
1204
+ pvid & PORT_DEFAULT_VLAN_MASK );
1205
+ }
1206
+
1201
1207
static int _mv88e6xxx_vtu_wait (struct dsa_switch * ds )
1202
1208
{
1203
1209
return _mv88e6xxx_wait (ds , REG_GLOBAL , GLOBAL_VTU_OP ,
@@ -1374,6 +1380,169 @@ static int _mv88e6xxx_vtu_loadpurge(struct dsa_switch *ds,
1374
1380
return _mv88e6xxx_vtu_cmd (ds , GLOBAL_VTU_OP_VTU_LOAD_PURGE );
1375
1381
}
1376
1382
1383
+ static int _mv88e6xxx_stu_getnext (struct dsa_switch * ds , u8 sid ,
1384
+ struct mv88e6xxx_vtu_stu_entry * entry )
1385
+ {
1386
+ struct mv88e6xxx_vtu_stu_entry next = { 0 };
1387
+ int ret ;
1388
+
1389
+ ret = _mv88e6xxx_vtu_wait (ds );
1390
+ if (ret < 0 )
1391
+ return ret ;
1392
+
1393
+ ret = _mv88e6xxx_reg_write (ds , REG_GLOBAL , GLOBAL_VTU_SID ,
1394
+ sid & GLOBAL_VTU_SID_MASK );
1395
+ if (ret < 0 )
1396
+ return ret ;
1397
+
1398
+ ret = _mv88e6xxx_vtu_cmd (ds , GLOBAL_VTU_OP_STU_GET_NEXT );
1399
+ if (ret < 0 )
1400
+ return ret ;
1401
+
1402
+ ret = _mv88e6xxx_reg_read (ds , REG_GLOBAL , GLOBAL_VTU_SID );
1403
+ if (ret < 0 )
1404
+ return ret ;
1405
+
1406
+ next .sid = ret & GLOBAL_VTU_SID_MASK ;
1407
+
1408
+ ret = _mv88e6xxx_reg_read (ds , REG_GLOBAL , GLOBAL_VTU_VID );
1409
+ if (ret < 0 )
1410
+ return ret ;
1411
+
1412
+ next .valid = !!(ret & GLOBAL_VTU_VID_VALID );
1413
+
1414
+ if (next .valid ) {
1415
+ ret = _mv88e6xxx_vtu_stu_data_read (ds , & next , 2 );
1416
+ if (ret < 0 )
1417
+ return ret ;
1418
+ }
1419
+
1420
+ * entry = next ;
1421
+ return 0 ;
1422
+ }
1423
+
1424
+ static int _mv88e6xxx_stu_loadpurge (struct dsa_switch * ds ,
1425
+ struct mv88e6xxx_vtu_stu_entry * entry )
1426
+ {
1427
+ u16 reg = 0 ;
1428
+ int ret ;
1429
+
1430
+ ret = _mv88e6xxx_vtu_wait (ds );
1431
+ if (ret < 0 )
1432
+ return ret ;
1433
+
1434
+ if (!entry -> valid )
1435
+ goto loadpurge ;
1436
+
1437
+ /* Write port states */
1438
+ ret = _mv88e6xxx_vtu_stu_data_write (ds , entry , 2 );
1439
+ if (ret < 0 )
1440
+ return ret ;
1441
+
1442
+ reg = GLOBAL_VTU_VID_VALID ;
1443
+ loadpurge :
1444
+ ret = _mv88e6xxx_reg_write (ds , REG_GLOBAL , GLOBAL_VTU_VID , reg );
1445
+ if (ret < 0 )
1446
+ return ret ;
1447
+
1448
+ reg = entry -> sid & GLOBAL_VTU_SID_MASK ;
1449
+ ret = _mv88e6xxx_reg_write (ds , REG_GLOBAL , GLOBAL_VTU_SID , reg );
1450
+ if (ret < 0 )
1451
+ return ret ;
1452
+
1453
+ return _mv88e6xxx_vtu_cmd (ds , GLOBAL_VTU_OP_STU_LOAD_PURGE );
1454
+ }
1455
+
1456
+ static int _mv88e6xxx_vlan_init (struct dsa_switch * ds , u16 vid ,
1457
+ struct mv88e6xxx_vtu_stu_entry * entry )
1458
+ {
1459
+ struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
1460
+ struct mv88e6xxx_vtu_stu_entry vlan = {
1461
+ .valid = true,
1462
+ .vid = vid ,
1463
+ };
1464
+ int i ;
1465
+
1466
+ /* exclude all ports except the CPU */
1467
+ for (i = 0 ; i < ps -> num_ports ; ++ i )
1468
+ vlan .data [i ] = dsa_is_cpu_port (ds , i ) ?
1469
+ GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED :
1470
+ GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER ;
1471
+
1472
+ if (mv88e6xxx_6097_family (ds ) || mv88e6xxx_6165_family (ds ) ||
1473
+ mv88e6xxx_6351_family (ds ) || mv88e6xxx_6352_family (ds )) {
1474
+ struct mv88e6xxx_vtu_stu_entry vstp ;
1475
+ int err ;
1476
+
1477
+ /* Adding a VTU entry requires a valid STU entry. As VSTP is not
1478
+ * implemented, only one STU entry is needed to cover all VTU
1479
+ * entries. Thus, validate the SID 0.
1480
+ */
1481
+ vlan .sid = 0 ;
1482
+ err = _mv88e6xxx_stu_getnext (ds , GLOBAL_VTU_SID_MASK , & vstp );
1483
+ if (err )
1484
+ return err ;
1485
+
1486
+ if (vstp .sid != vlan .sid || !vstp .valid ) {
1487
+ memset (& vstp , 0 , sizeof (vstp ));
1488
+ vstp .valid = true;
1489
+ vstp .sid = vlan .sid ;
1490
+
1491
+ err = _mv88e6xxx_stu_loadpurge (ds , & vstp );
1492
+ if (err )
1493
+ return err ;
1494
+ }
1495
+
1496
+ /* Non-bridged ports and bridge groups use FIDs from 1 to
1497
+ * num_ports; VLANs use FIDs from num_ports+1 to 4095.
1498
+ */
1499
+ vlan .fid = find_next_zero_bit (ps -> fid_bitmap , VLAN_N_VID ,
1500
+ ps -> num_ports + 1 );
1501
+ if (unlikely (vlan .fid == VLAN_N_VID )) {
1502
+ pr_err ("no more FID available for VLAN %d\n" , vid );
1503
+ return - ENOSPC ;
1504
+ }
1505
+
1506
+ err = _mv88e6xxx_flush_fid (ds , vlan .fid );
1507
+ if (err )
1508
+ return err ;
1509
+
1510
+ set_bit (vlan .fid , ps -> fid_bitmap );
1511
+ }
1512
+
1513
+ * entry = vlan ;
1514
+ return 0 ;
1515
+ }
1516
+
1517
+ int mv88e6xxx_port_vlan_add (struct dsa_switch * ds , int port , u16 vid ,
1518
+ bool untagged )
1519
+ {
1520
+ struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
1521
+ struct mv88e6xxx_vtu_stu_entry vlan ;
1522
+ int err ;
1523
+
1524
+ mutex_lock (& ps -> smi_mutex );
1525
+ err = _mv88e6xxx_vtu_getnext (ds , vid - 1 , & vlan );
1526
+ if (err )
1527
+ goto unlock ;
1528
+
1529
+ if (vlan .vid != vid || !vlan .valid ) {
1530
+ err = _mv88e6xxx_vlan_init (ds , vid , & vlan );
1531
+ if (err )
1532
+ goto unlock ;
1533
+ }
1534
+
1535
+ vlan .data [port ] = untagged ?
1536
+ GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED :
1537
+ GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED ;
1538
+
1539
+ err = _mv88e6xxx_vtu_loadpurge (ds , & vlan );
1540
+ unlock :
1541
+ mutex_unlock (& ps -> smi_mutex );
1542
+
1543
+ return err ;
1544
+ }
1545
+
1377
1546
int mv88e6xxx_port_vlan_del (struct dsa_switch * ds , int port , u16 vid )
1378
1547
{
1379
1548
struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
0 commit comments