@@ -1472,6 +1472,7 @@ struct mlxsw_sp_qevent_binding {
14721472 u32 handle ;
14731473 int tclass_num ;
14741474 enum mlxsw_sp_span_trigger span_trigger ;
1475+ unsigned int action_mask ;
14751476};
14761477
14771478static LIST_HEAD (mlxsw_sp_qevent_block_cb_list );
@@ -1482,27 +1483,30 @@ static int mlxsw_sp_qevent_span_configure(struct mlxsw_sp *mlxsw_sp,
14821483 const struct mlxsw_sp_span_agent_parms * agent_parms ,
14831484 int * p_span_id )
14841485{
1486+ enum mlxsw_sp_span_trigger span_trigger = qevent_binding -> span_trigger ;
14851487 struct mlxsw_sp_port * mlxsw_sp_port = qevent_binding -> mlxsw_sp_port ;
14861488 struct mlxsw_sp_span_trigger_parms trigger_parms = {};
1489+ bool ingress ;
14871490 int span_id ;
14881491 int err ;
14891492
14901493 err = mlxsw_sp_span_agent_get (mlxsw_sp , & span_id , agent_parms );
14911494 if (err )
14921495 return err ;
14931496
1494- err = mlxsw_sp_span_analyzed_port_get (mlxsw_sp_port , true);
1497+ ingress = mlxsw_sp_span_trigger_is_ingress (span_trigger );
1498+ err = mlxsw_sp_span_analyzed_port_get (mlxsw_sp_port , ingress );
14951499 if (err )
14961500 goto err_analyzed_port_get ;
14971501
14981502 trigger_parms .span_id = span_id ;
14991503 trigger_parms .probability_rate = 1 ;
1500- err = mlxsw_sp_span_agent_bind (mlxsw_sp , qevent_binding -> span_trigger , mlxsw_sp_port ,
1504+ err = mlxsw_sp_span_agent_bind (mlxsw_sp , span_trigger , mlxsw_sp_port ,
15011505 & trigger_parms );
15021506 if (err )
15031507 goto err_agent_bind ;
15041508
1505- err = mlxsw_sp_span_trigger_enable (mlxsw_sp_port , qevent_binding -> span_trigger ,
1509+ err = mlxsw_sp_span_trigger_enable (mlxsw_sp_port , span_trigger ,
15061510 qevent_binding -> tclass_num );
15071511 if (err )
15081512 goto err_trigger_enable ;
@@ -1511,10 +1515,10 @@ static int mlxsw_sp_qevent_span_configure(struct mlxsw_sp *mlxsw_sp,
15111515 return 0 ;
15121516
15131517err_trigger_enable :
1514- mlxsw_sp_span_agent_unbind (mlxsw_sp , qevent_binding -> span_trigger , mlxsw_sp_port ,
1518+ mlxsw_sp_span_agent_unbind (mlxsw_sp , span_trigger , mlxsw_sp_port ,
15151519 & trigger_parms );
15161520err_agent_bind :
1517- mlxsw_sp_span_analyzed_port_put (mlxsw_sp_port , true );
1521+ mlxsw_sp_span_analyzed_port_put (mlxsw_sp_port , ingress );
15181522err_analyzed_port_get :
15191523 mlxsw_sp_span_agent_put (mlxsw_sp , span_id );
15201524 return err ;
@@ -1524,16 +1528,20 @@ static void mlxsw_sp_qevent_span_deconfigure(struct mlxsw_sp *mlxsw_sp,
15241528 struct mlxsw_sp_qevent_binding * qevent_binding ,
15251529 int span_id )
15261530{
1531+ enum mlxsw_sp_span_trigger span_trigger = qevent_binding -> span_trigger ;
15271532 struct mlxsw_sp_port * mlxsw_sp_port = qevent_binding -> mlxsw_sp_port ;
15281533 struct mlxsw_sp_span_trigger_parms trigger_parms = {
15291534 .span_id = span_id ,
15301535 };
1536+ bool ingress ;
15311537
1532- mlxsw_sp_span_trigger_disable (mlxsw_sp_port , qevent_binding -> span_trigger ,
1538+ ingress = mlxsw_sp_span_trigger_is_ingress (span_trigger );
1539+
1540+ mlxsw_sp_span_trigger_disable (mlxsw_sp_port , span_trigger ,
15331541 qevent_binding -> tclass_num );
1534- mlxsw_sp_span_agent_unbind (mlxsw_sp , qevent_binding -> span_trigger , mlxsw_sp_port ,
1542+ mlxsw_sp_span_agent_unbind (mlxsw_sp , span_trigger , mlxsw_sp_port ,
15351543 & trigger_parms );
1536- mlxsw_sp_span_analyzed_port_put (mlxsw_sp_port , true );
1544+ mlxsw_sp_span_analyzed_port_put (mlxsw_sp_port , ingress );
15371545 mlxsw_sp_span_agent_put (mlxsw_sp , span_id );
15381546}
15391547
@@ -1583,10 +1591,17 @@ static void mlxsw_sp_qevent_trap_deconfigure(struct mlxsw_sp *mlxsw_sp,
15831591 mlxsw_sp_qevent_span_deconfigure (mlxsw_sp , qevent_binding , mall_entry -> trap .span_id );
15841592}
15851593
1586- static int mlxsw_sp_qevent_entry_configure (struct mlxsw_sp * mlxsw_sp ,
1587- struct mlxsw_sp_mall_entry * mall_entry ,
1588- struct mlxsw_sp_qevent_binding * qevent_binding )
1594+ static int
1595+ mlxsw_sp_qevent_entry_configure (struct mlxsw_sp * mlxsw_sp ,
1596+ struct mlxsw_sp_mall_entry * mall_entry ,
1597+ struct mlxsw_sp_qevent_binding * qevent_binding ,
1598+ struct netlink_ext_ack * extack )
15891599{
1600+ if (!(BIT (mall_entry -> type ) & qevent_binding -> action_mask )) {
1601+ NL_SET_ERR_MSG (extack , "Action not supported at this qevent" );
1602+ return - EOPNOTSUPP ;
1603+ }
1604+
15901605 switch (mall_entry -> type ) {
15911606 case MLXSW_SP_MALL_ACTION_TYPE_MIRROR :
15921607 return mlxsw_sp_qevent_mirror_configure (mlxsw_sp , mall_entry , qevent_binding );
@@ -1614,15 +1629,17 @@ static void mlxsw_sp_qevent_entry_deconfigure(struct mlxsw_sp *mlxsw_sp,
16141629 }
16151630}
16161631
1617- static int mlxsw_sp_qevent_binding_configure (struct mlxsw_sp_qevent_block * qevent_block ,
1618- struct mlxsw_sp_qevent_binding * qevent_binding )
1632+ static int
1633+ mlxsw_sp_qevent_binding_configure (struct mlxsw_sp_qevent_block * qevent_block ,
1634+ struct mlxsw_sp_qevent_binding * qevent_binding ,
1635+ struct netlink_ext_ack * extack )
16191636{
16201637 struct mlxsw_sp_mall_entry * mall_entry ;
16211638 int err ;
16221639
16231640 list_for_each_entry (mall_entry , & qevent_block -> mall_entry_list , list ) {
16241641 err = mlxsw_sp_qevent_entry_configure (qevent_block -> mlxsw_sp , mall_entry ,
1625- qevent_binding );
1642+ qevent_binding , extack );
16261643 if (err )
16271644 goto err_entry_configure ;
16281645 }
@@ -1646,13 +1663,17 @@ static void mlxsw_sp_qevent_binding_deconfigure(struct mlxsw_sp_qevent_block *qe
16461663 qevent_binding );
16471664}
16481665
1649- static int mlxsw_sp_qevent_block_configure (struct mlxsw_sp_qevent_block * qevent_block )
1666+ static int
1667+ mlxsw_sp_qevent_block_configure (struct mlxsw_sp_qevent_block * qevent_block ,
1668+ struct netlink_ext_ack * extack )
16501669{
16511670 struct mlxsw_sp_qevent_binding * qevent_binding ;
16521671 int err ;
16531672
16541673 list_for_each_entry (qevent_binding , & qevent_block -> binding_list , list ) {
1655- err = mlxsw_sp_qevent_binding_configure (qevent_block , qevent_binding );
1674+ err = mlxsw_sp_qevent_binding_configure (qevent_block ,
1675+ qevent_binding ,
1676+ extack );
16561677 if (err )
16571678 goto err_binding_configure ;
16581679 }
@@ -1737,7 +1758,7 @@ static int mlxsw_sp_qevent_mall_replace(struct mlxsw_sp *mlxsw_sp,
17371758
17381759 list_add_tail (& mall_entry -> list , & qevent_block -> mall_entry_list );
17391760
1740- err = mlxsw_sp_qevent_block_configure (qevent_block );
1761+ err = mlxsw_sp_qevent_block_configure (qevent_block , f -> common . extack );
17411762 if (err )
17421763 goto err_block_configure ;
17431764
@@ -1825,7 +1846,8 @@ static void mlxsw_sp_qevent_block_release(void *cb_priv)
18251846
18261847static struct mlxsw_sp_qevent_binding *
18271848mlxsw_sp_qevent_binding_create (struct mlxsw_sp_port * mlxsw_sp_port , u32 handle , int tclass_num ,
1828- enum mlxsw_sp_span_trigger span_trigger )
1849+ enum mlxsw_sp_span_trigger span_trigger ,
1850+ unsigned int action_mask )
18291851{
18301852 struct mlxsw_sp_qevent_binding * binding ;
18311853
@@ -1837,6 +1859,7 @@ mlxsw_sp_qevent_binding_create(struct mlxsw_sp_port *mlxsw_sp_port, u32 handle,
18371859 binding -> handle = handle ;
18381860 binding -> tclass_num = tclass_num ;
18391861 binding -> span_trigger = span_trigger ;
1862+ binding -> action_mask = action_mask ;
18401863 return binding ;
18411864}
18421865
@@ -1862,9 +1885,11 @@ mlxsw_sp_qevent_binding_lookup(struct mlxsw_sp_qevent_block *block,
18621885 return NULL ;
18631886}
18641887
1865- static int mlxsw_sp_setup_tc_block_qevent_bind (struct mlxsw_sp_port * mlxsw_sp_port ,
1866- struct flow_block_offload * f ,
1867- enum mlxsw_sp_span_trigger span_trigger )
1888+ static int
1889+ mlxsw_sp_setup_tc_block_qevent_bind (struct mlxsw_sp_port * mlxsw_sp_port ,
1890+ struct flow_block_offload * f ,
1891+ enum mlxsw_sp_span_trigger span_trigger ,
1892+ unsigned int action_mask )
18681893{
18691894 struct mlxsw_sp * mlxsw_sp = mlxsw_sp_port -> mlxsw_sp ;
18701895 struct mlxsw_sp_qevent_binding * qevent_binding ;
@@ -1904,14 +1929,18 @@ static int mlxsw_sp_setup_tc_block_qevent_bind(struct mlxsw_sp_port *mlxsw_sp_po
19041929 goto err_binding_exists ;
19051930 }
19061931
1907- qevent_binding = mlxsw_sp_qevent_binding_create (mlxsw_sp_port , f -> sch -> handle ,
1908- qdisc -> tclass_num , span_trigger );
1932+ qevent_binding = mlxsw_sp_qevent_binding_create (mlxsw_sp_port ,
1933+ f -> sch -> handle ,
1934+ qdisc -> tclass_num ,
1935+ span_trigger ,
1936+ action_mask );
19091937 if (IS_ERR (qevent_binding )) {
19101938 err = PTR_ERR (qevent_binding );
19111939 goto err_binding_create ;
19121940 }
19131941
1914- err = mlxsw_sp_qevent_binding_configure (qevent_block , qevent_binding );
1942+ err = mlxsw_sp_qevent_binding_configure (qevent_block , qevent_binding ,
1943+ f -> extack );
19151944 if (err )
19161945 goto err_binding_configure ;
19171946
@@ -1963,15 +1992,19 @@ static void mlxsw_sp_setup_tc_block_qevent_unbind(struct mlxsw_sp_port *mlxsw_sp
19631992 }
19641993}
19651994
1966- static int mlxsw_sp_setup_tc_block_qevent (struct mlxsw_sp_port * mlxsw_sp_port ,
1967- struct flow_block_offload * f ,
1968- enum mlxsw_sp_span_trigger span_trigger )
1995+ static int
1996+ mlxsw_sp_setup_tc_block_qevent (struct mlxsw_sp_port * mlxsw_sp_port ,
1997+ struct flow_block_offload * f ,
1998+ enum mlxsw_sp_span_trigger span_trigger ,
1999+ unsigned int action_mask )
19692000{
19702001 f -> driver_block_list = & mlxsw_sp_qevent_block_cb_list ;
19712002
19722003 switch (f -> command ) {
19732004 case FLOW_BLOCK_BIND :
1974- return mlxsw_sp_setup_tc_block_qevent_bind (mlxsw_sp_port , f , span_trigger );
2005+ return mlxsw_sp_setup_tc_block_qevent_bind (mlxsw_sp_port , f ,
2006+ span_trigger ,
2007+ action_mask );
19752008 case FLOW_BLOCK_UNBIND :
19762009 mlxsw_sp_setup_tc_block_qevent_unbind (mlxsw_sp_port , f , span_trigger );
19772010 return 0 ;
@@ -1983,7 +2016,22 @@ static int mlxsw_sp_setup_tc_block_qevent(struct mlxsw_sp_port *mlxsw_sp_port,
19832016int mlxsw_sp_setup_tc_block_qevent_early_drop (struct mlxsw_sp_port * mlxsw_sp_port ,
19842017 struct flow_block_offload * f )
19852018{
1986- return mlxsw_sp_setup_tc_block_qevent (mlxsw_sp_port , f , MLXSW_SP_SPAN_TRIGGER_EARLY_DROP );
2019+ unsigned int action_mask = BIT (MLXSW_SP_MALL_ACTION_TYPE_MIRROR ) |
2020+ BIT (MLXSW_SP_MALL_ACTION_TYPE_TRAP );
2021+
2022+ return mlxsw_sp_setup_tc_block_qevent (mlxsw_sp_port , f ,
2023+ MLXSW_SP_SPAN_TRIGGER_EARLY_DROP ,
2024+ action_mask );
2025+ }
2026+
2027+ int mlxsw_sp_setup_tc_block_qevent_mark (struct mlxsw_sp_port * mlxsw_sp_port ,
2028+ struct flow_block_offload * f )
2029+ {
2030+ unsigned int action_mask = BIT (MLXSW_SP_MALL_ACTION_TYPE_MIRROR );
2031+
2032+ return mlxsw_sp_setup_tc_block_qevent (mlxsw_sp_port , f ,
2033+ MLXSW_SP_SPAN_TRIGGER_ECN ,
2034+ action_mask );
19872035}
19882036
19892037int mlxsw_sp_tc_qdisc_init (struct mlxsw_sp_port * mlxsw_sp_port )
0 commit comments