DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD
@ 2020-03-16  9:33 Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 1/8] net/octeontx: add multi segment support Harman Kalra
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Harman Kalra @ 2020-03-16  9:33 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru, Harman Kalra

This patchset adds following new features to octeontx PMD:
* Multi segment support
* MTU support
* Setting link up and down
* VLAN filter offload
* flow control - pause frames
* Rx Tx checksum offload

Harman Kalra (6):
  net/octeontx: add multi segment support
  net/octeontx: add framework for Rx/Tx offloads
  net/octeontx: add fast mbuf free support
  net/octeontx: add MTU support
  net/octeontx: add set link up down support
  net/octeontx: support Rx Tx checksum offload

Vamsi Attunuru (2):
  net/octeontx: add VLAN filter offload support
  net/octeontx: add flow control support

 doc/guides/nics/features/octeontx.ini        |  10 +
 doc/guides/nics/octeontx.rst                 |   3 +
 drivers/event/octeontx/ssovf_worker.c        |   9 +-
 drivers/net/octeontx/Makefile                |   1 +
 drivers/net/octeontx/base/octeontx_bgx.c     |  79 ++++
 drivers/net/octeontx/base/octeontx_bgx.h     |  32 ++
 drivers/net/octeontx/base/octeontx_pki_var.h |  32 ++
 drivers/net/octeontx/base/octeontx_pkivf.c   |  40 ++
 drivers/net/octeontx/base/octeontx_pkivf.h   |  20 +
 drivers/net/octeontx/base/octeontx_pkovf.c   |  21 +
 drivers/net/octeontx/base/octeontx_pkovf.h   |  13 +-
 drivers/net/octeontx/meson.build             |   3 +-
 drivers/net/octeontx/octeontx_ethdev.c       | 363 ++++++++++++++---
 drivers/net/octeontx/octeontx_ethdev.h       |  98 ++++-
 drivers/net/octeontx/octeontx_ethdev_ops.c   | 343 ++++++++++++++++
 drivers/net/octeontx/octeontx_logs.h         |   3 +
 drivers/net/octeontx/octeontx_rxtx.c         |  58 +--
 drivers/net/octeontx/octeontx_rxtx.h         | 397 +++++++++++++++++--
 18 files changed, 1421 insertions(+), 104 deletions(-)
 create mode 100644 drivers/net/octeontx/octeontx_ethdev_ops.c

-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-dev] [PATCH 1/8] net/octeontx: add multi segment support
  2020-03-16  9:33 [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Harman Kalra
@ 2020-03-16  9:33 ` Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 2/8] net/octeontx: add framework for Rx/Tx offloads Harman Kalra
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Harman Kalra @ 2020-03-16  9:33 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru, Harman Kalra

Adding multi segment support to the octeontx PMD. Also
adding the logic to share rx/tx ofloads with the eventdev
code.

Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
 doc/guides/nics/features/octeontx.ini        |   1 +
 doc/guides/nics/octeontx.rst                 |   1 +
 drivers/event/octeontx/ssovf_worker.c        |   2 +-
 drivers/net/octeontx/base/octeontx_pki_var.h |  32 ++++++
 drivers/net/octeontx/base/octeontx_pkovf.h   |   5 +-
 drivers/net/octeontx/octeontx_ethdev.c       |  98 +++++++++++++++++-
 drivers/net/octeontx/octeontx_ethdev.h       |  13 ++-
 drivers/net/octeontx/octeontx_rxtx.c         |  30 +++++-
 drivers/net/octeontx/octeontx_rxtx.h         | 102 +++++++++++++++----
 9 files changed, 253 insertions(+), 31 deletions(-)

diff --git a/doc/guides/nics/features/octeontx.ini b/doc/guides/nics/features/octeontx.ini
index 323befe59..19caee61b 100644
--- a/doc/guides/nics/features/octeontx.ini
+++ b/doc/guides/nics/features/octeontx.ini
@@ -9,6 +9,7 @@ Link status          = Y
 Lock-free Tx queue   = Y
 Queue start/stop     = P
 Jumbo frame          = Y
+Scattered Rx         = Y
 Promiscuous mode     = Y
 Unicast MAC filter   = Y
 CRC offload          = Y
diff --git a/doc/guides/nics/octeontx.rst b/doc/guides/nics/octeontx.rst
index 8fc53810b..0c36e10cb 100644
--- a/doc/guides/nics/octeontx.rst
+++ b/doc/guides/nics/octeontx.rst
@@ -20,6 +20,7 @@ Features of the OCTEON TX Ethdev PMD are:
 - Promiscuous mode
 - Port hardware statistics
 - Jumbo frames
+- Scatter-Gather IO support
 - Link state information
 - SR-IOV VF
 - Multiple queues for TX
diff --git a/drivers/event/octeontx/ssovf_worker.c b/drivers/event/octeontx/ssovf_worker.c
index d940b5dd6..f11b9d8c4 100644
--- a/drivers/event/octeontx/ssovf_worker.c
+++ b/drivers/event/octeontx/ssovf_worker.c
@@ -300,7 +300,7 @@ sso_event_tx_adapter_enqueue(void *port,
 	dq = &txq->dq;
 
 	if (__octeontx_xmit_pkts(dq->lmtline_va, dq->ioreg_va, dq->fc_status_va,
-				m) < 0)
+				m, OCCTX_TX_OFFLOAD_NONE) < 0)
 		return 0;
 
 	return 1;
diff --git a/drivers/net/octeontx/base/octeontx_pki_var.h b/drivers/net/octeontx/base/octeontx_pki_var.h
index f4661d24e..4445369ce 100644
--- a/drivers/net/octeontx/base/octeontx_pki_var.h
+++ b/drivers/net/octeontx/base/octeontx_pki_var.h
@@ -215,4 +215,36 @@ enum lf_type_e {
 	LF_UDP_VXLAN	= OCCTX_PKI_LTYPE_UDP_VXLAN,
 	LF_NVGRE	= OCCTX_PKI_LTYPE_NVGRE,
 };
+
+/* Word 0 of HW segment buflink structure */
+typedef union octtx_pki_buflink_w0_u {
+	uint64_t v;
+	struct {
+		uint64_t        size:16;
+		uint64_t        rsvd1:15;
+		uint64_t        invfree:1;
+		/** Aura number of the next segment */
+		uint64_t        aura:16;
+		uint64_t        sw:9;
+		uint64_t        later_invfree:1;
+		uint64_t        rsvd2:5;
+		/** 1 if aura number is set */
+		uint64_t        has_aura:1;
+	} s;
+} octtx_pki_buflink_w0_t;
+
+/* Word 1 of HW segment buflink structure */
+typedef union octtx_pki_buflink_w1_u {
+	uint64_t v;
+	struct {
+		uint64_t        addr;
+	} s;
+} octtx_pki_buflink_w1_t;
+
+/* HW structure linking packet segments into singly linked list */
+typedef struct octtx_pki_buflink_s {
+	octtx_pki_buflink_w0_t    w0; /* Word 0 of the buflink */
+	octtx_pki_buflink_w1_t    w1; /* Word 1 of the buflink */
+} octtx_pki_buflink_t;
+
 #endif /* __OCTEONTX_PKI_VAR_H__ */
diff --git a/drivers/net/octeontx/base/octeontx_pkovf.h b/drivers/net/octeontx/base/octeontx_pkovf.h
index 4208ef880..4e0bb7c2e 100644
--- a/drivers/net/octeontx/base/octeontx_pkovf.h
+++ b/drivers/net/octeontx/base/octeontx_pkovf.h
@@ -36,7 +36,10 @@
 
 /* pko_send_hdr_s + pko_send_link */
 #define PKO_CMD_SZ			(2 << 1)
-#define PKO_SEND_GATHER_SUBDC		(0x0ull << 60)
+#define PKO_SEND_BUFLINK_SUBDC		(0x0ull << 60)
+#define PKO_SEND_BUFLINK_LDTYPE(x)	((x) << 58)
+#define PKO_SEND_BUFLINK_GAUAR(x)	((x) << 24)
+#define PKO_SEND_GATHER_SUBDC		(0x2ull << 60)
 #define PKO_SEND_GATHER_LDTYPE(x)	((x) << 58)
 #define PKO_SEND_GATHER_GAUAR(x)	((x) << 24)
 
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index e8aa4ec78..24c4e83a9 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -24,6 +24,10 @@
 #include "octeontx_rxtx.h"
 #include "octeontx_logs.h"
 
+struct evdev_priv_data {
+	OFFLOAD_FLAGS; /*Sequence should not be changed */
+} __rte_cache_aligned;
+
 struct octeontx_vdev_init_params {
 	uint8_t	nr_port;
 };
@@ -257,6 +261,43 @@ devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf,
 			info->max_num_events;
 }
 
+static uint16_t
+octeontx_tx_offload_flags(struct rte_eth_dev *eth_dev)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
+	uint16_t flags = 0;
+
+	/* Created function for supoorting future offloads */
+	if (nic->tx_offloads & DEV_TX_OFFLOAD_MULTI_SEGS)
+		flags |= OCCTX_TX_MULTI_SEG_F;
+
+	return flags;
+}
+
+static uint16_t
+octeontx_rx_offload_flags(struct rte_eth_dev *eth_dev)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
+	struct rte_eth_dev_data *data = eth_dev->data;
+	struct rte_eth_conf *conf = &data->dev_conf;
+	struct rte_eth_rxmode *rxmode = &conf->rxmode;
+	uint16_t flags = 0;
+
+	if (rxmode->mq_mode == ETH_MQ_RX_RSS)
+		flags |= OCCTX_RX_OFFLOAD_RSS_F;
+
+	if (nic->rx_offloads & DEV_RX_OFFLOAD_SCATTER) {
+		flags |= OCCTX_RX_MULTI_SEG_F;
+		eth_dev->data->scattered_rx = 1;
+		/* If scatter mode is enabled, TX should also be in multi
+		 * seg mode, else memory leak will occur
+		 */
+		nic->tx_offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
+	}
+
+	return flags;
+}
+
 static int
 octeontx_dev_configure(struct rte_eth_dev *dev)
 {
@@ -321,6 +362,11 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 	nic->pki.hash_enable = true;
 	nic->pki.initialized = false;
 
+	nic->rx_offloads |= rxmode->offloads;
+	nic->tx_offloads |= txmode->offloads;
+	nic->rx_offload_flags |= octeontx_rx_offload_flags(dev);
+	nic->tx_offload_flags |= octeontx_tx_offload_flags(dev);
+
 	return 0;
 }
 
@@ -359,6 +405,51 @@ octeontx_dev_close(struct rte_eth_dev *dev)
 	dev->rx_pkt_burst = NULL;
 }
 
+static int
+octeontx_recheck_rx_offloads(struct octeontx_rxq *rxq)
+{
+	struct rte_eth_dev *eth_dev = rxq->eth_dev;
+	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
+	struct rte_eth_dev_data *data = eth_dev->data;
+	struct rte_pktmbuf_pool_private *mbp_priv;
+	struct evdev_priv_data *evdev_priv;
+	struct rte_eventdev *dev;
+	uint32_t buffsz;
+
+	/* Get rx buffer size */
+	mbp_priv = rte_mempool_get_priv(rxq->pool);
+	buffsz = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
+
+	/* Setup scatter mode if needed by jumbo */
+	if (data->dev_conf.rxmode.max_rx_pkt_len > buffsz) {
+		nic->rx_offloads |= DEV_RX_OFFLOAD_SCATTER;
+		nic->rx_offload_flags |= octeontx_rx_offload_flags(eth_dev);
+		nic->tx_offload_flags |= octeontx_tx_offload_flags(eth_dev);
+	}
+
+	/* Sharing offload flags via eventdev priv region */
+	dev = &rte_eventdevs[rxq->evdev];
+	evdev_priv = dev->data->dev_private;
+	evdev_priv->rx_offload_flags = nic->rx_offload_flags;
+	evdev_priv->tx_offload_flags = nic->tx_offload_flags;
+
+	return 0;
+}
+
+static void
+octeontx_set_tx_function(struct rte_eth_dev *dev)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
+
+	const eth_tx_burst_t tx_burst_func[2] = {
+		[0] = octeontx_xmit_pkts,
+		[1] = octeontx_xmit_pkts_mseg,
+	};
+
+	dev->tx_pkt_burst =
+		tx_burst_func[!!(nic->tx_offloads & DEV_TX_OFFLOAD_MULTI_SEGS)];
+}
+
 static int
 octeontx_dev_start(struct rte_eth_dev *dev)
 {
@@ -371,7 +462,7 @@ octeontx_dev_start(struct rte_eth_dev *dev)
 	/*
 	 * Tx start
 	 */
-	dev->tx_pkt_burst = octeontx_xmit_pkts;
+	octeontx_set_tx_function(dev);
 	ret = octeontx_pko_channel_start(nic->base_ochan);
 	if (ret < 0) {
 		octeontx_log_err("fail to conf VF%d no. txq %d chan %d ret %d",
@@ -599,10 +690,8 @@ octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 					struct rte_ether_addr *addr)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
-	uint8_t prom_mode = dev->data->promiscuous;
 	int ret;
 
-	dev->data->promiscuous = 0;
 	ret = octeontx_bgx_port_mac_set(nic->port_id, addr->addr_bytes);
 	if (ret == 0) {
 		/* Update same mac address to BGX CAM table */
@@ -610,7 +699,6 @@ octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 						0);
 	}
 	if (ret < 0) {
-		dev->data->promiscuous = prom_mode;
 		octeontx_log_err("failed to set MAC address on port %d",
 				 nic->port_id);
 	}
@@ -977,7 +1065,9 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	rxq->evdev = nic->evdev;
 	rxq->ev_queues = ev_queues;
 	rxq->ev_ports = ev_ports;
+	rxq->pool = mb_pool;
 
+	octeontx_recheck_rx_offloads(rxq);
 	dev->data->rx_queues[qidx] = rxq;
 	dev->data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
 	return 0;
diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h
index 50fae35d9..10da6a2a0 100644
--- a/drivers/net/octeontx/octeontx_ethdev.h
+++ b/drivers/net/octeontx/octeontx_ethdev.h
@@ -29,8 +29,12 @@
 #define OCTEONTX_MAX_BGX_PORTS			4
 #define OCTEONTX_MAX_LMAC_PER_BGX		4
 
-#define OCTEONTX_RX_OFFLOADS			DEV_RX_OFFLOAD_CHECKSUM
-#define OCTEONTX_TX_OFFLOADS			DEV_TX_OFFLOAD_MT_LOCKFREE
+#define OCTEONTX_RX_OFFLOADS			(DEV_RX_OFFLOAD_CHECKSUM     | \
+						 DEV_RX_OFFLOAD_SCATTER	     | \
+						 DEV_RX_OFFLOAD_JUMBO_FRAME)
+
+#define OCTEONTX_TX_OFFLOADS			(DEV_TX_OFFLOAD_MT_LOCKFREE  | \
+						 DEV_TX_OFFLOAD_MULTI_SEGS)
 
 static inline struct octeontx_nic *
 octeontx_pmd_priv(struct rte_eth_dev *dev)
@@ -73,6 +77,10 @@ struct octeontx_nic {
 
 	uint16_t ev_queues;
 	uint16_t ev_ports;
+	uint64_t rx_offloads;
+	uint16_t rx_offload_flags;
+	uint64_t tx_offloads;
+	uint16_t tx_offload_flags;
 } __rte_cache_aligned;
 
 struct octeontx_txq {
@@ -88,6 +96,7 @@ struct octeontx_rxq {
 	struct rte_eth_dev *eth_dev;
 	uint16_t ev_queues;
 	uint16_t ev_ports;
+	struct rte_mempool *pool;
 } __rte_cache_aligned;
 
 #endif /* __OCTEONTX_ETHDEV_H__ */
diff --git a/drivers/net/octeontx/octeontx_rxtx.c b/drivers/net/octeontx/octeontx_rxtx.c
index 1e201f322..8f6d14b5f 100644
--- a/drivers/net/octeontx/octeontx_rxtx.c
+++ b/drivers/net/octeontx/octeontx_rxtx.c
@@ -32,8 +32,34 @@ octeontx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	rte_cio_wmb();
 	while (count < nb_pkts) {
 		res = __octeontx_xmit_pkts(dq->lmtline_va, dq->ioreg_va,
-					   dq->fc_status_va,
-					   tx_pkts[count]);
+					   dq->fc_status_va, tx_pkts[count],
+					   OCCTX_TX_OFFLOAD_NONE);
+		if (res < 0)
+			break;
+
+		count++;
+	}
+
+	return count; /* return number of pkts transmitted */
+}
+
+uint16_t __hot
+octeontx_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts,
+			uint16_t nb_pkts)
+{
+	int count;
+	struct octeontx_txq *txq = tx_queue;
+	octeontx_dq_t *dq = &txq->dq;
+	int res;
+
+	count = 0;
+
+	rte_cio_wmb();
+	while (count < nb_pkts) {
+		res = __octeontx_xmit_pkts(dq->lmtline_va, dq->ioreg_va,
+					   dq->fc_status_va, tx_pkts[count],
+					   OCCTX_TX_OFFLOAD_NONE |
+					   OCCTX_TX_MULTI_SEG_F);
 		if (res < 0)
 			break;
 
diff --git a/drivers/net/octeontx/octeontx_rxtx.h b/drivers/net/octeontx/octeontx_rxtx.h
index d0d73b304..562268f16 100644
--- a/drivers/net/octeontx/octeontx_rxtx.h
+++ b/drivers/net/octeontx/octeontx_rxtx.h
@@ -11,6 +11,19 @@
 #define __hot	__attribute__((hot))
 #endif
 
+#define OFFLOAD_FLAGS					\
+	uint16_t rx_offload_flags;			\
+	uint16_t tx_offload_flags
+
+#define BIT(nr) (1UL << (nr))
+
+#define OCCTX_RX_OFFLOAD_NONE		(0)
+#define OCCTX_RX_OFFLOAD_RSS_F          BIT(0)
+#define OCCTX_RX_MULTI_SEG_F		BIT(15)
+
+#define OCCTX_TX_OFFLOAD_NONE		(0)
+
+#define OCCTX_TX_MULTI_SEG_F		BIT(15)
 /* Packet type table */
 #define PTYPE_SIZE	OCCTX_PKI_LTYPE_LAST
 
@@ -102,33 +115,76 @@ ptype_table[PTYPE_SIZE][PTYPE_SIZE][PTYPE_SIZE] = {
 
 static __rte_always_inline int
 __octeontx_xmit_pkts(void *lmtline_va, void *ioreg_va, int64_t *fc_status_va,
-			struct rte_mbuf *tx_pkt)
+			struct rte_mbuf *tx_pkt, const uint16_t flag)
 {
-	uint64_t cmd_buf[4] __rte_cache_aligned;
-	uint16_t gaura_id;
+	uint8_t sz = (4 + (!!(flag & OCCTX_TX_MULTI_SEG_F) * 10));
+	/* Max size of PKO SEND desc is 112 bytes*/
+	uint64_t cmd_buf[sz] __rte_cache_aligned;
+	uint8_t nb_segs, nb_desc = 0;
+	uint16_t gaura_id, len = 0;
+	struct rte_mbuf *m_next = NULL;
 
 	if (unlikely(*((volatile int64_t *)fc_status_va) < 0))
 		return -ENOSPC;
 
-	/* Get the gaura Id */
-	gaura_id = octeontx_fpa_bufpool_gpool((uintptr_t)tx_pkt->pool->pool_id);
-
-	/* Setup PKO_SEND_HDR_S */
-	cmd_buf[0] = tx_pkt->data_len & 0xffff;
-	cmd_buf[1] = 0x0;
 
-	/* Set don't free bit if reference count > 1 */
-	if (rte_mbuf_refcnt_read(tx_pkt) > 1)
-		cmd_buf[0] |= (1ULL << 58); /* SET DF */
-
-	/* Setup PKO_SEND_GATHER_S */
-	cmd_buf[(1 << 1) | 1] = rte_mbuf_data_iova(tx_pkt);
-	cmd_buf[(1 << 1) | 0] = PKO_SEND_GATHER_SUBDC |
-				PKO_SEND_GATHER_LDTYPE(0x1ull) |
-				PKO_SEND_GATHER_GAUAR((long)gaura_id) |
-				tx_pkt->data_len;
-
-	octeontx_reg_lmtst(lmtline_va, ioreg_va, cmd_buf, PKO_CMD_SZ);
+	if (flag & OCCTX_TX_MULTI_SEG_F) {
+		nb_segs = tx_pkt->nb_segs;
+		/* Setup PKO_SEND_HDR_S */
+		cmd_buf[nb_desc++] = tx_pkt->pkt_len & 0xffff;
+		cmd_buf[nb_desc++] = 0x0;
+
+		do {
+			m_next = tx_pkt->next;
+			/* To handle case where mbufs belong to diff pools, like
+			 * fragmentation
+			 */
+			gaura_id = octeontx_fpa_bufpool_gpool((uintptr_t)
+							tx_pkt->pool->pool_id);
+
+			/* Setup PKO_SEND_GATHER_S */
+			cmd_buf[nb_desc] = PKO_SEND_GATHER_SUBDC           |
+					     PKO_SEND_GATHER_LDTYPE(0x1ull)  |
+					     PKO_SEND_GATHER_GAUAR((long)
+								   gaura_id) |
+					     tx_pkt->data_len;
+			/* Mark mempool object as "put" since it is freed by
+			 * PKO.
+			 */
+			if (!(cmd_buf[nb_desc] & (1ULL << 57))) {
+				tx_pkt->next = NULL;
+				__mempool_check_cookies(tx_pkt->pool,
+							(void **)&tx_pkt, 1, 0);
+			}
+			nb_desc++;
+
+			cmd_buf[nb_desc++] = rte_mbuf_data_iova(tx_pkt);
+
+			nb_segs--;
+			len += tx_pkt->data_len;
+			tx_pkt = m_next;
+		} while (nb_segs);
+	} else {
+		/* Setup PKO_SEND_HDR_S */
+		cmd_buf[nb_desc++] = tx_pkt->data_len & 0xffff;
+		cmd_buf[nb_desc++] = 0x0;
+
+		/* Mark mempool object as "put" since it is freed by PKO */
+		if (!(cmd_buf[0] & (1ULL << 58)))
+			__mempool_check_cookies(tx_pkt->pool, (void **)&tx_pkt,
+						1, 0);
+		/* Get the gaura Id */
+		gaura_id = octeontx_fpa_bufpool_gpool((uintptr_t)
+						      tx_pkt->pool->pool_id);
+
+		/* Setup PKO_SEND_BUFLINK_S */
+		cmd_buf[nb_desc++] = PKO_SEND_BUFLINK_SUBDC |
+				     PKO_SEND_BUFLINK_LDTYPE(0x1ull) |
+				     PKO_SEND_BUFLINK_GAUAR((long)gaura_id) |
+				     tx_pkt->data_len;
+		cmd_buf[nb_desc++] = rte_mbuf_data_iova(tx_pkt);
+	}
+	octeontx_reg_lmtst(lmtline_va, ioreg_va, cmd_buf, nb_desc);
 
 	return 0;
 }
@@ -136,6 +192,10 @@ __octeontx_xmit_pkts(void *lmtline_va, void *ioreg_va, int64_t *fc_status_va,
 uint16_t
 octeontx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
 
+uint16_t
+octeontx_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts,
+			uint16_t nb_pkts);
+
 uint16_t
 octeontx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-dev] [PATCH 2/8] net/octeontx: add framework for Rx/Tx offloads
  2020-03-16  9:33 [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 1/8] net/octeontx: add multi segment support Harman Kalra
@ 2020-03-16  9:33 ` Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 3/8] net/octeontx: add fast mbuf free support Harman Kalra
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Harman Kalra @ 2020-03-16  9:33 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru, Harman Kalra

