From 510aecab170dc8bd4a3d59d839a898a17cf2560f Mon Sep 17 00:00:00 2001 From: John Daley Date: Tue, 14 Apr 2020 18:06:40 -0700 Subject: [PATCH] net/enic: support flow API RSS ranges on outer headers Support rte_flow RSS action on outer headers (level 0). RSS ranges on the non-default port is OK. Restrictions: - The RETA is ignored. The hash function is simply applied across the RSS queue range. - The queues used in the RSS group must be sequential. - There is a performance hit if the number of queues is not a power of 2. Signed-off-by: John Daley Reviewed-by: Hyong Youb Kim --- doc/guides/nics/enic.rst | 4 +++ drivers/net/enic/enic_fm_flow.c | 56 ++++++++++++++++++++++----------- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst index 65e536d422..aa4fdc0e39 100644 --- a/doc/guides/nics/enic.rst +++ b/doc/guides/nics/enic.rst @@ -459,6 +459,10 @@ PKT_RX_VLAN_STRIPPED mbuf flags would not be set. This mode is enabled with the packets and then receive them normally. These require 1400 series VIC adapters and latest firmware. - RAW items are limited to matching UDP tunnel headers like VXLAN. + - For 1400 VICs, all flows using the RSS action on a port use same hash + configuration. The RETA is ignored. The queues used in the RSS group must be + sequential. There is a performance hit if the number of queues is not a power of 2. + Only level 0 (outer header) RSS is allowed. - **Statistics** diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c index 8d715fc436..86efeffc64 100644 --- a/drivers/net/enic/enic_fm_flow.c +++ b/drivers/net/enic/enic_fm_flow.c @@ -1174,8 +1174,8 @@ enic_fm_copy_action(struct enic_flowman *fm, actions->conf; /* - * If other fate kind is set, fail. Multiple - * queue actions are ok. + * If fate other than QUEUE or RSS, fail. Multiple + * rss and queue actions are ok. */ if ((overlap & FATE) && first_rq) goto unsupported; @@ -1185,6 +1185,7 @@ enic_fm_copy_action(struct enic_flowman *fm, fm_op.fa_op = FMOP_RQ_STEER; fm_op.rq_steer.rq_index = enic_rte_rq_idx_to_sop_idx(queue->index); + fm_op.rq_steer.rq_count = 1; fm_op.rq_steer.vnic_handle = vnic_h; ret = enic_fm_append_action_op(fm, &fm_op, error); if (ret) @@ -1219,27 +1220,44 @@ enic_fm_copy_action(struct enic_flowman *fm, uint16_t i; /* - * Hardware does not support general RSS actions, but - * we can still support the dummy one that is used to - * "receive normally". + * If fate other than QUEUE or RSS, fail. Multiple + * rss and queue actions are ok. + */ + if ((overlap & FATE) && first_rq) + goto unsupported; + first_rq = false; + overlap |= FATE; + + /* + * Hardware only supports RSS actions on outer level + * with default type and function. Queues must be + * sequential. */ allow = rss->func == RTE_ETH_HASH_FUNCTION_DEFAULT && - rss->level == 0 && - (rss->types == 0 || - rss->types == enic->rss_hf) && - rss->queue_num == enic->rq_count && - rss->key_len == 0; - /* Identity queue map is ok */ - for (i = 0; i < rss->queue_num; i++) - allow = allow && (i == rss->queue[i]); + rss->level == 0 && (rss->types == 0 || + rss->types == enic->rss_hf) && + rss->queue_num <= enic->rq_count && + rss->queue[rss->queue_num - 1] < enic->rq_count; + + + /* Identity queue map needs to be sequential */ + for (i = 1; i < rss->queue_num; i++) + allow = allow && (rss->queue[i] == + rss->queue[i - 1] + 1); if (!allow) goto unsupported; - if (overlap & FATE) - goto unsupported; - /* Need MARK or FLAG */ - if (!(overlap & MARK)) - goto unsupported; - overlap |= FATE; + + memset(&fm_op, 0, sizeof(fm_op)); + fm_op.fa_op = FMOP_RQ_STEER; + fm_op.rq_steer.rq_index = + enic_rte_rq_idx_to_sop_idx(rss->queue[0]); + fm_op.rq_steer.rq_count = rss->queue_num; + fm_op.rq_steer.vnic_handle = vnic_h; + ret = enic_fm_append_action_op(fm, &fm_op, error); + if (ret) + return ret; + ENICPMD_LOG(DEBUG, "create QUEUE action rq: %u", + fm_op.rq_steer.rq_index); break; } case RTE_FLOW_ACTION_TYPE_PORT_ID: { -- 2.20.1