11
11
#include <linux/refcount.h>
12
12
13
13
#include "spectrum.h"
14
+ #include "spectrum_router.h"
14
15
#include "reg.h"
15
16
16
17
struct mlxsw_sp_fid_family ;
@@ -115,6 +116,7 @@ struct mlxsw_sp_fid_ops {
115
116
116
117
enum mlxsw_sp_fid_flood_profile_id {
117
118
MLXSW_SP_FID_FLOOD_PROFILE_ID_BRIDGE = 1 ,
119
+ MLXSW_SP_FID_FLOOD_PROFILE_ID_RSP ,
118
120
};
119
121
120
122
struct mlxsw_sp_fid_flood_profile {
@@ -368,6 +370,36 @@ mlxsw_sp_fid_8021d_pgt_size(const struct mlxsw_sp_fid_family *fid_family,
368
370
return 0 ;
369
371
}
370
372
373
+ static unsigned int mlxsw_sp_fid_rfid_port_offset_cff (unsigned int local_port )
374
+ {
375
+ /* Port 0 is the CPU port. Since we never create RIFs based off that
376
+ * port, we don't need to count it.
377
+ */
378
+ return WARN_ON_ONCE (!local_port ) ? 0 : local_port - 1 ;
379
+ }
380
+
381
+ static int
382
+ mlxsw_sp_fid_rfid_pgt_size_cff (const struct mlxsw_sp_fid_family * fid_family ,
383
+ u16 * p_pgt_size )
384
+ {
385
+ struct mlxsw_core * core = fid_family -> mlxsw_sp -> core ;
386
+ unsigned int max_ports ;
387
+ u16 pgt_size ;
388
+ u16 max_lags ;
389
+ int err ;
390
+
391
+ max_ports = mlxsw_core_max_ports (core );
392
+
393
+ err = mlxsw_core_max_lag (core , & max_lags );
394
+ if (err )
395
+ return err ;
396
+
397
+ pgt_size = (mlxsw_sp_fid_rfid_port_offset_cff (max_ports ) + max_lags ) *
398
+ fid_family -> flood_profile -> nr_flood_tables ;
399
+ * p_pgt_size = pgt_size ;
400
+ return 0 ;
401
+ }
402
+
371
403
static u16
372
404
mlxsw_sp_fid_pgt_base_ctl (const struct mlxsw_sp_fid_family * fid_family ,
373
405
const struct mlxsw_sp_flood_table * flood_table )
@@ -519,6 +551,18 @@ static void mlxsw_sp_fid_fid_pack_cff(char *sfmr_pl,
519
551
fid_family -> flood_profile -> profile_id );
520
552
}
521
553
554
+ static u16 mlxsw_sp_fid_rfid_fid_offset_cff (struct mlxsw_sp * mlxsw_sp ,
555
+ u16 port_lag_id , bool is_lag )
556
+ {
557
+ u16 max_ports = mlxsw_core_max_ports (mlxsw_sp -> core );
558
+
559
+ if (is_lag )
560
+ return mlxsw_sp_fid_rfid_port_offset_cff (max_ports ) +
561
+ port_lag_id ;
562
+ else
563
+ return mlxsw_sp_fid_rfid_port_offset_cff (port_lag_id );
564
+ }
565
+
522
566
static int mlxsw_sp_fid_op (const struct mlxsw_sp_fid * fid , bool valid )
523
567
{
524
568
struct mlxsw_sp * mlxsw_sp = fid -> fid_family -> mlxsw_sp ;
@@ -1248,6 +1292,24 @@ struct mlxsw_sp_fid_flood_profile mlxsw_sp_fid_8021d_flood_profile = {
1248
1292
.profile_id = MLXSW_SP_FID_FLOOD_PROFILE_ID_BRIDGE ,
1249
1293
};
1250
1294
1295
+ static const struct mlxsw_sp_flood_table mlxsw_sp_fid_rsp_flood_tables_cff [] = {
1296
+ {
1297
+ .packet_type = MLXSW_SP_FLOOD_TYPE_UC ,
1298
+ .table_index = 0 ,
1299
+ },
1300
+ {
1301
+ .packet_type = MLXSW_SP_FLOOD_TYPE_NOT_UC ,
1302
+ .table_index = 1 ,
1303
+ },
1304
+ };
1305
+
1306
+ static const
1307
+ struct mlxsw_sp_fid_flood_profile mlxsw_sp_fid_rsp_flood_profile_cff = {
1308
+ .flood_tables = mlxsw_sp_fid_rsp_flood_tables_cff ,
1309
+ .nr_flood_tables = ARRAY_SIZE (mlxsw_sp_fid_rsp_flood_tables_cff ),
1310
+ .profile_id = MLXSW_SP_FID_FLOOD_PROFILE_ID_RSP ,
1311
+ };
1312
+
1251
1313
static bool
1252
1314
mlxsw_sp_fid_8021q_compare (const struct mlxsw_sp_fid * fid , const void * arg )
1253
1315
{
@@ -1271,6 +1333,29 @@ static int mlxsw_sp_fid_rfid_setup_ctl(struct mlxsw_sp_fid *fid,
1271
1333
return 0 ;
1272
1334
}
1273
1335
1336
+ static int mlxsw_sp_fid_rfid_setup_cff (struct mlxsw_sp_fid * fid ,
1337
+ const void * arg )
1338
+ {
1339
+ struct mlxsw_sp * mlxsw_sp = fid -> fid_family -> mlxsw_sp ;
1340
+ u16 rif_index = * (const u16 * )arg ;
1341
+ struct mlxsw_sp_rif * rif ;
1342
+ bool is_lag ;
1343
+ u16 port ;
1344
+ int err ;
1345
+
1346
+ rif = mlxsw_sp_rif_by_index (mlxsw_sp , rif_index );
1347
+ if (!rif )
1348
+ return - ENOENT ;
1349
+
1350
+ err = mlxsw_sp_rif_subport_port (rif , & port , & is_lag );
1351
+ if (err )
1352
+ return err ;
1353
+
1354
+ fid -> fid_offset = mlxsw_sp_fid_rfid_fid_offset_cff (mlxsw_sp , port ,
1355
+ is_lag );
1356
+ return 0 ;
1357
+ }
1358
+
1274
1359
static int mlxsw_sp_fid_rfid_configure (struct mlxsw_sp_fid * fid )
1275
1360
{
1276
1361
return mlxsw_sp_fid_op (fid , true);
@@ -1410,6 +1495,139 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_rfid_ops_ctl = {
1410
1495
.fid_pack = mlxsw_sp_fid_pack_ctl ,
1411
1496
};
1412
1497
1498
+ static int
1499
+ mlxsw_sp_fid_rfid_port_add_cff (struct mlxsw_sp * mlxsw_sp ,
1500
+ const struct mlxsw_sp_flood_table * flood_table ,
1501
+ u16 pgt_addr , u16 smpe , unsigned int local_port )
1502
+ {
1503
+ int err ;
1504
+
1505
+ err = mlxsw_sp_pgt_entry_port_set (mlxsw_sp , pgt_addr , smpe ,
1506
+ local_port , true);
1507
+ if (err )
1508
+ return err ;
1509
+
1510
+ if (flood_table -> packet_type == MLXSW_SP_FLOOD_TYPE_NOT_UC ) {
1511
+ u16 router_port = mlxsw_sp_router_port (mlxsw_sp );
1512
+
1513
+ err = mlxsw_sp_pgt_entry_port_set (mlxsw_sp , pgt_addr , smpe ,
1514
+ router_port , true);
1515
+ if (err )
1516
+ goto err_entry_port_set ;
1517
+ }
1518
+
1519
+ return 0 ;
1520
+
1521
+ err_entry_port_set :
1522
+ mlxsw_sp_pgt_entry_port_set (mlxsw_sp , pgt_addr , smpe , local_port ,
1523
+ false);
1524
+ return err ;
1525
+ }
1526
+
1527
+ static void
1528
+ mlxsw_sp_fid_rfid_port_del_cff (struct mlxsw_sp * mlxsw_sp ,
1529
+ const struct mlxsw_sp_flood_table * flood_table ,
1530
+ u16 pgt_addr , u16 smpe , u16 local_port )
1531
+ {
1532
+ if (flood_table -> packet_type == MLXSW_SP_FLOOD_TYPE_NOT_UC ) {
1533
+ u16 router_port = mlxsw_sp_router_port (mlxsw_sp );
1534
+
1535
+ mlxsw_sp_pgt_entry_port_set (mlxsw_sp , pgt_addr , smpe ,
1536
+ router_port , false);
1537
+ }
1538
+ mlxsw_sp_pgt_entry_port_set (mlxsw_sp , pgt_addr , smpe , local_port ,
1539
+ false);
1540
+ }
1541
+
1542
+ static int
1543
+ mlxsw_sp_fid_rfid_port_memb_ft_cff (const struct mlxsw_sp_fid_family * fid_family ,
1544
+ const struct mlxsw_sp_flood_table * flood_table ,
1545
+ const struct mlxsw_sp_port * mlxsw_sp_port ,
1546
+ bool member )
1547
+ {
1548
+ struct mlxsw_sp * mlxsw_sp = fid_family -> mlxsw_sp ;
1549
+ u16 local_port = mlxsw_sp_port -> local_port ;
1550
+ u16 fid_pgt_base ;
1551
+ u16 fid_offset ;
1552
+ u16 pgt_addr ;
1553
+ u16 smpe ;
1554
+ u16 port ;
1555
+
1556
+ /* In-PGT SMPE is only valid on Spectrum-1, CFF only on Spectrum>1. */
1557
+ smpe = 0 ;
1558
+
1559
+ port = mlxsw_sp_port -> lagged ? mlxsw_sp_port -> lag_id : local_port ;
1560
+ fid_offset = mlxsw_sp_fid_rfid_fid_offset_cff (mlxsw_sp , port ,
1561
+ mlxsw_sp_port -> lagged );
1562
+ fid_pgt_base = mlxsw_sp_fid_off_pgt_base_cff (fid_family , fid_offset );
1563
+ pgt_addr = fid_pgt_base + flood_table -> table_index ;
1564
+
1565
+ if (member )
1566
+ return mlxsw_sp_fid_rfid_port_add_cff (mlxsw_sp , flood_table ,
1567
+ pgt_addr , smpe ,
1568
+ local_port );
1569
+
1570
+ mlxsw_sp_fid_rfid_port_del_cff (mlxsw_sp , flood_table , pgt_addr , smpe ,
1571
+ local_port );
1572
+ return 0 ;
1573
+ }
1574
+
1575
+ static int
1576
+ mlxsw_sp_fid_rfid_port_memb_cff (const struct mlxsw_sp_fid_family * fid_family ,
1577
+ const struct mlxsw_sp_port * mlxsw_sp_port ,
1578
+ bool member )
1579
+ {
1580
+ int i ;
1581
+
1582
+ for (i = 0 ; i < fid_family -> flood_profile -> nr_flood_tables ; i ++ ) {
1583
+ const struct mlxsw_sp_flood_table * flood_table =
1584
+ & fid_family -> flood_profile -> flood_tables [i ];
1585
+ int err ;
1586
+
1587
+ err = mlxsw_sp_fid_rfid_port_memb_ft_cff (fid_family ,
1588
+ flood_table ,
1589
+ mlxsw_sp_port , member );
1590
+ if (err )
1591
+ return err ;
1592
+ }
1593
+
1594
+ return 0 ;
1595
+ }
1596
+
1597
+ static int
1598
+ mlxsw_sp_fid_rfid_port_init_cff (const struct mlxsw_sp_fid_family * fid_family ,
1599
+ const struct mlxsw_sp_port * mlxsw_sp_port )
1600
+ {
1601
+ return mlxsw_sp_fid_rfid_port_memb_cff (fid_family , mlxsw_sp_port , true);
1602
+ }
1603
+
1604
+ static void
1605
+ mlxsw_sp_fid_rfid_port_fini_cff (const struct mlxsw_sp_fid_family * fid_family ,
1606
+ const struct mlxsw_sp_port * mlxsw_sp_port )
1607
+ {
1608
+ mlxsw_sp_fid_rfid_port_memb_cff (fid_family , mlxsw_sp_port , false);
1609
+ }
1610
+
1611
+ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_rfid_ops_cff = {
1612
+ .setup = mlxsw_sp_fid_rfid_setup_cff ,
1613
+ .configure = mlxsw_sp_fid_rfid_configure ,
1614
+ .deconfigure = mlxsw_sp_fid_rfid_deconfigure ,
1615
+ .index_alloc = mlxsw_sp_fid_rfid_index_alloc ,
1616
+ .compare = mlxsw_sp_fid_rfid_compare ,
1617
+ .port_vid_map = mlxsw_sp_fid_rfid_port_vid_map ,
1618
+ .port_vid_unmap = mlxsw_sp_fid_rfid_port_vid_unmap ,
1619
+ .vni_set = mlxsw_sp_fid_rfid_vni_set ,
1620
+ .vni_clear = mlxsw_sp_fid_rfid_vni_clear ,
1621
+ .nve_flood_index_set = mlxsw_sp_fid_rfid_nve_flood_index_set ,
1622
+ .nve_flood_index_clear = mlxsw_sp_fid_rfid_nve_flood_index_clear ,
1623
+ .vid_to_fid_rif_update = mlxsw_sp_fid_rfid_vid_to_fid_rif_update ,
1624
+ .pgt_size = mlxsw_sp_fid_rfid_pgt_size_cff ,
1625
+ .fid_port_init = mlxsw_sp_fid_rfid_port_init_cff ,
1626
+ .fid_port_fini = mlxsw_sp_fid_rfid_port_fini_cff ,
1627
+ .fid_mid = mlxsw_sp_fid_fid_mid_cff ,
1628
+ .fid_pack = mlxsw_sp_fid_fid_pack_cff ,
1629
+ };
1630
+
1413
1631
static int mlxsw_sp_fid_dummy_setup (struct mlxsw_sp_fid * fid , const void * arg )
1414
1632
{
1415
1633
fid -> fid_offset = 0 ;
@@ -1726,10 +1944,22 @@ static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_family_cff = {
1726
1944
.smpe_index_valid = true,
1727
1945
};
1728
1946
1947
+ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_rfid_family_cff = {
1948
+ .type = MLXSW_SP_FID_TYPE_RFID ,
1949
+ .fid_size = sizeof (struct mlxsw_sp_fid ),
1950
+ .start_index = MLXSW_SP_RFID_START ,
1951
+ .end_index = MLXSW_SP_RFID_END ,
1952
+ .flood_profile = & mlxsw_sp_fid_rsp_flood_profile_cff ,
1953
+ .rif_type = MLXSW_SP_RIF_TYPE_SUBPORT ,
1954
+ .ops = & mlxsw_sp_fid_rfid_ops_cff ,
1955
+ .smpe_index_valid = false,
1956
+ };
1957
+
1729
1958
static const struct mlxsw_sp_fid_family * mlxsw_sp2_fid_family_arr_cff [] = {
1730
1959
[MLXSW_SP_FID_TYPE_8021Q ] = & mlxsw_sp2_fid_8021q_family_cff ,
1731
1960
[MLXSW_SP_FID_TYPE_8021D ] = & mlxsw_sp2_fid_8021d_family_cff ,
1732
1961
[MLXSW_SP_FID_TYPE_DUMMY ] = & mlxsw_sp2_fid_dummy_family ,
1962
+ [MLXSW_SP_FID_TYPE_RFID ] = & mlxsw_sp_fid_rfid_family_cff ,
1733
1963
};
1734
1964
1735
1965
static struct mlxsw_sp_fid * mlxsw_sp_fid_lookup (struct mlxsw_sp * mlxsw_sp ,
@@ -2180,6 +2410,7 @@ mlxsw_sp2_fids_init_flood_profile(struct mlxsw_sp *mlxsw_sp,
2180
2410
static const
2181
2411
struct mlxsw_sp_fid_flood_profile * mlxsw_sp_fid_flood_profiles [] = {
2182
2412
& mlxsw_sp_fid_8021d_flood_profile ,
2413
+ & mlxsw_sp_fid_rsp_flood_profile_cff ,
2183
2414
};
2184
2415
2185
2416
static int
0 commit comments