Adding macro based framework to hook rx/tx burst function
pointers to the appropriate function based on rx/tx offloads.

Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
 drivers/event/octeontx/ssovf_worker.c  |   9 +-
 drivers/net/octeontx/octeontx_ethdev.c |  27 ++--
 drivers/net/octeontx/octeontx_ethdev.h |  12 +-
 drivers/net/octeontx/octeontx_rxtx.c   |  81 +++++-------
 drivers/net/octeontx/octeontx_rxtx.h   | 173 +++++++++++++++----------
 5 files changed, 151 insertions(+), 151 deletions(-)

diff --git a/drivers/event/octeontx/ssovf_worker.c b/drivers/event/octeontx/ssovf_worker.c
index f11b9d8c4..169939d1a 100644
--- a/drivers/event/octeontx/ssovf_worker.c
+++ b/drivers/event/octeontx/ssovf_worker.c
@@ -272,7 +272,7 @@ sso_event_tx_adapter_enqueue(void *port,
 	struct rte_eth_dev *ethdev;
 	struct ssows *ws = port;
 	struct octeontx_txq *txq;
-	octeontx_dq_t *dq;
+	uint64_t cmd[4];
 
 	RTE_SET_USED(nb_events);
 	switch (ev->sched_type) {
@@ -297,11 +297,6 @@ sso_event_tx_adapter_enqueue(void *port,
 	queue_id = rte_event_eth_tx_adapter_txq_get(m);
 	ethdev = &rte_eth_devices[port_id];
 	txq = ethdev->data->tx_queues[queue_id];
-	dq = &txq->dq;
 
-	if (__octeontx_xmit_pkts(dq->lmtline_va, dq->ioreg_va, dq->fc_status_va,
-				m, OCCTX_TX_OFFLOAD_NONE) < 0)
-		return 0;
-
-	return 1;
+	return __octeontx_xmit_pkts(txq, &m, 1, cmd, OCCTX_TX_OFFLOAD_NONE);
 }
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 24c4e83a9..d6adbbc93 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -436,27 +436,20 @@ octeontx_recheck_rx_offloads(struct octeontx_rxq *rxq)
 	return 0;
 }
 
-static void
-octeontx_set_tx_function(struct rte_eth_dev *dev)
-{
-	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
-
-	const eth_tx_burst_t tx_burst_func[2] = {
-		[0] = octeontx_xmit_pkts,
-		[1] = octeontx_xmit_pkts_mseg,
-	};
-
-	dev->tx_pkt_burst =
-		tx_burst_func[!!(nic->tx_offloads & DEV_TX_OFFLOAD_MULTI_SEGS)];
-}
-
 static int
 octeontx_dev_start(struct rte_eth_dev *dev)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
-	int ret;
+	struct octeontx_rxq *rxq;
+	int ret = 0, i;
 
-	ret = 0;
+	/* Rechecking if any new offload set to update
+	 * rx/tx burst function pointer accordingly.
+	 */
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		octeontx_recheck_rx_offloads(rxq);
+	}
 
 	PMD_INIT_FUNC_TRACE();
 	/*
@@ -1159,7 +1152,7 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
 
 		eth_dev->dev_ops = &octeontx_dev_ops;
 		eth_dev->device = &dev->device;
-		eth_dev->tx_pkt_burst = octeontx_xmit_pkts;
+		octeontx_set_tx_function(eth_dev);
 		eth_dev->rx_pkt_burst = octeontx_recv_pkts;
 		rte_eth_dev_probing_finish(eth_dev);
 		return 0;
diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h
index 10da6a2a0..06223e6e7 100644
--- a/drivers/net/octeontx/octeontx_ethdev.h
+++ b/drivers/net/octeontx/octeontx_ethdev.h
@@ -29,12 +29,12 @@
 #define OCTEONTX_MAX_BGX_PORTS			4
 #define OCTEONTX_MAX_LMAC_PER_BGX		4
 
-#define OCTEONTX_RX_OFFLOADS			(DEV_RX_OFFLOAD_CHECKSUM     | \
-						 DEV_RX_OFFLOAD_SCATTER	     | \
-						 DEV_RX_OFFLOAD_JUMBO_FRAME)
+#define OCTEONTX_RX_OFFLOADS		(DEV_RX_OFFLOAD_CHECKSUM     | \
+					 DEV_RX_OFFLOAD_SCATTER	     | \
+					 DEV_RX_OFFLOAD_JUMBO_FRAME)
 
-#define OCTEONTX_TX_OFFLOADS			(DEV_TX_OFFLOAD_MT_LOCKFREE  | \
-						 DEV_TX_OFFLOAD_MULTI_SEGS)
+#define OCTEONTX_TX_OFFLOADS		(DEV_TX_OFFLOAD_MT_LOCKFREE    |  \
+					 DEV_TX_OFFLOAD_MULTI_SEGS)
 
 static inline struct octeontx_nic *
 octeontx_pmd_priv(struct rte_eth_dev *dev)
@@ -99,4 +99,6 @@ struct octeontx_rxq {
 	struct rte_mempool *pool;
 } __rte_cache_aligned;
 
+void
+octeontx_set_tx_function(struct rte_eth_dev *dev);
 #endif /* __OCTEONTX_ETHDEV_H__ */
diff --git a/drivers/net/octeontx/octeontx_rxtx.c b/drivers/net/octeontx/octeontx_rxtx.c
index 8f6d14b5f..3de88e187 100644
--- a/drivers/net/octeontx/octeontx_rxtx.c
+++ b/drivers/net/octeontx/octeontx_rxtx.c
@@ -19,56 +19,6 @@
 #include "octeontx_rxtx.h"
 #include "octeontx_logs.h"
 
-uint16_t __hot
-octeontx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
-	int count;
-	struct octeontx_txq *txq = tx_queue;
-	octeontx_dq_t *dq = &txq->dq;
-	int res;
-
-	count = 0;
-
-	rte_cio_wmb();
-	while (count < nb_pkts) {
-		res = __octeontx_xmit_pkts(dq->lmtline_va, dq->ioreg_va,
-					   dq->fc_status_va, tx_pkts[count],
-					   OCCTX_TX_OFFLOAD_NONE);
-		if (res < 0)
-			break;
-
-		count++;
-	}
-
-	return count; /* return number of pkts transmitted */
-}
-
-uint16_t __hot
-octeontx_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts,
-			uint16_t nb_pkts)
-{
-	int count;
-	struct octeontx_txq *txq = tx_queue;
-	octeontx_dq_t *dq = &txq->dq;
-	int res;
-
-	count = 0;
-
-	rte_cio_wmb();
-	while (count < nb_pkts) {
-		res = __octeontx_xmit_pkts(dq->lmtline_va, dq->ioreg_va,
-					   dq->fc_status_va, tx_pkts[count],
-					   OCCTX_TX_OFFLOAD_NONE |
-					   OCCTX_TX_MULTI_SEG_F);
-		if (res < 0)
-			break;
-
-		count++;
-	}
-
-	return count; /* return number of pkts transmitted */
-}
-
 uint16_t __hot
 octeontx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 {
@@ -90,3 +40,34 @@ octeontx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 
 	return count; /* return number of pkts received */
 }
+
+#define T(name, f1, sz, flags)					\
+static uint16_t __rte_noinline	__hot					\
+octeontx_xmit_pkts_ ##name(void *tx_queue,				\
+			struct rte_mbuf **tx_pkts, uint16_t pkts)	\
+{									\
+	uint64_t cmd[(sz)];						\
+									\
+	return __octeontx_xmit_pkts(tx_queue, tx_pkts, pkts, cmd,	\
+				    flags);				\
+}
+
+OCCTX_TX_FASTPATH_MODES
+#undef T
+
+void __hot
+octeontx_set_tx_function(struct rte_eth_dev *dev)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
+
+	const eth_tx_burst_t tx_burst_func[2] = {
+#define T(name, f0, sz, flags)			\
+	[f0] =  octeontx_xmit_pkts_ ##name,
+
+OCCTX_TX_FASTPATH_MODES
+#undef T
+	};
+
+	dev->tx_pkt_burst = tx_burst_func
+		[!!(nic->tx_offload_flags & OCCTX_TX_MULTI_SEG_F)];
+}
diff --git a/drivers/net/octeontx/octeontx_rxtx.h b/drivers/net/octeontx/octeontx_rxtx.h
index 562268f16..6182cd8ee 100644
--- a/drivers/net/octeontx/octeontx_rxtx.h
+++ b/drivers/net/octeontx/octeontx_rxtx.h
@@ -113,90 +113,119 @@ ptype_table[PTYPE_SIZE][PTYPE_SIZE][PTYPE_SIZE] = {
 
 };
 
-static __rte_always_inline int
-__octeontx_xmit_pkts(void *lmtline_va, void *ioreg_va, int64_t *fc_status_va,
-			struct rte_mbuf *tx_pkt, const uint16_t flag)
+
+static __rte_always_inline uint16_t
+__octeontx_xmit_prepare(struct rte_mbuf *tx_pkt, uint64_t *cmd_buf,
+			const uint16_t flag __rte_unused)
+{
+	uint16_t gaura_id, nb_desc = 0;
+
+	/* Setup PKO_SEND_HDR_S */
+	cmd_buf[nb_desc++] = tx_pkt->data_len & 0xffff;
+	cmd_buf[nb_desc++] = 0x0;
+
+	/* Mark mempool object as "put" since it is freed by PKO */
+	if (!(cmd_buf[0] & (1ULL << 58)))
+		__mempool_check_cookies(tx_pkt->pool, (void **)&tx_pkt,
+					1, 0);
+	/* Get the gaura Id */
+	gaura_id = octeontx_fpa_bufpool_gpool((uintptr_t)
+					      tx_pkt->pool->pool_id);
+
+	/* Setup PKO_SEND_BUFLINK_S */
+	cmd_buf[nb_desc++] = PKO_SEND_BUFLINK_SUBDC |
+		PKO_SEND_BUFLINK_LDTYPE(0x1ull) |
+		PKO_SEND_BUFLINK_GAUAR((long)gaura_id) |
+		tx_pkt->data_len;
+	cmd_buf[nb_desc++] = rte_mbuf_data_iova(tx_pkt);
+
+	return nb_desc;
+}
+
+static __rte_always_inline uint16_t
+__octeontx_xmit_mseg_prepare(struct rte_mbuf *tx_pkt, uint64_t *cmd_buf,
+			const uint16_t flag __rte_unused)
 {
-	uint8_t sz = (4 + (!!(flag & OCCTX_TX_MULTI_SEG_F) * 10));
-	/* Max size of PKO SEND desc is 112 bytes*/
-	uint64_t cmd_buf[sz] __rte_cache_aligned;
-	uint8_t nb_segs, nb_desc = 0;
+	uint16_t nb_segs, nb_desc = 0;
 	uint16_t gaura_id, len = 0;
 	struct rte_mbuf *m_next = NULL;
 
-	if (unlikely(*((volatile int64_t *)fc_status_va) < 0))
-		return -ENOSPC;
-
-
-	if (flag & OCCTX_TX_MULTI_SEG_F) {
-		nb_segs = tx_pkt->nb_segs;
-		/* Setup PKO_SEND_HDR_S */
-		cmd_buf[nb_desc++] = tx_pkt->pkt_len & 0xffff;
-		cmd_buf[nb_desc++] = 0x0;
-
-		do {
-			m_next = tx_pkt->next;
-			/* To handle case where mbufs belong to diff pools, like
-			 * fragmentation
-			 */
-			gaura_id = octeontx_fpa_bufpool_gpool((uintptr_t)
-							tx_pkt->pool->pool_id);
-
-			/* Setup PKO_SEND_GATHER_S */
-			cmd_buf[nb_desc] = PKO_SEND_GATHER_SUBDC           |
-					     PKO_SEND_GATHER_LDTYPE(0x1ull)  |
-					     PKO_SEND_GATHER_GAUAR((long)
-								   gaura_id) |
-					     tx_pkt->data_len;
-			/* Mark mempool object as "put" since it is freed by
-			 * PKO.
-			 */
-			if (!(cmd_buf[nb_desc] & (1ULL << 57))) {
-				tx_pkt->next = NULL;
-				__mempool_check_cookies(tx_pkt->pool,
-							(void **)&tx_pkt, 1, 0);
-			}
-			nb_desc++;
-
-			cmd_buf[nb_desc++] = rte_mbuf_data_iova(tx_pkt);
-
-			nb_segs--;
-			len += tx_pkt->data_len;
-			tx_pkt = m_next;
-		} while (nb_segs);
-	} else {
-		/* Setup PKO_SEND_HDR_S */
-		cmd_buf[nb_desc++] = tx_pkt->data_len & 0xffff;
-		cmd_buf[nb_desc++] = 0x0;
-
-		/* Mark mempool object as "put" since it is freed by PKO */
-		if (!(cmd_buf[0] & (1ULL << 58)))
-			__mempool_check_cookies(tx_pkt->pool, (void **)&tx_pkt,
-						1, 0);
-		/* Get the gaura Id */
+	nb_segs = tx_pkt->nb_segs;
+	/* Setup PKO_SEND_HDR_S */
+	cmd_buf[nb_desc++] = tx_pkt->pkt_len & 0xffff;
+	cmd_buf[nb_desc++] = 0x0;
+
+	do {
+		m_next = tx_pkt->next;
+		/* To handle case where mbufs belong to diff pools, like
+		 * fragmentation
+		 */
 		gaura_id = octeontx_fpa_bufpool_gpool((uintptr_t)
 						      tx_pkt->pool->pool_id);
 
-		/* Setup PKO_SEND_BUFLINK_S */
-		cmd_buf[nb_desc++] = PKO_SEND_BUFLINK_SUBDC |
-				     PKO_SEND_BUFLINK_LDTYPE(0x1ull) |
-				     PKO_SEND_BUFLINK_GAUAR((long)gaura_id) |
-				     tx_pkt->data_len;
+		/* Setup PKO_SEND_GATHER_S */
+		cmd_buf[nb_desc] = PKO_SEND_GATHER_SUBDC		 |
+				   PKO_SEND_GATHER_LDTYPE(0x1ull)	 |
+				   PKO_SEND_GATHER_GAUAR((long)gaura_id) |
+				   tx_pkt->data_len;
+
+		/* Mark mempool object as "put" since it is freed by
+		 * PKO.
+		 */
+		if (!(cmd_buf[nb_desc] & (1ULL << 57))) {
+			tx_pkt->next = NULL;
+			__mempool_check_cookies(tx_pkt->pool,
+						(void **)&tx_pkt, 1, 0);
+		}
+		nb_desc++;
+
 		cmd_buf[nb_desc++] = rte_mbuf_data_iova(tx_pkt);
-	}
-	octeontx_reg_lmtst(lmtline_va, ioreg_va, cmd_buf, nb_desc);
 
-	return 0;
-}
+		nb_segs--;
+		len += tx_pkt->data_len;
+		tx_pkt = m_next;
+	} while (nb_segs);
 
-uint16_t
-octeontx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
+	return nb_desc;
+}
 
-uint16_t
-octeontx_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts,
-			uint16_t nb_pkts);
+static __rte_always_inline uint16_t
+__octeontx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+		     uint16_t nb_pkts, uint64_t *cmd_buf,
+		     const uint16_t flags)
+{
+	struct octeontx_txq *txq = tx_queue;
+	octeontx_dq_t *dq = &txq->dq;
+	uint16_t count = 0, nb_desc;
+	rte_cio_wmb();
+
+	while (count < nb_pkts) {
+		if (unlikely(*((volatile int64_t *)dq->fc_status_va) < 0))
+			break;
+
+		if (flags & OCCTX_TX_MULTI_SEG_F) {
+			nb_desc = __octeontx_xmit_mseg_prepare(tx_pkts[count],
+							       cmd_buf, flags);
+		} else {
+			nb_desc = __octeontx_xmit_prepare(tx_pkts[count],
+							  cmd_buf, flags);
+		}
+
+		octeontx_reg_lmtst(dq->lmtline_va, dq->ioreg_va, cmd_buf,
+				   nb_desc);
+
+		count++;
+	}
+	return count;
+}
 
 uint16_t
 octeontx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 
-#endif /* __OCTEONTX_RXTX_H__ */
+#define MULT_F       OCCTX_TX_MULTI_SEG_F
+/* [NOFF] [MULTI_SEG] */
+#define OCCTX_TX_FASTPATH_MODES						      \
+T(no_offload,				0,	4,   OCCTX_TX_OFFLOAD_NONE)   \
+T(mseg,					1,	14,  MULT_F)		      \
+
+ #endif /* __OCTEONTX_RXTX_H__ */
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-dev] [PATCH 3/8] net/octeontx: add fast mbuf free support
  2020-03-16  9:33 [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 1/8] net/octeontx: add multi segment support Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 2/8] net/octeontx: add framework for Rx/Tx offloads Harman Kalra
