All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>
To: <dev@dpdk.org>
Cc: <xavier.huwei@huawei.com>
Subject: [dpdk-dev] [PATCH v3 3/4] net/hns3: support keeping CRC
Date: Tue, 14 Jul 2020 14:16:08 +0800	[thread overview]
Message-ID: <1594707369-36270-4-git-send-email-xavier.huwei@huawei.com> (raw)
In-Reply-To: <1594707369-36270-1-git-send-email-xavier.huwei@huawei.com>

From: "Min Hu (Connor)" <humin29@huawei.com>

CRC is the end of frame, which occupies 4 bytes. Keeping CRC is a feature
of MAC, which will not strip CRC field when receiving frames. The featrue
can be enabled using DEV_RX_OFFLOAD_KEEP_CRC offload by upper level
application. And the feature is only supported for hns3 PF PMD driver,
not supported for hns3 VF PMD driver

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
v2 -> v3:
	Because "rxm->next = NULL;" had been moved before, del the
        redundant statement.
v1 -> v2:
	fix typo, replacing 'recalulate' with 'recalculate'
---
 drivers/net/hns3/hns3_ethdev.c    | 10 +++++++-
 drivers/net/hns3/hns3_ethdev_vf.c |  1 -
 drivers/net/hns3/hns3_rxtx.c      | 54 ++++++++++++++++++++++++++++++++++++---
 drivers/net/hns3/hns3_rxtx.h      |  3 +++
 4 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 4712cc2..81e7730 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -4184,7 +4184,15 @@ hns3_cfg_mac_mode(struct hns3_hw *hw, bool enable)
 	hns3_set_bit(loop_en, HNS3_MAC_LINE_LP_B, 0);
 	hns3_set_bit(loop_en, HNS3_MAC_FCS_TX_B, val);
 	hns3_set_bit(loop_en, HNS3_MAC_RX_FCS_B, val);
-	hns3_set_bit(loop_en, HNS3_MAC_RX_FCS_STRIP_B, val);
+
+	/*
+	 * If DEV_RX_OFFLOAD_KEEP_CRC offload is set, MAC will not strip CRC
+	 * when receiving frames. Otherwise, CRC will be stripped.
+	 */
+	if (hw->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC)
+		hns3_set_bit(loop_en, HNS3_MAC_RX_FCS_STRIP_B, 0);
+	else
+		hns3_set_bit(loop_en, HNS3_MAC_RX_FCS_STRIP_B, val);
 	hns3_set_bit(loop_en, HNS3_MAC_TX_OVERSIZE_TRUNCATE_B, val);
 	hns3_set_bit(loop_en, HNS3_MAC_RX_OVERSIZE_TRUNCATE_B, val);
 	hns3_set_bit(loop_en, HNS3_MAC_TX_UNDER_MIN_ERR_B, val);
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index b881bbe..1d2941f 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -913,7 +913,6 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 				 DEV_RX_OFFLOAD_SCTP_CKSUM |
 				 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
 				 DEV_RX_OFFLOAD_OUTER_UDP_CKSUM |
-				 DEV_RX_OFFLOAD_KEEP_CRC |
 				 DEV_RX_OFFLOAD_SCATTER |
 				 DEV_RX_OFFLOAD_VLAN_STRIP |
 				 DEV_RX_OFFLOAD_VLAN_FILTER |
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index b0253d5..c0f7981 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -1312,6 +1312,12 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc,
 	rxq->ol3_csum_erros = 0;
 	rxq->ol4_csum_erros = 0;
 
+	/* CRC len set here is used for amending packet length */
+	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC)
+		rxq->crc_len = RTE_ETHER_CRC_LEN;
+	else
+		rxq->crc_len = 0;
+
 	rte_spinlock_lock(&hw->lock);
 	dev->data->rx_queues[idx] = rxq;
 	rte_spinlock_unlock(&hw->lock);
@@ -1578,6 +1584,23 @@ hns3_rxd_to_vlan_tci(struct hns3_rx_queue *rxq, struct rte_mbuf *mb,
 	}
 }
 
+static inline void
+recalculate_data_len(struct rte_mbuf *first_seg, struct rte_mbuf *last_seg,
+		    struct rte_mbuf *rxm, struct hns3_rx_queue *rxq,
+		    uint16_t data_len)
+{
+	uint8_t crc_len = rxq->crc_len;
+
+	if (data_len <= crc_len) {
+		rte_pktmbuf_free_seg(rxm);
+		first_seg->nb_segs--;
+		last_seg->data_len = (uint16_t)(last_seg->data_len -
+			(crc_len - data_len));
+		last_seg->next = NULL;
+	} else
+		rxm->data_len = (uint16_t)(data_len - crc_len);
+}
+
 uint16_t
 hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 {
@@ -1708,7 +1731,11 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		rxdp->rx.bd_base_info = 0;
 		rxdp->addr = dma_addr;
 
-		/* Load remained descriptor data and extract necessary fields */
+		/*
+		 * Load remained descriptor data and extract necessary fields.
+		 * Data size from buffer description may contains CRC len,
+		 * packet len should subtract it.
+		 */
 		data_len = (uint16_t)(rte_le_to_cpu_16(rxd.rx.size));
 		l234_info = rte_le_to_cpu_32(rxd.rx.l234_info);
 		ol_info = rte_le_to_cpu_32(rxd.rx.ol_info);
@@ -1729,9 +1756,31 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 			continue;
 		}
 
