#include <rte_memory.h>
#include "bnxt.h"
+#include "bnxt_reps.h"
#include "bnxt_ring.h"
#include "bnxt_rxr.h"
#include "bnxt_rxq.h"
}
#endif
-static void
+static uint32_t
bnxt_ulp_set_mark_in_mbuf(struct bnxt *bp, struct rx_pkt_cmpl_hi *rxcmp1,
- struct rte_mbuf *mbuf)
+ struct rte_mbuf *mbuf, uint32_t *vfr_flag)
{
uint32_t cfa_code;
uint32_t meta_fmt;
uint32_t meta;
- uint32_t eem = 0;
+ bool gfid = false;
uint32_t mark_id;
uint32_t flags2;
+ uint32_t gfid_support = 0;
int rc;
+ if (BNXT_GFID_ENABLED(bp))
+ gfid_support = 1;
+
cfa_code = rte_le_to_cpu_16(rxcmp1->cfa_code);
flags2 = rte_le_to_cpu_32(rxcmp1->flags2);
meta = rte_le_to_cpu_32(rxcmp1->metadata);
- if (meta) {
- meta >>= BNXT_RX_META_CFA_CODE_SHIFT;
- /* The flags field holds extra bits of info from [6:4]
- * which indicate if the flow is in TCAM or EM or EEM
- */
- meta_fmt = (flags2 & BNXT_CFA_META_FMT_MASK) >>
- BNXT_CFA_META_FMT_SHFT;
- /* meta_fmt == 4 => 'b100 => 'b10x => EM.
- * meta_fmt == 5 => 'b101 => 'b10x => EM + VLAN
- * meta_fmt == 6 => 'b110 => 'b11x => EEM
- * meta_fmt == 7 => 'b111 => 'b11x => EEM + VLAN.
+ /*
+ * The flags field holds extra bits of info from [6:4]
+ * which indicate if the flow is in TCAM or EM or EEM
+ */
+ meta_fmt = (flags2 & BNXT_CFA_META_FMT_MASK) >>
+ BNXT_CFA_META_FMT_SHFT;
+
+ switch (meta_fmt) {
+ case 0:
+ if (gfid_support) {
+ /* Not an LFID or GFID, a flush cmd. */
+ goto skip_mark;
+ } else {
+ /* LFID mode, no vlan scenario */
+ gfid = false;
+ }
+ break;
+ case 4:
+ case 5:
+ /*
+ * EM/TCAM case
+ * Assume that EM doesn't support Mark due to GFID
+ * collisions with EEM. Simply return without setting the mark
+ * in the mbuf.
*/
- meta_fmt >>= BNXT_CFA_META_FMT_EM_EEM_SHFT;
-
- eem = meta_fmt == BNXT_CFA_META_FMT_EEM;
+ if (BNXT_CFA_META_EM_TEST(meta)) {
+ /*This is EM hit {EM(1), GFID[27:16], 19'd0 or vtag } */
+ gfid = true;
+ meta >>= BNXT_RX_META_CFA_CODE_SHIFT;
+ cfa_code |= meta << BNXT_CFA_CODE_META_SHIFT;
+ } else {
+ /*
+ * It is a TCAM entry, so it is an LFID.
+ * The TCAM IDX and Mode can also be determined
+ * by decoding the meta_data. We are not
+ * using these for now.
+ */
+ }
+ break;
+ case 6:
+ case 7:
+ /* EEM Case, only using gfid in EEM for now. */
+ gfid = true;
- /* For EEM flows, The first part of cfa_code is 16 bits.
+ /*
+ * For EEM flows, The first part of cfa_code is 16 bits.
* The second part is embedded in the
* metadata field from bit 19 onwards. The driver needs to
* ignore the first 19 bits of metadata and use the next 12
* bits as higher 12 bits of cfa_code.
*/
- if (eem)
- cfa_code |= meta << BNXT_CFA_CODE_META_SHIFT;
+ meta >>= BNXT_RX_META_CFA_CODE_SHIFT;
+ cfa_code |= meta << BNXT_CFA_CODE_META_SHIFT;
+ break;
+ default:
+ /* For other values, the cfa_code is assumed to be an LFID. */
+ break;
}
- if (cfa_code) {
- mbuf->hash.fdir.hi = 0;
- mbuf->hash.fdir.id = 0;
- if (eem)
- rc = ulp_mark_db_mark_get(&bp->ulp_ctx, true,
- cfa_code, &mark_id);
- else
- rc = ulp_mark_db_mark_get(&bp->ulp_ctx, false,
- cfa_code, &mark_id);
- /* If the above fails, simply return and don't add the mark to
- * mbuf
- */
- if (rc)
- return;
-
- mbuf->hash.fdir.hi = mark_id;
- mbuf->udata64 = (cfa_code & 0xffffffffull) << 32;
- mbuf->hash.fdir.id = rxcmp1->cfa_code;
- mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
+ rc = ulp_mark_db_mark_get(bp->ulp_ctx, gfid,
+ cfa_code, vfr_flag, &mark_id);
+ if (!rc) {
+ /* Got the mark, write it to the mbuf and return */
+ mbuf->hash.fdir.hi = mark_id;
+ mbuf->udata64 = (cfa_code & 0xffffffffull) << 32;
+ mbuf->hash.fdir.id = rxcmp1->cfa_code;
+ mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
+ return mark_id;
}
+
+skip_mark:
+ mbuf->hash.fdir.hi = 0;
+ mbuf->hash.fdir.id = 0;
+
+ return 0;
}
void bnxt_set_mark_in_mbuf(struct bnxt *bp,
}
static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
- struct bnxt_rx_queue *rxq, uint32_t *raw_cons)
+ struct bnxt_rx_queue *rxq, uint32_t *raw_cons)
{
struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
int rc = 0;
uint8_t agg_buf = 0;
uint16_t cmp_type;
- uint32_t flags2_f = 0;
+ uint32_t flags2_f = 0, vfr_flag = 0, mark_id = 0;
uint16_t flags_type;
struct bnxt *bp = rxq->bp;
mbuf->ol_flags |= PKT_RX_RSS_HASH;
}
- if (bp->truflow)
- bnxt_ulp_set_mark_in_mbuf(rxq->bp, rxcmp1, mbuf);
+ if (BNXT_TRUFLOW_EN(bp))
+ mark_id = bnxt_ulp_set_mark_in_mbuf(rxq->bp, rxcmp1, mbuf,
+ &vfr_flag);
else
bnxt_set_mark_in_mbuf(rxq->bp, rxcmp1, mbuf);
rx:
*rx_pkt = mbuf;
+ if (BNXT_TRUFLOW_EN(bp) &&
+ (BNXT_VF_IS_TRUSTED(bp) || BNXT_PF(bp)) &&
+ vfr_flag) {
+ if (!bnxt_vfr_recv(mark_id, rxq->queue_id, mbuf)) {
+ /* Now return an error so that nb_rx_pkts is not
+ * incremented.
+ * This packet was meant to be given to the representor.
+ * So no need to account the packet and give it to
+ * parent Rx burst function.
+ */
+ rc = -ENODEV;
+ }
+ }
+
next_rx:
*raw_cons = tmp_raw_cons;
uint32_t raw_cons = cpr->cp_raw_cons;
uint32_t cons;
int nb_rx_pkts = 0;
+ int nb_rep_rx_pkts = 0;
struct rx_pkt_cmpl *rxcmp;
uint16_t prod = rxr->rx_prod;
uint16_t ag_prod = rxr->ag_prod;
!rte_spinlock_trylock(&rxq->lock)))
return 0;
+#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
+ /*
+ * Replenish buffers if needed when a transition has been made from
+ * vector- to non-vector- receive processing.
+ */
+ while (unlikely(rxq->rxrearm_nb)) {
+ if (!bnxt_alloc_rx_data(rxq, rxr, rxq->rxrearm_start)) {
+ rxr->rx_prod = rxq->rxrearm_start;
+ bnxt_db_write(&rxr->rx_db, rxr->rx_prod);
+ rxq->rxrearm_start++;
+ rxq->rxrearm_nb--;
+ } else {
+ /* Retry allocation on next call. */
+ break;
+ }
+ }
+#endif
+
/* Handle RX burst request */
while (1) {
cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
nb_rx_pkts++;
if (rc == -EBUSY) /* partial completion */
break;
+ if (rc == -ENODEV) /* completion for representor */
+ nb_rep_rx_pkts++;
} else if (!BNXT_NUM_ASYNC_CPR(rxq->bp)) {
evt =
bnxt_event_hwrm_resp_handler(rxq->bp,
}
cpr->cp_raw_cons = raw_cons;
- if (!nb_rx_pkts && !evt) {
+ if (!nb_rx_pkts && !nb_rep_rx_pkts && !evt) {
/*
* For PMD, there is no need to keep on pushing to REARM
* the doorbell if there are no new completions
rxq->queue_id, i, ring->ring_size);
break;
}
- rxr->rx_prod = prod;
- prod = RING_NEXT(rxr->rx_ring_struct, prod);
}
+ rxr->rx_prod = prod;
+ prod = RING_NEXT(rxr->rx_ring_struct, prod);
}
ring = rxr->ag_ring_struct;
rxq->queue_id, i, ring->ring_size);
break;
}
- rxr->ag_prod = prod;
- prod = RING_NEXT(rxr->ag_ring_struct, prod);
}
+ rxr->ag_prod = prod;
+ prod = RING_NEXT(rxr->ag_ring_struct, prod);
}
PMD_DRV_LOG(DEBUG, "AGG Done!\n");