From patchwork Tue Aug 12 03:12:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jijiang Liu X-Patchwork-Id: 148 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id 6DE38B3AA for ; Tue, 12 Aug 2014 05:09:39 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 11 Aug 2014 20:12:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,846,1400050800"; d="scan'208";a="575329733" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga001.fm.intel.com with ESMTP; 11 Aug 2014 20:12:31 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id s7C3CTw9012737; Tue, 12 Aug 2014 11:12:29 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id s7C3CQnN011138; Tue, 12 Aug 2014 11:12:28 +0800 Received: (from jijiangl@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id s7C3CQ8B011134; Tue, 12 Aug 2014 11:12:26 +0800 From: Jijiang Liu To: dev@dpdk.org Date: Tue, 12 Aug 2014 11:12:06 +0800 Message-Id: <1407813127-10991-6-git-send-email-jijiang.liu@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1407813127-10991-1-git-send-email-jijiang.liu@intel.com> References: <1407813127-10991-1-git-send-email-jijiang.liu@intel.com> Subject: [dpdk-dev] [PATCH 5/6]i40e:VxLAN Tx checksum offload 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: , X-List-Received-Date: Tue, 12 Aug 2014 03:09:40 -0000 Support VxLAN TX check offload, which include outer and inner L3(IP), inner L4(UDP,TCP and SCTP). Signed-off-by: jijiangl Acked-by: Helin Zhang Acked-by: Jingjing Wu Acked-by: Jing Chen --- lib/librte_mbuf/rte_mbuf.h | 4 +++ lib/librte_pmd_i40e/i40e_rxtx.c | 58 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index 2735f37..212ac3a 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -97,6 +97,8 @@ struct rte_ctrlmbuf { #define PKT_RX_IEEE1588_PTP 0x0200 /**< RX IEEE1588 L2 Ethernet PT Packet. */ #define PKT_RX_IEEE1588_TMST 0x0400 /**< RX IEEE1588 L2/L4 timestamped packet.*/ +#define PKT_TX_VXLAN_CKSUM 0x0001 /**< Checksum of TX VxLAN pkt. computed by NIC.. */ +#define PKT_TX_IVLAN_PKT 0x0002 /**< TX packet is VxLAN packet with an inner VLAN. */ #define PKT_TX_VLAN_PKT 0x0800 /**< TX packet is a 802.1q VLAN packet. */ #define PKT_TX_IP_CKSUM 0x1000 /**< IP cksum of TX pkt. computed by NIC. */ #define PKT_TX_IPV4_CSUM 0x1000 /**< Alias of PKT_TX_IP_CKSUM. */ @@ -594,6 +596,7 @@ static inline void rte_pktmbuf_reset(struct rte_mbuf *m) m->pkt.in_port = 0xff; m->ol_flags = 0; + m->reserved = 0; buf_ofs = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ? RTE_PKTMBUF_HEADROOM : m->buf_len; m->pkt.data = (char*) m->buf_addr + buf_ofs; @@ -658,6 +661,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) mi->pkt.pkt_len = mi->pkt.data_len; mi->pkt.nb_segs = 1; mi->ol_flags = md->ol_flags; + mi->reserved = md->reserved; __rte_mbuf_sanity_check(mi, RTE_MBUF_PKT, 1); __rte_mbuf_sanity_check(md, RTE_MBUF_PKT, 0); diff --git a/lib/librte_pmd_i40e/i40e_rxtx.c b/lib/librte_pmd_i40e/i40e_rxtx.c index 83b9462..17633e9 100644 --- a/lib/librte_pmd_i40e/i40e_rxtx.c +++ b/lib/librte_pmd_i40e/i40e_rxtx.c @@ -415,12 +415,16 @@ i40e_rxd_ptype_to_pkt_flags(uint64_t qword) return ip_ptype_map[ptype]; } +#define L4TUN_LEN (sizeof(struct udp_hdr) + sizeof(struct vxlan_hdr)\ + + sizeof(struct ether_hdr)) static inline void i40e_txd_enable_checksum(uint32_t ol_flags, uint32_t *td_cmd, uint32_t *td_offset, uint8_t l2_len, - uint8_t l3_len) + uint8_t l3_len, + uint8_t inner_l3_len, + uint32_t *cd_tunneling) { if (!l2_len) { PMD_DRV_LOG(DEBUG, "L2 length set to 0\n"); @@ -433,6 +437,31 @@ i40e_txd_enable_checksum(uint32_t ol_flags, return; } + /* VxLAN packet TX checksum offload */ + if (unlikely(ol_flags & PKT_TX_VXLAN_CKSUM)) { + uint8_t l4tun_len; + + /* packet with inner VLAN */ + if (ol_flags & PKT_TX_IVLAN_PKT) + l4tun_len = L4TUN_LEN + sizeof(struct vlan_hdr); + else + l4tun_len = L4TUN_LEN; + + if (ol_flags & PKT_TX_IPV4_CSUM) + *cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV4; + else if (ol_flags & PKT_TX_IPV6) + *cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6; + + /* Now set the ctx descriptor fields */ + *cd_tunneling |= (l3_len >> 2) << + I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT | + I40E_TXD_CTX_UDP_TUNNELING | + (l4tun_len >> 1) << + I40E_TXD_CTX_QW0_NATLEN_SHIFT; + + l3_len = inner_l3_len; + } + /* Enable L3 checksum offloads */ if (ol_flags & PKT_TX_IPV4_CSUM) { *td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4_CSUM; @@ -614,6 +643,12 @@ i40e_rx_scan_hw_ring(struct i40e_rx_queue *rxq) I40E_RXD_QW1_STATUS_SHIFT; pkt_len = ((qword1 & I40E_RXD_QW1_LENGTH_PBUF_MASK) >> I40E_RXD_QW1_LENGTH_PBUF_SHIFT) - rxq->crc_len; + + /* reserved is used to store packet type for RX side */ + mb->reserved = (uint8_t)((qword1 & + I40E_RXD_QW1_PTYPE_MASK) >> + I40E_RXD_QW1_PTYPE_SHIFT); + mb->pkt.data_len = pkt_len; mb->pkt.pkt_len = pkt_len; mb->pkt.vlan_macip.f.vlan_tci = rx_status & @@ -860,6 +895,8 @@ i40e_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) pkt_flags = i40e_rxd_status_to_pkt_flags(qword1); pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1); pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1); + rxm->reserved = (uint8_t)((qword1 & I40E_RXD_QW1_PTYPE_MASK) >> + I40E_RXD_QW1_PTYPE_SHIFT); rxm->ol_flags = pkt_flags; if (pkt_flags & PKT_RX_RSS_HASH) rxm->pkt.hash.rss = @@ -1013,6 +1050,9 @@ i40e_recv_scattered_pkts(void *rx_queue, pkt_flags = i40e_rxd_status_to_pkt_flags(qword1); pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1); pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1); + first_seg->reserved = (uint8_t)((qword1 & + I40E_RXD_QW1_PTYPE_MASK) >> + I40E_RXD_QW1_PTYPE_SHIFT); first_seg->ol_flags = pkt_flags; if (pkt_flags & PKT_RX_RSS_HASH) rxm->pkt.hash.rss = @@ -1055,6 +1095,9 @@ i40e_calc_context_desc(uint16_t flags) { uint16_t mask = 0; + if (flags | PKT_TX_VXLAN_CKSUM) + mask |= PKT_TX_VXLAN_CKSUM; + #ifdef RTE_LIBRTE_IEEE1588 mask |= PKT_TX_IEEE1588_TMST; #endif @@ -1074,6 +1117,7 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) volatile struct i40e_tx_desc *txr; struct rte_mbuf *tx_pkt; struct rte_mbuf *m_seg; + uint32_t cd_tunneling_params; uint16_t tx_id; uint16_t nb_tx; uint32_t td_cmd; @@ -1083,6 +1127,7 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) uint16_t ol_flags; uint8_t l2_len; uint8_t l3_len; + uint8_t inner_l3_len; uint16_t nb_used; uint16_t nb_ctx; uint16_t tx_last; @@ -1112,6 +1157,12 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) l2_len = tx_pkt->pkt.vlan_macip.f.l2_len; l3_len = tx_pkt->pkt.vlan_macip.f.l3_len; + /** + * the reserved in mbuf is used to store innel L3 + * header length. + */ + inner_l3_len = tx_pkt->reserved; + /* Calculate the number of context descriptors needed. */ nb_ctx = i40e_calc_context_desc(ol_flags); @@ -1158,15 +1209,16 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) td_cmd |= I40E_TX_DESC_CMD_ICRC; /* Enable checksum offloading */ + cd_tunneling_params = 0; i40e_txd_enable_checksum(ol_flags, &td_cmd, &td_offset, - l2_len, l3_len); + l2_len, l3_len, inner_l3_len, + &cd_tunneling_params); if (unlikely(nb_ctx)) { /* Setup TX context descriptor if required */ volatile struct i40e_tx_context_desc *ctx_txd = (volatile struct i40e_tx_context_desc *)\ &txr[tx_id]; - uint32_t cd_tunneling_params = 0; uint16_t cd_l2tag2 = 0; uint64_t cd_type_cmd_tso_mss = I40E_TX_DESC_DTYPE_CONTEXT;