3535#include "en/params.h"
3636#include "en/xsk/pool.h"
3737
38+ static int flow_type_to_traffic_type (u32 flow_type );
39+
40+ static u32 flow_type_mask (u32 flow_type )
41+ {
42+ return flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS );
43+ }
44+
3845struct mlx5e_ethtool_rule {
3946 struct list_head list ;
4047 struct ethtool_rx_flow_spec flow_spec ;
4148 struct mlx5_flow_handle * rule ;
4249 struct mlx5e_ethtool_table * eth_ft ;
50+ struct mlx5e_rss * rss ;
4351};
4452
4553static void put_flow_table (struct mlx5e_ethtool_table * eth_ft )
@@ -66,7 +74,7 @@ static struct mlx5e_ethtool_table *get_flow_table(struct mlx5e_priv *priv,
6674 int table_size ;
6775 int prio ;
6876
69- switch (fs -> flow_type & ~( FLOW_EXT | FLOW_MAC_EXT )) {
77+ switch (flow_type_mask ( fs -> flow_type )) {
7078 case TCP_V4_FLOW :
7179 case UDP_V4_FLOW :
7280 case TCP_V6_FLOW :
@@ -329,7 +337,7 @@ static int set_flow_attrs(u32 *match_c, u32 *match_v,
329337 outer_headers );
330338 void * outer_headers_v = MLX5_ADDR_OF (fte_match_param , match_v ,
331339 outer_headers );
332- u32 flow_type = fs -> flow_type & ~( FLOW_EXT | FLOW_MAC_EXT );
340+ u32 flow_type = flow_type_mask ( fs -> flow_type );
333341
334342 switch (flow_type ) {
335343 case TCP_V4_FLOW :
@@ -397,10 +405,53 @@ static bool outer_header_zero(u32 *match_criteria)
397405 size - 1 );
398406}
399407
408+ static int flow_get_tirn (struct mlx5e_priv * priv ,
409+ struct mlx5e_ethtool_rule * eth_rule ,
410+ struct ethtool_rx_flow_spec * fs ,
411+ u32 rss_context , u32 * tirn )
412+ {
413+ if (fs -> flow_type & FLOW_RSS ) {
414+ struct mlx5e_lro_param lro_param ;
415+ struct mlx5e_rss * rss ;
416+ u32 flow_type ;
417+ int err ;
418+ int tt ;
419+
420+ rss = mlx5e_rx_res_rss_get (priv -> rx_res , rss_context );
421+ if (!rss )
422+ return - ENOENT ;
423+
424+ flow_type = flow_type_mask (fs -> flow_type );
425+ tt = flow_type_to_traffic_type (flow_type );
426+ if (tt < 0 )
427+ return - EINVAL ;
428+
429+ lro_param = mlx5e_get_lro_param (& priv -> channels .params );
430+ err = mlx5e_rss_obtain_tirn (rss , tt , & lro_param , false, tirn );
431+ if (err )
432+ return err ;
433+ eth_rule -> rss = rss ;
434+ mlx5e_rss_refcnt_inc (eth_rule -> rss );
435+ } else {
436+ struct mlx5e_params * params = & priv -> channels .params ;
437+ enum mlx5e_rq_group group ;
438+ u16 ix ;
439+
440+ mlx5e_qid_get_ch_and_group (params , fs -> ring_cookie , & ix , & group );
441+
442+ * tirn = group == MLX5E_RQ_GROUP_XSK ?
443+ mlx5e_rx_res_get_tirn_xsk (priv -> rx_res , ix ) :
444+ mlx5e_rx_res_get_tirn_direct (priv -> rx_res , ix );
445+ }
446+
447+ return 0 ;
448+ }
449+
400450static struct mlx5_flow_handle *
401451add_ethtool_flow_rule (struct mlx5e_priv * priv ,
452+ struct mlx5e_ethtool_rule * eth_rule ,
402453 struct mlx5_flow_table * ft ,
403- struct ethtool_rx_flow_spec * fs )
454+ struct ethtool_rx_flow_spec * fs , u32 rss_context )
404455{
405456 struct mlx5_flow_act flow_act = { .flags = FLOW_ACT_NO_APPEND };
406457 struct mlx5_flow_destination * dst = NULL ;
@@ -419,23 +470,17 @@ add_ethtool_flow_rule(struct mlx5e_priv *priv,
419470 if (fs -> ring_cookie == RX_CLS_FLOW_DISC ) {
420471 flow_act .action = MLX5_FLOW_CONTEXT_ACTION_DROP ;
421472 } else {
422- struct mlx5e_params * params = & priv -> channels .params ;
423- enum mlx5e_rq_group group ;
424- u16 ix ;
425-
426- mlx5e_qid_get_ch_and_group (params , fs -> ring_cookie , & ix , & group );
427-
428473 dst = kzalloc (sizeof (* dst ), GFP_KERNEL );
429474 if (!dst ) {
430475 err = - ENOMEM ;
431476 goto free ;
432477 }
433478
479+ err = flow_get_tirn (priv , eth_rule , fs , rss_context , & dst -> tir_num );
480+ if (err )
481+ goto free ;
482+
434483 dst -> type = MLX5_FLOW_DESTINATION_TYPE_TIR ;
435- if (group == MLX5E_RQ_GROUP_XSK )
436- dst -> tir_num = mlx5e_rx_res_get_tirn_xsk (priv -> rx_res , ix );
437- else
438- dst -> tir_num = mlx5e_rx_res_get_tirn_direct (priv -> rx_res , ix );
439484 flow_act .action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ;
440485 }
441486
@@ -459,6 +504,8 @@ static void del_ethtool_rule(struct mlx5e_priv *priv,
459504{
460505 if (eth_rule -> rule )
461506 mlx5_del_flow_rules (eth_rule -> rule );
507+ if (eth_rule -> rss )
508+ mlx5e_rss_refcnt_dec (eth_rule -> rss );
462509 list_del (& eth_rule -> list );
463510 priv -> fs .ethtool .tot_num_rules -- ;
464511 put_flow_table (eth_rule -> eth_ft );
@@ -619,7 +666,7 @@ static int validate_flow(struct mlx5e_priv *priv,
619666 fs -> ring_cookie ))
620667 return - EINVAL ;
621668
622- switch (fs -> flow_type & ~( FLOW_EXT | FLOW_MAC_EXT )) {
669+ switch (flow_type_mask ( fs -> flow_type )) {
623670 case ETHER_FLOW :
624671 num_tuples += validate_ethter (fs );
625672 break ;
@@ -668,7 +715,7 @@ static int validate_flow(struct mlx5e_priv *priv,
668715
669716static int
670717mlx5e_ethtool_flow_replace (struct mlx5e_priv * priv ,
671- struct ethtool_rx_flow_spec * fs )
718+ struct ethtool_rx_flow_spec * fs , u32 rss_context )
672719{
673720 struct mlx5e_ethtool_table * eth_ft ;
674721 struct mlx5e_ethtool_rule * eth_rule ;
@@ -699,7 +746,7 @@ mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv,
699746 err = - EINVAL ;
700747 goto del_ethtool_rule ;
701748 }
702- rule = add_ethtool_flow_rule (priv , eth_ft -> ft , fs );
749+ rule = add_ethtool_flow_rule (priv , eth_rule , eth_ft -> ft , fs , rss_context );
703750 if (IS_ERR (rule )) {
704751 err = PTR_ERR (rule );
705752 goto del_ethtool_rule ;
@@ -745,10 +792,20 @@ mlx5e_ethtool_get_flow(struct mlx5e_priv *priv,
745792 return - EINVAL ;
746793
747794 list_for_each_entry (eth_rule , & priv -> fs .ethtool .rules , list ) {
748- if (eth_rule -> flow_spec .location == location ) {
749- info -> fs = eth_rule -> flow_spec ;
795+ int index ;
796+
797+ if (eth_rule -> flow_spec .location != location )
798+ continue ;
799+ if (!info )
750800 return 0 ;
751- }
801+ info -> fs = eth_rule -> flow_spec ;
802+ if (!eth_rule -> rss )
803+ return 0 ;
804+ index = mlx5e_rx_res_rss_index (priv -> rx_res , eth_rule -> rss );
805+ if (index < 0 )
806+ return index ;
807+ info -> rss_context = index ;
808+ return 0 ;
752809 }
753810
754811 return - ENOENT ;
@@ -764,7 +821,7 @@ mlx5e_ethtool_get_all_flows(struct mlx5e_priv *priv,
764821
765822 info -> data = MAX_NUM_OF_ETHTOOL_RULES ;
766823 while ((!err || err == - ENOENT ) && idx < info -> rule_cnt ) {
767- err = mlx5e_ethtool_get_flow (priv , info , location );
824+ err = mlx5e_ethtool_get_flow (priv , NULL , location );
768825 if (!err )
769826 rule_locs [idx ++ ] = location ;
770827 location ++ ;
@@ -887,7 +944,7 @@ int mlx5e_ethtool_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
887944
888945 switch (cmd -> cmd ) {
889946 case ETHTOOL_SRXCLSRLINS :
890- err = mlx5e_ethtool_flow_replace (priv , & cmd -> fs );
947+ err = mlx5e_ethtool_flow_replace (priv , & cmd -> fs , cmd -> rss_context );
891948 break ;
892949 case ETHTOOL_SRXCLSRLDEL :
893950 err = mlx5e_ethtool_flow_remove (priv , cmd -> fs .location );
0 commit comments