-		/* The last buffer of the received packet */
+		/*
+		 * The last buffer of the received packet. packet len from
+		 * buffer description may contains CRC len, packet len should
+		 * subtract it, same as data len.
+		 */
 		pkt_len = (uint16_t)(rte_le_to_cpu_16(rxd.rx.pkt_len));
 		first_seg->pkt_len = pkt_len;
+
+		/*
+		 * This is the last buffer of the received packet. If the CRC
+		 * is not stripped by the hardware:
+		 *  - Subtract the CRC length from the total packet length.
+		 *  - If the last buffer only contains the whole CRC or a part
+		 *  of it, free the mbuf associated to the last buffer. If part
+		 *  of the CRC is also contained in the previous mbuf, subtract
+		 *  the length of that CRC part from the data length of the
+		 *  previous mbuf.
+		 */
+		rxm->next = NULL;
+		if (unlikely(rxq->crc_len > 0)) {
+			first_seg->pkt_len -= rxq->crc_len;
+			recalculate_data_len(first_seg, last_seg, rxm, rxq,
+				data_len);
+		}
+
 		first_seg->port = rxq->port_id;
 		first_seg->hash.rss = rte_le_to_cpu_32(rxd.rx.rss_hash);
 		first_seg->ol_flags = PKT_RX_RSS_HASH;
@@ -1740,7 +1789,6 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 				rte_le_to_cpu_32(rxd.rx.fd_id);
 			first_seg->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
 		}
-		rxm->next = NULL;
 
 		gro_size = hns3_get_field(bd_base_info, HNS3_RXD_GRO_SIZE_M,
 					  HNS3_RXD_GRO_SIZE_S);
diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h
index ccd508b..0d20a27 100644
--- a/drivers/net/hns3/hns3_rxtx.h
+++ b/drivers/net/hns3/hns3_rxtx.h
@@ -256,6 +256,9 @@ struct hns3_rx_queue {
 	 */
 	uint16_t pvid_state;
 
+	/* 4 if DEV_RX_OFFLOAD_KEEP_CRC offload set, 0 otherwise */
+	uint8_t crc_len;
+
 	bool rx_deferred_start; /* don't start this queue in dev start */
 	bool configured;        /* indicate if rx queue has been configured */
 
-- 
2.7.4


  parent reply	other threads:[~2020-07-14  6:18 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-11 10:18 [dpdk-dev] [PATCH v2 0/4] updates for hns3 PMD driver Wei Hu (Xavier)
2020-07-11 10:18 ` [dpdk-dev] [PATCH v2 1/4] net/hns3: support copper media type Wei Hu (Xavier)
2020-07-14  6:16   ` [dpdk-dev] [PATCH v3 0/4] updates for hns3 PMD driver Wei Hu (Xavier)
2020-07-14  6:16     ` [dpdk-dev] [PATCH v3 1/4] net/hns3: support copper media type Wei Hu (Xavier)
2020-07-14  6:16     ` [dpdk-dev] [PATCH v3 2/4] net/hns3: support 200G speed rate Wei Hu (Xavier)
2020-07-14  6:16     ` Wei Hu (Xavier) [this message]
2020-07-14  6:16     ` [dpdk-dev] [PATCH v3 4/4] net/hns3: fix RSS configuration when empty RSS type Wei Hu (Xavier)
2020-07-14 11:07     ` [dpdk-dev] [PATCH v3 0/4] updates for hns3 PMD driver Ferruh Yigit
2020-07-11 10:18 ` [dpdk-dev] [PATCH v2 2/4] net/hns3: support 200G speed rate Wei Hu (Xavier)
2020-07-11 10:18 ` [dpdk-dev] [PATCH v2 3/4] net/hns3: support keeping CRC Wei Hu (Xavier)
2020-07-11 10:18 ` [dpdk-dev] [PATCH v2 4/4] net/hns3: fix RSS configuration when empty RSS type Wei Hu (Xavier)

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=1594707369-36270-4-git-send-email-xavier.huwei@huawei.com \
    --to=xavier.huwei@huawei.com \
    --cc=dev@dpdk.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.