* [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
* 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
* [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
* 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
* [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