From 64b36e4af127205a0ca27bcccae2979b9a566acc Mon Sep 17 00:00:00 2001 From: Jiawen Wu Date: Thu, 21 Oct 2021 17:50:03 +0800 Subject: [PATCH] net/ngbe: support CRC offload Support to strip or keep CRC in Rx path. Signed-off-by: Jiawen Wu --- doc/guides/nics/features/ngbe.ini | 1 + drivers/net/ngbe/ngbe_rxtx.c | 53 +++++++++++++++++++++++++++++-- drivers/net/ngbe/ngbe_rxtx.h | 1 + 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/features/ngbe.ini b/doc/guides/nics/features/ngbe.ini index 70bf91e6a1..053dff3a2f 100644 --- a/doc/guides/nics/features/ngbe.ini +++ b/doc/guides/nics/features/ngbe.ini @@ -11,6 +11,7 @@ Queue start/stop = Y Burst mode info = Y Scattered Rx = Y TSO = Y +CRC offload = Y L3 checksum offload = Y L4 checksum offload = Y Inner L3 checksum = Y diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c index 5941e0a2d8..6687d58e6a 100644 --- a/drivers/net/ngbe/ngbe_rxtx.c +++ b/drivers/net/ngbe/ngbe_rxtx.c @@ -965,7 +965,8 @@ ngbe_rx_scan_hw_ring(struct ngbe_rx_queue *rxq) /* Translate descriptor info to mbuf format */ for (j = 0; j < nb_dd; ++j) { mb = rxep[j].mbuf; - pkt_len = rte_le_to_cpu_16(rxdp[j].qw1.hi.len); + pkt_len = rte_le_to_cpu_16(rxdp[j].qw1.hi.len) - + rxq->crc_len; mb->data_len = pkt_len; mb->pkt_len = pkt_len; @@ -1268,7 +1269,8 @@ ngbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, * - IP checksum flag, * - error flags. */ - pkt_len = (uint16_t)(rte_le_to_cpu_16(rxd.qw1.hi.len)); + pkt_len = (uint16_t)(rte_le_to_cpu_16(rxd.qw1.hi.len) - + rxq->crc_len); rxm->data_off = RTE_PKTMBUF_HEADROOM; rte_packet_prefetch((char *)rxm->buf_addr + rxm->data_off); rxm->nb_segs = 1; @@ -1518,6 +1520,22 @@ next_desc: /* Initialize the first mbuf of the returned packet */ ngbe_fill_cluster_head_buf(first_seg, &rxd, rxq, staterr); + /* Deal with the case, when HW CRC srip is disabled. */ + first_seg->pkt_len -= rxq->crc_len; + if (unlikely(rxm->data_len <= rxq->crc_len)) { + struct rte_mbuf *lp; + + for (lp = first_seg; lp->next != rxm; lp = lp->next) + ; + + first_seg->nb_segs--; + lp->data_len -= rxq->crc_len - rxm->data_len; + lp->next = NULL; + rte_pktmbuf_free_seg(rxm); + } else { + rxm->data_len -= rxq->crc_len; + } + /* Prefetch data of first segment, if configured to do so. */ rte_packet_prefetch((char *)first_seg->buf_addr + first_seg->data_off); @@ -2014,6 +2032,7 @@ ngbe_get_rx_port_offloads(struct rte_eth_dev *dev __rte_unused) offloads = RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_TCP_CKSUM | + RTE_ETH_RX_OFFLOAD_KEEP_CRC | RTE_ETH_RX_OFFLOAD_SCATTER; return offloads; @@ -2054,6 +2073,10 @@ ngbe_dev_rx_queue_setup(struct rte_eth_dev *dev, rxq->queue_id = queue_idx; rxq->reg_idx = queue_idx; rxq->port_id = dev->data->port_id; + if (dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) + rxq->crc_len = RTE_ETHER_CRC_LEN; + else + rxq->crc_len = 0; rxq->drop_en = rx_conf->rx_drop_en; rxq->rx_deferred_start = rx_conf->rx_deferred_start; @@ -2309,6 +2332,7 @@ ngbe_dev_rx_init(struct rte_eth_dev *dev) uint32_t fctrl; uint32_t hlreg0; uint32_t srrctl; + uint32_t rdrxctl; uint32_t rxcsum; uint16_t buf_size; uint16_t i; @@ -2329,7 +2353,14 @@ ngbe_dev_rx_init(struct rte_eth_dev *dev) fctrl |= NGBE_PSRCTL_BCA; wr32(hw, NGBE_PSRCTL, fctrl); + /* + * Configure CRC stripping, if any. + */ hlreg0 = rd32(hw, NGBE_SECRXCTL); + if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) + hlreg0 &= ~NGBE_SECRXCTL_CRCSTRIP; + else + hlreg0 |= NGBE_SECRXCTL_CRCSTRIP; hlreg0 &= ~NGBE_SECRXCTL_XDSA; wr32(hw, NGBE_SECRXCTL, hlreg0); @@ -2340,6 +2371,15 @@ ngbe_dev_rx_init(struct rte_eth_dev *dev) for (i = 0; i < dev->data->nb_rx_queues; i++) { rxq = dev->data->rx_queues[i]; + /* + * Reset crc_len in case it was changed after queue setup by a + * call to configure. + */ + if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) + rxq->crc_len = RTE_ETHER_CRC_LEN; + else + rxq->crc_len = 0; + /* Setup the Base and Length of the Rx Descriptor Rings */ bus_addr = rxq->rx_ring_phys_addr; wr32(hw, NGBE_RXBAL(rxq->reg_idx), @@ -2384,6 +2424,15 @@ ngbe_dev_rx_init(struct rte_eth_dev *dev) wr32(hw, NGBE_PSRCTL, rxcsum); + if (hw->is_pf) { + rdrxctl = rd32(hw, NGBE_SECRXCTL); + if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) + rdrxctl &= ~NGBE_SECRXCTL_CRCSTRIP; + else + rdrxctl |= NGBE_SECRXCTL_CRCSTRIP; + wr32(hw, NGBE_SECRXCTL, rdrxctl); + } + ngbe_set_rx_function(dev); return 0; diff --git a/drivers/net/ngbe/ngbe_rxtx.h b/drivers/net/ngbe/ngbe_rxtx.h index eb86a79760..6364214ff5 100644 --- a/drivers/net/ngbe/ngbe_rxtx.h +++ b/drivers/net/ngbe/ngbe_rxtx.h @@ -266,6 +266,7 @@ struct ngbe_rx_queue { uint16_t queue_id; /**< RX queue index */ uint16_t reg_idx; /**< RX queue register index */ uint16_t port_id; /**< Device port identifier */ + uint8_t crc_len; /**< 0 if CRC stripped, 4 otherwise. */ uint8_t drop_en; /**< If not 0, set SRRCTL.Drop_En */ uint8_t rx_deferred_start; /**< not in global dev start */ /** need to alloc dummy mbuf, for wraparound when scanning hw ring */ -- 2.39.5