@@ -155,6 +155,7 @@ enum mlx5e_vlan_rule_type {
155155 MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID ,
156156 MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID ,
157157 MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID ,
158+ MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID ,
158159};
159160
160161static int __mlx5e_add_vlan_rule (struct mlx5e_priv * priv ,
@@ -174,6 +175,10 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
174175
175176 switch (rule_type ) {
176177 case MLX5E_VLAN_RULE_TYPE_UNTAGGED :
178+ /* cvlan_tag enabled in match criteria and
179+ * disabled in match value means both S & C tags
180+ * don't exist (untagged of both)
181+ */
177182 rule_p = & priv -> fs .vlan .untagged_rule ;
178183 MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
179184 outer_headers .cvlan_tag );
@@ -190,6 +195,16 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
190195 outer_headers .svlan_tag );
191196 MLX5_SET (fte_match_param , spec -> match_value , outer_headers .svlan_tag , 1 );
192197 break ;
198+ case MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID :
199+ rule_p = & priv -> fs .vlan .active_svlans_rule [vid ];
200+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
201+ outer_headers .svlan_tag );
202+ MLX5_SET (fte_match_param , spec -> match_value , outer_headers .svlan_tag , 1 );
203+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
204+ outer_headers .first_vid );
205+ MLX5_SET (fte_match_param , spec -> match_value , outer_headers .first_vid ,
206+ vid );
207+ break ;
193208 default : /* MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID */
194209 rule_p = & priv -> fs .vlan .active_cvlans_rule [vid ];
195210 MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
@@ -255,6 +270,12 @@ static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv,
255270 priv -> fs .vlan .any_svlan_rule = NULL ;
256271 }
257272 break ;
273+ case MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID :
274+ if (priv -> fs .vlan .active_svlans_rule [vid ]) {
275+ mlx5_del_flow_rules (priv -> fs .vlan .active_svlans_rule [vid ]);
276+ priv -> fs .vlan .active_svlans_rule [vid ] = NULL ;
277+ }
278+ break ;
258279 case MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID :
259280 mlx5e_vport_context_update_vlans (priv );
260281 if (priv -> fs .vlan .active_cvlans_rule [vid ]) {
@@ -305,10 +326,8 @@ void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv)
305326 mlx5e_add_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID , 0 );
306327}
307328
308- int mlx5e_vlan_rx_add_vid (struct net_device * dev , __always_unused __be16 proto ,
309- u16 vid )
329+ static int mlx5e_vlan_rx_add_cvid (struct mlx5e_priv * priv , u16 vid )
310330{
311- struct mlx5e_priv * priv = netdev_priv (dev );
312331 int err ;
313332
314333 set_bit (vid , priv -> fs .vlan .active_cvlans );
@@ -320,14 +339,48 @@ int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto,
320339 return err ;
321340}
322341
323- int mlx5e_vlan_rx_kill_vid (struct net_device * dev , __always_unused __be16 proto ,
324- u16 vid )
342+ static int mlx5e_vlan_rx_add_svid (struct mlx5e_priv * priv , u16 vid )
343+ {
344+ struct net_device * netdev = priv -> netdev ;
345+ int err ;
346+
347+ set_bit (vid , priv -> fs .vlan .active_svlans );
348+
349+ err = mlx5e_add_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID , vid );
350+ if (err ) {
351+ clear_bit (vid , priv -> fs .vlan .active_svlans );
352+ return err ;
353+ }
354+
355+ /* Need to fix some features.. */
356+ netdev_update_features (netdev );
357+ return err ;
358+ }
359+
360+ int mlx5e_vlan_rx_add_vid (struct net_device * dev , __be16 proto , u16 vid )
325361{
326362 struct mlx5e_priv * priv = netdev_priv (dev );
327363
328- clear_bit (vid , priv -> fs .vlan .active_cvlans );
364+ if (be16_to_cpu (proto ) == ETH_P_8021Q )
365+ return mlx5e_vlan_rx_add_cvid (priv , vid );
366+ else if (be16_to_cpu (proto ) == ETH_P_8021AD )
367+ return mlx5e_vlan_rx_add_svid (priv , vid );
329368
330- mlx5e_del_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID , vid );
369+ return - EOPNOTSUPP ;
370+ }
371+
372+ int mlx5e_vlan_rx_kill_vid (struct net_device * dev , __be16 proto , u16 vid )
373+ {
374+ struct mlx5e_priv * priv = netdev_priv (dev );
375+
376+ if (be16_to_cpu (proto ) == ETH_P_8021Q ) {
377+ clear_bit (vid , priv -> fs .vlan .active_cvlans );
378+ mlx5e_del_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID , vid );
379+ } else if (be16_to_cpu (proto ) == ETH_P_8021AD ) {
380+ clear_bit (vid , priv -> fs .vlan .active_svlans );
381+ mlx5e_del_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID , vid );
382+ netdev_update_features (dev );
383+ }
331384
332385 return 0 ;
333386}
@@ -342,6 +395,9 @@ static void mlx5e_add_vlan_rules(struct mlx5e_priv *priv)
342395 mlx5e_add_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID , i );
343396 }
344397
398+ for_each_set_bit (i , priv -> fs .vlan .active_svlans , VLAN_N_VID )
399+ mlx5e_add_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID , i );
400+
345401 if (priv -> fs .vlan .cvlan_filter_disabled &&
346402 !(priv -> netdev -> flags & IFF_PROMISC ))
347403 mlx5e_add_any_vid_rules (priv );
@@ -357,6 +413,9 @@ static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)
357413 mlx5e_del_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID , i );
358414 }
359415
416+ for_each_set_bit (i , priv -> fs .vlan .active_svlans , VLAN_N_VID )
417+ mlx5e_del_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID , i );
418+
360419 if (priv -> fs .vlan .cvlan_filter_disabled &&
361420 !(priv -> netdev -> flags & IFF_PROMISC ))
362421 mlx5e_del_any_vid_rules (priv );
@@ -550,6 +609,9 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
550609 bool disable_broadcast = ea -> broadcast_enabled && !broadcast_enabled ;
551610
552611 if (enable_promisc ) {
612+ if (!priv -> channels .params .vlan_strip_disable )
613+ netdev_warn_once (ndev ,
614+ "S-tagged traffic will be dropped while C-tag vlan stripping is enabled\n" );
553615 mlx5e_add_l2_flow_rule (priv , & ea -> promisc , MLX5E_PROMISC );
554616 if (!priv -> fs .vlan .cvlan_filter_disabled )
555617 mlx5e_add_any_vid_rules (priv );
@@ -1270,13 +1332,15 @@ static int mlx5e_create_l2_table(struct mlx5e_priv *priv)
12701332 return err ;
12711333}
12721334
1273- #define MLX5E_NUM_VLAN_GROUPS 3
1335+ #define MLX5E_NUM_VLAN_GROUPS 4
12741336#define MLX5E_VLAN_GROUP0_SIZE BIT(12)
1275- #define MLX5E_VLAN_GROUP1_SIZE BIT(1)
1276- #define MLX5E_VLAN_GROUP2_SIZE BIT(0)
1337+ #define MLX5E_VLAN_GROUP1_SIZE BIT(12)
1338+ #define MLX5E_VLAN_GROUP2_SIZE BIT(1)
1339+ #define MLX5E_VLAN_GROUP3_SIZE BIT(0)
12771340#define MLX5E_VLAN_TABLE_SIZE (MLX5E_VLAN_GROUP0_SIZE +\
12781341 MLX5E_VLAN_GROUP1_SIZE +\
1279- MLX5E_VLAN_GROUP2_SIZE)
1342+ MLX5E_VLAN_GROUP2_SIZE +\
1343+ MLX5E_VLAN_GROUP3_SIZE)
12801344
12811345static int __mlx5e_create_vlan_table_groups (struct mlx5e_flow_table * ft , u32 * in ,
12821346 int inlen )
@@ -1299,7 +1363,8 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in
12991363
13001364 memset (in , 0 , inlen );
13011365 MLX5_SET_CFG (in , match_criteria_enable , MLX5_MATCH_OUTER_HEADERS );
1302- MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .cvlan_tag );
1366+ MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .svlan_tag );
1367+ MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .first_vid );
13031368 MLX5_SET_CFG (in , start_flow_index , ix );
13041369 ix += MLX5E_VLAN_GROUP1_SIZE ;
13051370 MLX5_SET_CFG (in , end_flow_index , ix - 1 );
@@ -1310,7 +1375,7 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in
13101375
13111376 memset (in , 0 , inlen );
13121377 MLX5_SET_CFG (in , match_criteria_enable , MLX5_MATCH_OUTER_HEADERS );
1313- MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .svlan_tag );
1378+ MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .cvlan_tag );
13141379 MLX5_SET_CFG (in , start_flow_index , ix );
13151380 ix += MLX5E_VLAN_GROUP2_SIZE ;
13161381 MLX5_SET_CFG (in , end_flow_index , ix - 1 );
@@ -1319,6 +1384,17 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in
13191384 goto err_destroy_groups ;
13201385 ft -> num_groups ++ ;
13211386
1387+ memset (in , 0 , inlen );
1388+ MLX5_SET_CFG (in , match_criteria_enable , MLX5_MATCH_OUTER_HEADERS );
1389+ MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .svlan_tag );
1390+ MLX5_SET_CFG (in , start_flow_index , ix );
1391+ ix += MLX5E_VLAN_GROUP3_SIZE ;
1392+ MLX5_SET_CFG (in , end_flow_index , ix - 1 );
1393+ ft -> g [ft -> num_groups ] = mlx5_create_flow_group (ft -> t , in );
1394+ if (IS_ERR (ft -> g [ft -> num_groups ]))
1395+ goto err_destroy_groups ;
1396+ ft -> num_groups ++ ;
1397+
13221398 return 0 ;
13231399
13241400err_destroy_groups :
0 commit comments