All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gagandeep Singh <g.singh@nxp.com>
To: dev@dpdk.org, ferruh.yigit@intel.com
Cc: pankaj.chauhan@nxp.com, Gagandeep Singh <g.singh@nxp.com>
Subject: [PATCH v3 1/3] net/enetc: enable Rx and Tx
Date: Fri, 28 Sep 2018 10:46:45 +0530	[thread overview]
Message-ID: <20180928051647.32341-2-g.singh@nxp.com> (raw)
In-Reply-To: <20180928051647.32341-1-g.singh@nxp.com>

Add RX and TX queue setup, datapath functions

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/net/enetc/Makefile        |   3 +-
 drivers/net/enetc/base/enetc_hw.h |  19 +-
 drivers/net/enetc/enetc.h         |  25 ++-
 drivers/net/enetc/enetc_ethdev.c  | 326 +++++++++++++++++++++++++++++-
 drivers/net/enetc/enetc_rxtx.c    | 239 ++++++++++++++++++++++
 drivers/net/enetc/meson.build     |   3 +-
 6 files changed, 602 insertions(+), 13 deletions(-)
 create mode 100644 drivers/net/enetc/enetc_rxtx.c

diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
index 519153868..9895501db 100644
--- a/drivers/net/enetc/Makefile
+++ b/drivers/net/enetc/Makefile
@@ -14,8 +14,9 @@ EXPORT_MAP := rte_pmd_enetc_version.map
 LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_rxtx.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
 LDLIBS += -lrte_ethdev
 LDLIBS += -lrte_bus_pci
 
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
index c962b9ca1..c74c94875 100644
--- a/drivers/net/enetc/base/enetc_hw.h
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -104,16 +104,19 @@ enum enetc_bdr_type {TX, RX};
 #define ETH_ADDR_LEN			6
 
 /* general register accessors */
-#define enetc_rd_reg(reg)	rte_read32((reg))
-#define enetc_wr_reg(reg, val)	rte_write32((val), (reg))
-#define enetc_rd(hw, off)	enetc_rd_reg((hw)->reg + (off))
-#define enetc_wr(hw, off, val)	enetc_wr_reg((hw)->reg + (off), val)
+#define enetc_rd_reg(reg)	rte_read32((void *)(reg))
+#define enetc_wr_reg(reg, val)	rte_write32((val), (void *)(reg))
+#define enetc_rd(hw, off)	enetc_rd_reg((size_t)(hw)->reg + (off))
+#define enetc_wr(hw, off, val)	enetc_wr_reg((size_t)(hw)->reg + (off), val)
 /* port register accessors - PF only */
-#define enetc_port_rd(hw, off)		enetc_rd_reg((hw)->port + (off))
-#define enetc_port_wr(hw, off, val)	enetc_wr_reg((hw)->port + (off), val)
+#define enetc_port_rd(hw, off)	enetc_rd_reg((size_t)(hw)->port + (off))
+#define enetc_port_wr(hw, off, val) \
+				enetc_wr_reg((size_t)(hw)->port + (off), val)
 /* global register accessors - PF only */
-#define enetc_global_rd(hw, off)	enetc_rd_reg((hw)->global + (off))
-#define enetc_global_wr(hw, off, val)	enetc_wr_reg((hw)->global + (off), val)
+#define enetc_global_rd(hw, off) \
+				enetc_rd_reg((size_t)(hw)->global + (off))
+#define enetc_global_wr(hw, off, val) \
+				enetc_wr_reg((size_t)(hw)->global + (off), val)
 /* BDR register accessors, see ENETC_BDR() */
 #define enetc_bdr_rd(hw, t, n, off) \
 				enetc_rd(hw, ENETC_BDR(t, n, off))
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
index 9fa7c726c..140daf0dd 100644
--- a/drivers/net/enetc/enetc.h
+++ b/drivers/net/enetc/enetc.h
@@ -18,7 +18,11 @@
 #define MAX_RX_RINGS	1
 
 /* Max BD counts per Ring. */
