From: Gagandeep Singh <[email protected]> For default RSS distribution, mbuf is marked with RTE_MBUF_F_RX_RSS_HASH and the hash value from the high word of FLC.
Configure the flow steering action with FLC enabled to align the stashing setting with the RSS configuration. The TC ID and flow ID are packed into the FLC for mbuf Rx scheduling. An Rx mbuf received from the FS table is marked with RTE_MBUF_F_RX_FDIR along with the TC and flow ID decoded from the FLC low word. Known limitations and follow-up items: RTE_MBUF_F_RX_FDIR_ID is set without also setting RTE_MBUF_F_RX_FDIR. Applications conforming to the DPDK mbuf flags contract test RX_FDIR before reading hash.fdir.hi, so the ID value is never visible to them. The dump helper in the debug Rx path (dpaa2_dev_rx_print_parser_result, patch 10) also gates on RX_FDIR and therefore never prints this field either. RX_FDIR must be set together with RX_FDIR_ID; this will be corrected in a follow-up. hash.fdir.hi carries the raw FLC low word as received from the hardware. This word encodes stash bits and the flow-mark bit in addition to the TC/flow-ID fields, so it is not a clean user-visible filter identifier. User-visible flow IDs should be delivered via RTE_FLOW_ACTION_TYPE_MARK into hash.fdir.hi with only the mark value. Masking out the non-ID bits will be addressed in a follow-up. Signed-off-by: Gagandeep Singh <[email protected]> --- drivers/net/dpaa2/dpaa2_ethdev.h | 12 +++++++++ drivers/net/dpaa2/dpaa2_flow.c | 42 ++++++++++++++++++++++++++++++++ drivers/net/dpaa2/dpaa2_rxtx.c | 18 ++++++++++++-- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h index 58a47cd1a2..76a04c5858 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.h +++ b/drivers/net/dpaa2/dpaa2_ethdev.h @@ -282,6 +282,18 @@ enum dpaa2_ecpri_fafe_type { /* ECPRI shares SP context with VXLAN*/ #define DPAA2_ECPRI_MSG_OFFSET DPAA2_VXLAN_VNI_OFFSET +#define DPAA2_FS_FLC_FS_MARK_OFFSET \ + (DPAA2_FLC_DATA_STASHING + DPAA2_FLC_STASHING_MAX_BIT_SIZE) + +#define DPAA2_FS_FLC_TC_OFFSET \ + (DPAA2_FS_FLC_FS_MARK_OFFSET + DPAA2_FLC_STASHING_MAX_BIT_SIZE) + +#define DPAA2_FS_FLC_TC_BIT_SIZE (sizeof(uint8_t) * 8) +#define DPAA2_FS_FLC_TC_MASK ((1 << DPAA2_FS_FLC_TC_BIT_SIZE) - 1) + +#define DPAA2_FS_FLC_FLOW_OFFSET \ + (DPAA2_FS_FLC_TC_OFFSET + DPAA2_FS_FLC_TC_BIT_SIZE) + #define DPAA2_ECPRI_MAX_EXTRACT_NB 8 struct ipv4_sd_addr_extract_rule { diff --git a/drivers/net/dpaa2/dpaa2_flow.c b/drivers/net/dpaa2/dpaa2_flow.c index 2e844121a8..45660df31a 100644 --- a/drivers/net/dpaa2/dpaa2_flow.c +++ b/drivers/net/dpaa2/dpaa2_flow.c @@ -4383,6 +4383,13 @@ dpaa2_flow_verify_action(struct dpaa2_dev_priv *priv, switch (actions[j].type) { case RTE_FLOW_ACTION_TYPE_QUEUE: dest_queue = actions[j].conf; + if (dest_queue->index >= MAX_RX_QUEUES || + !priv->rx_vq[dest_queue->index]) { + DPAA2_PMD_ERR("Invalid FSQ index(%d)", + dest_queue->index); + + return -EINVAL; + } rxq = priv->rx_vq[dest_queue->index]; if (attr->group != rxq->tc_index) { DPAA2_PMD_ERR("FSQ(%d.%d) not in TC[%d]", @@ -4445,6 +4452,7 @@ dpaa2_configure_flow_fs_action(struct dpaa2_dev_priv *priv, struct dpaa2_dev_priv *dest_priv; const struct rte_flow_action_queue *dest_queue; struct dpaa2_queue *dest_q; + uint64_t flc = 0; memset(&flow->fs_action_cfg, 0, sizeof(struct dpni_fs_action_cfg)); @@ -4452,7 +4460,41 @@ dpaa2_configure_flow_fs_action(struct dpaa2_dev_priv *priv, if (flow->action_type == RTE_FLOW_ACTION_TYPE_QUEUE) { dest_queue = rte_action->conf; + if (dest_queue->index >= MAX_RX_QUEUES || + !priv->rx_vq[dest_queue->index]) { + DPAA2_PMD_ERR("Invalid FSQ index(%d)", + dest_queue->index); + + return -EINVAL; + } dest_q = priv->rx_vq[dest_queue->index]; + if (flow->tc_id != dest_q->tc_index) { + DPAA2_PMD_ERR("RXQ[%d](%d.%d) not in TC[%d]", + dest_queue->index, + dest_q->tc_index, dest_q->flow_id, + flow->tc_id); + + return -EINVAL; + } + flow->fs_action_cfg.options = + DPNI_FS_OPT_SET_FLC | DPNI_FS_OPT_SET_STASH_CONTROL; + + if (dest_q->data_stashing_off) { + dpaa2_flc_stashing_set(DPAA2_FLC_DATA_STASHING, + 0, &flc); + } else { + dpaa2_flc_stashing_set(DPAA2_FLC_DATA_STASHING, + 1, &flc); + } + if ((dpaa2_svr_family & 0xffff0000) != SVR_LX2160A) { + dpaa2_flc_stashing_set(DPAA2_FLC_ANNO_STASHING, + 1, &flc); + } + + flc |= ((uint64_t)1) << DPAA2_FS_FLC_FS_MARK_OFFSET; + flc |= ((uint64_t)dest_q->tc_index) << DPAA2_FS_FLC_TC_OFFSET; + flc |= ((uint64_t)dest_q->flow_id) << DPAA2_FS_FLC_FLOW_OFFSET; + flow->fs_action_cfg.flc = flc; flow->fs_action_cfg.flow_id = dest_q->flow_id; } else if (flow->action_type == RTE_FLOW_ACTION_TYPE_PORT_ID || flow->action_type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT) { diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c index c31d6556ad..7ba6a4563f 100644 --- a/drivers/net/dpaa2/dpaa2_rxtx.c +++ b/drivers/net/dpaa2/dpaa2_rxtx.c @@ -58,6 +58,7 @@ dpaa2_dev_rx_parse_new(struct rte_mbuf *m, const struct qbman_fd *fd, uint16_t frc = DPAA2_GET_FD_FRC_PARSE_SUM(fd); struct dpaa2_annot_hdr *annotation = (struct dpaa2_annot_hdr *)hw_annot_addr; + uint32_t flc_lo, tc, flow; if (unlikely(dpaa2_print_parser_result)) dpaa2_print_parse_result(annotation); @@ -118,8 +119,21 @@ dpaa2_dev_rx_parse_new(struct rte_mbuf *m, const struct qbman_fd *fd, default: m->packet_type = dpaa2_dev_rx_parse_slow(m, annotation); } - m->hash.rss = fd->simple.flc_hi; - m->ol_flags |= RTE_MBUF_F_RX_RSS_HASH; + flc_lo = fd->simple.flc_lo; + if (flc_lo & (1 << DPAA2_FS_FLC_FS_MARK_OFFSET)) { + m->ol_flags |= RTE_MBUF_F_RX_FDIR; + tc = (flc_lo >> DPAA2_FS_FLC_TC_OFFSET) & + DPAA2_FS_FLC_TC_MASK; + flow = flc_lo >> DPAA2_FS_FLC_FLOW_OFFSET; + rte_mbuf_sched_set(m, flow, tc, 0); + DPAA2_PMD_DP_DEBUG("FS frame received from TC[%d]->flow%d", + tc, flow); + } else { + m->hash.rss = fd->simple.flc_hi; + m->ol_flags |= RTE_MBUF_F_RX_RSS_HASH; + DPAA2_PMD_DP_DEBUG("Hash frame received with RSS(%08x)", + m->hash.rss); + } if (dpaa2_enable_ts[m->port]) { *dpaa2_timestamp_dynfield(m) = annotation->word2; -- 2.43.0

