DPDK patches and discussions
 help / color / mirror / Atom feed
From: Vasily Philipov <vasilyf@mellanox.com>
To: dev@dpdk.org
Cc: Vasily Philipov <vasilyf@mellanox.com>,
	Adrien Mazarguil <adrien.mazarguil@6wind.com>,
	Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Subject: [dpdk-dev] [PATCH 2/2] net/mlx4: get back RX offloads
Date: Thu,  3 Aug 2017 11:49:15 +0300	[thread overview]
Message-ID: <a3af1dec4c036507cd8341c809dca54534817e96.1501749963.git.vasilyf@mellanox.com> (raw)
In-Reply-To: <fa8e5827c13923dd42fa54405c9b1069adcf718a.1501749963.git.vasilyf@mellanox.com>
In-Reply-To: <fa8e5827c13923dd42fa54405c9b1069adcf718a.1501749963.git.vasilyf@mellanox.com>

Adding support for RX checksum and packet type HW offloads.

Signed-off-by: Vasily Philipov <vasilyf@mellanox.com>
---
 drivers/net/mlx4/mlx4.c        |  11 ++++
 drivers/net/mlx4/mlx4.h        |   2 +
 drivers/net/mlx4/mlx4_ethdev.c |   7 ++-
 drivers/net/mlx4/mlx4_prm.h    |   9 ++++
 drivers/net/mlx4/mlx4_rxq.c    |   5 ++
 drivers/net/mlx4/mlx4_rxtx.c   | 120 ++++++++++++++++++++++++++++++++++++++++-
 drivers/net/mlx4/mlx4_rxtx.h   |   2 +
 7 files changed, 153 insertions(+), 3 deletions(-)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 8573e14..6842df1 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -571,6 +571,17 @@ struct mlx4_conf {
 		priv->pd = pd;
 		priv->mtu = ETHER_MTU;
 		priv->vf = vf;
+		priv->hw_csum =
+			((to_mctx(ctx)->exp_device_cap_flags &
+			  MLX4_DEVICE_RX_CSUM_TCP_UDP_PKT) &&
+			 (to_mctx(ctx)->exp_device_cap_flags &
+			  MLX4_DEVICE_RX_CSUM_IP_PKT));
+		DEBUG("checksum offloading is %ssupported",
+		      (priv->hw_csum ? "" : "not "));
+		priv->hw_csum_l2tun = !!(to_mctx(ctx)->exp_device_cap_flags &
+					 MLX4_DEVICE_VXLAN_SUPPORT);
+		DEBUG("L2 tunnel checksum offloads are %ssupported",
+		      (priv->hw_csum_l2tun ? "" : "not "));
 		/* Configure the first MAC address by default. */
 		if (mlx4_get_mac(priv, &mac.addr_bytes)) {
 			ERROR("cannot get MAC address, is mlx4_en loaded?"
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 4b7f98b..b81dcb0 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -107,6 +107,8 @@ struct priv {
 	unsigned int vf:1; /* This is a VF device. */
 	unsigned int intr_alarm:1; /* An interrupt alarm is scheduled. */
 	unsigned int isolated:1; /* Toggle isolated mode. */
+	unsigned int hw_csum:1; /* Checksum offload is supported. */
+	unsigned int hw_csum_l2tun:1; /* Same for L2 tunnels. */
 	/* RX/TX queues. */
 	unsigned int rxqs_n; /* RX queues array size. */
 	unsigned int txqs_n; /* TX queues array size. */
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index 8c6b1fd..9b5ba31 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -551,7 +551,12 @@
 	info->max_tx_queues = max;
 	/* Last array entry is reserved for broadcast. */
 	info->max_mac_addrs = 1;
-	info->rx_offload_capa = 0;
+	info->rx_offload_capa =
+		(priv->hw_csum ?
+		 (DEV_RX_OFFLOAD_IPV4_CKSUM |
+		  DEV_RX_OFFLOAD_UDP_CKSUM |
+		  DEV_RX_OFFLOAD_TCP_CKSUM) :
+		 0);
 	info->tx_offload_capa = 0;
 	if (mlx4_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
diff --git a/drivers/net/mlx4/mlx4_prm.h b/drivers/net/mlx4/mlx4_prm.h
index 03c1192..a06781e 100644
--- a/drivers/net/mlx4/mlx4_prm.h
+++ b/drivers/net/mlx4/mlx4_prm.h
@@ -402,4 +402,13 @@ static inline struct mlx4_qp *to_mqp(struct ibv_qp *ibqp)
 			    struct mlx4_qp, verbs_qp);
 }
 
+enum mlx4_device_cap_flags {
+	MLX4_START_FLAG_LOC = 0x20,
+	MLX4_START_FLAG	    = (1ULL << MLX4_START_FLAG_LOC),
+
+	MLX4_DEVICE_VXLAN_SUPPORT	= (MLX4_START_FLAG << 10),
+	MLX4_DEVICE_RX_CSUM_TCP_UDP_PKT = (MLX4_START_FLAG << 11),
+	MLX4_DEVICE_RX_CSUM_IP_PKT	= (MLX4_START_FLAG << 12),
+};
+
 #endif /* RTE_PMD_MLX4_PRM_H_ */
diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
index bbe9c89..c431033 100644
--- a/drivers/net/mlx4/mlx4_rxq.c
+++ b/drivers/net/mlx4/mlx4_rxq.c
@@ -274,6 +274,11 @@
 
 	(void)conf; /* Thresholds configuration (ignored). */
 	mb_len = rte_pktmbuf_data_room_size(mp);
+	/* Toggle RX checksum offload if hardware supports it. */
+	if (priv->hw_csum)
+		tmpl.csum = !!dev->data->dev_conf.rxmode.hw_ip_checksum;
+	if (priv->hw_csum_l2tun)
+		tmpl.csum_l2tun = !!dev->data->dev_conf.rxmode.hw_ip_checksum;
 	/* Enable scattered packets support for this queue if necessary. */
 	assert(mb_len >= RTE_PKTMBUF_HEADROOM);
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
diff --git a/drivers/net/mlx4/mlx4_rxtx.c b/drivers/net/mlx4/mlx4_rxtx.c
index f11c84c..f090354 100644
--- a/drivers/net/mlx4/mlx4_rxtx.c
+++ b/drivers/net/mlx4/mlx4_rxtx.c
@@ -348,6 +348,115 @@
 }
 
 /**
+ * Translate RX completion flags to packet type.
+ *
+ * @param flags
+ *   RX completion flags returned by poll_length_flags().
+ *
+ * @return
+ *   Packet type for struct rte_mbuf.
+ */
+static inline uint32_t
+rxq_cq_to_pkt_type(uint32_t flags)
+{
+	uint32_t pkt_type;
+
+	if (flags & MLX4_CQE_L2_TUNNEL)
+		pkt_type =
+			MLX4_TRANSPOSE(flags,
+				       MLX4_CQE_L2_TUNNEL_IPV4,
+				       RTE_PTYPE_L3_IPV4_EXT_UNKNOWN) |
+			MLX4_TRANSPOSE(~flags,
+				       MLX4_CQE_L2_TUNNEL_IPV4,
+				       RTE_PTYPE_L3_IPV6_EXT_UNKNOWN) |
+			MLX4_TRANSPOSE(flags,
+				       MLX4_CQE_STATUS_IPV4,
+				       RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN) |
+			MLX4_TRANSPOSE(flags,
+				       MLX4_CQE_STATUS_IPV6,
+				       RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN);
+	else
+		pkt_type =
+			MLX4_TRANSPOSE(flags,
+				       MLX4_CQE_STATUS_IPV4,
+				       RTE_PTYPE_L3_IPV4_EXT_UNKNOWN) |
+			MLX4_TRANSPOSE(flags,
+				       MLX4_CQE_STATUS_IPV6,
+				       RTE_PTYPE_L3_IPV6_EXT_UNKNOWN);
+	return pkt_type;
+}
+
+/**
+ * Translate RX completion flags to offload flags.
+ *
+ * @param[in] rxq
+ *   Pointer to RX queue structure.
+ * @param flags
+ *   RX completion flags returned by poll_length_flags().
+ *
+ * @return
+ *   Offload flags (ol_flags) for struct rte_mbuf.
+ */
+static inline uint32_t
+rxq_cq_to_ol_flags(const struct rxq *rxq, uint32_t flags)
+{
+	uint32_t ol_flags = 0;
+
+	if (rxq->csum)
+		ol_flags |=
+			MLX4_TRANSPOSE(flags,
+				       MLX4_CQE_STATUS_IPOK,
+				       PKT_RX_IP_CKSUM_GOOD) |
+			MLX4_TRANSPOSE(flags,
+				       MLX4_CQE_STATUS_L4_CSUM,
+				       PKT_RX_L4_CKSUM_GOOD);
+	if ((flags & MLX4_CQE_L2_TUNNEL) && (rxq->csum_l2tun))
+		ol_flags |=
+			MLX4_TRANSPOSE(flags,
+				       MLX4_CQE_L2_TUNNEL_IPOK,
+				       PKT_RX_IP_CKSUM_GOOD) |
+			MLX4_TRANSPOSE(flags,
+				       MLX4_CQE_L2_TUNNEL_L4_CSUM,
+				       PKT_RX_L4_CKSUM_GOOD);
+	return ol_flags;
+}
+
+/**
+ * Get cqe flags.
+ *
+ * @param cqe
+ *   Pointer to cqe structure.
+ * @param mlx4_qp
+ *   Pointer to QP structure.
+ *
+ * @return
+ *   CQE's flags.
+ */
+static inline uint32_t
+mlx4_cqe_flags(struct mlx4_cqe *cqe, struct ibv_qp *qp)
+{
+	uint32_t flags = 0;
+	struct mlx4_qp *mlx4_qp = to_mqp(qp);
+
+	/*
+	 * The relevant bits are in different locations on their
+	 * CQE fields therefore we can join them in one 32bit
+	 * variable.
+	 */
+	if (mlx4_qp->qp_cap_cache & MLX4_RX_CSUM_MODE_IP_OK_IP_NON_TCP_UDP)
+		flags = (cqe->badfcs_enc & MLX4_CQE_STATUS_L4_CSUM) |
+			(ntohs(cqe->status) & (MLX4_CQE_STATUS_IPOK |
+					       MLX4_CQE_STATUS_IPV4 |
+					       MLX4_CQE_STATUS_IPV6));
+	if (mlx4_qp->qp_cap_cache & MLX4_RX_VXLAN)
+		flags |= ntohl(cqe->vlan_my_qpn) & (MLX4_CQE_L2_TUNNEL     |
+						MLX4_CQE_L2_TUNNEL_IPOK    |
+						MLX4_CQE_L2_TUNNEL_L4_CSUM |
+						MLX4_CQE_L2_TUNNEL_IPV4);
+	return flags;
+}
+
+/**
  * Get next cqe from HW.
  *
  * @param cq
@@ -485,8 +594,15 @@
 				goto skip;
 			}
 			pkt = seg;
-			pkt->packet_type = 0;
-			pkt->ol_flags = 0;
+			if (rxq->csum | rxq->csum_l2tun) {
+				uint32_t flags = mlx4_cqe_flags(cqe, rxq->qp);
+
+				pkt->packet_type = rxq_cq_to_pkt_type(flags);
+				pkt->ol_flags = rxq_cq_to_ol_flags(rxq, flags);
+			} else {
+				pkt->packet_type = 0;
+				pkt->ol_flags = 0;
+			}
 			pkt->pkt_len = len;
 		}
 		rep->nb_segs = 1;
diff --git a/drivers/net/mlx4/mlx4_rxtx.h b/drivers/net/mlx4/mlx4_rxtx.h
index 077fdd8..2f03a94 100644
--- a/drivers/net/mlx4/mlx4_rxtx.h
+++ b/drivers/net/mlx4/mlx4_rxtx.h
@@ -87,6 +87,8 @@ struct rxq {
 		uint16_t rq_ci;
 	} hw;
 	unsigned int sge_n; /**< Log 2 of SGEs number. */
+	unsigned int csum:1; /**< Enable checksum offloading. */
+	unsigned int csum_l2tun:1; /**< Same for L2 tunnels. */
 	struct mlx4_rxq_stats stats; /**< Rx queue counters. */
 	unsigned int socket; /**< CPU socket ID for allocations. */
 };
-- 
1.8.3.1

  reply	other threads:[~2017-08-03  8:49 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-03  8:49 [dpdk-dev] [PATCH 1/2] net/mlx4: get back RX flow functionality Vasily Philipov
2017-08-03  8:49 ` Vasily Philipov [this message]
2017-09-25 13:42 ` Ferruh Yigit

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=a3af1dec4c036507cd8341c809dca54534817e96.1501749963.git.vasilyf@mellanox.com \
    --to=vasilyf@mellanox.com \
    --cc=adrien.mazarguil@6wind.com \
    --cc=dev@dpdk.org \
    --cc=nelio.laranjeiro@6wind.com \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).