aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2018-04-05 08:42:06 -0400
committerSaeed Mahameed <saeedm@mellanox.com>2018-05-14 18:10:21 -0400
commitd708f902989b844907c5f7720abe67812a256c33 (patch)
tree38c88038ca1fac70bc1be6274ce30075c6d0dc65
parent547829004c98941f73d010c87c2111e29a6c03ae (diff)
net/mlx5e: Get the required HW match level while parsing TC flow matches
Introduce levels of matching on headers of offloaded flows (none, L2, L3, L4) that follow the inline mode levels. This is pre-step for us to offload flows without any matches on headers. Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Reviewed-by: Roi Dayan <roid@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c34
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.h7
2 files changed, 24 insertions, 17 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 78f5c47affb4..e84bcea8b071 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1192,7 +1192,7 @@ vxlan_match_offload_err:
1192static int __parse_cls_flower(struct mlx5e_priv *priv, 1192static int __parse_cls_flower(struct mlx5e_priv *priv,
1193 struct mlx5_flow_spec *spec, 1193 struct mlx5_flow_spec *spec,
1194 struct tc_cls_flower_offload *f, 1194 struct tc_cls_flower_offload *f,
1195 u8 *min_inline) 1195 u8 *match_level)
1196{ 1196{
1197 void *headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, 1197 void *headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
1198 outer_headers); 1198 outer_headers);
@@ -1201,7 +1201,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1201 u16 addr_type = 0; 1201 u16 addr_type = 0;
1202 u8 ip_proto = 0; 1202 u8 ip_proto = 0;
1203 1203
1204 *min_inline = MLX5_INLINE_MODE_NONE; 1204 *match_level = MLX5_MATCH_NONE;
1205 1205
1206 if (f->dissector->used_keys & 1206 if (f->dissector->used_keys &
1207 ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) | 1207 ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
@@ -1276,7 +1276,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1276 key->src); 1276 key->src);
1277 1277
1278 if (!is_zero_ether_addr(mask->src) || !is_zero_ether_addr(mask->dst)) 1278 if (!is_zero_ether_addr(mask->src) || !is_zero_ether_addr(mask->dst))
1279 *min_inline = MLX5_INLINE_MODE_L2; 1279 *match_level = MLX5_MATCH_L2;
1280 } 1280 }
1281 1281
1282 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) { 1282 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
@@ -1298,7 +1298,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1298 MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_prio, mask->vlan_priority); 1298 MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_prio, mask->vlan_priority);
1299 MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_prio, key->vlan_priority); 1299 MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_prio, key->vlan_priority);
1300 1300
1301 *min_inline = MLX5_INLINE_MODE_L2; 1301 *match_level = MLX5_MATCH_L2;
1302 } 1302 }
1303 } 1303 }
1304 1304
@@ -1317,7 +1317,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1317 ntohs(key->n_proto)); 1317 ntohs(key->n_proto));
1318 1318
1319 if (mask->n_proto) 1319 if (mask->n_proto)
1320 *min_inline = MLX5_INLINE_MODE_L2; 1320 *match_level = MLX5_MATCH_L2;
1321 } 1321 }
1322 1322
1323 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CONTROL)) { 1323 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
@@ -1343,10 +1343,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1343 1343
1344 /* the HW doesn't need L3 inline to match on frag=no */ 1344 /* the HW doesn't need L3 inline to match on frag=no */
1345 if (!(key->flags & FLOW_DIS_IS_FRAGMENT)) 1345 if (!(key->flags & FLOW_DIS_IS_FRAGMENT))
1346 *min_inline = MLX5_INLINE_MODE_L2; 1346 *match_level = MLX5_INLINE_MODE_L2;
1347 /* *** L2 attributes parsing up to here *** */ 1347 /* *** L2 attributes parsing up to here *** */
1348 else 1348 else
1349 *min_inline = MLX5_INLINE_MODE_IP; 1349 *match_level = MLX5_INLINE_MODE_IP;
1350 } 1350 }
1351 } 1351 }
1352 1352
@@ -1367,7 +1367,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1367 key->ip_proto); 1367 key->ip_proto);
1368 1368
1369 if (mask->ip_proto) 1369 if (mask->ip_proto)
1370 *min_inline = MLX5_INLINE_MODE_IP; 1370 *match_level = MLX5_MATCH_L3;
1371 } 1371 }
1372 1372
1373 if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { 1373 if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
@@ -1394,7 +1394,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1394 &key->dst, sizeof(key->dst)); 1394 &key->dst, sizeof(key->dst));
1395 1395
1396 if (mask->src || mask->dst) 1396 if (mask->src || mask->dst)
1397 *min_inline = MLX5_INLINE_MODE_IP; 1397 *match_level = MLX5_MATCH_L3;
1398 } 1398 }
1399 1399
1400 if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { 1400 if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
@@ -1423,7 +1423,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1423 1423
1424 if (ipv6_addr_type(&mask->src) != IPV6_ADDR_ANY || 1424 if (ipv6_addr_type(&mask->src) != IPV6_ADDR_ANY ||
1425 ipv6_addr_type(&mask->dst) != IPV6_ADDR_ANY) 1425 ipv6_addr_type(&mask->dst) != IPV6_ADDR_ANY)
1426 *min_inline = MLX5_INLINE_MODE_IP; 1426 *match_level = MLX5_MATCH_L3;
1427 } 1427 }
1428 1428
1429 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_IP)) { 1429 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_IP)) {
@@ -1451,7 +1451,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1451 return -EOPNOTSUPP; 1451 return -EOPNOTSUPP;
1452 1452
1453 if (mask->tos || mask->ttl) 1453 if (mask->tos || mask->ttl)
1454 *min_inline = MLX5_INLINE_MODE_IP; 1454 *match_level = MLX5_MATCH_L3;
1455 } 1455 }
1456 1456
1457 /* *** L3 attributes parsing up to here *** */ 1457 /* *** L3 attributes parsing up to here *** */
@@ -1496,7 +1496,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1496 } 1496 }
1497 1497
1498 if (mask->src || mask->dst) 1498 if (mask->src || mask->dst)
1499 *min_inline = MLX5_INLINE_MODE_TCP_UDP; 1499 *match_level = MLX5_MATCH_L4;
1500 } 1500 }
1501 1501
1502 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_TCP)) { 1502 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_TCP)) {
@@ -1515,7 +1515,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
1515 ntohs(key->flags)); 1515 ntohs(key->flags));
1516 1516
1517 if (mask->flags) 1517 if (mask->flags)
1518 *min_inline = MLX5_INLINE_MODE_TCP_UDP; 1518 *match_level = MLX5_MATCH_L4;
1519 } 1519 }
1520 1520
1521 return 0; 1521 return 0;
@@ -1530,19 +1530,19 @@ static int parse_cls_flower(struct mlx5e_priv *priv,
1530 struct mlx5_eswitch *esw = dev->priv.eswitch; 1530 struct mlx5_eswitch *esw = dev->priv.eswitch;
1531 struct mlx5e_rep_priv *rpriv = priv->ppriv; 1531 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1532 struct mlx5_eswitch_rep *rep; 1532 struct mlx5_eswitch_rep *rep;
1533 u8 min_inline; 1533 u8 match_level;
1534 int err; 1534 int err;
1535 1535
1536 err = __parse_cls_flower(priv, spec, f, &min_inline); 1536 err = __parse_cls_flower(priv, spec, f, &match_level);
1537 1537
1538 if (!err && (flow->flags & MLX5E_TC_FLOW_ESWITCH)) { 1538 if (!err && (flow->flags & MLX5E_TC_FLOW_ESWITCH)) {
1539 rep = rpriv->rep; 1539 rep = rpriv->rep;
1540 if (rep->vport != FDB_UPLINK_VPORT && 1540 if (rep->vport != FDB_UPLINK_VPORT &&
1541 (esw->offloads.inline_mode != MLX5_INLINE_MODE_NONE && 1541 (esw->offloads.inline_mode != MLX5_INLINE_MODE_NONE &&
1542 esw->offloads.inline_mode < min_inline)) { 1542 esw->offloads.inline_mode < match_level)) {
1543 netdev_warn(priv->netdev, 1543 netdev_warn(priv->netdev,
1544 "Flow is not offloaded due to min inline setting, required %d actual %d\n", 1544 "Flow is not offloaded due to min inline setting, required %d actual %d\n",
1545 min_inline, esw->offloads.inline_mode); 1545 match_level, esw->offloads.inline_mode);
1546 return -EOPNOTSUPP; 1546 return -EOPNOTSUPP;
1547 } 1547 }
1548 } 1548 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 4cd773fa55e3..efae77dd1e35 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -227,6 +227,13 @@ enum {
227 SET_VLAN_INSERT = BIT(1) 227 SET_VLAN_INSERT = BIT(1)
228}; 228};
229 229
230enum mlx5_flow_match_level {
231 MLX5_MATCH_NONE = MLX5_INLINE_MODE_NONE,
232 MLX5_MATCH_L2 = MLX5_INLINE_MODE_L2,
233 MLX5_MATCH_L3 = MLX5_INLINE_MODE_IP,
234 MLX5_MATCH_L4 = MLX5_INLINE_MODE_TCP_UDP,
235};
236
230struct mlx5_esw_flow_attr { 237struct mlx5_esw_flow_attr {
231 struct mlx5_eswitch_rep *in_rep; 238 struct mlx5_eswitch_rep *in_rep;
232 struct mlx5_eswitch_rep *out_rep; 239 struct mlx5_eswitch_rep *out_rep;