#define MLX5_RSS_HASH_IPV6_UDP \
(MLX5_RSS_HASH_IPV6 | \
IBV_RX_HASH_SRC_PORT_UDP | IBV_RX_HASH_DST_PORT_UDP)
+#define MLX5_RSS_HASH_IPV4_SRC_ONLY IBV_RX_HASH_SRC_IPV4
+#define MLX5_RSS_HASH_IPV4_DST_ONLY IBV_RX_HASH_DST_IPV4
+#define MLX5_RSS_HASH_IPV6_SRC_ONLY IBV_RX_HASH_SRC_IPV6
+#define MLX5_RSS_HASH_IPV6_DST_ONLY IBV_RX_HASH_DST_IPV6
+#define MLX5_RSS_HASH_IPV4_UDP_SRC_ONLY \
+ (MLX5_RSS_HASH_IPV4 | IBV_RX_HASH_SRC_PORT_UDP)
+#define MLX5_RSS_HASH_IPV4_UDP_DST_ONLY \
+ (MLX5_RSS_HASH_IPV4 | IBV_RX_HASH_DST_PORT_UDP)
+#define MLX5_RSS_HASH_IPV6_UDP_SRC_ONLY \
+ (MLX5_RSS_HASH_IPV6 | IBV_RX_HASH_SRC_PORT_UDP)
+#define MLX5_RSS_HASH_IPV6_UDP_DST_ONLY \
+ (MLX5_RSS_HASH_IPV6 | IBV_RX_HASH_DST_PORT_UDP)
+#define MLX5_RSS_HASH_IPV4_TCP_SRC_ONLY \
+ (MLX5_RSS_HASH_IPV4 | IBV_RX_HASH_SRC_PORT_TCP)
+#define MLX5_RSS_HASH_IPV4_TCP_DST_ONLY \
+ (MLX5_RSS_HASH_IPV4 | IBV_RX_HASH_DST_PORT_TCP)
+#define MLX5_RSS_HASH_IPV6_TCP_SRC_ONLY \
+ (MLX5_RSS_HASH_IPV6 | IBV_RX_HASH_SRC_PORT_TCP)
+#define MLX5_RSS_HASH_IPV6_TCP_DST_ONLY \
+ (MLX5_RSS_HASH_IPV6 | IBV_RX_HASH_DST_PORT_TCP)
#define MLX5_RSS_HASH_NONE 0ULL
/* array of valid combinations of RX Hash fields for RSS */
switch (hash_fields & ~IBV_RX_HASH_INNER) {
case MLX5_RSS_HASH_IPV4:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_SRC_ONLY:
hrxqs[0] = hrxq_idx;
return 0;
case MLX5_RSS_HASH_IPV4_TCP:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_TCP_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_TCP_SRC_ONLY:
hrxqs[1] = hrxq_idx;
return 0;
case MLX5_RSS_HASH_IPV4_UDP:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_UDP_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_UDP_SRC_ONLY:
hrxqs[2] = hrxq_idx;
return 0;
case MLX5_RSS_HASH_IPV6:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_SRC_ONLY:
hrxqs[3] = hrxq_idx;
return 0;
case MLX5_RSS_HASH_IPV6_TCP:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_TCP_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_TCP_SRC_ONLY:
hrxqs[4] = hrxq_idx;
return 0;
case MLX5_RSS_HASH_IPV6_UDP:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_UDP_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_UDP_SRC_ONLY:
hrxqs[5] = hrxq_idx;
return 0;
case MLX5_RSS_HASH_NONE:
switch (hash_fields & ~IBV_RX_HASH_INNER) {
case MLX5_RSS_HASH_IPV4:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_SRC_ONLY:
return hrxqs[0];
case MLX5_RSS_HASH_IPV4_TCP:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_TCP_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_TCP_SRC_ONLY:
return hrxqs[1];
case MLX5_RSS_HASH_IPV4_UDP:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_UDP_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV4_UDP_SRC_ONLY:
return hrxqs[2];
case MLX5_RSS_HASH_IPV6:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_SRC_ONLY:
return hrxqs[3];
case MLX5_RSS_HASH_IPV6_TCP:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_TCP_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_TCP_SRC_ONLY:
return hrxqs[4];
case MLX5_RSS_HASH_IPV6_UDP:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_UDP_DST_ONLY:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_UDP_SRC_ONLY:
return hrxqs[5];
case MLX5_RSS_HASH_NONE:
return hrxqs[6];
default:
return 0;
}
+
}
/**
return __flow_dv_hrxqs_release(dev, &shared_rss->hrxq);
}
+/**
+ * Adjust L3/L4 hash value of pre-created shared RSS hrxq according to
+ * user input.
+ *
+ * Only one hash value is available for one L3+L4 combination:
+ * for example:
+ * MLX5_RSS_HASH_IPV4, MLX5_RSS_HASH_IPV4_SRC_ONLY, and
+ * MLX5_RSS_HASH_IPV4_DST_ONLY are mutually exclusive so they can share
+ * same slot in mlx5_rss_hash_fields.
+ *
+ * @param[in] rss
+ * Pointer to the shared action RSS conf.
+ * @param[in, out] hash_field
+ * hash_field variable needed to be adjusted.
+ *
+ * @return
+ * void
+ */
+static void
+__flow_dv_action_rss_l34_hash_adjust(struct mlx5_shared_action_rss *rss,
+ uint64_t *hash_field)
+{
+ uint64_t rss_types = rss->origin.types;
+
+ switch (*hash_field & ~IBV_RX_HASH_INNER) {
+ case MLX5_RSS_HASH_IPV4:
+ if (rss_types & MLX5_IPV4_LAYER_TYPES) {
+ *hash_field &= ~MLX5_RSS_HASH_IPV4;
+ if (rss_types & ETH_RSS_L3_DST_ONLY)
+ *hash_field |= IBV_RX_HASH_DST_IPV4;
+ else if (rss_types & ETH_RSS_L3_SRC_ONLY)
+ *hash_field |= IBV_RX_HASH_SRC_IPV4;
+ else
+ *hash_field |= MLX5_RSS_HASH_IPV4;
+ }
+ return;
+ case MLX5_RSS_HASH_IPV6:
+ if (rss_types & MLX5_IPV6_LAYER_TYPES) {
+ *hash_field &= ~MLX5_RSS_HASH_IPV6;
+ if (rss_types & ETH_RSS_L3_DST_ONLY)
+ *hash_field |= IBV_RX_HASH_DST_IPV6;
+ else if (rss_types & ETH_RSS_L3_SRC_ONLY)
+ *hash_field |= IBV_RX_HASH_SRC_IPV6;
+ else
+ *hash_field |= MLX5_RSS_HASH_IPV6;
+ }
+ return;
+ case MLX5_RSS_HASH_IPV4_UDP:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_UDP:
+ if (rss_types & ETH_RSS_UDP) {
+ *hash_field &= ~MLX5_UDP_IBV_RX_HASH;
+ if (rss_types & ETH_RSS_L4_DST_ONLY)
+ *hash_field |= IBV_RX_HASH_DST_PORT_UDP;
+ else if (rss_types & ETH_RSS_L4_SRC_ONLY)
+ *hash_field |= IBV_RX_HASH_SRC_PORT_UDP;
+ else
+ *hash_field |= MLX5_UDP_IBV_RX_HASH;
+ }
+ return;
+ case MLX5_RSS_HASH_IPV4_TCP:
+ /* fall-through. */
+ case MLX5_RSS_HASH_IPV6_TCP:
+ if (rss_types & ETH_RSS_TCP) {
+ *hash_field &= ~MLX5_TCP_IBV_RX_HASH;
+ if (rss_types & ETH_RSS_L4_DST_ONLY)
+ *hash_field |= IBV_RX_HASH_DST_PORT_TCP;
+ else if (rss_types & ETH_RSS_L4_SRC_ONLY)
+ *hash_field |= IBV_RX_HASH_SRC_PORT_TCP;
+ else
+ *hash_field |= MLX5_TCP_IBV_RX_HASH;
+ }
+ return;
+ default:
+ return;
+ }
+}
+
/**
* Setup shared RSS action.
* Prepare set of hash RX queue objects sufficient to handle all valid
uint64_t hash_fields = mlx5_rss_hash_fields[i];
int tunnel = 0;
+ __flow_dv_action_rss_l34_hash_adjust(shared_rss, &hash_fields);
if (shared_rss->origin.level > 1) {
hash_fields |= IBV_RX_HASH_INNER;
tunnel = 1;