@ 2020-03-16  9:33 ` Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 4/8] net/octeontx: add MTU support Harman Kalra
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Harman Kalra @ 2020-03-16  9:33 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru, Harman Kalra

This patch adds capability to fast release of mbuf
following successful transmission.

Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
 drivers/net/octeontx/octeontx_ethdev.c |  4 +-
 drivers/net/octeontx/octeontx_ethdev.h |  1 +
 drivers/net/octeontx/octeontx_rxtx.c   |  9 +--
 drivers/net/octeontx/octeontx_rxtx.h   | 93 ++++++++++++++++++++++++--
 4 files changed, 98 insertions(+), 9 deletions(-)

diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index d6adbbc93..97b4298fe 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -267,7 +267,9 @@ octeontx_tx_offload_flags(struct rte_eth_dev *eth_dev)
 	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
 	uint16_t flags = 0;
 
-	/* Created function for supoorting future offloads */
+	if (!(nic->tx_offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE))
+		flags |= OCCTX_TX_OFFLOAD_MBUF_NOFF_F;
+
 	if (nic->tx_offloads & DEV_TX_OFFLOAD_MULTI_SEGS)
 		flags |= OCCTX_TX_MULTI_SEG_F;
 
diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h
index 06223e6e7..1abe1703b 100644
--- a/drivers/net/octeontx/octeontx_ethdev.h
+++ b/drivers/net/octeontx/octeontx_ethdev.h
@@ -34,6 +34,7 @@
 					 DEV_RX_OFFLOAD_JUMBO_FRAME)
 
 #define OCTEONTX_TX_OFFLOADS		(DEV_TX_OFFLOAD_MT_LOCKFREE    |  \
+					 DEV_TX_OFFLOAD_MBUF_FAST_FREE |  \
 					 DEV_TX_OFFLOAD_MULTI_SEGS)
 
 static inline struct octeontx_nic *
diff --git a/drivers/net/octeontx/octeontx_rxtx.c b/drivers/net/octeontx/octeontx_rxtx.c
index 3de88e187..c817f7179 100644
--- a/drivers/net/octeontx/octeontx_rxtx.c
+++ b/drivers/net/octeontx/octeontx_rxtx.c
@@ -41,7 +41,7 @@ octeontx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	return count; /* return number of pkts received */
 }
 
-#define T(name, f1, sz, flags)					\
+#define T(name, f1, f0, sz, flags)					\
 static uint16_t __rte_noinline	__hot					\
 octeontx_xmit_pkts_ ##name(void *tx_queue,				\
 			struct rte_mbuf **tx_pkts, uint16_t pkts)	\
@@ -60,14 +60,15 @@ octeontx_set_tx_function(struct rte_eth_dev *dev)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 
-	const eth_tx_burst_t tx_burst_func[2] = {
-#define T(name, f0, sz, flags)			\
-	[f0] =  octeontx_xmit_pkts_ ##name,
+	const eth_tx_burst_t tx_burst_func[2][2] = {
+#define T(name, f1, f0, sz, flags)			\
+	[f1][f0] =  octeontx_xmit_pkts_ ##name,
 
 OCCTX_TX_FASTPATH_MODES
 #undef T
 	};
 
 	dev->tx_pkt_burst = tx_burst_func
+		[!!(nic->tx_offload_flags & OCCTX_TX_OFFLOAD_MBUF_NOFF_F)]
 		[!!(nic->tx_offload_flags & OCCTX_TX_MULTI_SEG_F)];
 }
diff --git a/drivers/net/octeontx/octeontx_rxtx.h b/drivers/net/octeontx/octeontx_rxtx.h
index 6182cd8ee..2383a8eb6 100644
--- a/drivers/net/octeontx/octeontx_rxtx.h
+++ b/drivers/net/octeontx/octeontx_rxtx.h
@@ -22,6 +22,7 @@
 #define OCCTX_RX_MULTI_SEG_F		BIT(15)
 
 #define OCCTX_TX_OFFLOAD_NONE		(0)
+#define OCCTX_TX_OFFLOAD_MBUF_NOFF_F	BIT(3)
 
 #define OCCTX_TX_MULTI_SEG_F		BIT(15)
 /* Packet type table */
@@ -114,9 +115,75 @@ ptype_table[PTYPE_SIZE][PTYPE_SIZE][PTYPE_SIZE] = {
 };
 
 
+static __rte_always_inline uint64_t
+octeontx_pktmbuf_detach(struct rte_mbuf *m)
+{
+	struct rte_mempool *mp = m->pool;
+	uint32_t mbuf_size, buf_len;
+	struct rte_mbuf *md;
+	uint16_t priv_size;
+	uint16_t refcount;
+
+	/* Update refcount of direct mbuf */
+	md = rte_mbuf_from_indirect(m);
+	refcount = rte_mbuf_refcnt_update(md, -1);
+
+	priv_size = rte_pktmbuf_priv_size(mp);
+	mbuf_size = (uint32_t)(sizeof(struct rte_mbuf) + priv_size);
+	buf_len = rte_pktmbuf_data_room_size(mp);
+
+	m->priv_size = priv_size;
+	m->buf_addr = (char *)m + mbuf_size;
+	m->buf_iova = rte_mempool_virt2iova(m) + mbuf_size;
+	m->buf_len = (uint16_t)buf_len;
+	rte_pktmbuf_reset_headroom(m);
+	m->data_len = 0;
+	m->ol_flags = 0;
+	m->next = NULL;
+	m->nb_segs = 1;
+
+	/* Now indirect mbuf is safe to free */
+	rte_pktmbuf_free(m);
+
+	if (refcount == 0) {
+		rte_mbuf_refcnt_set(md, 1);
+		md->data_len = 0;
+		md->ol_flags = 0;
+		md->next = NULL;
+		md->nb_segs = 1;
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+static __rte_always_inline uint64_t
+octeontx_prefree_seg(struct rte_mbuf *m)
+{
+	if (likely(rte_mbuf_refcnt_read(m) == 1)) {
+		if (!RTE_MBUF_DIRECT(m))
+			return octeontx_pktmbuf_detach(m);
+
+		m->next = NULL;
+		m->nb_segs = 1;
+		return 0;
+	} else if (rte_mbuf_refcnt_update(m, -1) == 0) {
+		if (!RTE_MBUF_DIRECT(m))
+			return octeontx_pktmbuf_detach(m);
+
+		rte_mbuf_refcnt_set(m, 1);
+		m->next = NULL;
+		m->nb_segs = 1;
+		return 0;
+	}
+
+	/* Mbuf is having refcount more than 1 so need not to be freed */
+	return 1;
+}
+
 static __rte_always_inline uint16_t
 __octeontx_xmit_prepare(struct rte_mbuf *tx_pkt, uint64_t *cmd_buf,
-			const uint16_t flag __rte_unused)
+			const uint16_t flag)
 {
 	uint16_t gaura_id, nb_desc = 0;
 
@@ -124,6 +191,13 @@ __octeontx_xmit_prepare(struct rte_mbuf *tx_pkt, uint64_t *cmd_buf,
 	cmd_buf[nb_desc++] = tx_pkt->data_len & 0xffff;
 	cmd_buf[nb_desc++] = 0x0;
 
+	/* SEND_HDR[DF] bit controls if buffer is to be freed or
+	 * not, as SG_DESC[I] and SEND_HDR[II] are clear.
+	 */
+	if (flag & OCCTX_TX_OFFLOAD_MBUF_NOFF_F)
+		cmd_buf[0] |= (octeontx_prefree_seg(tx_pkt) <<
+			       58);
+
 	/* Mark mempool object as "put" since it is freed by PKO */
 	if (!(cmd_buf[0] & (1ULL << 58)))
 		__mempool_check_cookies(tx_pkt->pool, (void **)&tx_pkt,
@@ -144,7 +218,7 @@ __octeontx_xmit_prepare(struct rte_mbuf *tx_pkt, uint64_t *cmd_buf,
 
 static __rte_always_inline uint16_t
 __octeontx_xmit_mseg_prepare(struct rte_mbuf *tx_pkt, uint64_t *cmd_buf,
-			const uint16_t flag __rte_unused)
+			const uint16_t flag)
 {
 	uint16_t nb_segs, nb_desc = 0;
 	uint16_t gaura_id, len = 0;
@@ -169,6 +243,14 @@ __octeontx_xmit_mseg_prepare(struct rte_mbuf *tx_pkt, uint64_t *cmd_buf,
 				   PKO_SEND_GATHER_GAUAR((long)gaura_id) |
 				   tx_pkt->data_len;
 
+		/* SG_DESC[I] bit controls if buffer is to be freed or
+		 * not, as SEND_HDR[DF] and SEND_HDR[II] are clear.
+		 */
+		if (flag & OCCTX_TX_OFFLOAD_MBUF_NOFF_F) {
+			cmd_buf[nb_desc] |=
+			     (octeontx_prefree_seg(tx_pkt) << 57);
+		}
+
 		/* Mark mempool object as "put" since it is freed by
 		 * PKO.
 		 */
@@ -222,10 +304,13 @@ __octeontx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 uint16_t
 octeontx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 
+#define NOFF_F       OCCTX_TX_OFFLOAD_MBUF_NOFF_F
 #define MULT_F       OCCTX_TX_MULTI_SEG_F
 /* [NOFF] [MULTI_SEG] */
 #define OCCTX_TX_FASTPATH_MODES						      \
-T(no_offload,				0,	4,   OCCTX_TX_OFFLOAD_NONE)   \
-T(mseg,					1,	14,  MULT_F)		      \
+T(no_offload,				0, 0,	4,   OCCTX_TX_OFFLOAD_NONE)   \
+T(mseg,					0, 1,	14,  MULT_F)		      \
+T(noff,					1, 0,	4,   NOFF_F)		      \
+T(noff_mseg,				1, 1,	14,  NOFF_F | MULT_F)
 
  #endif /* __OCTEONTX_RXTX_H__ */
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-dev] [PATCH 4/8] net/octeontx: add MTU support
  2020-03-16  9:33 [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Harman Kalra
                   ` (2 preceding siblings ...)
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 3/8] net/octeontx: add fast mbuf free support Harman Kalra
@ 2020-03-16  9:33 ` Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 5/8] net/octeontx: add VLAN filter offload support Harman Kalra
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Harman Kalra @ 2020-03-16  9:33 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru, Harman Kalra

Adding support for mtu eth operation which configures mtu based
on max pkt len.

Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
 doc/guides/nics/features/octeontx.ini      |  1 +
 doc/guides/nics/octeontx.rst               |  1 +
 drivers/net/octeontx/base/octeontx_bgx.c   | 17 +++++
 drivers/net/octeontx/base/octeontx_bgx.h   |  1 +
 drivers/net/octeontx/base/octeontx_pkovf.c | 21 +++++++
 drivers/net/octeontx/base/octeontx_pkovf.h |  8 +++
 drivers/net/octeontx/octeontx_ethdev.c     | 72 +++++++++++++++++++++-
 drivers/net/octeontx/octeontx_ethdev.h     | 25 ++++++++
 drivers/net/octeontx/octeontx_logs.h       |  3 +
 9 files changed, 146 insertions(+), 3 deletions(-)

diff --git a/doc/guides/nics/features/octeontx.ini b/doc/guides/nics/features/octeontx.ini
index 19caee61b..e3ee79f0f 100644
--- a/doc/guides/nics/features/octeontx.ini
+++ b/doc/guides/nics/features/octeontx.ini
@@ -8,6 +8,7 @@ Speed capabilities   = Y
 Link status          = Y
 Lock-free Tx queue   = Y
 Queue start/stop     = P
+MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
 Promiscuous mode     = Y
diff --git a/doc/guides/nics/octeontx.rst b/doc/guides/nics/octeontx.rst
index 0c36e10cb..ddb626bc3 100644
--- a/doc/guides/nics/octeontx.rst
+++ b/doc/guides/nics/octeontx.rst
@@ -22,6 +22,7 @@ Features of the OCTEON TX Ethdev PMD are:
 - Jumbo frames
 - Scatter-Gather IO support
 - Link state information
+- MTU update
 - SR-IOV VF
 - Multiple queues for TX
 - Lock-free Tx queue
diff --git a/drivers/net/octeontx/base/octeontx_bgx.c b/drivers/net/octeontx/base/octeontx_bgx.c
index a2d615fb2..cc2bbd104 100644
--- a/drivers/net/octeontx/base/octeontx_bgx.c
+++ b/drivers/net/octeontx/base/octeontx_bgx.c
@@ -226,6 +226,23 @@ octeontx_bgx_port_promisc_set(int port, int en)
 	return res;
 }
 
+int
+octeontx_bgx_port_mtu_set(int port, int mtu)
+{
+	struct octeontx_mbox_hdr hdr;
+	int res;
+
+	hdr.coproc = OCTEONTX_BGX_COPROC;
+	hdr.msg = MBOX_BGX_PORT_SET_MTU;
+	hdr.vfid = port;
+
+	res = octeontx_mbox_send(&hdr, &mtu, sizeof(mtu), NULL, 0);
+	if (res < 0)
+		return -EACCES;
+
+	return res;
+}
+
 int
 octeontx_bgx_port_mac_set(int port, uint8_t *mac_addr)
 {
diff --git a/drivers/net/octeontx/base/octeontx_bgx.h b/drivers/net/octeontx/base/octeontx_bgx.h
index 11c25db67..e385de42d 100644
--- a/drivers/net/octeontx/base/octeontx_bgx.h
+++ b/drivers/net/octeontx/base/octeontx_bgx.h
@@ -131,6 +131,7 @@ int octeontx_bgx_port_mac_set(int port, uint8_t *mac_addr);
 int octeontx_bgx_port_mac_add(int port, uint8_t *mac_addr, int index);
 int octeontx_bgx_port_mac_del(int port, uint32_t index);
 int octeontx_bgx_port_mac_entries_get(int port);
+int octeontx_bgx_port_mtu_set(int port, int mtu);
 
 #endif	/* __OCTEONTX_BGX_H__ */
 
diff --git a/drivers/net/octeontx/base/octeontx_pkovf.c b/drivers/net/octeontx/base/octeontx_pkovf.c
index dacbdd0b4..bf28bc799 100644
--- a/drivers/net/octeontx/base/octeontx_pkovf.c
+++ b/drivers/net/octeontx/base/octeontx_pkovf.c
@@ -465,6 +465,27 @@ octeontx_pko_get_vfid(void)
 	return SIZE_MAX;
 }
 
+int
+octeontx_pko_send_mtu(int port, int mtu)
+{
+	struct octeontx_mbox_hdr hdr;
+	int res;
+	mbox_pko_mtu_cfg_t cfg;
+
+	cfg.mtu = mtu;
+
+	hdr.coproc = OCTEONTX_PKO_COPROC;
+	hdr.msg = MBOX_PKO_MTU_CONFIG;
+	hdr.vfid = port;
+
+	res = octeontx_mbox_send(&hdr, &cfg, sizeof(mbox_pko_mtu_cfg_t),
+				 NULL, 0);
+	if (res < 0)
+		return -EACCES;
+
+	return res;
+}
+
 int
 octeontx_pko_init_fc(const size_t pko_vf_count)
 {
diff --git a/drivers/net/octeontx/base/octeontx_pkovf.h b/drivers/net/octeontx/base/octeontx_pkovf.h
index 4e0bb7c2e..7e1aba3e3 100644
--- a/drivers/net/octeontx/base/octeontx_pkovf.h
+++ b/drivers/net/octeontx/base/octeontx_pkovf.h
@@ -43,6 +43,13 @@
 #define PKO_SEND_GATHER_LDTYPE(x)	((x) << 58)
 #define PKO_SEND_GATHER_GAUAR(x)	((x) << 24)
 
+#define OCTEONTX_PKO_COPROC                     4
+#define MBOX_PKO_MTU_CONFIG			1
+
+typedef struct mbox_pko_mtu_cfg {
+	uint32_t mtu;
+} mbox_pko_mtu_cfg_t;
+
 typedef struct octeontx_dq_s {
 	void *lmtline_va;
 	void *ioreg_va;
@@ -71,5 +78,6 @@ int octeontx_pko_vf_count(void);
 size_t octeontx_pko_get_vfid(void);
 int octeontx_pko_init_fc(const size_t pko_vf_count);
 void octeontx_pko_fc_free(void);
+int octeontx_pko_send_mtu(int port, int mtu);
 
 #endif /* __OCTEONTX_PKO_H__ */
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 97b4298fe..91b9ea645 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -139,7 +139,7 @@ octeontx_port_open(struct octeontx_nic *nic)
 	nic->base_ochan = bgx_port_conf.base_chan;
 	nic->num_ichans = bgx_port_conf.num_chans;
 	nic->num_ochans = bgx_port_conf.num_chans;
-	nic->mtu = bgx_port_conf.mtu;
+	nic->bgx_mtu = bgx_port_conf.mtu;
 	nic->bpen = bgx_port_conf.bpen;
 	nic->fcs_strip = bgx_port_conf.fcs_strip;
 	nic->bcast_mode = bgx_port_conf.bcast_mode;
@@ -407,6 +407,55 @@ octeontx_dev_close(struct rte_eth_dev *dev)
 	dev->rx_pkt_burst = NULL;
 }
 
+static int
+octeontx_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
+{
+	uint32_t buffsz, frame_size = mtu + OCCTX_L2_OVERHEAD;
+	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
+	struct rte_eth_dev_data *data = eth_dev->data;
+	int rc = 0;
+
+	/* Check if MTU is within the allowed range */
+	if (frame_size < OCCTX_MIN_FRS || frame_size > OCCTX_MAX_FRS)
+		return -EINVAL;
+
+	buffsz = data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM;
+
+	/* Refuse MTU that requires the support of scattered packets
+	 * when this feature has not been enabled before.
+	 */
+	if (data->dev_started && frame_size > buffsz &&
+	    !(nic->rx_offloads & DEV_RX_OFFLOAD_SCATTER)) {
+		octeontx_log_err("Scatter mode is disabled");
+		return -EINVAL;
+	}
+
+	/* Check <seg size> * <max_seg>  >= max_frame */
+	if ((nic->rx_offloads & DEV_RX_OFFLOAD_SCATTER)	&&
+	    (frame_size > buffsz * OCCTX_RX_NB_SEG_MAX))
+		return -EINVAL;
+
+	rc = octeontx_pko_send_mtu(nic->port_id, frame_size);
+	if (rc)
+		return rc;
+
+	rc = octeontx_bgx_port_mtu_set(nic->port_id, frame_size);
+	if (rc)
+		return rc;
+
+	if (frame_size > RTE_ETHER_MAX_LEN)
+		nic->rx_offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
+	else
+		nic->rx_offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
+
+	/* Update max_rx_pkt_len */
+	data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+	octeontx_log_info("Received pkt beyond  maxlen %d will be dropped",
+			  frame_size);
+
+	return rc;
+}
+
 static int
 octeontx_recheck_rx_offloads(struct octeontx_rxq *rxq)
 {
@@ -435,6 +484,9 @@ octeontx_recheck_rx_offloads(struct octeontx_rxq *rxq)
 	evdev_priv->rx_offload_flags = nic->rx_offload_flags;
 	evdev_priv->tx_offload_flags = nic->tx_offload_flags;
 
+	/* Setup MTU based on max_rx_pkt_len */
+	nic->mtu = data->dev_conf.rxmode.max_rx_pkt_len - OCCTX_L2_OVERHEAD;
+
 	return 0;
 }
 
@@ -445,6 +497,7 @@ octeontx_dev_start(struct rte_eth_dev *dev)
 	struct octeontx_rxq *rxq;
 	int ret = 0, i;
 
+	PMD_INIT_FUNC_TRACE();
 	/* Rechecking if any new offload set to update
 	 * rx/tx burst function pointer accordingly.
 	 */
@@ -453,7 +506,13 @@ octeontx_dev_start(struct rte_eth_dev *dev)
 		octeontx_recheck_rx_offloads(rxq);
 	}
 
-	PMD_INIT_FUNC_TRACE();
+	/* Setting up the mtu based on max_rx_pkt_len */
+	ret = octeontx_dev_mtu_set(dev, nic->mtu);
+	if (ret) {
+		octeontx_log_err("Failed to set default MTU size %d", ret);
+		goto error;
+	}
+
 	/*
 	 * Tx start
 	 */
@@ -713,6 +772,12 @@ octeontx_dev_info(struct rte_eth_dev *dev,
 			ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
 			ETH_LINK_SPEED_40G;
 
+	/* Min/Max MTU supported */
+	dev_info->min_rx_bufsize = OCCTX_MIN_FRS;
+	dev_info->max_rx_pktlen = OCCTX_MAX_FRS;
+	dev_info->max_mtu = dev_info->max_rx_pktlen - OCCTX_L2_OVERHEAD;
+	dev_info->min_mtu = dev_info->min_rx_bufsize - OCCTX_L2_OVERHEAD;
+
 	dev_info->max_mac_addrs =
 				octeontx_bgx_port_mac_entries_get(nic->port_id);
 	dev_info->max_rx_pktlen = PKI_MAX_PKTLEN;
@@ -1127,6 +1192,7 @@ static const struct eth_dev_ops octeontx_dev_ops = {
 	.rx_queue_setup		 = octeontx_dev_rx_queue_setup,
 	.rx_queue_release	 = octeontx_dev_rx_queue_release,
 	.dev_supported_ptypes_get = octeontx_dev_supported_ptypes_get,
+	.mtu_set                 = octeontx_dev_mtu_set,
 	.pool_ops_supported      = octeontx_pool_ops,
 };
 
@@ -1256,7 +1322,7 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
 				nic->port_id, nic->port_ena,
 				nic->base_ochan, nic->num_ochans,
 				nic->num_tx_queues);
-	PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->mtu);
+	PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->bgx_mtu);
 
 	rte_octeontx_pchan_map[(nic->base_ochan >> 8) & 0x7]
 		[(nic->base_ochan >> 4) & 0xF] = data->port_id;
diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h
index 1abe1703b..27f6556dd 100644
--- a/drivers/net/octeontx/octeontx_ethdev.h
+++ b/drivers/net/octeontx/octeontx_ethdev.h
@@ -29,6 +29,30 @@
 #define OCTEONTX_MAX_BGX_PORTS			4
 #define OCTEONTX_MAX_LMAC_PER_BGX		4
 
+#define OCCTX_RX_NB_SEG_MAX			6
+
+/* VLAN tag inserted by OCCTX_TX_VTAG_ACTION.
+ * In Tx space is always reserved for this in FRS.
+ */
+#define OCCTX_MAX_VTAG_INS		2
+#define OCCTX_MAX_VTAG_ACT_SIZE		(4 * OCCTX_MAX_VTAG_INS)
+
+/* HW config of frame size doesn't include FCS */
+#define OCCTX_MAX_HW_FRS		9212
+#define OCCTX_MIN_HW_FRS		60
+
+/* ETH_HLEN+ETH_FCS+2*VLAN_HLEN */
+#define OCCTX_L2_OVERHEAD	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + \
+				 OCCTX_MAX_VTAG_ACT_SIZE)
+
+/* Since HW FRS includes NPC VTAG insertion space, user has reduced FRS */
+#define OCCTX_MAX_FRS	\
+	(OCCTX_MAX_HW_FRS + RTE_ETHER_CRC_LEN - OCCTX_MAX_VTAG_ACT_SIZE)
+
+#define OCCTX_MIN_FRS		(OCCTX_MIN_HW_FRS + RTE_ETHER_CRC_LEN)
+
+#define OCCTX_MAX_MTU		(OCCTX_MAX_FRS - OCCTX_L2_OVERHEAD)
+
 #define OCTEONTX_RX_OFFLOADS		(DEV_RX_OFFLOAD_CHECKSUM     | \
 					 DEV_RX_OFFLOAD_SCATTER	     | \
 					 DEV_RX_OFFLOAD_JUMBO_FRAME)
@@ -67,6 +91,7 @@ struct octeontx_nic {
 	uint8_t link_up;
 	uint8_t	duplex;
 	uint8_t speed;
+	uint16_t bgx_mtu;
 	uint16_t mtu;
 	uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
 	/* Rx port parameters */
diff --git a/drivers/net/octeontx/octeontx_logs.h b/drivers/net/octeontx/octeontx_logs.h
index ccb8a1b0a..dec8042c6 100644
--- a/drivers/net/octeontx/octeontx_logs.h
+++ b/drivers/net/octeontx/octeontx_logs.h
@@ -19,6 +19,9 @@
 	rte_log(RTE_LOG_ ## level, otx_net_logtype_mbox, \
 			"%s(): " fmt "\n", __func__, ## args)
 
+#define octeontx_log_info(fmt, args...)			\
+	RTE_LOG(INFO, PMD, fmt "\n", ## args)
+
 #define octeontx_log_err(s, ...) PMD_INIT_LOG(ERR, s, ##__VA_ARGS__)
 #define octeontx_log_dbg(s, ...) PMD_DRV_LOG(DEBUG, s, ##__VA_ARGS__)
 #define octeontx_mbox_log(s, ...) PMD_MBOX_LOG(DEBUG, s, ##__VA_ARGS__)
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-dev] [PATCH 5/8] net/octeontx: add VLAN filter offload support
  2020-03-16  9:33 [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Harman Kalra
                   ` (3 preceding siblings ...)
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 4/8] net/octeontx: add MTU support Harman Kalra
@ 2020-03-16  9:33 ` Harman Kalra
  2020-04-06 10:09   ` Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 6/8] net/octeontx: add set link up down support Harman Kalra
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 12+ messages in thread
From: Harman Kalra @ 2020-03-16  9:33 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru

From: Vamsi Attunuru <vattunuru@marvell.com>

Patch adds support for vlan filter offload support.
MBOX messages for vlan filter on/off and vlan filter
entry add/rm are added to configure PCAM entries to
filter out the vlan traffic on a given port.

Patch also defines rx_offload_flag for vlan filtering.

Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
 doc/guides/nics/features/octeontx.ini      |   2 +
 doc/guides/nics/octeontx.rst               |   1 +
 drivers/net/octeontx/Makefile              |   1 +
 drivers/net/octeontx/base/octeontx_pkivf.c |  40 +++++
 drivers/net/octeontx/base/octeontx_pkivf.h |  20 +++
 drivers/net/octeontx/meson.build           |   3 +-
 drivers/net/octeontx/octeontx_ethdev.c     |  10 ++
 drivers/net/octeontx/octeontx_ethdev.h     |  24 ++-
 drivers/net/octeontx/octeontx_ethdev_ops.c | 184 +++++++++++++++++++++
 drivers/net/octeontx/octeontx_rxtx.h       |   1 +
 10 files changed, 284 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/octeontx/octeontx_ethdev_ops.c

diff --git a/doc/guides/nics/features/octeontx.ini b/doc/guides/nics/features/octeontx.ini
index e3ee79f0f..53c541f4b 100644
--- a/doc/guides/nics/features/octeontx.ini
+++ b/doc/guides/nics/features/octeontx.ini
@@ -13,6 +13,8 @@ Jumbo frame          = Y
 Scattered Rx         = Y
 Promiscuous mode     = Y
 Unicast MAC filter   = Y
