From patchwork Fri Jun 5 23:15:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 5224 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 EFBF0C392; Sat, 6 Jun 2015 01:15:54 +0200 (CEST) Received: from mail-wi0-f177.google.com (mail-wi0-f177.google.com [209.85.212.177]) by dpdk.org (Postfix) with ESMTP id 538F7C390 for ; Sat, 6 Jun 2015 01:15:54 +0200 (CEST) Received: by wiwd19 with SMTP id d19so34698775wiw.0 for ; Fri, 05 Jun 2015 16:15:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=l5dBf6ms68Dh0h/XA5n67kspD/PCJz5+HygNyDM0pBI=; b=J0x2PVdq548ZDEN3AmolzTwGPl91NrcpReq/3QdzZUfxJFgFEDGvqaqKzncB+Q/4SL UHLiat5MEF336MW6OsdboFZ2lC+rdzQ/OImJmBPy3nr7+tEvHG8H0KjoTDVvZ9SxbPHr eVvnLaGfFdJfXHwh/ZIGgLi3k6vJBgP1FrR0b1iukSEmiU54U2vh21LJw6ExR22wjqRS ex96d68OSnMt+rMVkZnLJRsEX/KgMSqHGoTgLbpXHfJJlJwr/Fz0PHEkWCo1xV6ROJ7c DhbgDv95FAWBmBF5uN87VwEY3tfjB74Eg8I5pk8zS5LKXetgQTJLo1UrvtxrtOYIL/GP bgBQ== X-Gm-Message-State: ALoCoQk4JgnF853wGeWkY9iLyYeq5RyWp9fQh3TnqrLm/c6ylzi9Ggf4udGMGp79igpQ6EWuYLWC X-Received: by 10.194.123.4 with SMTP id lw4mr10228018wjb.94.1433546154222; Fri, 05 Jun 2015 16:15:54 -0700 (PDT) Received: from 6wind.com (guy78-3-82-239-227-177.fbx.proxad.net. [82.239.227.177]) by mx.google.com with ESMTPSA id di7sm5291152wib.23.2015.06.05.16.15.52 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 05 Jun 2015 16:15:53 -0700 (PDT) From: Adrien Mazarguil To: dev@dpdk.org Date: Sat, 6 Jun 2015 01:15:08 +0200 Message-Id: <1433546120-2254-5-git-send-email-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1433546120-2254-1-git-send-email-adrien.mazarguil@6wind.com> References: <1433546120-2254-1-git-send-email-adrien.mazarguil@6wind.com> Subject: [dpdk-dev] [PATCH 04/16] mlx4: add L3 and L4 RX checksum offload support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Gilad Berman Mellanox ConnectX-3 adapters can handle L3 (IPv4) and L4 (TCP, UDP, TCP6, UDP6) RX checksums validation, with and without 802.1Q (VLAN) headers. Signed-off-by: Gilad Berman Signed-off-by: Adrien Mazarguil Acked-by: Guillaume Gaudonville --- drivers/net/mlx4/mlx4.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index e32e433..cec894f 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -141,6 +141,12 @@ static inline void wr_id_t_check(void) (void)wr_id_t_check; } +/* Transpose flags. Useful to convert IBV to DPDK flags. */ +#define TRANSPOSE(val, from, to) \ + (((from) >= (to)) ? \ + (((val) & (from)) / ((from) / (to))) : \ + (((val) & (from)) * ((to) / (from)))) + /* If raw send operations are available, use them since they are faster. */ #ifdef SEND_RAW_WR_SUPPORT typedef struct ibv_send_wr_raw mlx4_send_wr_t; @@ -205,6 +211,7 @@ struct rxq { struct rxq_elt (*no_sp)[]; /* RX elements. */ } elts; unsigned int sp:1; /* Use scattered RX elements. */ + unsigned int csum:1; /* Enable checksum offloading. */ uint32_t mb_len; /* Length of a mp-issued mbuf. */ struct mlx4_rxq_stats stats; /* RX queue counters. */ unsigned int socket; /* CPU socket ID for allocations. */ @@ -277,6 +284,7 @@ struct priv { unsigned int hw_qpg:1; /* QP groups are supported. */ unsigned int hw_tss:1; /* TSS is supported. */ unsigned int hw_rss:1; /* RSS is supported. */ + unsigned int hw_csum:1; /* Checksum offload is supported. */ unsigned int rss:1; /* RSS is enabled. */ unsigned int vf:1; /* This is a VF device. */ #ifdef INLINE_RECV @@ -2296,6 +2304,34 @@ rxq_cleanup(struct rxq *rxq) memset(rxq, 0, sizeof(*rxq)); } +/** + * Translate RX work completion flags to offload flags. + * + * @param[in] rxq + * Pointer to RX queue structure. + * @param exp_wc_flags + * RX flags from struct ibv_exp_wc. + * + * @return + * Offload flags (ol_flags) for struct rte_mbuf. + */ +static inline uint32_t +rxq_wc_to_ol_flags(const struct rxq *rxq, uint64_t exp_wc_flags) +{ + uint32_t ol_flags; + + ol_flags = + TRANSPOSE(exp_wc_flags, IBV_EXP_IPV4_PACKET, PKT_RX_IPV4_HDR) | + TRANSPOSE(exp_wc_flags, IBV_EXP_IPV6_PACKET, PKT_RX_IPV6_HDR); + if (rxq->csum) + ol_flags |= + TRANSPOSE(~exp_wc_flags, + IBV_EXP_L3_RX_CSUM_OK, PKT_RX_IP_CKSUM_BAD) | + TRANSPOSE(~exp_wc_flags, + IBV_EXP_L4_RX_CSUM_OK, PKT_RX_L4_CKSUM_BAD); + return ol_flags; +} + static uint16_t mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n); @@ -2453,7 +2489,7 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) NB_SEGS(pkt_buf) = j; PORT(pkt_buf) = rxq->port_id; PKT_LEN(pkt_buf) = wc->byte_len; - pkt_buf->ol_flags = 0; + pkt_buf->ol_flags = rxq_wc_to_ol_flags(rxq, wc->exp_wc_flags); /* Return packet. */ *(pkts++) = pkt_buf; @@ -2594,7 +2630,7 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) NEXT(seg) = NULL; PKT_LEN(seg) = len; DATA_LEN(seg) = len; - seg->ol_flags = 0; + seg->ol_flags = rxq_wc_to_ol_flags(rxq, wc->exp_wc_flags); /* Return packet. */ *(pkts++) = seg; @@ -2818,6 +2854,11 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq) /* Number of descriptors and mbufs currently allocated. */ desc_n = (tmpl.elts_n * (tmpl.sp ? MLX4_PMD_SGE_WR_N : 1)); mbuf_n = desc_n; + /* Toggle RX checksum offload if hardware supports it. */ + if (priv->hw_csum) { + tmpl.csum = !!dev->data->dev_conf.rxmode.hw_ip_checksum; + rxq->csum = tmpl.csum; + } /* Enable scattered packets support for this queue if necessary. */ if ((dev->data->dev_conf.rxmode.jumbo_frame) && (dev->data->dev_conf.rxmode.max_rx_pkt_len > @@ -3034,6 +3075,9 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc, rte_pktmbuf_tailroom(buf)) == tmpl.mb_len); assert(rte_pktmbuf_headroom(buf) == RTE_PKTMBUF_HEADROOM); rte_pktmbuf_free(buf); + /* Toggle RX checksum offload if hardware supports it. */ + if (priv->hw_csum) + tmpl.csum = !!dev->data->dev_conf.rxmode.hw_ip_checksum; /* Enable scattered packets support for this queue if necessary. */ if ((dev->data->dev_conf.rxmode.jumbo_frame) && (dev->data->dev_conf.rxmode.max_rx_pkt_len > @@ -3509,6 +3553,13 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) info->max_rx_queues = max; info->max_tx_queues = max; info->max_mac_addrs = elemof(priv->mac); + 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; priv_unlock(priv); } @@ -4540,6 +4591,14 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) exp_device_attr.max_rss_tbl_sz); #endif /* RSS_SUPPORT */ + priv->hw_csum = + ((exp_device_attr.exp_device_cap_flags & + IBV_EXP_DEVICE_RX_CSUM_L4_PKT) && + (exp_device_attr.exp_device_cap_flags & + IBV_EXP_DEVICE_RX_CSUM_L3_PKT)); + DEBUG("checksum offloading is %ssupported", + (priv->hw_csum ? "" : "not ")); + #ifdef INLINE_RECV priv->inl_recv_size = mlx4_getenv_int("MLX4_INLINE_RECV_SIZE");