IB/mlx5: Add ability to hash by IPSEC_SPI when creating a TIR
authorMatan Barak <matanb@mellanox.com>
Wed, 28 Mar 2018 06:27:55 +0000 (09:27 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 4 Apr 2018 18:06:28 +0000 (12:06 -0600)
When a Raw Ethernet QP is created, we actually create a few objects.
One of these objects is a TIR. Currently, a TIR could hash (and spread
the traffic) by IP or port only. Adding a hashing by IPSec SPI to TIR
creation with the required UAPI bit.

Signed-off-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/qp.c
include/uapi/rdma/mlx5-abi.h

index 25e70ae0b484a8d5623139777fb7b4fcd637c765..31295e39896c994e6eaf18b342df14161722ac80 100644 (file)
@@ -856,6 +856,10 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                                                MLX5_RX_HASH_SRC_PORT_UDP |
                                                MLX5_RX_HASH_DST_PORT_UDP |
                                                MLX5_RX_HASH_INNER;
+                       if (mlx5_accel_ipsec_device_caps(dev->mdev) &
+                           MLX5_ACCEL_IPSEC_CAP_DEVICE)
+                               resp.rss_caps.rx_hash_fields_mask |=
+                                       MLX5_RX_HASH_IPSEC_SPI;
                        resp.response_length += sizeof(resp.rss_caps);
                }
        } else {
index c8f01f32ebb43118182ebca9ab5f96666631c922..0a0524f60924d122662825aab816ce2059f1733e 100644 (file)
@@ -1413,6 +1413,7 @@ static int create_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
        void *tirc;
        void *hfso;
        u32 selected_fields = 0;
+       u32 outer_l4;
        size_t min_resp_len;
        u32 tdn = mucontext->tdn;
        struct mlx5_ib_create_qp_rss ucmd = {};
@@ -1543,10 +1544,14 @@ static int create_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
                MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
                         MLX5_L3_PROT_TYPE_IPV6);
 
-       if (((ucmd.rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_TCP) ||
-            (ucmd.rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_TCP)) &&
-            ((ucmd.rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_UDP) ||
-            (ucmd.rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_UDP))) {
+       outer_l4 = ((ucmd.rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_TCP) ||
+                   (ucmd.rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_TCP)) << 0 |
+                  ((ucmd.rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_UDP) ||
+                   (ucmd.rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_UDP)) << 1 |
+                  (ucmd.rx_hash_fields_mask & MLX5_RX_HASH_IPSEC_SPI) << 2;
+
+       /* Check that only one l4 protocol is set */
+       if (outer_l4 & (outer_l4 - 1)) {
                err = -EINVAL;
                goto err;
        }
@@ -1577,6 +1582,9 @@ static int create_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
            (ucmd.rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_UDP))
                selected_fields |= MLX5_HASH_FIELD_SEL_L4_DPORT;
 
+       if (ucmd.rx_hash_fields_mask & MLX5_RX_HASH_IPSEC_SPI)
+               selected_fields |= MLX5_HASH_FIELD_SEL_IPSEC_SPI;
+
        MLX5_SET(rx_hash_field_select, hfso, selected_fields, selected_fields);
 
 create_tir:
index f60d2659cdb7090fe03756941c892f025164def5..d86a65b993f873ed1e2e16fca0868b6385051062 100644 (file)
@@ -327,6 +327,7 @@ enum mlx5_rx_hash_fields {
        MLX5_RX_HASH_DST_PORT_TCP       = 1 << 5,
        MLX5_RX_HASH_SRC_PORT_UDP       = 1 << 6,
        MLX5_RX_HASH_DST_PORT_UDP       = 1 << 7,
+       MLX5_RX_HASH_IPSEC_SPI          = 1 << 8,
        /* Save bits for future fields */
        MLX5_RX_HASH_INNER              = (1UL << 31),
 };