@@ -46,7 +46,6 @@ static void mlx5e_del_l2_flow_rule(struct mlx5e_priv *priv,
4646enum {
4747 MLX5E_FULLMATCH = 0 ,
4848 MLX5E_ALLMULTI = 1 ,
49- MLX5E_PROMISC = 2 ,
5049};
5150
5251enum {
@@ -596,6 +595,83 @@ static void mlx5e_handle_netdev_addr(struct mlx5e_priv *priv)
596595 mlx5e_apply_netdev_addr (priv );
597596}
598597
598+ #define MLX5E_PROMISC_GROUP0_SIZE BIT(0)
599+ #define MLX5E_PROMISC_TABLE_SIZE MLX5E_PROMISC_GROUP0_SIZE
600+
601+ static int mlx5e_add_promisc_rule (struct mlx5e_priv * priv )
602+ {
603+ struct mlx5_flow_table * ft = priv -> fs .promisc .ft .t ;
604+ struct mlx5_flow_destination dest = {};
605+ struct mlx5_flow_handle * * rule_p ;
606+ MLX5_DECLARE_FLOW_ACT (flow_act );
607+ struct mlx5_flow_spec * spec ;
608+ int err = 0 ;
609+
610+ spec = kvzalloc (sizeof (* spec ), GFP_KERNEL );
611+ if (!spec )
612+ return - ENOMEM ;
613+ dest .type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE ;
614+ dest .ft = priv -> fs .ttc .ft .t ;
615+
616+ rule_p = & priv -> fs .promisc .rule ;
617+ * rule_p = mlx5_add_flow_rules (ft , spec , & flow_act , & dest , 1 );
618+ if (IS_ERR (* rule_p )) {
619+ err = PTR_ERR (* rule_p );
620+ * rule_p = NULL ;
621+ netdev_err (priv -> netdev , "%s: add promiscuous rule failed\n" , __func__ );
622+ }
623+ kvfree (spec );
624+ return err ;
625+ }
626+
627+ static int mlx5e_create_promisc_table (struct mlx5e_priv * priv )
628+ {
629+ struct mlx5e_flow_table * ft = & priv -> fs .promisc .ft ;
630+ struct mlx5_flow_table_attr ft_attr = {};
631+ int err ;
632+
633+ ft_attr .max_fte = MLX5E_PROMISC_TABLE_SIZE ;
634+ ft_attr .autogroup .max_num_groups = 1 ;
635+ ft_attr .level = MLX5E_PROMISC_FT_LEVEL ;
636+ ft_attr .prio = MLX5E_NIC_PRIO ;
637+
638+ ft -> t = mlx5_create_auto_grouped_flow_table (priv -> fs .ns , & ft_attr );
639+ if (IS_ERR (ft -> t )) {
640+ err = PTR_ERR (ft -> t );
641+ netdev_err (priv -> netdev , "fail to create promisc table err=%d\n" , err );
642+ return err ;
643+ }
644+
645+ err = mlx5e_add_promisc_rule (priv );
646+ if (err )
647+ goto err_destroy_promisc_table ;
648+
649+ return 0 ;
650+
651+ err_destroy_promisc_table :
652+ mlx5_destroy_flow_table (ft -> t );
653+ ft -> t = NULL ;
654+
655+ return err ;
656+ }
657+
658+ static void mlx5e_del_promisc_rule (struct mlx5e_priv * priv )
659+ {
660+ if (WARN (!priv -> fs .promisc .rule , "Trying to remove non-existing promiscuous rule" ))
661+ return ;
662+ mlx5_del_flow_rules (priv -> fs .promisc .rule );
663+ priv -> fs .promisc .rule = NULL ;
664+ }
665+
666+ static void mlx5e_destroy_promisc_table (struct mlx5e_priv * priv )
667+ {
668+ if (WARN (!priv -> fs .promisc .ft .t , "Trying to remove non-existing promiscuous table" ))
669+ return ;
670+ mlx5e_del_promisc_rule (priv );
671+ mlx5_destroy_flow_table (priv -> fs .promisc .ft .t );
672+ priv -> fs .promisc .ft .t = NULL ;
673+ }
674+
599675void mlx5e_set_rx_mode_work (struct work_struct * work )
600676{
601677 struct mlx5e_priv * priv = container_of (work , struct mlx5e_priv ,
@@ -615,14 +691,15 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
615691 bool disable_allmulti = ea -> allmulti_enabled && !allmulti_enabled ;
616692 bool enable_broadcast = !ea -> broadcast_enabled && broadcast_enabled ;
617693 bool disable_broadcast = ea -> broadcast_enabled && !broadcast_enabled ;
694+ int err ;
618695
619696 if (enable_promisc ) {
620- if (!priv -> channels .params .vlan_strip_disable )
697+ err = mlx5e_create_promisc_table (priv );
698+ if (err )
699+ enable_promisc = false;
700+ if (!priv -> channels .params .vlan_strip_disable && !err )
621701 netdev_warn_once (ndev ,
622702 "S-tagged traffic will be dropped while C-tag vlan stripping is enabled\n" );
623- mlx5e_add_l2_flow_rule (priv , & ea -> promisc , MLX5E_PROMISC );
624- if (!priv -> fs .vlan .cvlan_filter_disabled )
625- mlx5e_add_any_vid_rules (priv );
626703 }
627704 if (enable_allmulti )
628705 mlx5e_add_l2_flow_rule (priv , & ea -> allmulti , MLX5E_ALLMULTI );
@@ -635,11 +712,8 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
635712 mlx5e_del_l2_flow_rule (priv , & ea -> broadcast );
636713 if (disable_allmulti )
637714 mlx5e_del_l2_flow_rule (priv , & ea -> allmulti );
638- if (disable_promisc ) {
639- if (!priv -> fs .vlan .cvlan_filter_disabled )
640- mlx5e_del_any_vid_rules (priv );
641- mlx5e_del_l2_flow_rule (priv , & ea -> promisc );
642- }
715+ if (disable_promisc )
716+ mlx5e_destroy_promisc_table (priv );
643717
644718 ea -> promisc_enabled = promisc_enabled ;
645719 ea -> allmulti_enabled = allmulti_enabled ;
@@ -1306,9 +1380,6 @@ static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
13061380 mc_dmac [0 ] = 0x01 ;
13071381 mv_dmac [0 ] = 0x01 ;
13081382 break ;
1309-
1310- case MLX5E_PROMISC :
1311- break ;
13121383 }
13131384
13141385 ai -> rule = mlx5_add_flow_rules (ft , spec , & flow_act , & dest , 1 );
@@ -1324,13 +1395,11 @@ static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
13241395 return err ;
13251396}
13261397
1327- #define MLX5E_NUM_L2_GROUPS 3
1328- #define MLX5E_L2_GROUP1_SIZE BIT(0)
1329- #define MLX5E_L2_GROUP2_SIZE BIT(15)
1330- #define MLX5E_L2_GROUP3_SIZE BIT(0)
1398+ #define MLX5E_NUM_L2_GROUPS 2
1399+ #define MLX5E_L2_GROUP1_SIZE BIT(15)
1400+ #define MLX5E_L2_GROUP2_SIZE BIT(0)
13311401#define MLX5E_L2_TABLE_SIZE (MLX5E_L2_GROUP1_SIZE +\
1332- MLX5E_L2_GROUP2_SIZE +\
1333- MLX5E_L2_GROUP3_SIZE)
1402+ MLX5E_L2_GROUP2_SIZE)
13341403static int mlx5e_create_l2_table_groups (struct mlx5e_l2_table * l2_table )
13351404{
13361405 int inlen = MLX5_ST_SZ_BYTES (create_flow_group_in );
@@ -1353,20 +1422,11 @@ static int mlx5e_create_l2_table_groups(struct mlx5e_l2_table *l2_table)
13531422 mc = MLX5_ADDR_OF (create_flow_group_in , in , match_criteria );
13541423 mc_dmac = MLX5_ADDR_OF (fte_match_param , mc ,
13551424 outer_headers .dmac_47_16 );
1356- /* Flow Group for promiscuous */
1357- MLX5_SET_CFG (in , start_flow_index , ix );
1358- ix += MLX5E_L2_GROUP1_SIZE ;
1359- MLX5_SET_CFG (in , end_flow_index , ix - 1 );
1360- ft -> g [ft -> num_groups ] = mlx5_create_flow_group (ft -> t , in );
1361- if (IS_ERR (ft -> g [ft -> num_groups ]))
1362- goto err_destroy_groups ;
1363- ft -> num_groups ++ ;
1364-
13651425 /* Flow Group for full match */
13661426 eth_broadcast_addr (mc_dmac );
13671427 MLX5_SET_CFG (in , match_criteria_enable , MLX5_MATCH_OUTER_HEADERS );
13681428 MLX5_SET_CFG (in , start_flow_index , ix );
1369- ix += MLX5E_L2_GROUP2_SIZE ;
1429+ ix += MLX5E_L2_GROUP1_SIZE ;
13701430 MLX5_SET_CFG (in , end_flow_index , ix - 1 );
13711431 ft -> g [ft -> num_groups ] = mlx5_create_flow_group (ft -> t , in );
13721432 if (IS_ERR (ft -> g [ft -> num_groups ]))
@@ -1377,7 +1437,7 @@ static int mlx5e_create_l2_table_groups(struct mlx5e_l2_table *l2_table)
13771437 eth_zero_addr (mc_dmac );
13781438 mc_dmac [0 ] = 0x01 ;
13791439 MLX5_SET_CFG (in , start_flow_index , ix );
1380- ix += MLX5E_L2_GROUP3_SIZE ;
1440+ ix += MLX5E_L2_GROUP2_SIZE ;
13811441 MLX5_SET_CFG (in , end_flow_index , ix - 1 );
13821442 ft -> g [ft -> num_groups ] = mlx5_create_flow_group (ft -> t , in );
13831443 if (IS_ERR (ft -> g [ft -> num_groups ]))
0 commit comments