Skip to content

Commit 4fdc302

Browse files
committed
Merge tag 'mlx5-updates-2017-11-09' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux
Saeed Mahameed says: ==================== mlx5-updates-2017-11-09 This series introduces vlan offloads related improvements for mlx5 ethernet netdev driver, from Gal Pressman. - Add support for 802.1ad vlan filter - Add support for 802.1ad vlan insertion - Add vlan offloads statistics to ethtool (inserted/stripped vlans) - CHECKSUM_COMPLETE support for vlan traffic when vlan stripping is off! (Finally) ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 5d37636 + f938dae commit 4fdc302

File tree

9 files changed

+214
-52
lines changed

9 files changed

+214
-52
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -655,12 +655,14 @@ struct mlx5e_tc_table {
655655

656656
struct mlx5e_vlan_table {
657657
struct mlx5e_flow_table ft;
658-
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
659-
struct mlx5_flow_handle *active_vlans_rule[VLAN_N_VID];
658+
DECLARE_BITMAP(active_cvlans, VLAN_N_VID);
659+
DECLARE_BITMAP(active_svlans, VLAN_N_VID);
660+
struct mlx5_flow_handle *active_cvlans_rule[VLAN_N_VID];
661+
struct mlx5_flow_handle *active_svlans_rule[VLAN_N_VID];
660662
struct mlx5_flow_handle *untagged_rule;
661663
struct mlx5_flow_handle *any_cvlan_rule;
662664
struct mlx5_flow_handle *any_svlan_rule;
663-
bool filter_disabled;
665+
bool cvlan_filter_disabled;
664666
};
665667

666668
struct mlx5e_l2_table {
@@ -887,8 +889,8 @@ int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto,
887889
u16 vid);
888890
int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __always_unused __be16 proto,
889891
u16 vid);
890-
void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv);
891-
void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv);
892+
void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv);
893+
void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv);
892894
void mlx5e_timestamp_set(struct mlx5e_priv *priv);
893895

894896
struct mlx5e_redirect_rqt_param {

drivers/net/ethernet/mellanox/mlx5/core/en_fs.c

Lines changed: 120 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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

160161
static 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

12791348
static 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

13221403
err_destroy_groups:

0 commit comments

Comments
 (0)