+VLAN filter          = Y
+VLAN offload         = P
 CRC offload          = Y
 Packet type parsing  = Y
 Basic stats          = Y
diff --git a/doc/guides/nics/octeontx.rst b/doc/guides/nics/octeontx.rst
index ddb626bc3..c8655bf37 100644
--- a/doc/guides/nics/octeontx.rst
+++ b/doc/guides/nics/octeontx.rst
@@ -22,6 +22,7 @@ Features of the OCTEON TX Ethdev PMD are:
 - Jumbo frames
 - Scatter-Gather IO support
 - Link state information
+- MAC/VLAN filtering
 - MTU update
 - SR-IOV VF
 - Multiple queues for TX
diff --git a/drivers/net/octeontx/Makefile b/drivers/net/octeontx/Makefile
index 8ddfc3089..694f403f1 100644
--- a/drivers/net/octeontx/Makefile
+++ b/drivers/net/octeontx/Makefile
@@ -28,6 +28,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_pkovf.c
 SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_pkivf.c
 SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_bgx.c
 SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_ethdev_ops.c
 
 ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)
 CFLAGS_octeontx_rxtx.o += -fno-prefetch-loop-arrays
diff --git a/drivers/net/octeontx/base/octeontx_pkivf.c b/drivers/net/octeontx/base/octeontx_pkivf.c
index 8ce041955..0ddff5488 100644
--- a/drivers/net/octeontx/base/octeontx_pkivf.c
+++ b/drivers/net/octeontx/base/octeontx_pkivf.c
@@ -136,6 +136,46 @@ octeontx_pki_port_errchk_config(int port, pki_errchk_cfg_t *cfg)
 	return res;
 }
 
+int
+octeontx_pki_port_vlan_fltr_config(int port,
+				   pki_port_vlan_filter_config_t *fltr_cfg)
+{
+	struct octeontx_mbox_hdr hdr;
+	int res;
+
+	pki_port_vlan_filter_config_t cfg = *fltr_cfg;
+	int len = sizeof(pki_port_vlan_filter_config_t);
+
+	hdr.coproc = OCTEONTX_PKI_COPROC;
+	hdr.msg = MBOX_PKI_PORT_VLAN_FILTER_CONFIG;
+	hdr.vfid = port;
+
+	res = octeontx_mbox_send(&hdr, &cfg, len, NULL, 0);
+	if (res < 0)
+		return -EACCES;
+	return res;
+}
+
+int
+octeontx_pki_port_vlan_fltr_entry_config(int port,
+				   pki_port_vlan_filter_entry_config_t *e_cfg)
+{
+	struct octeontx_mbox_hdr hdr;
+	int res;
+
+	pki_port_vlan_filter_entry_config_t cfg = *e_cfg;
+	int len = sizeof(pki_port_vlan_filter_entry_config_t);
+
+	hdr.coproc = OCTEONTX_PKI_COPROC;
+	hdr.msg = MBOX_PKI_PORT_VLAN_FILTER_ENTRY_CONFIG;
+	hdr.vfid = port;
+
+	res = octeontx_mbox_send(&hdr, &cfg, len, NULL, 0);
+	if (res < 0)
+		return -EACCES;
+	return res;
+}
+
 #define PCI_VENDOR_ID_CAVIUM               0x177D
 #define PCI_DEVICE_ID_OCTEONTX_PKI_VF      0xA0DD
 
diff --git a/drivers/net/octeontx/base/octeontx_pkivf.h b/drivers/net/octeontx/base/octeontx_pkivf.h
index d541dc3bd..d41eaa57e 100644
--- a/drivers/net/octeontx/base/octeontx_pkivf.h
+++ b/drivers/net/octeontx/base/octeontx_pkivf.h
@@ -36,6 +36,8 @@
 #define MBOX_PKI_PORT_ALLOC_QPG			21
 #define MBOX_PKI_PORT_FREE_QPG			22
 #define MBOX_PKI_SET_PORT_CONFIG		23
+#define MBOX_PKI_PORT_VLAN_FILTER_CONFIG	24
+#define MBOX_PKI_PORT_VLAN_FILTER_ENTRY_CONFIG	25
 
 #define MBOX_PKI_MAX_QOS_ENTRY 64
 
@@ -236,6 +238,20 @@ typedef struct pki_port_modify_qos_entry {
 	struct pki_qos_entry qos_entry;
 } pki_mod_qos_t;
 
+/* pki port VLAN filter config */
+typedef struct pki_port_vlan_filter_config {
+	uint8_t port_type;  /* OCTTX_PORT_TYPE_[NET/INT/PCI] */
+	uint8_t fltr_conf; /* '1' to enable & '0' to disable */
+} pki_port_vlan_filter_config_t;
+
+/* pki port VLAN filter entry config */
+typedef struct pki_port_vlan_filter_entry_config {
+	uint8_t port_type;  /* OCTTX_PORT_TYPE_[NET/INT/PCI] */
+	uint8_t entry_conf; /* '1' to add & '0' to remove */
+	uint16_t vlan_tpid; /* in host byte-order */
+	uint16_t vlan_id;   /* in host byte-order */
+} pki_port_vlan_filter_entry_config_t;
+
 static inline int
 octeontx_pki_port_modify_qos(int port, pki_mod_qos_t *qos_cfg)
 {
@@ -348,5 +364,9 @@ int octeontx_pki_port_pktbuf_config(int port, pki_pktbuf_cfg_t *buf_cfg);
 int octeontx_pki_port_create_qos(int port, pki_qos_cfg_t *qos_cfg);
 int octeontx_pki_port_close(int port);
 int octeontx_pki_port_errchk_config(int port, pki_errchk_cfg_t *cfg);
+int octeontx_pki_port_vlan_fltr_config(int port,
+				pki_port_vlan_filter_config_t *fltr_cfg);
+int octeontx_pki_port_vlan_fltr_entry_config(int port,
+				pki_port_vlan_filter_entry_config_t *entry_cfg);
 
 #endif /* __OCTEONTX_PKI_H__ */
diff --git a/drivers/net/octeontx/meson.build b/drivers/net/octeontx/meson.build
index 0e249eb98..f7ba6e68b 100644
--- a/drivers/net/octeontx/meson.build
+++ b/drivers/net/octeontx/meson.build
@@ -5,7 +5,8 @@ subdir('base')
 objs = [base_objs]
 
 sources = files('octeontx_rxtx.c',
-		'octeontx_ethdev.c'
+		'octeontx_ethdev.c',
+		'octeontx_ethdev_ops.c'
 		)
 
 allow_experimental_apis = true
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 91b9ea645..5dd40bc04 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -360,6 +360,12 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 		return -EFAULT;
 	}
 
+	ret = octeontx_dev_vlan_offload_init(dev);
+	if (ret) {
+		octeontx_log_err("failed to initialize vlan offload");
+		return -EFAULT;
+	}
+
 	nic->pki.classifier_enable = false;
 	nic->pki.hash_enable = true;
 	nic->pki.initialized = false;
@@ -384,6 +390,8 @@ octeontx_dev_close(struct rte_eth_dev *dev)
 
 	rte_event_dev_close(nic->evdev);
 
+	octeontx_dev_vlan_offload_fini(dev);
+
 	ret = octeontx_pko_channel_close(nic->base_ochan);
 	if (ret < 0) {
 		octeontx_log_err("failed to close channel %d VF%d %d %d",
@@ -1185,6 +1193,8 @@ static const struct eth_dev_ops octeontx_dev_ops = {
 	.mac_addr_remove	 = octeontx_dev_mac_addr_del,
 	.mac_addr_add		 = octeontx_dev_mac_addr_add,
 	.mac_addr_set		 = octeontx_dev_default_mac_addr_set,
+	.vlan_offload_set	 = octeontx_dev_vlan_offload_set,
+	.vlan_filter_set	 = octeontx_dev_vlan_filter_set,
 	.tx_queue_start		 = octeontx_dev_tx_queue_start,
 	.tx_queue_stop		 = octeontx_dev_tx_queue_stop,
 	.tx_queue_setup		 = octeontx_dev_tx_queue_setup,
diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h
index 27f6556dd..e7e0d40c7 100644
--- a/drivers/net/octeontx/octeontx_ethdev.h
+++ b/drivers/net/octeontx/octeontx_ethdev.h
@@ -55,7 +55,8 @@
 
 #define OCTEONTX_RX_OFFLOADS		(DEV_RX_OFFLOAD_CHECKSUM     | \
 					 DEV_RX_OFFLOAD_SCATTER	     | \
-					 DEV_RX_OFFLOAD_JUMBO_FRAME)
+					 DEV_RX_OFFLOAD_JUMBO_FRAME  | \
+					 DEV_RX_OFFLOAD_VLAN_FILTER)
 
 #define OCTEONTX_TX_OFFLOADS		(DEV_TX_OFFLOAD_MT_LOCKFREE    |  \
 					 DEV_TX_OFFLOAD_MBUF_FAST_FREE |  \
@@ -70,6 +71,18 @@ octeontx_pmd_priv(struct rte_eth_dev *dev)
 extern uint16_t
 rte_octeontx_pchan_map[OCTEONTX_MAX_BGX_PORTS][OCTEONTX_MAX_LMAC_PER_BGX];
 
+struct vlan_entry {
+	TAILQ_ENTRY(vlan_entry) next;
+	uint16_t vlan_id;
+};
+
+TAILQ_HEAD(octeontx_vlan_filter_tbl, vlan_entry);
+
+struct octeontx_vlan_info {
+	struct octeontx_vlan_filter_tbl fltr_tbl;
+	uint8_t filter_on;
+};
+
 /* Octeontx ethdev nic */
 struct octeontx_nic {
 	struct rte_eth_dev *dev;
@@ -107,6 +120,7 @@ struct octeontx_nic {
 	uint16_t rx_offload_flags;
 	uint64_t tx_offloads;
 	uint16_t tx_offload_flags;
+	struct octeontx_vlan_info vlan_info;
 } __rte_cache_aligned;
 
 struct octeontx_txq {
@@ -127,4 +141,12 @@ struct octeontx_rxq {
 
 void
 octeontx_set_tx_function(struct rte_eth_dev *dev);
+
+/* VLAN */
+int octeontx_dev_vlan_offload_init(struct rte_eth_dev *dev);
+int octeontx_dev_vlan_offload_fini(struct rte_eth_dev *eth_dev);
+int octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+int octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev,
+				 uint16_t vlan_id, int on);
+
 #endif /* __OCTEONTX_ETHDEV_H__ */
diff --git a/drivers/net/octeontx/octeontx_ethdev_ops.c b/drivers/net/octeontx/octeontx_ethdev_ops.c
new file mode 100644
index 000000000..8c3065542
--- /dev/null
+++ b/drivers/net/octeontx/octeontx_ethdev_ops.c
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <rte_malloc.h>
+
+#include "octeontx_ethdev.h"
+#include "octeontx_logs.h"
+#include "octeontx_rxtx.h"
+
+static int
+octeontx_vlan_hw_filter(struct octeontx_nic *nic, uint8_t flag)
+{
+	struct octeontx_vlan_info *vlan = &nic->vlan_info;
+	pki_port_vlan_filter_config_t fltr_conf;
+	int rc = 0;
+
+	if (vlan->filter_on == flag)
+		return rc;
+
+	fltr_conf.port_type = OCTTX_PORT_TYPE_NET;
+	fltr_conf.fltr_conf = flag;
+
+	rc = octeontx_pki_port_vlan_fltr_config(nic->port_id, &fltr_conf);
+	if (rc != 0) {
+		octeontx_log_err("Fail to configure vlan hw filter for port %d",
+				 nic->port_id);
+		goto done;
+	}
+
+	vlan->filter_on = flag;
+
+done:
+	return rc;
+}
+
+int
+octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
+	struct rte_eth_rxmode *rxmode;
+	int rc = 0;
+
+	rxmode = &dev->data->dev_conf.rxmode;
+
+	if (mask & ETH_VLAN_EXTEND_MASK) {
+		octeontx_log_err("Extend offload not supported");
+		return -ENOTSUP;
+	}
+
+	if (mask & ETH_VLAN_STRIP_MASK) {
+		octeontx_log_err("VLAN strip offload not supported");
+		return -ENOTSUP;
+	}
+
+	if (mask & ETH_VLAN_FILTER_MASK) {
+		if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
+			rc = octeontx_vlan_hw_filter(nic, true);
+			if (rc)
+				goto done;
+
+			nic->rx_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
+			nic->rx_offload_flags |= OCCTX_RX_VLAN_FLTR_F;
+		} else {
+			rc = octeontx_vlan_hw_filter(nic, false);
+			if (rc)
+				goto done;
+
+			nic->rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
+			nic->rx_offload_flags &= ~OCCTX_RX_VLAN_FLTR_F;
+		}
+	}
+
+done:
+	return rc;
+}
+
+int
+octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
+	struct octeontx_vlan_info *vlan = &nic->vlan_info;
+	pki_port_vlan_filter_entry_config_t fltr_entry;
+	struct vlan_entry *entry = NULL;
+	int entry_count = 0;
+	int rc = -EINVAL;
+
+	if (on) {
+		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
+			if (entry->vlan_id == vlan_id) {
+				octeontx_log_dbg("Vlan Id is already set");
+				return 0;
+			}
+	} else {
+		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
+			entry_count++;
+
+		if (!entry_count)
+			return 0;
+	}
+
+	fltr_entry.port_type = OCTTX_PORT_TYPE_NET;
+	fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN;
+	fltr_entry.vlan_id = vlan_id;
+	fltr_entry.entry_conf = on;
+
+	if (on) {
+		entry = rte_zmalloc("octeontx_nic_vlan_entry",
+				    sizeof(struct vlan_entry), 0);
+		if (!entry) {
+			octeontx_log_err("Failed to allocate memory");
+			return -ENOMEM;
+		}
+	}
+
+	rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id,
+						      &fltr_entry);
+	if (rc != 0) {
+		octeontx_log_err("Fail to configure vlan filter entry "
+				 "for port %d", nic->port_id);
+		if (entry)
+			rte_free(entry);
+
+		goto done;
+	}
+
+	if (on) {
+		entry->vlan_id  = vlan_id;
+		TAILQ_INSERT_HEAD(&vlan->fltr_tbl, entry, next);
+	} else {
+		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
+			if (entry->vlan_id == vlan_id) {
+				TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
+				rte_free(entry);
+				break;
+			}
+		}
+	}
+
+done:
+	return rc;
+}
+
+int
+octeontx_dev_vlan_offload_init(struct rte_eth_dev *dev)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
+	int rc;
+
+	TAILQ_INIT(&nic->vlan_info.fltr_tbl);
+
+	rc = octeontx_dev_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK);
+	if (rc)
+		octeontx_log_err("Failed to set vlan offload rc=%d", rc);
+
+	return rc;
+}
+
+int
+octeontx_dev_vlan_offload_fini(struct rte_eth_dev *dev)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
+	struct octeontx_vlan_info *vlan = &nic->vlan_info;
+	pki_port_vlan_filter_entry_config_t fltr_entry;
+	struct vlan_entry *entry;
+	int rc = 0;
+
+	TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
+		fltr_entry.port_type = OCTTX_PORT_TYPE_NET;
+		fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN;
+		fltr_entry.vlan_id = entry->vlan_id;
+		fltr_entry.entry_conf = 0;
+
+		rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id,
+							      &fltr_entry);
+		if (rc != 0) {
+			octeontx_log_err("Fail to configure vlan filter entry "
+					 "for port %d", nic->port_id);
+			break;
+		}
+	}
+
+	return rc;
+}
diff --git a/drivers/net/octeontx/octeontx_rxtx.h b/drivers/net/octeontx/octeontx_rxtx.h
index 2383a8eb6..cc044dd79 100644
--- a/drivers/net/octeontx/octeontx_rxtx.h
+++ b/drivers/net/octeontx/octeontx_rxtx.h
@@ -19,6 +19,7 @@
 
 #define OCCTX_RX_OFFLOAD_NONE		(0)
 #define OCCTX_RX_OFFLOAD_RSS_F          BIT(0)
+#define OCCTX_RX_VLAN_FLTR_F            BIT(1)
 #define OCCTX_RX_MULTI_SEG_F		BIT(15)
 
 #define OCCTX_TX_OFFLOAD_NONE		(0)
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-dev] [PATCH 6/8] net/octeontx: add set link up down support
  2020-03-16  9:33 [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Harman Kalra
                   ` (4 preceding siblings ...)
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 5/8] net/octeontx: add VLAN filter offload support Harman Kalra
@ 2020-03-16  9:33 ` Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 7/8] net/octeontx: add flow control support Harman Kalra
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Harman Kalra @ 2020-03-16  9:33 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru, Harman Kalra

Adding support for setting link up/down eth operation.
It is used to enable disable lmac.  Also implemented a
poll function for getting the link status at regular
intervals.

Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
 doc/guides/nics/features/octeontx.ini      |   1 +
 drivers/net/octeontx/base/octeontx_bgx.c   |  12 ++
 drivers/net/octeontx/base/octeontx_bgx.h   |   3 +
 drivers/net/octeontx/octeontx_ethdev.c     | 152 ++++++++++++++++-----
 drivers/net/octeontx/octeontx_ethdev.h     |   7 +-
 drivers/net/octeontx/octeontx_ethdev_ops.c |  31 +++++
 6 files changed, 169 insertions(+), 37 deletions(-)

diff --git a/doc/guides/nics/features/octeontx.ini b/doc/guides/nics/features/octeontx.ini
index 53c541f4b..377bb4d30 100644
--- a/doc/guides/nics/features/octeontx.ini
+++ b/doc/guides/nics/features/octeontx.ini
@@ -6,6 +6,7 @@
 [Features]
 Speed capabilities   = Y
 Link status          = Y
+Link status event    = Y
 Lock-free Tx queue   = Y
 Queue start/stop     = P
 MTU update           = Y
diff --git a/drivers/net/octeontx/base/octeontx_bgx.c b/drivers/net/octeontx/base/octeontx_bgx.c
index cc2bbd104..d8611cb77 100644
--- a/drivers/net/octeontx/base/octeontx_bgx.c
+++ b/drivers/net/octeontx/base/octeontx_bgx.c
@@ -207,6 +207,18 @@ octeontx_bgx_port_link_status(int port)
 	return link;
 }
 
+int
+octeontx_bgx_port_set_link_state(int port, bool enable)
+{
+	struct octeontx_mbox_hdr hdr;
+
+	hdr.coproc = OCTEONTX_BGX_COPROC;
+	hdr.msg = MBOX_BGX_PORT_SET_LINK_STATE;
+	hdr.vfid = port;
+
+	return octeontx_mbox_send(&hdr, &enable, sizeof(bool), NULL, 0);
+}
+
 int
 octeontx_bgx_port_promisc_set(int port, int en)
 {
diff --git a/drivers/net/octeontx/base/octeontx_bgx.h b/drivers/net/octeontx/base/octeontx_bgx.h
index e385de42d..6b7476510 100644
--- a/drivers/net/octeontx/base/octeontx_bgx.h
+++ b/drivers/net/octeontx/base/octeontx_bgx.h
@@ -5,6 +5,7 @@
 #ifndef __OCTEONTX_BGX_H__
 #define __OCTEONTX_BGX_H__
 
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
 
@@ -31,6 +32,7 @@
 #define MBOX_BGX_PORT_ADD_MACADDR	15
 #define MBOX_BGX_PORT_DEL_MACADDR	16
 #define MBOX_BGX_PORT_GET_MACADDR_ENTRIES 17
+#define MBOX_BGX_PORT_SET_LINK_STATE	20
 
 /* BGX port configuration parameters: */
 typedef struct octeontx_mbox_bgx_port_conf {
@@ -132,6 +134,7 @@ int octeontx_bgx_port_mac_add(int port, uint8_t *mac_addr, int index);
 int octeontx_bgx_port_mac_del(int port, uint32_t index);
 int octeontx_bgx_port_mac_entries_get(int port);
 int octeontx_bgx_port_mtu_set(int port, int mtu);
+int octeontx_bgx_port_set_link_state(int port, bool en);
 
 #endif	/* __OCTEONTX_BGX_H__ */
 
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 5dd40bc04..08c621b4b 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -11,6 +11,8 @@
 
 #include <rte_alarm.h>
 #include <rte_branch_prediction.h>
+#include <rte_bus_vdev.h>
+#include <rte_cycles.h>
 #include <rte_debug.h>
 #include <rte_devargs.h>
 #include <rte_dev.h>
@@ -18,7 +20,6 @@
 #include <rte_malloc.h>
 #include <rte_mbuf_pool_ops.h>
 #include <rte_prefetch.h>
-#include <rte_bus_vdev.h>
 
 #include "octeontx_ethdev.h"
 #include "octeontx_rxtx.h"
@@ -153,11 +154,102 @@ octeontx_port_open(struct octeontx_nic *nic)
 	return res;
 }
 
+static void
+octeontx_link_status_print(struct rte_eth_dev *eth_dev,
+			   struct rte_eth_link *link)
+{
+	if (link && link->link_status)
+		octeontx_log_info("Port %u: Link Up - speed %u Mbps - %s",
+			  (eth_dev->data->port_id),
+			  link->link_speed,
+			  link->link_duplex == ETH_LINK_FULL_DUPLEX ?
+			  "full-duplex" : "half-duplex");
+	else
+		octeontx_log_info("Port %d: Link Down",
+				  (int)(eth_dev->data->port_id));
+}
+
+static void
+octeontx_link_status_update(struct octeontx_nic *nic,
+			 struct rte_eth_link *link)
+{
+	memset(link, 0, sizeof(*link));
+
+	link->link_status = nic->link_up ? ETH_LINK_UP : ETH_LINK_DOWN;
+
+	switch (nic->speed) {
+	case OCTEONTX_LINK_SPEED_SGMII:
+		link->link_speed = ETH_SPEED_NUM_1G;
+		break;
+
+	case OCTEONTX_LINK_SPEED_XAUI:
+		link->link_speed = ETH_SPEED_NUM_10G;
+		break;
+
+	case OCTEONTX_LINK_SPEED_RXAUI:
+	case OCTEONTX_LINK_SPEED_10G_R:
+		link->link_speed = ETH_SPEED_NUM_10G;
+		break;
+	case OCTEONTX_LINK_SPEED_QSGMII:
+		link->link_speed = ETH_SPEED_NUM_5G;
+		break;
+	case OCTEONTX_LINK_SPEED_40G_R:
+		link->link_speed = ETH_SPEED_NUM_40G;
+		break;
+
+	case OCTEONTX_LINK_SPEED_RESERVE1:
+	case OCTEONTX_LINK_SPEED_RESERVE2:
+	default:
+		link->link_speed = ETH_SPEED_NUM_NONE;
+		octeontx_log_err("incorrect link speed %d", nic->speed);
+		break;
+	}
+
+	link->link_duplex = ETH_LINK_FULL_DUPLEX;
+	link->link_autoneg = ETH_LINK_AUTONEG;
+}
+
+static void
+octeontx_link_status_poll(void *arg)
+{
+	struct octeontx_nic *nic = arg;
+	struct rte_eth_link link;
+	struct rte_eth_dev *dev;
+	int res;
+
+	PMD_INIT_FUNC_TRACE();
+
+	dev = nic->dev;
+
+	res = octeontx_bgx_port_link_status(nic->port_id);
+	if (res < 0) {
+		octeontx_log_err("Failed to get port %d link status",
+				nic->port_id);
+	} else {
+		if (nic->link_up != (uint8_t)res) {
+			nic->link_up = (uint8_t)res;
+			octeontx_link_status_update(nic, &link);
+			octeontx_link_status_print(dev, &link);
+			rte_eth_linkstatus_set(dev, &link);
+			_rte_eth_dev_callback_process(dev,
+						      RTE_ETH_EVENT_INTR_LSC,
+						      NULL);
+		}
+	}
+
+	res = rte_eal_alarm_set(OCCTX_INTR_POLL_INTERVAL_MS * 1000,
+				octeontx_link_status_poll, nic);
+	if (res < 0)
+		octeontx_log_err("Failed to restart alarm for port %d, err: %d",
+				nic->port_id, res);
+}
+
 static void
 octeontx_port_close(struct octeontx_nic *nic)
 {
 	PMD_INIT_FUNC_TRACE();
 
+	rte_eal_alarm_cancel(octeontx_link_status_poll, nic);
 	octeontx_bgx_port_close(nic->port_id);
 	octeontx_log_dbg("port closed %d", nic->port_id);
 }
@@ -411,6 +503,8 @@ octeontx_dev_close(struct rte_eth_dev *dev)
 	rte_free(dev->data->mac_addrs);
 	dev->data->mac_addrs = NULL;
 
+	octeontx_port_close(nic);
+
 	dev->tx_pkt_burst = NULL;
 	dev->rx_pkt_burst = NULL;
 }