-#define MAX_BD_COUNT	256
+#define MAX_BD_COUNT	64000
+/* Min BD counts per Ring. */
+#define MIN_BD_COUNT	32
+/* BD ALIGN */
+#define BD_ALIGN	8
 
 /*
  * upper_32_bits - return bits 32-63 of a number
@@ -87,4 +91,23 @@ struct enetc_eth_adapter {
 #define ENETC_REG_WRITE(addr, val) (*(uint32_t *)addr = val)
 #define ENETC_REG_WRITE_RELAXED(addr, val) (*(uint32_t *)addr = val)
 
+/*
+ * RX/TX ENETC function prototypes
+ */
+uint16_t enetc_xmit_pkts(void *txq, struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts);
+uint16_t enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts);
+
+
+int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt);
+
+static inline int
+enetc_bd_unused(struct enetc_bdr *bdr)
+{
+	if (bdr->next_to_clean > bdr->next_to_use)
+		return bdr->next_to_clean - bdr->next_to_use - 1;
+
+	return bdr->bd_count + bdr->next_to_clean - bdr->next_to_use - 1;
+}
 #endif /* _ENETC_H_ */
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index 47e2a8ebf..2d90d8fd5 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -19,6 +19,15 @@ static void enetc_dev_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
 static int enetc_hardware_init(struct enetc_eth_hw *hw);
+static int enetc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
+		uint16_t nb_rx_desc, unsigned int socket_id,
+		const struct rte_eth_rxconf *rx_conf,
+		struct rte_mempool *mb_pool);
+static void enetc_rx_queue_release(void *rxq);
+static int enetc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
+		uint16_t nb_tx_desc, unsigned int socket_id,
+		const struct rte_eth_txconf *tx_conf);
+static void enetc_tx_queue_release(void *txq);
 
 /*
  * The set of PCI devices this driver supports
@@ -37,6 +46,10 @@ static const struct eth_dev_ops enetc_ops = {
 	.dev_close            = enetc_dev_close,
 	.link_update          = enetc_link_update,
 	.dev_infos_get        = enetc_dev_infos_get,
+	.rx_queue_setup       = enetc_rx_queue_setup,
+	.rx_queue_release     = enetc_rx_queue_release,
+	.tx_queue_setup       = enetc_tx_queue_setup,
+	.tx_queue_release     = enetc_tx_queue_release,
 };
 
 /**
@@ -59,8 +72,8 @@ enetc_dev_init(struct rte_eth_dev *eth_dev)
 
 	PMD_INIT_FUNC_TRACE();
 	eth_dev->dev_ops = &enetc_ops;
-	eth_dev->rx_pkt_burst = NULL;
-	eth_dev->tx_pkt_burst = NULL;
+	eth_dev->rx_pkt_burst = &enetc_recv_pkts;
+	eth_dev->tx_pkt_burst = &enetc_xmit_pkts;
 
 	/* Retrieving and storing the HW base address of device */
 	hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
@@ -212,11 +225,320 @@ enetc_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
 		    struct rte_eth_dev_info *dev_info)
 {
 	PMD_INIT_FUNC_TRACE();
+	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = MAX_BD_COUNT,
+		.nb_min = MIN_BD_COUNT,
+		.nb_align = BD_ALIGN,
+	};
+	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = MAX_BD_COUNT,
+		.nb_min = MIN_BD_COUNT,
+		.nb_align = BD_ALIGN,
+	};
 	dev_info->max_rx_queues = MAX_RX_RINGS;
 	dev_info->max_tx_queues = MAX_TX_RINGS;
 	dev_info->max_rx_pktlen = 1500;
 }
 
