#include "sfc_dp_rx.h"
#include "sfc_kvargs.h"
#include "sfc_ef100.h"
+#include "sfc_nic_dma_dp.h"
#define sfc_ef100_rx_err(_rxq, ...) \
#define SFC_EF100_RXQ_FLAG_INTR_EN 0x40
#define SFC_EF100_RXQ_INGRESS_MPORT 0x80
#define SFC_EF100_RXQ_USER_FLAG 0x100
+#define SFC_EF100_RXQ_NIC_DMA_MAP 0x200
unsigned int ptr_mask;
unsigned int evq_phase_bit_shift;
unsigned int ready_pkts;
/* Datapath receive queue anchor */
struct sfc_dp_rxq dp;
+
+ const struct sfc_nic_dma_info *nic_dma_info;
};
static inline struct sfc_ef100_rxq *
SFC_ASSERT(bulks > 0);
do {
- unsigned int id;
unsigned int i;
if (unlikely(rte_mempool_get_bulk(rxq->refill_mb_pool, objs,
break;
}
- for (i = 0, id = added & ptr_mask;
- i < RTE_DIM(objs);
- ++i, ++id) {
+ for (i = 0; i < RTE_DIM(objs); ++i) {
struct rte_mbuf *m = objs[i];
struct sfc_ef100_rx_sw_desc *rxd;
- rte_iova_t phys_addr;
+ rte_iova_t dma_addr;
__rte_mbuf_raw_sanity_check(m);
- SFC_ASSERT((id & ~ptr_mask) == 0);
- rxd = &rxq->sw_ring[id];
+ dma_addr = rte_mbuf_data_iova_default(m);
+ if (rxq->flags & SFC_EF100_RXQ_NIC_DMA_MAP) {
+ dma_addr = sfc_nic_dma_map(rxq->nic_dma_info,
+ dma_addr,
+ rte_pktmbuf_data_len(m));
+ if (unlikely(dma_addr == RTE_BAD_IOVA)) {
+ sfc_ef100_rx_err(rxq,
+ "failed to map DMA address on Rx");
+ /* Just skip buffer and try to continue */
+ rte_mempool_put(rxq->refill_mb_pool, m);
+ continue;
+ }
+ }
+
+ rxd = &rxq->sw_ring[added & ptr_mask];
rxd->mbuf = m;
/*
* structure members.
*/
- phys_addr = rte_mbuf_data_iova_default(m);
- EFX_POPULATE_QWORD_1(rxq->rxq_hw_ring[id],
- ESF_GZ_RX_BUF_ADDR, phys_addr);
+ EFX_POPULATE_QWORD_1(rxq->rxq_hw_ring[added & ptr_mask],
+ ESF_GZ_RX_BUF_ADDR, dma_addr);
+ added++;
}
-
- added += RTE_DIM(objs);
} while (--bulks > 0);
SFC_ASSERT(rxq->added != added);
info->fcw_offset +
ER_GZ_EVQ_INT_PRIME_OFST;
+ rxq->nic_dma_info = info->nic_dma_info;
+ if (rxq->nic_dma_info->nb_regions > 0)
+ rxq->flags |= SFC_EF100_RXQ_NIC_DMA_MAP;
+
sfc_ef100_rx_debug(rxq, "RxQ doorbell is %p", rxq->doorbell);
*dp_rxqp = &rxq->dp;