@@ -503,7 +597,7 @@ octeontx_dev_start(struct rte_eth_dev *dev)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 	struct octeontx_rxq *rxq;
-	int ret = 0, i;
+	int ret, i;
 
 	PMD_INIT_FUNC_TRACE();
 	/* Rechecking if any new offload set to update
@@ -636,7 +730,10 @@ octeontx_port_link_status(struct octeontx_nic *nic)
 		return res;
 	}
 
-	nic->link_up = (uint8_t)res;
+	if (nic->link_up != (uint8_t)res || nic->print_flag == -1) {
+		nic->link_up = (uint8_t)res;
+		nic->print_flag = 1;
+	}
 	octeontx_log_dbg("port %d link status %d", nic->port_id, nic->link_up);
 
 	return res;
@@ -661,39 +758,12 @@ octeontx_dev_link_update(struct rte_eth_dev *dev,
 		return res;
 	}
 
-	link.link_status = nic->link_up;
-
-	switch (nic->speed) {
-	case OCTEONTX_LINK_SPEED_SGMII:
-		link.link_speed = ETH_SPEED_NUM_1G;
-		break;
-
-	case OCTEONTX_LINK_SPEED_XAUI:
-		link.link_speed = ETH_SPEED_NUM_10G;
-		break;
-
-	case OCTEONTX_LINK_SPEED_RXAUI:
-	case OCTEONTX_LINK_SPEED_10G_R:
-		link.link_speed = ETH_SPEED_NUM_10G;
-		break;
-	case OCTEONTX_LINK_SPEED_QSGMII:
-		link.link_speed = ETH_SPEED_NUM_5G;
-		break;
-	case OCTEONTX_LINK_SPEED_40G_R:
-		link.link_speed = ETH_SPEED_NUM_40G;
-		break;
-
-	case OCTEONTX_LINK_SPEED_RESERVE1:
-	case OCTEONTX_LINK_SPEED_RESERVE2:
-	default:
-		link.link_speed = ETH_SPEED_NUM_NONE;
-		octeontx_log_err("incorrect link speed %d", nic->speed);
-		break;
+	octeontx_link_status_update(nic, &link);
+	if (nic->print_flag) {
+		octeontx_link_status_print(nic->dev, &link);
+		nic->print_flag = 0;
 	}
 
-	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_autoneg = ETH_LINK_AUTONEG;
-
 	return rte_eth_linkstatus_set(dev, &link);
 }
 
@@ -855,7 +925,7 @@ octeontx_vf_start_tx_queue(struct rte_eth_dev *dev, struct octeontx_nic *nic,
 	return res;
 }
 
-static int
+int
 octeontx_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t qidx)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
@@ -881,7 +951,7 @@ octeontx_vf_stop_tx_queue(struct rte_eth_dev *dev, struct octeontx_nic *nic,
 	return ret;
 }
 
-static int
+int
 octeontx_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t qidx)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
@@ -1201,6 +1271,8 @@ static const struct eth_dev_ops octeontx_dev_ops = {
 	.tx_queue_release	 = octeontx_dev_tx_queue_release,
 	.rx_queue_setup		 = octeontx_dev_rx_queue_setup,
 	.rx_queue_release	 = octeontx_dev_rx_queue_release,
+	.dev_set_link_up          = octeontx_dev_set_link_up,
+	.dev_set_link_down        = octeontx_dev_set_link_down,
 	.dev_supported_ptypes_get = octeontx_dev_supported_ptypes_get,
 	.mtu_set                 = octeontx_dev_mtu_set,
 	.pool_ops_supported      = octeontx_pool_ops,
@@ -1285,6 +1357,7 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
 
 	nic->ev_queues = 1;
 	nic->ev_ports = 1;
+	nic->print_flag = -1;
 
 	data->dev_link.link_status = ETH_LINK_DOWN;
 	data->dev_started = 0;
@@ -1321,6 +1394,13 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
 		goto free_mac_addrs;
 	}
 
+	res = rte_eal_alarm_set(OCCTX_INTR_POLL_INTERVAL_MS * 1000,
+				octeontx_link_status_poll, nic);
+	if (res) {
+		octeontx_log_err("Failed to start link polling alarm");
+		goto err;
+	}
+
 	/* Update port_id mac to eth_dev */
 	memcpy(data->mac_addrs, nic->mac_addr, RTE_ETHER_ADDR_LEN);
 
diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h
index e7e0d40c7..186a044f7 100644
--- a/drivers/net/octeontx/octeontx_ethdev.h
+++ b/drivers/net/octeontx/octeontx_ethdev.h
@@ -30,7 +30,7 @@
 #define OCTEONTX_MAX_LMAC_PER_BGX		4
 
 #define OCCTX_RX_NB_SEG_MAX			6
-
+#define OCCTX_INTR_POLL_INTERVAL_MS		1000
 /* VLAN tag inserted by OCCTX_TX_VTAG_ACTION.
  * In Tx space is always reserved for this in FRS.
  */
@@ -121,6 +121,7 @@ struct octeontx_nic {
 	uint64_t tx_offloads;
 	uint16_t tx_offload_flags;
 	struct octeontx_vlan_info vlan_info;
+	int print_flag;
 } __rte_cache_aligned;
 
 struct octeontx_txq {
@@ -143,10 +144,14 @@ void
 octeontx_set_tx_function(struct rte_eth_dev *dev);
 
 /* VLAN */
+int octeontx_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t qidx);
+int octeontx_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t qidx);
 int octeontx_dev_vlan_offload_init(struct rte_eth_dev *dev);
 int octeontx_dev_vlan_offload_fini(struct rte_eth_dev *eth_dev);
 int octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 int octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				 uint16_t vlan_id, int on);
+int octeontx_dev_set_link_up(struct rte_eth_dev *eth_dev);
+int octeontx_dev_set_link_down(struct rte_eth_dev *eth_dev);
 
 #endif /* __OCTEONTX_ETHDEV_H__ */
diff --git a/drivers/net/octeontx/octeontx_ethdev_ops.c b/drivers/net/octeontx/octeontx_ethdev_ops.c
index 8c3065542..b5f0bfe8a 100644
--- a/drivers/net/octeontx/octeontx_ethdev_ops.c
+++ b/drivers/net/octeontx/octeontx_ethdev_ops.c
@@ -182,3 +182,34 @@ octeontx_dev_vlan_offload_fini(struct rte_eth_dev *dev)
 
 	return rc;
 }