+static int
+enetc_alloc_txbdr(struct enetc_bdr *txr, uint16_t nb_desc)
+{
+	int size;
+
+	size = nb_desc * sizeof(struct enetc_swbd);
+	txr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (txr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = nb_desc * sizeof(struct enetc_tx_bd);
+	txr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (txr->bd_base == NULL) {
+		rte_free(txr->q_swbd);
+		txr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+
+	txr->bd_count = nb_desc;
+	txr->next_to_clean = 0;
+	txr->next_to_use = 0;
+
+	return 0;
+}
+
+static void
+enetc_free_bdr(struct enetc_bdr *rxr)
+{
+	rte_free(rxr->q_swbd);
+	rte_free(rxr->bd_base);
+	rxr->q_swbd = NULL;
+	rxr->bd_base = NULL;
+}
+
+static void
+enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+{
+	int idx = tx_ring->index;
+	uintptr_t base_addr;
+	uint32_t tbmr;
+
+	base_addr = (uintptr_t)tx_ring->bd_base;
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR0,
+		       lower_32_bits((uint64_t)base_addr));
+	enetc_txbdr_wr(hw, idx, ENETC_TBBAR1,
+		       upper_32_bits((uint64_t)base_addr));
+	enetc_txbdr_wr(hw, idx, ENETC_TBLENR,
+		       ENETC_RTBLENR_LEN(tx_ring->bd_count));
+
+	tbmr = ENETC_TBMR_EN;
+	/* enable ring */
+	enetc_txbdr_wr(hw, idx, ENETC_TBMR, tbmr);
+	enetc_txbdr_wr(hw, idx, ENETC_TBCIR, 0);
+	enetc_txbdr_wr(hw, idx, ENETC_TBCISR, 0);
+	tx_ring->tcir = (void *)((size_t)hw->reg +
+			ENETC_BDR(TX, idx, ENETC_TBCIR));
+	tx_ring->tcisr = (void *)((size_t)hw->reg +
+			 ENETC_BDR(TX, idx, ENETC_TBCISR));
+}
+
+static int
+enetc_alloc_tx_resources(struct rte_eth_dev *dev,
+			 uint16_t queue_idx,
+			 uint16_t nb_desc)
+{
+	int err;
+	struct enetc_bdr *tx_ring;
+	struct rte_eth_dev_data *data = dev->data;
+	struct enetc_eth_adapter *priv =
+			ENETC_DEV_PRIVATE(data->dev_private);
+
+	tx_ring = rte_zmalloc(NULL, sizeof(struct enetc_bdr), 0);
+	if (tx_ring == NULL) {
+		ENETC_PMD_ERR("Failed to allocate TX ring memory");
+		err = -ENOMEM;
+		return -1;
+	}
+
+	err = enetc_alloc_txbdr(tx_ring, nb_desc);
+	if (err)
+		goto fail;
+
+	tx_ring->index = queue_idx;
+	tx_ring->ndev = dev;
+	enetc_setup_txbdr(&priv->hw.hw, tx_ring);
+	data->tx_queues[queue_idx] = tx_ring;
+
+	return 0;
+fail:
+	rte_free(tx_ring);
+
+	return err;
+}
+
+static int
+enetc_tx_queue_setup(struct rte_eth_dev *dev,
+		     uint16_t queue_idx,
+		     uint16_t nb_desc,
+		     unsigned int socket_id __rte_unused,
+		     const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+	int err = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	if (nb_desc > MAX_BD_COUNT)
+		return -1;
+
+	err = enetc_alloc_tx_resources(dev, queue_idx, nb_desc);
+
+	return err;
+}
+
+static void
+enetc_tx_queue_release(void *txq)
+{
+	if (txq == NULL)
+		return;
+
+	struct enetc_bdr *tx_ring = (struct enetc_bdr *)txq;
+	struct enetc_eth_hw *eth_hw =
+		ENETC_DEV_PRIVATE_TO_HW(tx_ring->ndev->data->dev_private);
+	struct enetc_hw *hw;
+	struct enetc_swbd *tx_swbd;
+	int i;
+	uint32_t val;
+
+	/* Disable the ring */
+	hw = &eth_hw->hw;
+	val = enetc_txbdr_rd(hw, tx_ring->index, ENETC_TBMR);
+	val &= (~ENETC_TBMR_EN);
+	enetc_txbdr_wr(hw, tx_ring->index, ENETC_TBMR, val);
+
+	/* clean the ring*/
+	i = tx_ring->next_to_clean;
+	tx_swbd = &tx_ring->q_swbd[i];
+	while (tx_swbd->buffer_addr != NULL) {
+		rte_pktmbuf_free(tx_swbd->buffer_addr);
+		tx_swbd->buffer_addr = NULL;
+		tx_swbd++;
+		i++;
+		if (unlikely(i == tx_ring->bd_count)) {
+			i = 0;
+			tx_swbd = &tx_ring->q_swbd[i];
+		}
+	}
+
+	enetc_free_bdr(tx_ring);
+	rte_free(tx_ring);
+}
+
+static int
+enetc_alloc_rxbdr(struct enetc_bdr *rxr,
+		  uint16_t nb_rx_desc)
+{
+	int size;
+
+	size = nb_rx_desc * sizeof(struct enetc_swbd);
+	rxr->q_swbd = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (rxr->q_swbd == NULL)
+		return -ENOMEM;
+
+	size = nb_rx_desc * sizeof(union enetc_rx_bd);
+	rxr->bd_base = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (rxr->bd_base == NULL) {
+		rte_free(rxr->q_swbd);
+		rxr->q_swbd = NULL;
+		return -ENOMEM;
+	}
+
+	rxr->bd_count = nb_rx_desc;
+	rxr->next_to_clean = 0;
+	rxr->next_to_use = 0;
+	rxr->next_to_alloc = 0;
+
+	return 0;
+}
+
+static void
+enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring,
+		  struct rte_mempool *mb_pool)
+{
+	int idx = rx_ring->index;
+	uintptr_t base_addr;
+	uint16_t buf_size;
+
+	base_addr = (uintptr_t)rx_ring->bd_base;
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR0,
+		       lower_32_bits((uint64_t)base_addr));
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBAR1,
+		       upper_32_bits((uint64_t)base_addr));
+	enetc_rxbdr_wr(hw, idx, ENETC_RBLENR,
+		       ENETC_RTBLENR_LEN(rx_ring->bd_count));
+
+	rx_ring->mb_pool = mb_pool;
+	/* enable ring */
+	enetc_rxbdr_wr(hw, idx, ENETC_RBMR, ENETC_RBMR_EN);
+	enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
+	rx_ring->rcir = (void *)((size_t)hw->reg +
+			ENETC_BDR(RX, idx, ENETC_RBCIR));
+	enetc_refill_rx_ring(rx_ring, (enetc_bd_unused(rx_ring)));
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rx_ring->mb_pool) -
+		   RTE_PKTMBUF_HEADROOM);
+	enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, buf_size);
+}
+
+static int
+enetc_alloc_rx_resources(struct rte_eth_dev *dev,
+			 uint16_t rx_queue_id,
+			 uint16_t nb_rx_desc,
+			 struct rte_mempool *mb_pool)
+{
+	int err;
+	struct enetc_bdr *rx_ring;
+	struct rte_eth_dev_data *data =  dev->data;
+	struct enetc_eth_adapter *adapter =
+			ENETC_DEV_PRIVATE(data->dev_private);
+
+	rx_ring = rte_zmalloc(NULL, sizeof(struct enetc_bdr), 0);
+	if (rx_ring == NULL) {
+		ENETC_PMD_ERR("Failed to allocate RX ring memory");
+		err = -ENOMEM;
+		return err;
+	}
+
+	err = enetc_alloc_rxbdr(rx_ring, nb_rx_desc);
+	if (err)
+		goto fail;
+
+	rx_ring->index = rx_queue_id;
+	rx_ring->ndev = dev;
+	enetc_setup_rxbdr(&adapter->hw.hw, rx_ring, mb_pool);
+	data->rx_queues[rx_queue_id] = rx_ring;
+
+	return 0;
+fail:
+	rte_free(rx_ring);
+
+	return err;
+}
+
+static int
+enetc_rx_queue_setup(struct rte_eth_dev *dev,
+		     uint16_t rx_queue_id,
+		     uint16_t nb_rx_desc,
+		     unsigned int socket_id __rte_unused,
+		     const struct rte_eth_rxconf *rx_conf __rte_unused,
+		     struct rte_mempool *mb_pool)
+{
+	int err = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	if (nb_rx_desc > MAX_BD_COUNT)
+		return -1;
+
+	err = enetc_alloc_rx_resources(dev, rx_queue_id,
+				       nb_rx_desc,
+				       mb_pool);
+
+	return err;
+}
+
+static void
+enetc_rx_queue_release(void *rxq)
+{
+	if (rxq == NULL)
+		return;
+
+	struct enetc_bdr *rx_ring = (struct enetc_bdr *)rxq;
+	struct enetc_eth_hw *eth_hw =
+		ENETC_DEV_PRIVATE_TO_HW(rx_ring->ndev->data->dev_private);
+	struct enetc_swbd *q_swbd;
+	struct enetc_hw *hw;
+	uint32_t val;
+	int i;
+
+	/* Disable the ring */
+	hw = &eth_hw->hw;
+	val = enetc_rxbdr_rd(hw, rx_ring->index, ENETC_RBMR);
+	val &= (~ENETC_RBMR_EN);
+	enetc_rxbdr_wr(hw, rx_ring->index, ENETC_RBMR, val);
+
+	/* Clean the ring */
+	i = rx_ring->next_to_clean;
+	q_swbd = &rx_ring->q_swbd[i];
+	while (i != rx_ring->next_to_use) {
+		rte_pktmbuf_free(q_swbd->buffer_addr);
+		q_swbd->buffer_addr = NULL;
+		q_swbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			q_swbd = &rx_ring->q_swbd[i];
+		}
+	}
+
+	enetc_free_bdr(rx_ring);
+	rte_free(rx_ring);
+}
+
 static int
 enetc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 			   struct rte_pci_device *pci_dev)
diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c
new file mode 100644
index 000000000..631e2430d
--- /dev/null
+++ b/drivers/net/enetc/enetc_rxtx.c
@@ -0,0 +1,239 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "rte_ethdev.h"
+#include "rte_malloc.h"
+#include "rte_memzone.h"
+
+#include "base/enetc_hw.h"
+#include "enetc.h"
+#include "enetc_logs.h"
+
+#define ENETC_RXBD_BUNDLE 8 /* Number of BDs to update at once */
+
+static int
+enetc_clean_tx_ring(struct enetc_bdr *tx_ring)
+{
+	int tx_frm_cnt = 0;
+	struct enetc_swbd *tx_swbd;
+	int i;
+
+	i = tx_ring->next_to_clean;
+	tx_swbd = &tx_ring->q_swbd[i];
+	while ((int)(enetc_rd_reg(tx_ring->tcisr) &
+	       ENETC_TBCISR_IDX_MASK) != i) {
+		rte_pktmbuf_free(tx_swbd->buffer_addr);
+		tx_swbd->buffer_addr = NULL;
+		tx_swbd++;
+		i++;
+		if (unlikely(i == tx_ring->bd_count)) {
+			i = 0;
+			tx_swbd = &tx_ring->q_swbd[0];
+		}
+
+		tx_frm_cnt++;
+	}
+
+	tx_ring->next_to_clean = i;
+	return tx_frm_cnt++;
+}
+
+uint16_t
+enetc_xmit_pkts(void *tx_queue,
+		struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts)
+{
+	struct enetc_swbd *tx_swbd;
+	int i, start;
+	struct enetc_tx_bd *txbd;
+	struct enetc_bdr *tx_ring = (struct enetc_bdr *)tx_queue;
+
+	i = tx_ring->next_to_use;
+	start = 0;
+	while (nb_pkts--) {
+		enetc_clean_tx_ring(tx_ring);
+		tx_ring->q_swbd[i].buffer_addr = tx_pkts[start];
+		txbd = ENETC_TXBD(*tx_ring, i);
+		tx_swbd = &tx_ring->q_swbd[i];
+		txbd->frm_len = tx_pkts[start]->pkt_len;
+		txbd->buf_len = txbd->frm_len;
+		txbd->flags = rte_cpu_to_le_16(ENETC_TXBD_FLAGS_F);
+		txbd->addr = (uint64_t)(uintptr_t)
+		rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_addr +
+				 tx_swbd->buffer_addr->data_off);
+		i++;
+		start++;
+		if (unlikely(i == tx_ring->bd_count))
+			i = 0;
+	}
+
+	tx_ring->next_to_use = i;
+	enetc_wr_reg(tx_ring->tcir, i);
+	return start;
+}
+
+int
+enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
+{
+	struct enetc_swbd *rx_swbd;
+	union enetc_rx_bd *rxbd;
+	int i, j;
+
+	i = rx_ring->next_to_use;
+	rx_swbd = &rx_ring->q_swbd[i];
+	rxbd = ENETC_RXBD(*rx_ring, i);
+	for (j = 0; j < buff_cnt; j++) {
+		rx_swbd->buffer_addr =
+			rte_cpu_to_le_64(rte_mbuf_raw_alloc(rx_ring->mb_pool));
+		rxbd->w.addr = (uint64_t)(uintptr_t)
+			       rx_swbd->buffer_addr->buf_addr +
+			       rx_swbd->buffer_addr->data_off;
+		/* clear 'R" as well */
+		rxbd->r.lstatus = 0;
+		rx_swbd++;
+		rxbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rxbd = ENETC_RXBD(*rx_ring, 0);
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+	}
+
+	if (likely(j)) {
+		rx_ring->next_to_alloc = i;
+		rx_ring->next_to_use = i;
+		enetc_wr_reg(rx_ring->rcir, i);
+	}
+
+	return j;
+}
+
+
+static inline void __attribute__((hot))
+enetc_dev_rx_parse(struct rte_mbuf *m, uint16_t parse_results)
+{
+	ENETC_PMD_DP_DEBUG("parse summary = 0x%x   ", parse_results);
+
+	m->packet_type = RTE_PTYPE_UNKNOWN;
+	switch (parse_results) {
+	case ENETC_PKT_TYPE_ETHER:
+		m->packet_type = RTE_PTYPE_L2_ETHER;
+		break;
+	case ENETC_PKT_TYPE_IPV4:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4;
+		break;
+	case ENETC_PKT_TYPE_IPV6:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6;
+		break;
+	case ENETC_PKT_TYPE_IPV4_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_TCP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_TCP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_UDP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_UDP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_SCTP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_SCTP;
+		break;
+	case ENETC_PKT_TYPE_IPV4_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV4 |
+				 RTE_PTYPE_L4_ICMP;
+		break;
+	case ENETC_PKT_TYPE_IPV6_ICMP:
+		m->packet_type = RTE_PTYPE_L2_ETHER |
+				 RTE_PTYPE_L3_IPV6 |
+				 RTE_PTYPE_L4_ICMP;
+		break;
+	/* More switch cases can be added */
+	default:
+		m->packet_type = RTE_PTYPE_UNKNOWN;
+	}
+}
+
+static int
+enetc_clean_rx_ring(struct enetc_bdr *rx_ring,
+		    struct rte_mbuf **rx_pkts,
+		    int work_limit)
+{
+	int rx_frm_cnt = 0;
+	int cleaned_cnt, i;
+	struct enetc_swbd *rx_swbd;
+
+	cleaned_cnt = enetc_bd_unused(rx_ring);
+	/* next descriptor to process */
+	i = rx_ring->next_to_clean;
+	rx_swbd = &rx_ring->q_swbd[i];
+	while (likely(rx_frm_cnt < work_limit)) {
+		union enetc_rx_bd *rxbd;
+		uint32_t bd_status;
+
+		if (cleaned_cnt >= ENETC_RXBD_BUNDLE) {
+			int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt);
+
+			cleaned_cnt -= count;
+		}
+
+		rxbd = ENETC_RXBD(*rx_ring, i);
+		bd_status = rte_le_to_cpu_32(rxbd->r.lstatus);
+		if (!bd_status)
+			break;
+
+		rx_swbd->buffer_addr->pkt_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->data_len = rxbd->r.buf_len;
+		rx_swbd->buffer_addr->hash.rss = rxbd->r.rss_hash;
+		rx_swbd->buffer_addr->ol_flags = 0;
+		enetc_dev_rx_parse(rx_swbd->buffer_addr,
+				   rxbd->r.parse_summary);
+		rx_pkts[rx_frm_cnt] = rx_swbd->buffer_addr;
+		cleaned_cnt++;
+		rx_swbd++;
+		i++;
+		if (unlikely(i == rx_ring->bd_count)) {
+			i = 0;
+			rx_swbd = &rx_ring->q_swbd[i];
+		}
+
+		rx_ring->next_to_clean = i;
+		rx_frm_cnt++;
+	}
+
+	return rx_frm_cnt;
+}
+
+uint16_t
+enetc_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts)
+{
+	struct enetc_bdr *rx_ring = (struct enetc_bdr *)rxq;
+
+	return enetc_clean_rx_ring(rx_ring, rx_pkts, nb_pkts);
+}
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
index 506b174ed..733156bbf 100644
--- a/drivers/net/enetc/meson.build
+++ b/drivers/net/enetc/meson.build
@@ -5,6 +5,7 @@ if host_machine.system() != 'linux'
 	build = false
 endif
 
