From patchwork Thu Aug 3 08:49:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vasily Philipov X-Patchwork-Id: 27398 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 4ABAD2E41; Thu, 3 Aug 2017 10:49:33 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id D1EDC2C6E for ; Thu, 3 Aug 2017 10:49:31 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from vasilyf@mellanox.com) with ESMTPS (AES256-SHA encrypted); 3 Aug 2017 11:49:22 +0300 Received: from hpchead.mtr.labs.mlnx. (hpchead.mtr.labs.mlnx [10.209.44.59]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id v738nLjk025660; Thu, 3 Aug 2017 11:49:21 +0300 Received: from hpchead.mtr.labs.mlnx. (localhost.localdomain [127.0.0.1]) by hpchead.mtr.labs.mlnx. (8.14.7/8.14.7) with ESMTP id v738nLPt006867; Thu, 3 Aug 2017 11:49:21 +0300 Received: (from vasilyf@localhost) by hpchead.mtr.labs.mlnx. (8.14.7/8.14.7/Submit) id v738nLhJ006866; Thu, 3 Aug 2017 11:49:21 +0300 From: Vasily Philipov To: dev@dpdk.org Cc: Vasily Philipov , Adrien Mazarguil , Nelio Laranjeiro Date: Thu, 3 Aug 2017 11:49:15 +0300 Message-Id: X-Mailer: git-send-email 1.8.3.1 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH 2/2] net/mlx4: get back RX offloads X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Adding support for RX checksum and packet type HW offloads. Signed-off-by: Vasily Philipov --- 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. */ };