+
+int
+octeontx_dev_set_link_up(struct rte_eth_dev *eth_dev)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
+	int rc, i;
+
+	rc = octeontx_bgx_port_set_link_state(nic->port_id, true);
+	if (rc)
+		goto done;
+
+	/* Start tx queues  */
+	for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
+		octeontx_dev_tx_queue_start(eth_dev, i);
+
+done:
+	return rc;
+}
+
+int
+octeontx_dev_set_link_down(struct rte_eth_dev *eth_dev)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
+	int i;
+
+	/* Stop tx queues  */
+	for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
+		octeontx_dev_tx_queue_stop(eth_dev, i);
+
+	return octeontx_bgx_port_set_link_state(nic->port_id, false);
+}
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-dev] [PATCH 7/8] net/octeontx: add flow control support
  2020-03-16  9:33 [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Harman Kalra
                   ` (5 preceding siblings ...)
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 6/8] net/octeontx: add set link up down support Harman Kalra
@ 2020-03-16  9:33 ` Harman Kalra
  2020-04-06 10:07   ` Harman Kalra
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 8/8] net/octeontx: support Rx Tx checksum offload Harman Kalra
  2020-04-05 15:44 ` [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Jerin Jacob
  8 siblings, 1 reply; 12+ messages in thread
From: Harman Kalra @ 2020-03-16  9:33 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru

From: Vamsi Attunuru <vattunuru@marvell.com>

Patch adds ethdev flow control set/get callback ops,
pmd enables modifying flow control attributes like
rx_pause, tx_pause, high & low water mark.

Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
 doc/guides/nics/features/octeontx.ini      |   1 +
 drivers/net/octeontx/base/octeontx_bgx.c   |  50 ++++++++
 drivers/net/octeontx/base/octeontx_bgx.h   |  28 +++++
 drivers/net/octeontx/octeontx_ethdev.c     |  20 ++++
 drivers/net/octeontx/octeontx_ethdev.h     |  19 +++
 drivers/net/octeontx/octeontx_ethdev_ops.c | 128 +++++++++++++++++++++
 6 files changed, 246 insertions(+)

diff --git a/doc/guides/nics/features/octeontx.ini b/doc/guides/nics/features/octeontx.ini
index 377bb4d30..6049c1c43 100644
--- a/doc/guides/nics/features/octeontx.ini
+++ b/doc/guides/nics/features/octeontx.ini
@@ -18,6 +18,7 @@ VLAN filter          = Y
 VLAN offload         = P
 CRC offload          = Y
 Packet type parsing  = Y
+Flow control         = Y
 Basic stats          = Y
 Linux VFIO           = Y
 ARMv8                = Y
diff --git a/drivers/net/octeontx/base/octeontx_bgx.c b/drivers/net/octeontx/base/octeontx_bgx.c
index d8611cb77..ac856ff86 100644
--- a/drivers/net/octeontx/base/octeontx_bgx.c
+++ b/drivers/net/octeontx/base/octeontx_bgx.c
@@ -326,3 +326,53 @@ octeontx_bgx_port_mac_entries_get(int port)
 
 	return resp;
 }
+
+int octeontx_bgx_port_get_fifo_cfg(int port,
+				   octeontx_mbox_bgx_port_fifo_cfg_t *cfg)
+{
+	int len = sizeof(octeontx_mbox_bgx_port_fifo_cfg_t);
+	octeontx_mbox_bgx_port_fifo_cfg_t conf;
+	struct octeontx_mbox_hdr hdr;
+
+	hdr.coproc = OCTEONTX_BGX_COPROC;
+	hdr.msg = MBOX_BGX_PORT_GET_FIFO_CFG;
+	hdr.vfid = port;
+
+	if (octeontx_mbox_send(&hdr, NULL, 0, &conf, len) < 0)
+		return -EACCES;
+
+	cfg->rx_fifosz = conf.rx_fifosz;
+
+	return 0;
+}
+
+int octeontx_bgx_port_flow_ctrl_cfg(int port,
+				    octeontx_mbox_bgx_port_fc_cfg_t *cfg)
+{
+	int len = sizeof(octeontx_mbox_bgx_port_fc_cfg_t);
+	octeontx_mbox_bgx_port_fc_cfg_t conf;
+	struct octeontx_mbox_hdr hdr;
+
+	hdr.coproc = OCTEONTX_BGX_COPROC;
+	hdr.msg = MBOX_BGX_PORT_FLOW_CTRL_CFG;
+	hdr.vfid = port;
+
+	if (cfg->fc_cfg == BGX_PORT_FC_CFG_SET)
+		memcpy(&conf, cfg, len);
+	else
+		memset(&conf, 0, len);
+
+	if (octeontx_mbox_send(&hdr, &conf, len, &conf, len) < 0)
+		return -EACCES;
+
+	if (cfg->fc_cfg == BGX_PORT_FC_CFG_SET)
+		goto done;
+
+	cfg->rx_pause = conf.rx_pause;
+	cfg->tx_pause = conf.tx_pause;
+	cfg->low_water = conf.low_water;
+	cfg->high_water = conf.high_water;
+
+done:
+	return 0;
+}
diff --git a/drivers/net/octeontx/base/octeontx_bgx.h b/drivers/net/octeontx/base/octeontx_bgx.h
index 6b7476510..d126a0b7f 100644
--- a/drivers/net/octeontx/base/octeontx_bgx.h
+++ b/drivers/net/octeontx/base/octeontx_bgx.h
@@ -11,6 +11,8 @@
 
 #include <octeontx_mbox.h>
 
+#define OCTEONTX_BGX_RSVD_RX_FIFOBYTES	0x40
+
 #define OCTEONTX_BGX_COPROC	        6
 
 /* BGX messages */
@@ -32,6 +34,8 @@
 #define MBOX_BGX_PORT_ADD_MACADDR	15
 #define MBOX_BGX_PORT_DEL_MACADDR	16
 #define MBOX_BGX_PORT_GET_MACADDR_ENTRIES 17
+#define MBOX_BGX_PORT_GET_FIFO_CFG	18
+#define MBOX_BGX_PORT_FLOW_CTRL_CFG	19
 #define MBOX_BGX_PORT_SET_LINK_STATE	20
 
 /* BGX port configuration parameters: */
@@ -119,6 +123,26 @@ struct octeontx_mbox_bgx_port_mac_filter {
 	int index;
 };
 
+/* BGX port fifo config: */
+typedef struct octeontx_mbox_bgx_port_fifo_cfg {
+	uint32_t rx_fifosz; /* in Bytes */
+} octeontx_mbox_bgx_port_fifo_cfg_t;
+
+typedef enum {
+	BGX_PORT_FC_CFG_GET = 0,
+	BGX_PORT_FC_CFG_SET = 1
+} bgx_port_fc_t;
+
+/* BGX port flow control config: */
+typedef struct octeontx_mbox_bgx_port_fc_cfg {
+	/* BP on/off threshold levels in Bytes, must be a multiple of 16 */
+	uint16_t high_water;
+	uint16_t low_water;
+	uint8_t rx_pause; /* rx_pause = 1/0 to enable/disable fc on Tx */
+	uint8_t tx_pause; /* tx_pause = 1/0 to enable/disable fc on Rx */
+	bgx_port_fc_t fc_cfg;
+} octeontx_mbox_bgx_port_fc_cfg_t;
+
 int octeontx_bgx_port_open(int port, octeontx_mbox_bgx_port_conf_t *conf);
 int octeontx_bgx_port_close(int port);
 int octeontx_bgx_port_start(int port);
@@ -135,6 +159,10 @@ int octeontx_bgx_port_mac_del(int port, uint32_t index);
 int octeontx_bgx_port_mac_entries_get(int port);
 int octeontx_bgx_port_mtu_set(int port, int mtu);
 int octeontx_bgx_port_set_link_state(int port, bool en);
+int octeontx_bgx_port_get_fifo_cfg(int port,
+				   octeontx_mbox_bgx_port_fifo_cfg_t *cfg);
+int octeontx_bgx_port_flow_ctrl_cfg(int port,
+				    octeontx_mbox_bgx_port_fc_cfg_t *cfg);
 
 #endif	/* __OCTEONTX_BGX_H__ */
 
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 08c621b4b..191869683 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -122,6 +122,7 @@ static int
 octeontx_port_open(struct octeontx_nic *nic)
 {
 	octeontx_mbox_bgx_port_conf_t bgx_port_conf;
+	octeontx_mbox_bgx_port_fifo_cfg_t fifo_cfg;
 	int res;
 
 	res = 0;
@@ -147,6 +148,16 @@ octeontx_port_open(struct octeontx_nic *nic)
 	nic->mcast_mode = bgx_port_conf.mcast_mode;
 	nic->speed	= bgx_port_conf.mode;
 
+	memset(&fifo_cfg, 0x0, sizeof(fifo_cfg));
+
+	res = octeontx_bgx_port_get_fifo_cfg(nic->port_id, &fifo_cfg);
+	if (res < 0) {
+		octeontx_log_err("failed to get port %d fifo cfg", res);
+		return res;
+	}
+
+	nic->fc.rx_fifosz = fifo_cfg.rx_fifosz;
+
 	memcpy(&nic->mac_addr[0], &bgx_port_conf.macaddr[0],
 		RTE_ETHER_ADDR_LEN);
 
@@ -482,6 +493,8 @@ octeontx_dev_close(struct rte_eth_dev *dev)
 
 	rte_event_dev_close(nic->evdev);
 
+	octeontx_dev_flow_ctrl_fini(dev);
+
 	octeontx_dev_vlan_offload_fini(dev);
 
 	ret = octeontx_pko_channel_close(nic->base_ochan);
@@ -1208,6 +1221,7 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	octeontx_recheck_rx_offloads(rxq);
 	dev->data->rx_queues[qidx] = rxq;
 	dev->data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
+
 	return 0;
 }
 
@@ -1276,6 +1290,8 @@ static const struct eth_dev_ops octeontx_dev_ops = {
 	.dev_supported_ptypes_get = octeontx_dev_supported_ptypes_get,
 	.mtu_set                 = octeontx_dev_mtu_set,
 	.pool_ops_supported      = octeontx_pool_ops,
+	.flow_ctrl_get           = octeontx_dev_flow_ctrl_get,
+	.flow_ctrl_set           = octeontx_dev_flow_ctrl_set,
 };
 
 /* Create Ethdev interface per BGX LMAC ports */
@@ -1407,6 +1423,10 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
 	/* Update same mac address to BGX CAM table at index 0 */
 	octeontx_bgx_port_mac_add(nic->port_id, nic->mac_addr, 0);
 
+	res = octeontx_dev_flow_ctrl_init(eth_dev);
+	if (res < 0)
+		goto err;
+
 	PMD_INIT_LOG(DEBUG, "ethdev info: ");
 	PMD_INIT_LOG(DEBUG, "port %d, port_ena %d ochan %d num_ochan %d tx_q %d",
 				nic->port_id, nic->port_ena,
diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h
index 186a044f7..dc53b53be 100644
--- a/drivers/net/octeontx/octeontx_ethdev.h
+++ b/drivers/net/octeontx/octeontx_ethdev.h
@@ -83,6 +83,16 @@ struct octeontx_vlan_info {
 	uint8_t filter_on;
 };
 
+struct octeontx_fc_info {
+	enum rte_eth_fc_mode mode;  /**< Link flow control mode */
+	enum rte_eth_fc_mode def_mode;
+	uint16_t high_water;
+	uint16_t low_water;
+	uint16_t def_highmark;
+	uint16_t def_lowmark;
+	uint32_t rx_fifosz;
+};
+
 /* Octeontx ethdev nic */
 struct octeontx_nic {
 	struct rte_eth_dev *dev;
@@ -122,6 +132,7 @@ struct octeontx_nic {
 	uint16_t tx_offload_flags;
 	struct octeontx_vlan_info vlan_info;
 	int print_flag;
+	struct octeontx_fc_info fc;
 } __rte_cache_aligned;
 
 struct octeontx_txq {
@@ -154,4 +165,12 @@ int octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev,
 int octeontx_dev_set_link_up(struct rte_eth_dev *eth_dev);
 int octeontx_dev_set_link_down(struct rte_eth_dev *eth_dev);
 
+/* Flow control */
+int octeontx_dev_flow_ctrl_init(struct rte_eth_dev *dev);
+int octeontx_dev_flow_ctrl_fini(struct rte_eth_dev *dev);
+int octeontx_dev_flow_ctrl_get(struct rte_eth_dev *dev,
+			       struct rte_eth_fc_conf *fc_conf);
+int octeontx_dev_flow_ctrl_set(struct rte_eth_dev *dev,
+			       struct rte_eth_fc_conf *fc_conf);
+
 #endif /* __OCTEONTX_ETHDEV_H__ */
diff --git a/drivers/net/octeontx/octeontx_ethdev_ops.c b/drivers/net/octeontx/octeontx_ethdev_ops.c
index b5f0bfe8a..ff627a68e 100644
--- a/drivers/net/octeontx/octeontx_ethdev_ops.c
+++ b/drivers/net/octeontx/octeontx_ethdev_ops.c
@@ -213,3 +213,131 @@ octeontx_dev_set_link_down(struct rte_eth_dev *eth_dev)
 
 	return octeontx_bgx_port_set_link_state(nic->port_id, false);
 }
+
+int
+octeontx_dev_flow_ctrl_get(struct rte_eth_dev *dev,
+			   struct rte_eth_fc_conf *fc_conf)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
+	octeontx_mbox_bgx_port_fc_cfg_t conf;
+	int rc;
+
+	memset(&conf, 0, sizeof(octeontx_mbox_bgx_port_fc_cfg_t));
+
+	rc = octeontx_bgx_port_flow_ctrl_cfg(nic->port_id, &conf);
+	if (rc)
+		return rc;
+
+	if (conf.rx_pause && conf.tx_pause)
+		fc_conf->mode = RTE_FC_FULL;
+	else if (conf.rx_pause)
+		fc_conf->mode = RTE_FC_RX_PAUSE;
+	else if (conf.tx_pause)
+		fc_conf->mode = RTE_FC_TX_PAUSE;
+	else
+		fc_conf->mode = RTE_FC_NONE;
+
+	/* low_water & high_water values are in Bytes */
+	fc_conf->low_water = conf.low_water;
+	fc_conf->high_water = conf.high_water;
+
+	return rc;
+}
+
+int
+octeontx_dev_flow_ctrl_set(struct rte_eth_dev *dev,
+			   struct rte_eth_fc_conf *fc_conf)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
+	struct octeontx_fc_info *fc = &nic->fc;
+	octeontx_mbox_bgx_port_fc_cfg_t conf;
+	uint8_t tx_pause, rx_pause;
+	uint16_t max_high_water;
+	int rc;
+
+	if (fc_conf->pause_time || fc_conf->mac_ctrl_frame_fwd ||
+	    fc_conf->autoneg) {
+		octeontx_log_err("Below flowctrl parameters are not supported "
+				 "pause_time, mac_ctrl_frame_fwd and autoneg");
+		return -EINVAL;
+	}
+
+	if (fc_conf->high_water == fc->high_water &&
+	    fc_conf->low_water == fc->low_water &&
+	    fc_conf->mode == fc->mode)
+		return 0;
+
+	max_high_water = fc->rx_fifosz - OCTEONTX_BGX_RSVD_RX_FIFOBYTES;
+
+	if (fc_conf->high_water > max_high_water ||
+	    fc_conf->high_water < fc_conf->low_water) {
+		octeontx_log_err("Invalid high/low water values "
+				 "High_water(in Bytes) must <= 0x%x ",
+				 max_high_water);
+		return -EINVAL;
+	}
+
+	if (fc_conf->high_water % BIT(4) || fc_conf->low_water % BIT(4)) {
+		octeontx_log_err("High/low water value must be multiple of 16");
+		return -EINVAL;
+	}
+
+	rx_pause = (fc_conf->mode == RTE_FC_FULL) ||
+			(fc_conf->mode == RTE_FC_RX_PAUSE);
+	tx_pause = (fc_conf->mode == RTE_FC_FULL) ||
+			(fc_conf->mode == RTE_FC_TX_PAUSE);
+
+	conf.high_water = fc_conf->high_water;
+	conf.low_water = fc_conf->low_water;
+	conf.fc_cfg = BGX_PORT_FC_CFG_SET;
+	conf.rx_pause = rx_pause;
+	conf.tx_pause = tx_pause;
+
+	rc = octeontx_bgx_port_flow_ctrl_cfg(nic->port_id, &conf);
+	if (rc)
+		return rc;
+
+	fc->high_water = fc_conf->high_water;
+	fc->low_water = fc_conf->low_water;
+	fc->mode = fc_conf->mode;
+
+	return rc;
+}
+
+int
+octeontx_dev_flow_ctrl_init(struct rte_eth_dev *dev)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
+	struct octeontx_fc_info *fc = &nic->fc;
+	struct rte_eth_fc_conf fc_conf;
+	int rc;
+
+	rc = octeontx_dev_flow_ctrl_get(dev, &fc_conf);
+	if (rc) {
+		octeontx_log_err("Failed to get flow control info");
+		return rc;
+	}
+
+	fc->def_highmark = fc_conf.high_water;
+	fc->def_lowmark = fc_conf.low_water;
+	fc->def_mode = fc_conf.mode;
+
+	return rc;
+}
+
+int
+octeontx_dev_flow_ctrl_fini(struct rte_eth_dev *dev)
+{
+	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
+	struct octeontx_fc_info *fc = &nic->fc;
+	struct rte_eth_fc_conf fc_conf;
+
+	memset(&fc_conf, 0, sizeof(struct rte_eth_fc_conf));
+
+	/* Restore flow control parameters with default values */
+	fc_conf.high_water = fc->def_highmark;
+	fc_conf.low_water = fc->def_lowmark;
+	fc_conf.mode = fc->def_mode;
+
+	return octeontx_dev_flow_ctrl_set(dev, &fc_conf);
+}
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-dev] [PATCH 8/8] net/octeontx: support Rx Tx checksum offload
  2020-03-16  9:33 [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Harman Kalra
                   ` (6 preceding siblings ...)
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 7/8] net/octeontx: add flow control support Harman Kalra
@ 2020-03-16  9:33 ` Harman Kalra
  2020-04-05 15:44 ` [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Jerin Jacob
  8 siblings, 0 replies; 12+ messages in thread
From: Harman Kalra @ 2020-03-16  9:33 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru, Harman Kalra

This patch implements rx/tx checksum offload. In case of
wrong checksum received (inner/outer l3/l4) it reports the
corresponding layer which has bad checksum and also corrects
it if hw checksum is enabled on tx side.

Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
 doc/guides/nics/features/octeontx.ini  |   4 +
 drivers/net/octeontx/octeontx_ethdev.c |  22 ++-
 drivers/net/octeontx/octeontx_ethdev.h |  21 ++-
 drivers/net/octeontx/octeontx_rxtx.c   |  10 +-
 drivers/net/octeontx/octeontx_rxtx.h   | 194 +++++++++++++++++++++++--
 5 files changed, 227 insertions(+), 24 deletions(-)

diff --git a/doc/guides/nics/features/octeontx.ini b/doc/guides/nics/features/octeontx.ini
index 6049c1c43..8a95c216c 100644
--- a/doc/guides/nics/features/octeontx.ini
+++ b/doc/guides/nics/features/octeontx.ini
@@ -17,6 +17,10 @@ Unicast MAC filter   = Y
 VLAN filter          = Y
 VLAN offload         = P
 CRC offload          = Y
+L3 checksum offload  = Y
+L4 checksum offload  = Y
+Inner L3 checksum    = Y
+Inner L4 checksum    = Y
 Packet type parsing  = Y
 Flow control         = Y
 Basic stats          = Y
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 191869683..ea3b278a1 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -370,6 +370,16 @@ octeontx_tx_offload_flags(struct rte_eth_dev *eth_dev)
 	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
 	uint16_t flags = 0;
 
+	if (nic->tx_offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM ||
+	    nic->tx_offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM)
+		flags |= OCCTX_TX_OFFLOAD_OL3_OL4_CSUM_F;
+
+	if (nic->tx_offloads & DEV_TX_OFFLOAD_IPV4_CKSUM ||
+	    nic->tx_offloads & DEV_TX_OFFLOAD_TCP_CKSUM ||
+	    nic->tx_offloads & DEV_TX_OFFLOAD_UDP_CKSUM ||
+	    nic->tx_offloads & DEV_TX_OFFLOAD_SCTP_CKSUM)
+		flags |= OCCTX_TX_OFFLOAD_L3_L4_CSUM_F;
+
 	if (!(nic->tx_offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE))
 		flags |= OCCTX_TX_OFFLOAD_MBUF_NOFF_F;
 
@@ -383,13 +393,15 @@ static uint16_t
 octeontx_rx_offload_flags(struct rte_eth_dev *eth_dev)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
-	struct rte_eth_dev_data *data = eth_dev->data;
-	struct rte_eth_conf *conf = &data->dev_conf;
-	struct rte_eth_rxmode *rxmode = &conf->rxmode;
 	uint16_t flags = 0;
 
-	if (rxmode->mq_mode == ETH_MQ_RX_RSS)
-		flags |= OCCTX_RX_OFFLOAD_RSS_F;
+	if (nic->rx_offloads & (DEV_RX_OFFLOAD_TCP_CKSUM |
+			 DEV_RX_OFFLOAD_UDP_CKSUM))
+		flags |= OCCTX_RX_OFFLOAD_CSUM_F;
+
+	if (nic->rx_offloads & (DEV_RX_OFFLOAD_IPV4_CKSUM |
+				DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
+		flags |= OCCTX_RX_OFFLOAD_CSUM_F;
 
 	if (nic->rx_offloads & DEV_RX_OFFLOAD_SCATTER) {
 		flags |= OCCTX_RX_MULTI_SEG_F;
diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h
index dc53b53be..7246fb6d1 100644
--- a/drivers/net/octeontx/octeontx_ethdev.h
+++ b/drivers/net/octeontx/octeontx_ethdev.h
@@ -53,13 +53,24 @@
 
 #define OCCTX_MAX_MTU		(OCCTX_MAX_FRS - OCCTX_L2_OVERHEAD)
 
-#define OCTEONTX_RX_OFFLOADS		(DEV_RX_OFFLOAD_CHECKSUM     | \
-					 DEV_RX_OFFLOAD_SCATTER	     | \
-					 DEV_RX_OFFLOAD_JUMBO_FRAME  | \
+#define OCTEONTX_RX_OFFLOADS		(				   \
+					 DEV_RX_OFFLOAD_CHECKSUM	 | \
+					 DEV_RX_OFFLOAD_SCTP_CKSUM       | \
+					 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | \
+					 DEV_RX_OFFLOAD_SCATTER	         | \
+					 DEV_RX_OFFLOAD_SCATTER		 | \
+					 DEV_RX_OFFLOAD_JUMBO_FRAME	 | \
 					 DEV_RX_OFFLOAD_VLAN_FILTER)
 
-#define OCTEONTX_TX_OFFLOADS		(DEV_TX_OFFLOAD_MT_LOCKFREE    |  \
-					 DEV_TX_OFFLOAD_MBUF_FAST_FREE |  \
+#define OCTEONTX_TX_OFFLOADS		(				   \
+					 DEV_TX_OFFLOAD_MBUF_FAST_FREE	 | \
+					 DEV_TX_OFFLOAD_MT_LOCKFREE	 | \
+					 DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+					 DEV_TX_OFFLOAD_OUTER_UDP_CKSUM	 | \
+					 DEV_TX_OFFLOAD_IPV4_CKSUM	 | \
+					 DEV_TX_OFFLOAD_TCP_CKSUM	 | \
+					 DEV_TX_OFFLOAD_UDP_CKSUM	 | \
+					 DEV_TX_OFFLOAD_SCTP_CKSUM	 | \
 					 DEV_TX_OFFLOAD_MULTI_SEGS)
 
 static inline struct octeontx_nic *
diff --git a/drivers/net/octeontx/octeontx_rxtx.c b/drivers/net/octeontx/octeontx_rxtx.c
index c817f7179..d2453ba26 100644
--- a/drivers/net/octeontx/octeontx_rxtx.c
+++ b/drivers/net/octeontx/octeontx_rxtx.c
@@ -41,7 +41,7 @@ octeontx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	return count; /* return number of pkts received */
 }
 
-#define T(name, f1, f0, sz, flags)					\
+#define T(name, f3, f2, f1, f0, sz, flags)				\
 static uint16_t __rte_noinline	__hot					\
 octeontx_xmit_pkts_ ##name(void *tx_queue,				\
 			struct rte_mbuf **tx_pkts, uint16_t pkts)	\
@@ -60,9 +60,9 @@ octeontx_set_tx_function(struct rte_eth_dev *dev)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 
-	const eth_tx_burst_t tx_burst_func[2][2] = {
-#define T(name, f1, f0, sz, flags)			\
-	[f1][f0] =  octeontx_xmit_pkts_ ##name,
+	const eth_tx_burst_t tx_burst_func[2][2][2][2] = {
+#define T(name, f3, f2, f1, f0, sz, flags)			\
+	[f3][f2][f1][f0] =  octeontx_xmit_pkts_ ##name,
 
 OCCTX_TX_FASTPATH_MODES
 #undef T
@@ -70,5 +70,7 @@ OCCTX_TX_FASTPATH_MODES
 
 	dev->tx_pkt_burst = tx_burst_func
 		[!!(nic->tx_offload_flags & OCCTX_TX_OFFLOAD_MBUF_NOFF_F)]
+		[!!(nic->tx_offload_flags & OCCTX_TX_OFFLOAD_OL3_OL4_CSUM_F)]
+		[!!(nic->tx_offload_flags & OCCTX_TX_OFFLOAD_L3_L4_CSUM_F)]
 		[!!(nic->tx_offload_flags & OCCTX_TX_MULTI_SEG_F)];
 }
diff --git a/drivers/net/octeontx/octeontx_rxtx.h b/drivers/net/octeontx/octeontx_rxtx.h
index cc044dd79..acc1f5cb8 100644
--- a/drivers/net/octeontx/octeontx_rxtx.h
+++ b/drivers/net/octeontx/octeontx_rxtx.h
@@ -18,17 +18,65 @@
 #define BIT(nr) (1UL << (nr))
 
 #define OCCTX_RX_OFFLOAD_NONE		(0)
-#define OCCTX_RX_OFFLOAD_RSS_F          BIT(0)
-#define OCCTX_RX_VLAN_FLTR_F            BIT(1)
-#define OCCTX_RX_MULTI_SEG_F		BIT(15)
+#define OCCTX_RX_MULTI_SEG_F		BIT(0)
+#define OCCTX_RX_OFFLOAD_CSUM_F         BIT(1)
+#define OCCTX_RX_VLAN_FLTR_F            BIT(2)
 
 #define OCCTX_TX_OFFLOAD_NONE		(0)
+#define OCCTX_TX_MULTI_SEG_F		BIT(0)
+#define OCCTX_TX_OFFLOAD_L3_L4_CSUM_F	BIT(1)
+#define OCCTX_TX_OFFLOAD_OL3_OL4_CSUM_F	BIT(2)
 #define OCCTX_TX_OFFLOAD_MBUF_NOFF_F	BIT(3)
 
-#define OCCTX_TX_MULTI_SEG_F		BIT(15)
 /* Packet type table */
 #define PTYPE_SIZE	OCCTX_PKI_LTYPE_LAST
 
+/* octeontx send header sub descriptor structure */
+RTE_STD_C11
+union octeontx_send_hdr_w0_u {
+	uint64_t u;
+	struct {
+		uint64_t total   : 16;
+		uint64_t markptr : 8;
+		uint64_t l3ptr   : 8;
+		uint64_t l4ptr   : 8;
+		uint64_t ii	 : 1;
+		uint64_t shp_dis : 1;
+		uint64_t ckle    : 1;
+		uint64_t cklf    : 2;
+		uint64_t ckl3    : 1;
+		uint64_t ckl4    : 2;
+		uint64_t p	 : 1;
+		uint64_t format	 : 7;
+		uint64_t tstamp  : 1;
+		uint64_t tso_eom : 1;
+		uint64_t df	 : 1;
+		uint64_t tso	 : 1;
+		uint64_t n2	 : 1;
+		uint64_t scntn1	 : 3;
+	};
+};
+
+RTE_STD_C11
+union octeontx_send_hdr_w1_u {
+	uint64_t u;
+	struct {
+		uint64_t tso_mss : 14;
+		uint64_t shp_ra  : 2;
+		uint64_t tso_sb  : 8;
+		uint64_t leptr   : 8;
+		uint64_t lfptr   : 8;
+		uint64_t shp_chg : 9;
+		uint64_t tso_fn  : 7;
+		uint64_t l2len   : 8;
+	};
+};
+
+struct octeontx_send_hdr_s {
+	union octeontx_send_hdr_w0_u w0;
+	union octeontx_send_hdr_w1_u w1;
+};
+
 static const uint32_t __rte_cache_aligned
 ptype_table[PTYPE_SIZE][PTYPE_SIZE][PTYPE_SIZE] = {
 	[LC_NONE][LE_NONE][LF_NONE] = RTE_PTYPE_UNKNOWN,
@@ -182,6 +230,90 @@ octeontx_prefree_seg(struct rte_mbuf *m)
 	return 1;
 }
 
+static __rte_always_inline void
+octeontx_tx_checksum_offload(uint64_t *cmd_buf, const uint16_t flags,
+			     struct rte_mbuf *m)
+{
+	struct octeontx_send_hdr_s *send_hdr =
+				(struct octeontx_send_hdr_s *)cmd_buf;
+	uint64_t ol_flags = m->ol_flags;
+
+	/* PKO Checksum L4 Algorithm Enumeration
+	 * 0x0 - No checksum
+	 * 0x1 - UDP L4 checksum
+	 * 0x2 - TCP L4 checksum
+	 * 0x3 - SCTP L4 checksum
+	 */
+	const uint8_t csum = (!(((ol_flags ^ PKT_TX_UDP_CKSUM) >> 52) & 0x3) +
+		      (!(((ol_flags ^ PKT_TX_TCP_CKSUM) >> 52) & 0x3) * 2) +
+		      (!(((ol_flags ^ PKT_TX_SCTP_CKSUM) >> 52) & 0x3) * 3));
+
+	const uint8_t is_tunnel_parsed = (!!(ol_flags & PKT_TX_TUNNEL_GTP) ||
+				      !!(ol_flags & PKT_TX_TUNNEL_VXLAN_GPE) ||
+				      !!(ol_flags & PKT_TX_TUNNEL_VXLAN) ||
+				      !!(ol_flags & PKT_TX_TUNNEL_GRE) ||
+				      !!(ol_flags & PKT_TX_TUNNEL_GENEVE) ||
+				      !!(ol_flags & PKT_TX_TUNNEL_IP) ||
+				      !!(ol_flags & PKT_TX_TUNNEL_IPIP));
+
+	const uint8_t csum_outer = (!!(ol_flags & PKT_TX_OUTER_UDP_CKSUM) ||
+				    !!(ol_flags & PKT_TX_TUNNEL_UDP));
+	const uint8_t outer_l2_len = m->outer_l2_len;
+	const uint8_t l2_len = m->l2_len;
+
+	if ((flags & OCCTX_TX_OFFLOAD_OL3_OL4_CSUM_F) &&
+	    (flags & OCCTX_TX_OFFLOAD_L3_L4_CSUM_F)) {
+		if (is_tunnel_parsed) {
+			/* Outer L3 */
+			send_hdr->w0.l3ptr = outer_l2_len;
+			send_hdr->w0.l4ptr = outer_l2_len + m->outer_l3_len;
+			/* Set clk3 for PKO to calculate IPV4 header checksum */
+			send_hdr->w0.ckl3 = !!(ol_flags & PKT_TX_OUTER_IPV4);
+
+			/* Outer L4 */
+			send_hdr->w0.ckl4 = csum_outer;
+
+			/* Inner L3 */
+			send_hdr->w1.leptr = send_hdr->w0.l4ptr + l2_len;
+			send_hdr->w1.lfptr = send_hdr->w1.leptr + m->l3_len;
+			/* Set clke for PKO to calculate inner IPV4 header
+			 * checksum.
+			 */
+			send_hdr->w0.ckle = !!(ol_flags & PKT_TX_IPV4);
+
+			/* Inner L4 */
+			send_hdr->w0.cklf = csum;
+		} else {
+			/* Inner L3 */
+			send_hdr->w0.l3ptr = l2_len;
+			send_hdr->w0.l4ptr = l2_len + m->l3_len;
+			/* Set clk3 for PKO to calculate IPV4 header checksum */
+			send_hdr->w0.ckl3 = !!(ol_flags & PKT_TX_IPV4);
+
+			/* Inner L4 */
+			send_hdr->w0.ckl4 = csum;
+		}
+	} else if (flags & OCCTX_TX_OFFLOAD_OL3_OL4_CSUM_F) {
+		/* Outer L3 */
+		send_hdr->w0.l3ptr = outer_l2_len;
+		send_hdr->w0.l4ptr = outer_l2_len + m->outer_l3_len;
+		/* Set clk3 for PKO to calculate IPV4 header checksum */
+		send_hdr->w0.ckl3 = !!(ol_flags & PKT_TX_OUTER_IPV4);
+
+		/* Outer L4 */
+		send_hdr->w0.ckl4 = csum_outer;
+	} else if (flags & OCCTX_TX_OFFLOAD_L3_L4_CSUM_F) {
+		/* Inner L3 */
+		send_hdr->w0.l3ptr = l2_len;
+		send_hdr->w0.l4ptr = l2_len + m->l3_len;
+		/* Set clk3 for PKO to calculate IPV4 header checksum */
+		send_hdr->w0.ckl3 = !!(ol_flags & PKT_TX_IPV4);
+
+		/* Inner L4 */
+		send_hdr->w0.ckl4 = csum;
+	}
+}
+
 static __rte_always_inline uint16_t
 __octeontx_xmit_prepare(struct rte_mbuf *tx_pkt, uint64_t *cmd_buf,
 			const uint16_t flag)
@@ -192,6 +324,11 @@ __octeontx_xmit_prepare(struct rte_mbuf *tx_pkt, uint64_t *cmd_buf,
 	cmd_buf[nb_desc++] = tx_pkt->data_len & 0xffff;
 	cmd_buf[nb_desc++] = 0x0;
 
+	/* Enable tx checksum offload */
+	if ((flag & OCCTX_TX_OFFLOAD_OL3_OL4_CSUM_F) ||
+	    (flag & OCCTX_TX_OFFLOAD_L3_L4_CSUM_F))
+		octeontx_tx_checksum_offload(cmd_buf, flag, tx_pkt);
+
 	/* SEND_HDR[DF] bit controls if buffer is to be freed or
 	 * not, as SG_DESC[I] and SEND_HDR[II] are clear.
 	 */
@@ -230,6 +367,11 @@ __octeontx_xmit_mseg_prepare(struct rte_mbuf *tx_pkt, uint64_t *cmd_buf,
 	cmd_buf[nb_desc++] = tx_pkt->pkt_len & 0xffff;
 	cmd_buf[nb_desc++] = 0x0;
 
+	/* Enable tx checksum offload */
+	if ((flag & OCCTX_TX_OFFLOAD_OL3_OL4_CSUM_F) ||
+	    (flag & OCCTX_TX_OFFLOAD_L3_L4_CSUM_F))
+		octeontx_tx_checksum_offload(cmd_buf, flag, tx_pkt);
+
 	do {
 		m_next = tx_pkt->next;
 		/* To handle case where mbufs belong to diff pools, like
@@ -305,13 +447,45 @@ __octeontx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 uint16_t
 octeontx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 
+#define L3L4CSUM_F   OCCTX_TX_OFFLOAD_L3_L4_CSUM_F
+#define OL3OL4CSUM_F OCCTX_TX_OFFLOAD_OL3_OL4_CSUM_F
 #define NOFF_F       OCCTX_TX_OFFLOAD_MBUF_NOFF_F
 #define MULT_F       OCCTX_TX_MULTI_SEG_F
-/* [NOFF] [MULTI_SEG] */
-#define OCCTX_TX_FASTPATH_MODES						      \
-T(no_offload,				0, 0,	4,   OCCTX_TX_OFFLOAD_NONE)   \
-T(mseg,					0, 1,	14,  MULT_F)		      \
-T(noff,					1, 0,	4,   NOFF_F)		      \
-T(noff_mseg,				1, 1,	14,  NOFF_F | MULT_F)
+
+/* [L3L4CSUM_F] [OL3OL4CSUM_F] [NOFF] [MULTI_SEG] */
+#define OCCTX_TX_FASTPATH_MODES						       \
+T(no_offload,				0, 0, 0, 0,	4,		       \
+					OCCTX_TX_OFFLOAD_NONE)		       \
+T(mseg,					0, 0, 0, 1,	14,		       \
+					MULT_F)			               \
+T(l3l4csum,				0, 0, 1, 0,     4,		       \
+					L3L4CSUM_F)			       \
+T(l3l4csum_mseg,			0, 0, 1, 1,	14,		       \
+					L3L4CSUM_F | MULT_F)		       \
+T(ol3ol4csum,				0, 1, 0, 0,	4,		       \
+					OL3OL4CSUM_F)			       \
+T(ol3l4csum_mseg,			0, 1, 0, 1,	14,		       \
+					OL3OL4CSUM_F | MULT_F)	               \
+T(ol3l4csum_l3l4csum,			0, 1, 1, 0,     4,		       \
+					OL3OL4CSUM_F | L3L4CSUM_F)	       \
+T(ol3l4csum_l3l4csum_mseg,		0, 1, 1, 1,	14,		       \
+					OL3OL4CSUM_F | L3L4CSUM_F | MULT_F)    \
+T(noff,					1, 0, 0, 0,     4,		       \
+					NOFF_F)				       \
+T(noff_mseg,				1, 0, 0, 1,	14,		       \
+					NOFF_F | MULT_F)	               \
+T(noff_l3l4csum,			1, 0, 1, 0,     4,		       \
+					NOFF_F | L3L4CSUM_F)		       \
+T(noff_l3l4csum_mseg,			1, 0, 1, 1,	14,		       \
+					NOFF_F | L3L4CSUM_F | MULT_F)	       \
+T(noff_ol3ol4csum,			1, 1, 0, 0,	4,		       \
+					NOFF_F | OL3OL4CSUM_F)		       \
+T(noff_ol3ol4csum_mseg,			1, 1, 0, 1,	14,		       \
+					NOFF_F | OL3OL4CSUM_F | MULT_F)	       \
+T(noff_ol3ol4csum_l3l4csum,		1, 1, 1, 0,     4,		       \
+					NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F)    \
+T(noff_ol3ol4csum_l3l4csum_mseg,	1, 1, 1, 1,	14,		       \
+					NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F |   \
+					MULT_F)
 
  #endif /* __OCTEONTX_RXTX_H__ */
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD
  2020-03-16  9:33 [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Harman Kalra
                   ` (7 preceding siblings ...)
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 8/8] net/octeontx: support Rx Tx checksum offload Harman Kalra
@ 2020-04-05 15:44 ` Jerin Jacob
  8 siblings, 0 replies; 12+ messages in thread
From: Jerin Jacob @ 2020-04-05 15:44 UTC (permalink / raw)
  To: Harman Kalra
  Cc: Jerin Jacob, John McNamara, Marko Kovacevic, dpdk-dev, Vamsi Attunuru

On Mon, Mar 16, 2020 at 3:04 PM Harman Kalra <hkalra@marvell.com> wrote:
>
> This patchset adds following new features to octeontx PMD:
> * Multi segment support
> * MTU support
> * Setting link up and down
> * VLAN filter offload
> * flow control - pause frames
> * Rx Tx checksum offload
>
> Harman Kalra (6):
>   net/octeontx: add multi segment support
>   net/octeontx: add framework for Rx/Tx offloads
>   net/octeontx: add fast mbuf free support
>   net/octeontx: add MTU support
>   net/octeontx: add set link up down support
>   net/octeontx: support Rx Tx checksum offload
>
> Vamsi Attunuru (2):
>   net/octeontx: add VLAN filter offload support
>   net/octeontx: add flow control support



Series applied to dpdk-next-net-mrvl/master. Thanks.




>
>  doc/guides/nics/features/octeontx.ini        |  10 +
>  doc/guides/nics/octeontx.rst                 |   3 +
>  drivers/event/octeontx/ssovf_worker.c        |   9 +-
>  drivers/net/octeontx/Makefile                |   1 +
>  drivers/net/octeontx/base/octeontx_bgx.c     |  79 ++++
>  drivers/net/octeontx/base/octeontx_bgx.h     |  32 ++
>  drivers/net/octeontx/base/octeontx_pki_var.h |  32 ++
>  drivers/net/octeontx/base/octeontx_pkivf.c   |  40 ++
>  drivers/net/octeontx/base/octeontx_pkivf.h   |  20 +
>  drivers/net/octeontx/base/octeontx_pkovf.c   |  21 +
>  drivers/net/octeontx/base/octeontx_pkovf.h   |  13 +-
>  drivers/net/octeontx/meson.build             |   3 +-
>  drivers/net/octeontx/octeontx_ethdev.c       | 363 ++++++++++++++---
>  drivers/net/octeontx/octeontx_ethdev.h       |  98 ++++-
>  drivers/net/octeontx/octeontx_ethdev_ops.c   | 343 ++++++++++++++++
>  drivers/net/octeontx/octeontx_logs.h         |   3 +
>  drivers/net/octeontx/octeontx_rxtx.c         |  58 +--
>  drivers/net/octeontx/octeontx_rxtx.h         | 397 +++++++++++++++++--
>  18 files changed, 1421 insertions(+), 104 deletions(-)
>  create mode 100644 drivers/net/octeontx/octeontx_ethdev_ops.c
>
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [dpdk-dev] [PATCH 7/8] net/octeontx: add flow control support
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 7/8] net/octeontx: add flow control support Harman Kalra
@ 2020-04-06 10:07   ` Harman Kalra
  0 siblings, 0 replies; 12+ messages in thread