-sources = files('enetc_ethdev.c')
+sources = files('enetc_ethdev.c',
+		'enetc_rxtx.c')
 
 includes += include_directories('base')
-- 
2.17.1

  reply	other threads:[~2018-09-28  5:17 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-06  5:54 [PATCH 0/3] introduces the ENETC PMD Gagandeep Singh
2018-09-06  5:54 ` [PATCH 1/3] doc: add usage doc for " Gagandeep Singh
2018-09-06  5:54 ` [PATCH 2/3] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
2018-09-19 12:15   ` Shreyansh Jain
2018-09-06  5:54 ` [PATCH 3/3] net/enetc: enable Rx and Tx Gagandeep Singh
2018-09-13  9:41 ` [PATCH v2 0/3] introduces the enetc PMD driver Gagandeep Singh
2018-09-13  9:41   ` [PATCH v2 1/3] doc: add usage doc for ENETC PMD Gagandeep Singh
2018-09-21 13:22     ` Ferruh Yigit
2018-09-13  9:42   ` [PATCH v2 2/3] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
2018-09-21 13:27     ` Ferruh Yigit
2018-09-13  9:42   ` [PATCH v2 3/3] net/enetc: enable Rx and Tx Gagandeep Singh
2018-09-19 12:26     ` Shreyansh Jain
2018-09-21 13:28     ` Ferruh Yigit
2018-09-28  5:16   ` [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
2018-09-28  5:16     ` Gagandeep Singh [this message]
2018-09-28  5:16     ` [PATCH v3 2/3] net/enetc: support packet parse type Gagandeep Singh
2018-09-28  5:16     ` [PATCH v3 3/3] doc: add usage doc for ENETC PMD Gagandeep Singh
2018-09-28  5:26     ` [PATCH v3 0/3] introduces the enetc PMD driver Gagandeep Singh
2018-09-28  7:45     ` [PATCH v4 0/4] " Gagandeep Singh
2018-09-28  7:45       ` [PATCH v4 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
2018-10-01 15:58         ` Ferruh Yigit
2018-09-28  7:45       ` [PATCH v4 2/4] net/enetc: enable Rx and Tx Gagandeep Singh
2018-10-01 15:59         ` Ferruh Yigit
2018-09-28  7:46       ` [PATCH v4 3/4] net/enetc: support packet parse type Gagandeep Singh
2018-09-28 10:17         ` Shreyansh Jain
2018-10-01 15:59           ` Ferruh Yigit
2018-09-28  7:46       ` [PATCH v4 4/4] doc: add usage doc for ENETC PMD Gagandeep Singh
2018-10-01 16:00         ` Ferruh Yigit
2018-09-28 10:36       ` [PATCH v4 0/4] introduces the enetc PMD driver Shreyansh Jain
2018-10-03 13:36       ` [PATCH v5 " Gagandeep Singh
2018-10-03 13:36         ` [PATCH v5 1/4] net/enetc: add ENETC PMD with basic operations Gagandeep Singh
2018-10-03 19:47           ` Ferruh Yigit
2018-10-03 13:36         ` [PATCH v5 2/4] net/enetc: enable Rx and Tx Gagandeep Singh
2018-10-03 13:36         ` [PATCH v5 3/4] net/enetc: support packet parse type Gagandeep Singh
2018-10-03 13:36         ` [PATCH v5 4/4] doc: add usage doc for ENETC PMD Gagandeep Singh
2018-10-03 19:47           ` Ferruh Yigit
2018-10-03 19:48         ` [PATCH v5 0/4] introduces the enetc PMD driver Ferruh Yigit
2018-11-21 17:36           ` Ferruh Yigit
2018-11-22 10:34             ` Shreyansh Jain
2018-11-22 12:08               ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180928051647.32341-2-g.singh@nxp.com \
    --to=g.singh@nxp.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=pankaj.chauhan@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.