@@ -118,7 +118,7 @@ static int mlx5e_vport_context_update_vlans(struct mlx5e_priv *priv)
118118 int i ;
119119
120120 list_size = 0 ;
121- for_each_set_bit (vlan , priv -> fs .vlan .active_vlans , VLAN_N_VID )
121+ for_each_set_bit (vlan , priv -> fs .vlan .active_cvlans , VLAN_N_VID )
122122 list_size ++ ;
123123
124124 max_list_size = 1 << MLX5_CAP_GEN (priv -> mdev , log_max_vlan_list );
@@ -135,7 +135,7 @@ static int mlx5e_vport_context_update_vlans(struct mlx5e_priv *priv)
135135 return - ENOMEM ;
136136
137137 i = 0 ;
138- for_each_set_bit (vlan , priv -> fs .vlan .active_vlans , VLAN_N_VID ) {
138+ for_each_set_bit (vlan , priv -> fs .vlan .active_cvlans , VLAN_N_VID ) {
139139 if (i >= list_size )
140140 break ;
141141 vlans [i ++ ] = vlan ;
@@ -154,7 +154,8 @@ enum mlx5e_vlan_rule_type {
154154 MLX5E_VLAN_RULE_TYPE_UNTAGGED ,
155155 MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID ,
156156 MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID ,
157- MLX5E_VLAN_RULE_TYPE_MATCH_VID ,
157+ 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,8 +195,18 @@ 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 ;
193- default : /* MLX5E_VLAN_RULE_TYPE_MATCH_VID */
194- rule_p = & priv -> fs .vlan .active_vlans_rule [vid ];
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 ;
208+ default : /* MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID */
209+ rule_p = & priv -> fs .vlan .active_cvlans_rule [vid ];
195210 MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
196211 outer_headers .cvlan_tag );
197212 MLX5_SET (fte_match_param , spec -> match_value , outer_headers .cvlan_tag , 1 );
@@ -223,7 +238,7 @@ static int mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
223238 if (!spec )
224239 return - ENOMEM ;
225240
226- if (rule_type == MLX5E_VLAN_RULE_TYPE_MATCH_VID )
241+ if (rule_type == MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID )
227242 mlx5e_vport_context_update_vlans (priv );
228243
229244 err = __mlx5e_add_vlan_rule (priv , rule_type , vid , spec );
@@ -255,11 +270,17 @@ static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv,
255270 priv -> fs .vlan .any_svlan_rule = NULL ;
256271 }
257272 break ;
258- case MLX5E_VLAN_RULE_TYPE_MATCH_VID :
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 ;
279+ case MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID :
259280 mlx5e_vport_context_update_vlans (priv );
260- if (priv -> fs .vlan .active_vlans_rule [vid ]) {
261- mlx5_del_flow_rules (priv -> fs .vlan .active_vlans_rule [vid ]);
262- priv -> fs .vlan .active_vlans_rule [vid ] = NULL ;
281+ if (priv -> fs .vlan .active_cvlans_rule [vid ]) {
282+ mlx5_del_flow_rules (priv -> fs .vlan .active_cvlans_rule [vid ]);
283+ priv -> fs .vlan .active_cvlans_rule [vid ] = NULL ;
263284 }
264285 mlx5e_vport_context_update_vlans (priv );
265286 break ;
@@ -283,46 +304,83 @@ static int mlx5e_add_any_vid_rules(struct mlx5e_priv *priv)
283304 return mlx5e_add_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID , 0 );
284305}
285306
286- void mlx5e_enable_vlan_filter (struct mlx5e_priv * priv )
307+ void mlx5e_enable_cvlan_filter (struct mlx5e_priv * priv )
287308{
288- if (!priv -> fs .vlan .filter_disabled )
309+ if (!priv -> fs .vlan .cvlan_filter_disabled )
289310 return ;
290311
291- priv -> fs .vlan .filter_disabled = false;
312+ priv -> fs .vlan .cvlan_filter_disabled = false;
292313 if (priv -> netdev -> flags & IFF_PROMISC )
293314 return ;
294315 mlx5e_del_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID , 0 );
295316}
296317
297- void mlx5e_disable_vlan_filter (struct mlx5e_priv * priv )
318+ void mlx5e_disable_cvlan_filter (struct mlx5e_priv * priv )
298319{
299- if (priv -> fs .vlan .filter_disabled )
320+ if (priv -> fs .vlan .cvlan_filter_disabled )
300321 return ;
301322
302- priv -> fs .vlan .filter_disabled = true;
323+ priv -> fs .vlan .cvlan_filter_disabled = true;
303324 if (priv -> netdev -> flags & IFF_PROMISC )
304325 return ;
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 );
331+ int err ;
332+
333+ set_bit (vid , priv -> fs .vlan .active_cvlans );
312334
313- set_bit (vid , priv -> fs .vlan .active_vlans );
335+ err = mlx5e_add_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID , vid );
336+ if (err )
337+ clear_bit (vid , priv -> fs .vlan .active_cvlans );
338+
339+ return err ;
340+ }
341+
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+ }
314354
315- return mlx5e_add_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_VID , vid );
355+ /* Need to fix some features.. */
356+ netdev_update_features (netdev );
357+ return err ;
316358}
317359
318- int mlx5e_vlan_rx_kill_vid (struct net_device * dev , __always_unused __be16 proto ,
319- u16 vid )
360+ int mlx5e_vlan_rx_add_vid (struct net_device * dev , __be16 proto , u16 vid )
320361{
321362 struct mlx5e_priv * priv = netdev_priv (dev );
322363
323- clear_bit (vid , priv -> fs .vlan .active_vlans );
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 );
324368
325- mlx5e_del_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_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+ }
326384
327385 return 0 ;
328386}
@@ -333,11 +391,14 @@ static void mlx5e_add_vlan_rules(struct mlx5e_priv *priv)
333391
334392 mlx5e_add_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_UNTAGGED , 0 );
335393
336- for_each_set_bit (i , priv -> fs .vlan .active_vlans , VLAN_N_VID ) {
337- mlx5e_add_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_VID , i );
394+ for_each_set_bit (i , priv -> fs .vlan .active_cvlans , VLAN_N_VID ) {
395+ mlx5e_add_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID , i );
338396 }
339397
340- if (priv -> fs .vlan .filter_disabled &&
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+
401+ if (priv -> fs .vlan .cvlan_filter_disabled &&
341402 !(priv -> netdev -> flags & IFF_PROMISC ))
342403 mlx5e_add_any_vid_rules (priv );
343404}
@@ -348,11 +409,14 @@ static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)
348409
349410 mlx5e_del_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_UNTAGGED , 0 );
350411
351- for_each_set_bit (i , priv -> fs .vlan .active_vlans , VLAN_N_VID ) {
352- mlx5e_del_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_VID , i );
412+ for_each_set_bit (i , priv -> fs .vlan .active_cvlans , VLAN_N_VID ) {
413+ mlx5e_del_vlan_rule (priv , MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID , i );
353414 }
354415
355- if (priv -> fs .vlan .filter_disabled &&
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+
419+ if (priv -> fs .vlan .cvlan_filter_disabled &&
356420 !(priv -> netdev -> flags & IFF_PROMISC ))
357421 mlx5e_del_any_vid_rules (priv );
358422}
@@ -548,8 +612,11 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
548612 bool disable_broadcast = ea -> broadcast_enabled && !broadcast_enabled ;
549613
550614 if (enable_promisc ) {
615+ if (!priv -> channels .params .vlan_strip_disable )
616+ netdev_warn_once (ndev ,
617+ "S-tagged traffic will be dropped while C-tag vlan stripping is enabled\n" );
551618 mlx5e_add_l2_flow_rule (priv , & ea -> promisc , MLX5E_PROMISC );
552- if (!priv -> fs .vlan .filter_disabled )
619+ if (!priv -> fs .vlan .cvlan_filter_disabled )
553620 mlx5e_add_any_vid_rules (priv );
554621 }
555622 if (enable_allmulti )
@@ -564,7 +631,7 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
564631 if (disable_allmulti )
565632 mlx5e_del_l2_flow_rule (priv , & ea -> allmulti );
566633 if (disable_promisc ) {
567- if (!priv -> fs .vlan .filter_disabled )
634+ if (!priv -> fs .vlan .cvlan_filter_disabled )
568635 mlx5e_del_any_vid_rules (priv );
569636 mlx5e_del_l2_flow_rule (priv , & ea -> promisc );
570637 }
@@ -1268,13 +1335,15 @@ static int mlx5e_create_l2_table(struct mlx5e_priv *priv)
12681335 return err ;
12691336}
12701337
1271- #define MLX5E_NUM_VLAN_GROUPS 3
1338+ #define MLX5E_NUM_VLAN_GROUPS 4
12721339#define MLX5E_VLAN_GROUP0_SIZE BIT(12)
1273- #define MLX5E_VLAN_GROUP1_SIZE BIT(1)
1274- #define MLX5E_VLAN_GROUP2_SIZE BIT(0)
1340+ #define MLX5E_VLAN_GROUP1_SIZE BIT(12)
1341+ #define MLX5E_VLAN_GROUP2_SIZE BIT(1)
1342+ #define MLX5E_VLAN_GROUP3_SIZE BIT(0)
12751343#define MLX5E_VLAN_TABLE_SIZE (MLX5E_VLAN_GROUP0_SIZE +\
12761344 MLX5E_VLAN_GROUP1_SIZE +\
1277- MLX5E_VLAN_GROUP2_SIZE)
1345+ MLX5E_VLAN_GROUP2_SIZE +\
1346+ MLX5E_VLAN_GROUP3_SIZE)
12781347
12791348static int __mlx5e_create_vlan_table_groups (struct mlx5e_flow_table * ft , u32 * in ,
12801349 int inlen )
@@ -1297,7 +1366,8 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in
12971366
12981367 memset (in , 0 , inlen );
12991368 MLX5_SET_CFG (in , match_criteria_enable , MLX5_MATCH_OUTER_HEADERS );
1300- MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .cvlan_tag );
1369+ MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .svlan_tag );
1370+ MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .first_vid );
13011371 MLX5_SET_CFG (in , start_flow_index , ix );
13021372 ix += MLX5E_VLAN_GROUP1_SIZE ;
13031373 MLX5_SET_CFG (in , end_flow_index , ix - 1 );
@@ -1308,7 +1378,7 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in
13081378
13091379 memset (in , 0 , inlen );
13101380 MLX5_SET_CFG (in , match_criteria_enable , MLX5_MATCH_OUTER_HEADERS );
1311- MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .svlan_tag );
1381+ MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .cvlan_tag );
13121382 MLX5_SET_CFG (in , start_flow_index , ix );
13131383 ix += MLX5E_VLAN_GROUP2_SIZE ;
13141384 MLX5_SET_CFG (in , end_flow_index , ix - 1 );
@@ -1317,6 +1387,17 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in
13171387 goto err_destroy_groups ;
13181388 ft -> num_groups ++ ;
13191389
1390+ memset (in , 0 , inlen );
1391+ MLX5_SET_CFG (in , match_criteria_enable , MLX5_MATCH_OUTER_HEADERS );
1392+ MLX5_SET_TO_ONES (fte_match_param , mc , outer_headers .svlan_tag );
1393+ MLX5_SET_CFG (in , start_flow_index , ix );
1394+ ix += MLX5E_VLAN_GROUP3_SIZE ;
1395+ MLX5_SET_CFG (in , end_flow_index , ix - 1 );
1396+ ft -> g [ft -> num_groups ] = mlx5_create_flow_group (ft -> t , in );
1397+ if (IS_ERR (ft -> g [ft -> num_groups ]))
1398+ goto err_destroy_groups ;
1399+ ft -> num_groups ++ ;
1400+
13201401 return 0 ;
13211402
13221403err_destroy_groups :
0 commit comments