From: Harman Kalra @ 2020-04-06 10:07 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru

On Mon, Mar 16, 2020 at 03:03:43PM +0530, Harman Kalra wrote:
> From: Vamsi Attunuru <vattunuru@marvell.com>
> 
> Patch adds ethdev flow control set/get callback ops,
> pmd enables modifying flow control attributes like
> rx_pause, tx_pause, high & low water mark.
> 
> Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>

Acked-by: Harman Kalra <hkalra@marvell.com>

> ---
>  doc/guides/nics/features/octeontx.ini      |   1 +
>  drivers/net/octeontx/base/octeontx_bgx.c   |  50 ++++++++
>  drivers/net/octeontx/base/octeontx_bgx.h   |  28 +++++
>  drivers/net/octeontx/octeontx_ethdev.c     |  20 ++++
>  drivers/net/octeontx/octeontx_ethdev.h     |  19 +++
>  drivers/net/octeontx/octeontx_ethdev_ops.c | 128 +++++++++++++++++++++
>  6 files changed, 246 insertions(+)
> 
> diff --git a/doc/guides/nics/features/octeontx.ini b/doc/guides/nics/features/octeontx.ini
> index 377bb4d30..6049c1c43 100644
> --- a/doc/guides/nics/features/octeontx.ini
> +++ b/doc/guides/nics/features/octeontx.ini
> @@ -18,6 +18,7 @@ VLAN filter          = Y
>  VLAN offload         = P
>  CRC offload          = Y
>  Packet type parsing  = Y
> +Flow control         = Y
>  Basic stats          = Y
>  Linux VFIO           = Y
>  ARMv8                = Y
> diff --git a/drivers/net/octeontx/base/octeontx_bgx.c b/drivers/net/octeontx/base/octeontx_bgx.c
> index d8611cb77..ac856ff86 100644
> --- a/drivers/net/octeontx/base/octeontx_bgx.c
> +++ b/drivers/net/octeontx/base/octeontx_bgx.c
> @@ -326,3 +326,53 @@ octeontx_bgx_port_mac_entries_get(int port)
>  
>  	return resp;
>  }
> +
> +int octeontx_bgx_port_get_fifo_cfg(int port,
> +				   octeontx_mbox_bgx_port_fifo_cfg_t *cfg)
> +{
> +	int len = sizeof(octeontx_mbox_bgx_port_fifo_cfg_t);
> +	octeontx_mbox_bgx_port_fifo_cfg_t conf;
> +	struct octeontx_mbox_hdr hdr;
> +
> +	hdr.coproc = OCTEONTX_BGX_COPROC;
> +	hdr.msg = MBOX_BGX_PORT_GET_FIFO_CFG;
> +	hdr.vfid = port;
> +
> +	if (octeontx_mbox_send(&hdr, NULL, 0, &conf, len) < 0)
> +		return -EACCES;
> +
> +	cfg->rx_fifosz = conf.rx_fifosz;
> +
> +	return 0;
> +}
> +
> +int octeontx_bgx_port_flow_ctrl_cfg(int port,
> +				    octeontx_mbox_bgx_port_fc_cfg_t *cfg)
> +{
> +	int len = sizeof(octeontx_mbox_bgx_port_fc_cfg_t);
> +	octeontx_mbox_bgx_port_fc_cfg_t conf;
> +	struct octeontx_mbox_hdr hdr;
> +
> +	hdr.coproc = OCTEONTX_BGX_COPROC;
> +	hdr.msg = MBOX_BGX_PORT_FLOW_CTRL_CFG;
> +	hdr.vfid = port;
> +
> +	if (cfg->fc_cfg == BGX_PORT_FC_CFG_SET)
> +		memcpy(&conf, cfg, len);
> +	else
> +		memset(&conf, 0, len);
> +
> +	if (octeontx_mbox_send(&hdr, &conf, len, &conf, len) < 0)
> +		return -EACCES;
> +
> +	if (cfg->fc_cfg == BGX_PORT_FC_CFG_SET)
> +		goto done;
> +
> +	cfg->rx_pause = conf.rx_pause;
> +	cfg->tx_pause = conf.tx_pause;
> +	cfg->low_water = conf.low_water;
> +	cfg->high_water = conf.high_water;
> +
> +done:
> +	return 0;
> +}
> diff --git a/drivers/net/octeontx/base/octeontx_bgx.h b/drivers/net/octeontx/base/octeontx_bgx.h
> index 6b7476510..d126a0b7f 100644
> --- a/drivers/net/octeontx/base/octeontx_bgx.h
> +++ b/drivers/net/octeontx/base/octeontx_bgx.h
> @@ -11,6 +11,8 @@
>  
>  #include <octeontx_mbox.h>
>  
> +#define OCTEONTX_BGX_RSVD_RX_FIFOBYTES	0x40
> +
>  #define OCTEONTX_BGX_COPROC	        6
>  
>  /* BGX messages */
> @@ -32,6 +34,8 @@
>  #define MBOX_BGX_PORT_ADD_MACADDR	15
>  #define MBOX_BGX_PORT_DEL_MACADDR	16
>  #define MBOX_BGX_PORT_GET_MACADDR_ENTRIES 17
> +#define MBOX_BGX_PORT_GET_FIFO_CFG	18
> +#define MBOX_BGX_PORT_FLOW_CTRL_CFG	19
>  #define MBOX_BGX_PORT_SET_LINK_STATE	20
>  
>  /* BGX port configuration parameters: */
> @@ -119,6 +123,26 @@ struct octeontx_mbox_bgx_port_mac_filter {
>  	int index;
>  };
>  
> +/* BGX port fifo config: */
> +typedef struct octeontx_mbox_bgx_port_fifo_cfg {
> +	uint32_t rx_fifosz; /* in Bytes */
> +} octeontx_mbox_bgx_port_fifo_cfg_t;
> +
> +typedef enum {
> +	BGX_PORT_FC_CFG_GET = 0,
> +	BGX_PORT_FC_CFG_SET = 1
> +} bgx_port_fc_t;
> +
> +/* BGX port flow control config: */
> +typedef struct octeontx_mbox_bgx_port_fc_cfg {
> +	/* BP on/off threshold levels in Bytes, must be a multiple of 16 */
> +	uint16_t high_water;
> +	uint16_t low_water;
> +	uint8_t rx_pause; /* rx_pause = 1/0 to enable/disable fc on Tx */
> +	uint8_t tx_pause; /* tx_pause = 1/0 to enable/disable fc on Rx */
> +	bgx_port_fc_t fc_cfg;
> +} octeontx_mbox_bgx_port_fc_cfg_t;
> +
>  int octeontx_bgx_port_open(int port, octeontx_mbox_bgx_port_conf_t *conf);
>  int octeontx_bgx_port_close(int port);
>  int octeontx_bgx_port_start(int port);
> @@ -135,6 +159,10 @@ int octeontx_bgx_port_mac_del(int port, uint32_t index);
>  int octeontx_bgx_port_mac_entries_get(int port);
>  int octeontx_bgx_port_mtu_set(int port, int mtu);
>  int octeontx_bgx_port_set_link_state(int port, bool en);
> +int octeontx_bgx_port_get_fifo_cfg(int port,
> +				   octeontx_mbox_bgx_port_fifo_cfg_t *cfg);
> +int octeontx_bgx_port_flow_ctrl_cfg(int port,
> +				    octeontx_mbox_bgx_port_fc_cfg_t *cfg);
>  
>  #endif	/* __OCTEONTX_BGX_H__ */
>  
> diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
> index 08c621b4b..191869683 100644
> --- a/drivers/net/octeontx/octeontx_ethdev.c
> +++ b/drivers/net/octeontx/octeontx_ethdev.c
> @@ -122,6 +122,7 @@ static int
>  octeontx_port_open(struct octeontx_nic *nic)
>  {
>  	octeontx_mbox_bgx_port_conf_t bgx_port_conf;
> +	octeontx_mbox_bgx_port_fifo_cfg_t fifo_cfg;
>  	int res;
>  
>  	res = 0;
> @@ -147,6 +148,16 @@ octeontx_port_open(struct octeontx_nic *nic)
>  	nic->mcast_mode = bgx_port_conf.mcast_mode;
>  	nic->speed	= bgx_port_conf.mode;
>  
> +	memset(&fifo_cfg, 0x0, sizeof(fifo_cfg));
> +
> +	res = octeontx_bgx_port_get_fifo_cfg(nic->port_id, &fifo_cfg);
> +	if (res < 0) {
> +		octeontx_log_err("failed to get port %d fifo cfg", res);
> +		return res;
> +	}
> +
> +	nic->fc.rx_fifosz = fifo_cfg.rx_fifosz;
> +
>  	memcpy(&nic->mac_addr[0], &bgx_port_conf.macaddr[0],
>  		RTE_ETHER_ADDR_LEN);
>  
> @@ -482,6 +493,8 @@ octeontx_dev_close(struct rte_eth_dev *dev)
>  
>  	rte_event_dev_close(nic->evdev);
>  
> +	octeontx_dev_flow_ctrl_fini(dev);
> +
>  	octeontx_dev_vlan_offload_fini(dev);
>  
>  	ret = octeontx_pko_channel_close(nic->base_ochan);
> @@ -1208,6 +1221,7 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
>  	octeontx_recheck_rx_offloads(rxq);
>  	dev->data->rx_queues[qidx] = rxq;
>  	dev->data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
> +
>  	return 0;
>  }
>  
> @@ -1276,6 +1290,8 @@ static const struct eth_dev_ops octeontx_dev_ops = {
>  	.dev_supported_ptypes_get = octeontx_dev_supported_ptypes_get,
>  	.mtu_set                 = octeontx_dev_mtu_set,
>  	.pool_ops_supported      = octeontx_pool_ops,
> +	.flow_ctrl_get           = octeontx_dev_flow_ctrl_get,
> +	.flow_ctrl_set           = octeontx_dev_flow_ctrl_set,
>  };
>  
>  /* Create Ethdev interface per BGX LMAC ports */
> @@ -1407,6 +1423,10 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
>  	/* Update same mac address to BGX CAM table at index 0 */
>  	octeontx_bgx_port_mac_add(nic->port_id, nic->mac_addr, 0);
>  
> +	res = octeontx_dev_flow_ctrl_init(eth_dev);
> +	if (res < 0)
> +		goto err;
> +
>  	PMD_INIT_LOG(DEBUG, "ethdev info: ");
>  	PMD_INIT_LOG(DEBUG, "port %d, port_ena %d ochan %d num_ochan %d tx_q %d",
>  				nic->port_id, nic->port_ena,
> diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h
> index 186a044f7..dc53b53be 100644
> --- a/drivers/net/octeontx/octeontx_ethdev.h
> +++ b/drivers/net/octeontx/octeontx_ethdev.h
> @@ -83,6 +83,16 @@ struct octeontx_vlan_info {
>  	uint8_t filter_on;
>  };
>  
> +struct octeontx_fc_info {
> +	enum rte_eth_fc_mode mode;  /**< Link flow control mode */
> +	enum rte_eth_fc_mode def_mode;
> +	uint16_t high_water;
> +	uint16_t low_water;
> +	uint16_t def_highmark;
> +	uint16_t def_lowmark;
> +	uint32_t rx_fifosz;
> +};
> +
>  /* Octeontx ethdev nic */
>  struct octeontx_nic {
>  	struct rte_eth_dev *dev;
> @@ -122,6 +132,7 @@ struct octeontx_nic {
>  	uint16_t tx_offload_flags;
>  	struct octeontx_vlan_info vlan_info;
>  	int print_flag;
> +	struct octeontx_fc_info fc;
>  } __rte_cache_aligned;
>  
>  struct octeontx_txq {
> @@ -154,4 +165,12 @@ int octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev,
>  int octeontx_dev_set_link_up(struct rte_eth_dev *eth_dev);
>  int octeontx_dev_set_link_down(struct rte_eth_dev *eth_dev);
>  
> +/* Flow control */
> +int octeontx_dev_flow_ctrl_init(struct rte_eth_dev *dev);
> +int octeontx_dev_flow_ctrl_fini(struct rte_eth_dev *dev);
> +int octeontx_dev_flow_ctrl_get(struct rte_eth_dev *dev,
> +			       struct rte_eth_fc_conf *fc_conf);
> +int octeontx_dev_flow_ctrl_set(struct rte_eth_dev *dev,
> +			       struct rte_eth_fc_conf *fc_conf);
> +
>  #endif /* __OCTEONTX_ETHDEV_H__ */
> diff --git a/drivers/net/octeontx/octeontx_ethdev_ops.c b/drivers/net/octeontx/octeontx_ethdev_ops.c
> index b5f0bfe8a..ff627a68e 100644
> --- a/drivers/net/octeontx/octeontx_ethdev_ops.c
> +++ b/drivers/net/octeontx/octeontx_ethdev_ops.c
> @@ -213,3 +213,131 @@ octeontx_dev_set_link_down(struct rte_eth_dev *eth_dev)
>  
>  	return octeontx_bgx_port_set_link_state(nic->port_id, false);
>  }
> +
> +int
> +octeontx_dev_flow_ctrl_get(struct rte_eth_dev *dev,
> +			   struct rte_eth_fc_conf *fc_conf)
> +{
> +	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
> +	octeontx_mbox_bgx_port_fc_cfg_t conf;
> +	int rc;
> +
> +	memset(&conf, 0, sizeof(octeontx_mbox_bgx_port_fc_cfg_t));
> +
> +	rc = octeontx_bgx_port_flow_ctrl_cfg(nic->port_id, &conf);
> +	if (rc)
> +		return rc;
> +
> +	if (conf.rx_pause && conf.tx_pause)
> +		fc_conf->mode = RTE_FC_FULL;
> +	else if (conf.rx_pause)
> +		fc_conf->mode = RTE_FC_RX_PAUSE;
> +	else if (conf.tx_pause)
> +		fc_conf->mode = RTE_FC_TX_PAUSE;
> +	else
> +		fc_conf->mode = RTE_FC_NONE;
> +
> +	/* low_water & high_water values are in Bytes */
> +	fc_conf->low_water = conf.low_water;
> +	fc_conf->high_water = conf.high_water;
> +
> +	return rc;
> +}
> +
> +int
> +octeontx_dev_flow_ctrl_set(struct rte_eth_dev *dev,
> +			   struct rte_eth_fc_conf *fc_conf)
> +{
> +	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
> +	struct octeontx_fc_info *fc = &nic->fc;
> +	octeontx_mbox_bgx_port_fc_cfg_t conf;
> +	uint8_t tx_pause, rx_pause;
> +	uint16_t max_high_water;
> +	int rc;
> +
> +	if (fc_conf->pause_time || fc_conf->mac_ctrl_frame_fwd ||
> +	    fc_conf->autoneg) {
> +		octeontx_log_err("Below flowctrl parameters are not supported "
> +				 "pause_time, mac_ctrl_frame_fwd and autoneg");
> +		return -EINVAL;
> +	}
> +
> +	if (fc_conf->high_water == fc->high_water &&
> +	    fc_conf->low_water == fc->low_water &&
> +	    fc_conf->mode == fc->mode)
> +		return 0;
> +
> +	max_high_water = fc->rx_fifosz - OCTEONTX_BGX_RSVD_RX_FIFOBYTES;
> +
> +	if (fc_conf->high_water > max_high_water ||
> +	    fc_conf->high_water < fc_conf->low_water) {
> +		octeontx_log_err("Invalid high/low water values "
> +				 "High_water(in Bytes) must <= 0x%x ",
> +				 max_high_water);
> +		return -EINVAL;
> +	}
> +
> +	if (fc_conf->high_water % BIT(4) || fc_conf->low_water % BIT(4)) {
> +		octeontx_log_err("High/low water value must be multiple of 16");
> +		return -EINVAL;
> +	}
> +
> +	rx_pause = (fc_conf->mode == RTE_FC_FULL) ||
> +			(fc_conf->mode == RTE_FC_RX_PAUSE);
> +	tx_pause = (fc_conf->mode == RTE_FC_FULL) ||
> +			(fc_conf->mode == RTE_FC_TX_PAUSE);
> +
> +	conf.high_water = fc_conf->high_water;
> +	conf.low_water = fc_conf->low_water;
> +	conf.fc_cfg = BGX_PORT_FC_CFG_SET;
> +	conf.rx_pause = rx_pause;
> +	conf.tx_pause = tx_pause;
> +
> +	rc = octeontx_bgx_port_flow_ctrl_cfg(nic->port_id, &conf);
> +	if (rc)
> +		return rc;
> +
> +	fc->high_water = fc_conf->high_water;
> +	fc->low_water = fc_conf->low_water;
> +	fc->mode = fc_conf->mode;
> +
> +	return rc;
> +}
> +
> +int
> +octeontx_dev_flow_ctrl_init(struct rte_eth_dev *dev)
> +{
> +	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
> +	struct octeontx_fc_info *fc = &nic->fc;
> +	struct rte_eth_fc_conf fc_conf;
> +	int rc;
> +
> +	rc = octeontx_dev_flow_ctrl_get(dev, &fc_conf);
> +	if (rc) {
> +		octeontx_log_err("Failed to get flow control info");
> +		return rc;
> +	}
> +
> +	fc->def_highmark = fc_conf.high_water;
> +	fc->def_lowmark = fc_conf.low_water;
> +	fc->def_mode = fc_conf.mode;
> +
> +	return rc;
> +}
> +
> +int
> +octeontx_dev_flow_ctrl_fini(struct rte_eth_dev *dev)
> +{
> +	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
> +	struct octeontx_fc_info *fc = &nic->fc;
> +	struct rte_eth_fc_conf fc_conf;
> +
> +	memset(&fc_conf, 0, sizeof(struct rte_eth_fc_conf));
> +
> +	/* Restore flow control parameters with default values */
> +	fc_conf.high_water = fc->def_highmark;
> +	fc_conf.low_water = fc->def_lowmark;
> +	fc_conf.mode = fc->def_mode;
> +
> +	return octeontx_dev_flow_ctrl_set(dev, &fc_conf);
> +}
> -- 
> 2.18.0
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [dpdk-dev] [PATCH 5/8] net/octeontx: add VLAN filter offload support
  2020-03-16  9:33 ` [dpdk-dev] [PATCH 5/8] net/octeontx: add VLAN filter offload support Harman Kalra
@ 2020-04-06 10:09   ` Harman Kalra
  0 siblings, 0 replies; 12+ messages in thread
From: Harman Kalra @ 2020-04-06 10:09 UTC (permalink / raw)
  To: jerinj, john.mcnamara, marko.kovacevic; +Cc: dev, vattunuru

On Mon, Mar 16, 2020 at 03:03:41PM +0530, Harman Kalra wrote:
> From: Vamsi Attunuru <vattunuru@marvell.com>
> 
> Patch adds support for vlan filter offload support.
> MBOX messages for vlan filter on/off and vlan filter
> entry add/rm are added to configure PCAM entries to
> filter out the vlan traffic on a given port.
> 
> Patch also defines rx_offload_flag for vlan filtering.
> 
> Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>

Acked-by: Harman Kalra <hkalra@marvell.com>

> ---
>  doc/guides/nics/features/octeontx.ini      |   2 +
>  doc/guides/nics/octeontx.rst               |   1 +
>  drivers/net/octeontx/Makefile              |   1 +
>  drivers/net/octeontx/base/octeontx_pkivf.c |  40 +++++
>  drivers/net/octeontx/base/octeontx_pkivf.h |  20 +++
>  drivers/net/octeontx/meson.build           |   3 +-
>  drivers/net/octeontx/octeontx_ethdev.c     |  10 ++
>  drivers/net/octeontx/octeontx_ethdev.h     |  24 ++-
>  drivers/net/octeontx/octeontx_ethdev_ops.c | 184 +++++++++++++++++++++
>  drivers/net/octeontx/octeontx_rxtx.h       |   1 +
>  10 files changed, 284 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/net/octeontx/octeontx_ethdev_ops.c
> 
> diff --git a/doc/guides/nics/features/octeontx.ini b/doc/guides/nics/features/octeontx.ini
> index e3ee79f0f..53c541f4b 100644
> --- a/doc/guides/nics/features/octeontx.ini
> +++ b/doc/guides/nics/features/octeontx.ini
> @@ -13,6 +13,8 @@ Jumbo frame          = Y
>  Scattered Rx         = Y
>  Promiscuous mode     = Y
>  Unicast MAC filter   = Y
> +VLAN filter          = Y
> +VLAN offload         = P
>  CRC offload          = Y
>  Packet type parsing  = Y
>  Basic stats          = Y
> diff --git a/doc/guides/nics/octeontx.rst b/doc/guides/nics/octeontx.rst
> index ddb626bc3..c8655bf37 100644
> --- a/doc/guides/nics/octeontx.rst
> +++ b/doc/guides/nics/octeontx.rst
> @@ -22,6 +22,7 @@ Features of the OCTEON TX Ethdev PMD are:
>  - Jumbo frames
>  - Scatter-Gather IO support
>  - Link state information
> +- MAC/VLAN filtering
>  - MTU update
>  - SR-IOV VF
>  - Multiple queues for TX
> diff --git a/drivers/net/octeontx/Makefile b/drivers/net/octeontx/Makefile
> index 8ddfc3089..694f403f1 100644
> --- a/drivers/net/octeontx/Makefile
> +++ b/drivers/net/octeontx/Makefile
> @@ -28,6 +28,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_pkovf.c
>  SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_pkivf.c
>  SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_bgx.c
>  SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_ethdev.c
> +SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_ethdev_ops.c
>  
>  ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)
>  CFLAGS_octeontx_rxtx.o += -fno-prefetch-loop-arrays
> diff --git a/drivers/net/octeontx/base/octeontx_pkivf.c b/drivers/net/octeontx/base/octeontx_pkivf.c
> index 8ce041955..0ddff5488 100644
> --- a/drivers/net/octeontx/base/octeontx_pkivf.c
> +++ b/drivers/net/octeontx/base/octeontx_pkivf.c
> @@ -136,6 +136,46 @@ octeontx_pki_port_errchk_config(int port, pki_errchk_cfg_t *cfg)
>  	return res;
>  }
>  
> +int
> +octeontx_pki_port_vlan_fltr_config(int port,
> +				   pki_port_vlan_filter_config_t *fltr_cfg)
> +{
> +	struct octeontx_mbox_hdr hdr;
> +	int res;
> +
> +	pki_port_vlan_filter_config_t cfg = *fltr_cfg;
> +	int len = sizeof(pki_port_vlan_filter_config_t);
> +
> +	hdr.coproc = OCTEONTX_PKI_COPROC;
> +	hdr.msg = MBOX_PKI_PORT_VLAN_FILTER_CONFIG;
> +	hdr.vfid = port;
> +
> +	res = octeontx_mbox_send(&hdr, &cfg, len, NULL, 0);
> +	if (res < 0)
> +		return -EACCES;
> +	return res;
> +}
> +
> +int
> +octeontx_pki_port_vlan_fltr_entry_config(int port,
> +				   pki_port_vlan_filter_entry_config_t *e_cfg)
> +{
> +	struct octeontx_mbox_hdr hdr;
> +	int res;
> +
> +	pki_port_vlan_filter_entry_config_t cfg = *e_cfg;
> +	int len = sizeof(pki_port_vlan_filter_entry_config_t);
> +
> +	hdr.coproc = OCTEONTX_PKI_COPROC;
> +	hdr.msg = MBOX_PKI_PORT_VLAN_FILTER_ENTRY_CONFIG;
> +	hdr.vfid = port;
> +
> +	res = octeontx_mbox_send(&hdr, &cfg, len, NULL, 0);
> +	if (res < 0)
> +		return -EACCES;
> +	return res;
> +}
> +
>  #define PCI_VENDOR_ID_CAVIUM               0x177D
>  #define PCI_DEVICE_ID_OCTEONTX_PKI_VF      0xA0DD
>  
> diff --git a/drivers/net/octeontx/base/octeontx_pkivf.h b/drivers/net/octeontx/base/octeontx_pkivf.h
> index d541dc3bd..d41eaa57e 100644
> --- a/drivers/net/octeontx/base/octeontx_pkivf.h
> +++ b/drivers/net/octeontx/base/octeontx_pkivf.h
> @@ -36,6 +36,8 @@
>  #define MBOX_PKI_PORT_ALLOC_QPG			21
>  #define MBOX_PKI_PORT_FREE_QPG			22
>  #define MBOX_PKI_SET_PORT_CONFIG		23
> +#define MBOX_PKI_PORT_VLAN_FILTER_CONFIG	24
> +#define MBOX_PKI_PORT_VLAN_FILTER_ENTRY_CONFIG	25
>  
>  #define MBOX_PKI_MAX_QOS_ENTRY 64
>  
> @@ -236,6 +238,20 @@ typedef struct pki_port_modify_qos_entry {
>  	struct pki_qos_entry qos_entry;
>  } pki_mod_qos_t;
>  
> +/* pki port VLAN filter config */
> +typedef struct pki_port_vlan_filter_config {
> +	uint8_t port_type;  /* OCTTX_PORT_TYPE_[NET/INT/PCI] */
> +	uint8_t fltr_conf; /* '1' to enable & '0' to disable */
> +} pki_port_vlan_filter_config_t;
> +
> +/* pki port VLAN filter entry config */
> +typedef struct pki_port_vlan_filter_entry_config {
> +	uint8_t port_type;  /* OCTTX_PORT_TYPE_[NET/INT/PCI] */
> +	uint8_t entry_conf; /* '1' to add & '0' to remove */
> +	uint16_t vlan_tpid; /* in host byte-order */
> +	uint16_t vlan_id;   /* in host byte-order */
> +} pki_port_vlan_filter_entry_config_t;
> +
>  static inline int
>  octeontx_pki_port_modify_qos(int port, pki_mod_qos_t *qos_cfg)
>  {
> @@ -348,5 +364,9 @@ int octeontx_pki_port_pktbuf_config(int port, pki_pktbuf_cfg_t *buf_cfg);
>  int octeontx_pki_port_create_qos(int port, pki_qos_cfg_t *qos_cfg);
>  int octeontx_pki_port_close(int port);
>  int octeontx_pki_port_errchk_config(int port, pki_errchk_cfg_t *cfg);
> +int octeontx_pki_port_vlan_fltr_config(int port,
> +				pki_port_vlan_filter_config_t *fltr_cfg);
> +int octeontx_pki_port_vlan_fltr_entry_config(int port,
> +				pki_port_vlan_filter_entry_config_t *entry_cfg);
>  
>  #endif /* __OCTEONTX_PKI_H__ */
> diff --git a/drivers/net/octeontx/meson.build b/drivers/net/octeontx/meson.build
> index 0e249eb98..f7ba6e68b 100644
> --- a/drivers/net/octeontx/meson.build
> +++ b/drivers/net/octeontx/meson.build
> @@ -5,7 +5,8 @@ subdir('base')
>  objs = [base_objs]
>  
>  sources = files('octeontx_rxtx.c',
> -		'octeontx_ethdev.c'
> +		'octeontx_ethdev.c',
> +		'octeontx_ethdev_ops.c'
>  		)
>  
>  allow_experimental_apis = true
> diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
> index 91b9ea645..5dd40bc04 100644
> --- a/drivers/net/octeontx/octeontx_ethdev.c
> +++ b/drivers/net/octeontx/octeontx_ethdev.c
> @@ -360,6 +360,12 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
>  		return -EFAULT;
>  	}
>  
> +	ret = octeontx_dev_vlan_offload_init(dev);
> +	if (ret) {
> +		octeontx_log_err("failed to initialize vlan offload");
> +		return -EFAULT;
> +	}
> +
>  	nic->pki.classifier_enable = false;
>  	nic->pki.hash_enable = true;
>  	nic->pki.initialized = false;
> @@ -384,6 +390,8 @@ octeontx_dev_close(struct rte_eth_dev *dev)
>  
>  	rte_event_dev_close(nic->evdev);
>  
> +	octeontx_dev_vlan_offload_fini(dev);
> +
>  	ret = octeontx_pko_channel_close(nic->base_ochan);
>  	if (ret < 0) {
>  		octeontx_log_err("failed to close channel %d VF%d %d %d",
> @@ -1185,6 +1193,8 @@ static const struct eth_dev_ops octeontx_dev_ops = {
>  	.mac_addr_remove	 = octeontx_dev_mac_addr_del,
>  	.mac_addr_add		 = octeontx_dev_mac_addr_add,
>  	.mac_addr_set		 = octeontx_dev_default_mac_addr_set,
> +	.vlan_offload_set	 = octeontx_dev_vlan_offload_set,
> +	.vlan_filter_set	 = octeontx_dev_vlan_filter_set,
>  	.tx_queue_start		 = octeontx_dev_tx_queue_start,
>  	.tx_queue_stop		 = octeontx_dev_tx_queue_stop,
>  	.tx_queue_setup		 = octeontx_dev_tx_queue_setup,
> diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h
> index 27f6556dd..e7e0d40c7 100644
> --- a/drivers/net/octeontx/octeontx_ethdev.h
> +++ b/drivers/net/octeontx/octeontx_ethdev.h
> @@ -55,7 +55,8 @@
>  
>  #define OCTEONTX_RX_OFFLOADS		(DEV_RX_OFFLOAD_CHECKSUM     | \
>  					 DEV_RX_OFFLOAD_SCATTER	     | \
> -					 DEV_RX_OFFLOAD_JUMBO_FRAME)
> +					 DEV_RX_OFFLOAD_JUMBO_FRAME  | \
> +					 DEV_RX_OFFLOAD_VLAN_FILTER)
>  
>  #define OCTEONTX_TX_OFFLOADS		(DEV_TX_OFFLOAD_MT_LOCKFREE    |  \
>  					 DEV_TX_OFFLOAD_MBUF_FAST_FREE |  \
> @@ -70,6 +71,18 @@ octeontx_pmd_priv(struct rte_eth_dev *dev)
>  extern uint16_t
>  rte_octeontx_pchan_map[OCTEONTX_MAX_BGX_PORTS][OCTEONTX_MAX_LMAC_PER_BGX];
>  
> +struct vlan_entry {
> +	TAILQ_ENTRY(vlan_entry) next;
> +	uint16_t vlan_id;
> +};
> +
> +TAILQ_HEAD(octeontx_vlan_filter_tbl, vlan_entry);
> +
> +struct octeontx_vlan_info {
> +	struct octeontx_vlan_filter_tbl fltr_tbl;
> +	uint8_t filter_on;
> +};
> +
>  /* Octeontx ethdev nic */
>  struct octeontx_nic {
>  	struct rte_eth_dev *dev;
> @@ -107,6 +120,7 @@ struct octeontx_nic {
>  	uint16_t rx_offload_flags;
>  	uint64_t tx_offloads;
>  	uint16_t tx_offload_flags;
> +	struct octeontx_vlan_info vlan_info;
>  } __rte_cache_aligned;
>  
>  struct octeontx_txq {
> @@ -127,4 +141,12 @@ struct octeontx_rxq {
>  
>  void
>  octeontx_set_tx_function(struct rte_eth_dev *dev);
> +
> +/* VLAN */
> +int octeontx_dev_vlan_offload_init(struct rte_eth_dev *dev);
> +int octeontx_dev_vlan_offload_fini(struct rte_eth_dev *eth_dev);
> +int octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
> +int octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev,
> +				 uint16_t vlan_id, int on);
> +
>  #endif /* __OCTEONTX_ETHDEV_H__ */
> diff --git a/drivers/net/octeontx/octeontx_ethdev_ops.c b/drivers/net/octeontx/octeontx_ethdev_ops.c
> new file mode 100644
> index 000000000..8c3065542
> --- /dev/null
> +++ b/drivers/net/octeontx/octeontx_ethdev_ops.c
> @@ -0,0 +1,184 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2020 Marvell International Ltd.
> + */
> +
> +#include <rte_malloc.h>
> +
> +#include "octeontx_ethdev.h"
> +#include "octeontx_logs.h"
> +#include "octeontx_rxtx.h"
> +
> +static int
> +octeontx_vlan_hw_filter(struct octeontx_nic *nic, uint8_t flag)
> +{
> +	struct octeontx_vlan_info *vlan = &nic->vlan_info;
> +	pki_port_vlan_filter_config_t fltr_conf;
> +	int rc = 0;
> +
> +	if (vlan->filter_on == flag)
> +		return rc;
> +
> +	fltr_conf.port_type = OCTTX_PORT_TYPE_NET;
> +	fltr_conf.fltr_conf = flag;
> +
> +	rc = octeontx_pki_port_vlan_fltr_config(nic->port_id, &fltr_conf);
> +	if (rc != 0) {
> +		octeontx_log_err("Fail to configure vlan hw filter for port %d",
> +				 nic->port_id);
> +		goto done;
> +	}
> +
> +	vlan->filter_on = flag;
> +
> +done:
> +	return rc;
> +}
> +
> +int
> +octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
> +{
> +	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
> +	struct rte_eth_rxmode *rxmode;
> +	int rc = 0;
> +
> +	rxmode = &dev->data->dev_conf.rxmode;
> +
> +	if (mask & ETH_VLAN_EXTEND_MASK) {
> +		octeontx_log_err("Extend offload not supported");
> +		return -ENOTSUP;
> +	}
> +
> +	if (mask & ETH_VLAN_STRIP_MASK) {
> +		octeontx_log_err("VLAN strip offload not supported");
> +		return -ENOTSUP;
> +	}
> +
> +	if (mask & ETH_VLAN_FILTER_MASK) {
> +		if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
> +			rc = octeontx_vlan_hw_filter(nic, true);
> +			if (rc)
> +				goto done;
> +
> +			nic->rx_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
> +			nic->rx_offload_flags |= OCCTX_RX_VLAN_FLTR_F;
> +		} else {
> +			rc = octeontx_vlan_hw_filter(nic, false);
> +			if (rc)
> +				goto done;
> +
> +			nic->rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
> +			nic->rx_offload_flags &= ~OCCTX_RX_VLAN_FLTR_F;
> +		}
> +	}
> +
> +done:
> +	return rc;
> +}
> +
> +int
> +octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
> +{
> +	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
> +	struct octeontx_vlan_info *vlan = &nic->vlan_info;
> +	pki_port_vlan_filter_entry_config_t fltr_entry;
> +	struct vlan_entry *entry = NULL;
> +	int entry_count = 0;
> +	int rc = -EINVAL;
> +
> +	if (on) {
> +		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
> +			if (entry->vlan_id == vlan_id) {
> +				octeontx_log_dbg("Vlan Id is already set");
> +				return 0;
> +			}
> +	} else {
> +		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
> +			entry_count++;
> +
> +		if (!entry_count)
> +			return 0;
> +	}
> +
> +	fltr_entry.port_type = OCTTX_PORT_TYPE_NET;
> +	fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN;
> +	fltr_entry.vlan_id = vlan_id;
> +	fltr_entry.entry_conf = on;
> +
> +	if (on) {
> +		entry = rte_zmalloc("octeontx_nic_vlan_entry",
> +				    sizeof(struct vlan_entry), 0);
> +		if (!entry) {
> +			octeontx_log_err("Failed to allocate memory");
> +			return -ENOMEM;
> +		}
> +	}
> +
> +	rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id,
> +						      &fltr_entry);
> +	if (rc != 0) {
> +		octeontx_log_err("Fail to configure vlan filter entry "
> +				 "for port %d", nic->port_id);
> +		if (entry)
> +			rte_free(entry);
> +
> +		goto done;
> +	}
> +
> +	if (on) {
> +		entry->vlan_id  = vlan_id;
> +		TAILQ_INSERT_HEAD(&vlan->fltr_tbl, entry, next);
> +	} else {
> +		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
> +			if (entry->vlan_id == vlan_id) {
> +				TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
> +				rte_free(entry);
> +				break;
> +			}
> +		}
> +	}
> +
> +done:
> +	return rc;
> +}
> +
> +int
> +octeontx_dev_vlan_offload_init(struct rte_eth_dev *dev)
> +{
> +	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
> +	int rc;
> +
> +	TAILQ_INIT(&nic->vlan_info.fltr_tbl);
> +
> +	rc = octeontx_dev_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK);
> +	if (rc)
> +		octeontx_log_err("Failed to set vlan offload rc=%d", rc);
> +
> +	return rc;
> +}
> +
> +int
> +octeontx_dev_vlan_offload_fini(struct rte_eth_dev *dev)
> +{
> +	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
> +	struct octeontx_vlan_info *vlan = &nic->vlan_info;
> +	pki_port_vlan_filter_entry_config_t fltr_entry;
> +	struct vlan_entry *entry;
> +	int rc = 0;
> +
> +	TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
> +		fltr_entry.port_type = OCTTX_PORT_TYPE_NET;
> +		fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN;
> +		fltr_entry.vlan_id = entry->vlan_id;
> +		fltr_entry.entry_conf = 0;
> +
> +		rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id,
> +							      &fltr_entry);
> +		if (rc != 0) {
> +			octeontx_log_err("Fail to configure vlan filter entry "
> +					 "for port %d", nic->port_id);
> +			break;
> +		}
> +	}
> +
> +	return rc;
> +}
> diff --git a/drivers/net/octeontx/octeontx_rxtx.h b/drivers/net/octeontx/octeontx_rxtx.h
> index 2383a8eb6..cc044dd79 100644
> --- a/drivers/net/octeontx/octeontx_rxtx.h
> +++ b/drivers/net/octeontx/octeontx_rxtx.h
> @@ -19,6 +19,7 @@
>  
>  #define OCCTX_RX_OFFLOAD_NONE		(0)
>  #define OCCTX_RX_OFFLOAD_RSS_F          BIT(0)
> +#define OCCTX_RX_VLAN_FLTR_F            BIT(1)
>  #define OCCTX_RX_MULTI_SEG_F		BIT(15)
>  
>  #define OCCTX_TX_OFFLOAD_NONE		(0)
> -- 
> 2.18.0
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-04-06 10:09 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-16  9:33 [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Harman Kalra
2020-03-16  9:33 ` [dpdk-dev] [PATCH 1/8] net/octeontx: add multi segment support Harman Kalra
2020-03-16  9:33 ` [dpdk-dev] [PATCH 2/8] net/octeontx: add framework for Rx/Tx offloads Harman Kalra
2020-03-16  9:33 ` [dpdk-dev] [PATCH 3/8] net/octeontx: add fast mbuf free support Harman Kalra
2020-03-16  9:33 ` [dpdk-dev] [PATCH 4/8] net/octeontx: add MTU support Harman Kalra
2020-03-16  9:33 ` [dpdk-dev] [PATCH 5/8] net/octeontx: add VLAN filter offload support Harman Kalra
2020-04-06 10:09   ` Harman Kalra
2020-03-16  9:33 ` [dpdk-dev] [PATCH 6/8] net/octeontx: add set link up down support Harman Kalra
2020-03-16  9:33 ` [dpdk-dev] [PATCH 7/8] net/octeontx: add flow control support Harman Kalra
2020-04-06 10:07   ` Harman Kalra
2020-03-16  9:33 ` [dpdk-dev] [PATCH 8/8] net/octeontx: support Rx Tx checksum offload Harman Kalra
2020-04-05 15:44 ` [dpdk-dev] [PATCH 0/8] add new features to octeontx PMD Jerin Jacob

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).