1111#include <linux/refcount.h>
1212
1313#include "spectrum.h"
14+ #include "spectrum_router.h"
1415#include "reg.h"
1516
1617struct mlxsw_sp_fid_family ;
@@ -115,6 +116,7 @@ struct mlxsw_sp_fid_ops {
115116
116117enum mlxsw_sp_fid_flood_profile_id {
117118 MLXSW_SP_FID_FLOOD_PROFILE_ID_BRIDGE = 1 ,
119+ MLXSW_SP_FID_FLOOD_PROFILE_ID_RSP ,
118120};
119121
120122struct mlxsw_sp_fid_flood_profile {
@@ -368,6 +370,36 @@ mlxsw_sp_fid_8021d_pgt_size(const struct mlxsw_sp_fid_family *fid_family,
368370 return 0 ;
369371}
370372
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+
371403static u16
372404mlxsw_sp_fid_pgt_base_ctl (const struct mlxsw_sp_fid_family * fid_family ,
373405 const struct mlxsw_sp_flood_table * flood_table )
@@ -519,6 +551,18 @@ static void mlxsw_sp_fid_fid_pack_cff(char *sfmr_pl,
519551 fid_family -> flood_profile -> profile_id );
520552}
521553
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+
522566static int mlxsw_sp_fid_op (const struct mlxsw_sp_fid * fid , bool valid )
523567{
524568 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 = {
12481292 .profile_id = MLXSW_SP_FID_FLOOD_PROFILE_ID_BRIDGE ,
12491293};
12501294
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+
12511313static bool
12521314mlxsw_sp_fid_8021q_compare (const struct mlxsw_sp_fid * fid , const void * arg )
12531315{
@@ -1271,6 +1333,29 @@ static int mlxsw_sp_fid_rfid_setup_ctl(struct mlxsw_sp_fid *fid,
12711333 return 0 ;
12721334}
12731335
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+
12741359static int mlxsw_sp_fid_rfid_configure (struct mlxsw_sp_fid * fid )
12751360{
12761361 return mlxsw_sp_fid_op (fid , true);
@@ -1410,6 +1495,139 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_rfid_ops_ctl = {
14101495 .fid_pack = mlxsw_sp_fid_pack_ctl ,
14111496};
14121497
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+
14131631static int mlxsw_sp_fid_dummy_setup (struct mlxsw_sp_fid * fid , const void * arg )
14141632{
14151633 fid -> fid_offset = 0 ;
@@ -1726,10 +1944,22 @@ static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_family_cff = {
17261944 .smpe_index_valid = true,
17271945};
17281946
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+
17291958static const struct mlxsw_sp_fid_family * mlxsw_sp2_fid_family_arr_cff [] = {
17301959 [MLXSW_SP_FID_TYPE_8021Q ] = & mlxsw_sp2_fid_8021q_family_cff ,
17311960 [MLXSW_SP_FID_TYPE_8021D ] = & mlxsw_sp2_fid_8021d_family_cff ,
17321961 [MLXSW_SP_FID_TYPE_DUMMY ] = & mlxsw_sp2_fid_dummy_family ,
1962+ [MLXSW_SP_FID_TYPE_RFID ] = & mlxsw_sp_fid_rfid_family_cff ,
17331963};
17341964
17351965static 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,
21802410static const
21812411struct mlxsw_sp_fid_flood_profile * mlxsw_sp_fid_flood_profiles [] = {
21822412 & mlxsw_sp_fid_8021d_flood_profile ,
2413+ & mlxsw_sp_fid_rsp_flood_profile_cff ,
21832414};
21842415
21852416static int
0 commit comments