From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 30E73461E4; Mon, 10 Feb 2025 08:29:48 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E51B9415D7; Mon, 10 Feb 2025 08:27:54 +0100 (CET) Received: from localhost.localdomain (unknown [103.233.162.252]) by mails.dpdk.org (Postfix) with ESMTP id CCFEB40F1A for ; Mon, 10 Feb 2025 08:27:48 +0100 (CET) Received: by localhost.localdomain (Postfix, from userid 0) id D2DCCA3A49; Mon, 10 Feb 2025 15:27:22 +0800 (CST) From: Wenbo Cao To: thomas@monjalon.net, Wenbo Cao Cc: stephen@networkplumber.org, dev@dpdk.org, ferruh.yigit@amd.com, andrew.rybchenko@oktetlabs.ru, yaojun@mucse.com Subject: [PATCH v8 23/28] net/rnp: add support Rx checksum offload Date: Mon, 10 Feb 2025 15:26:50 +0800 Message-Id: <1739172415-48507-24-git-send-email-caowenbo@mucse.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1739172415-48507-1-git-send-email-caowenbo@mucse.com> References: <1739172415-48507-1-git-send-email-caowenbo@mucse.com> X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support Rx l3/l4 checum and tunnel inner l3/l4, out l3 chksum. Signed-off-by: Wenbo Cao --- doc/guides/nics/features/rnp.ini | 4 ++ doc/guides/nics/rnp.rst | 1 + drivers/net/rnp/base/rnp_eth_regs.h | 13 ++++ drivers/net/rnp/rnp.h | 7 +++ drivers/net/rnp/rnp_ethdev.c | 65 ++++++++++++++++++- drivers/net/rnp/rnp_rxtx.c | 97 ++++++++++++++++++++++++++++- 6 files changed, 185 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/features/rnp.ini b/doc/guides/nics/features/rnp.ini index b81f11d904..7e97da9325 100644 --- a/doc/guides/nics/features/rnp.ini +++ b/doc/guides/nics/features/rnp.ini @@ -8,6 +8,10 @@ Speed capabilities = Y Link status = Y Link status event = Y Packet type parsing = Y +L3 checksum offload = P +L4 checksum offload = P +Inner L3 checksum = P +Inner L4 checksum = P Basic stats = Y Stats per queue = Y Extended stats = Y diff --git a/doc/guides/nics/rnp.rst b/doc/guides/nics/rnp.rst index 39ea2d1636..8f667a481e 100644 --- a/doc/guides/nics/rnp.rst +++ b/doc/guides/nics/rnp.rst @@ -22,6 +22,7 @@ Features - Scatter-Gather IO support - Port hardware statistic - Packet type parsing +- Checksum offload Prerequisites ------------- diff --git a/drivers/net/rnp/base/rnp_eth_regs.h b/drivers/net/rnp/base/rnp_eth_regs.h index 8a448b9eec..b0961a1459 100644 --- a/drivers/net/rnp/base/rnp_eth_regs.h +++ b/drivers/net/rnp/base/rnp_eth_regs.h @@ -16,6 +16,19 @@ #define RNP_RX_ETH_F_CTRL(n) _ETH_(0x8070 + ((n) * 0x8)) #define RNP_RX_ETH_F_OFF (0x7ff) #define RNP_RX_ETH_F_ON (0x270) +/* rx checksum ctrl */ +#define RNP_HW_SCTP_CKSUM_CTRL _ETH_(0x8038) +#define RNP_HW_CHECK_ERR_CTRL _ETH_(0x8060) +#define RNP_HW_ERR_HDR_LEN RTE_BIT32(0) +#define RNP_HW_ERR_PKTLEN RTE_BIT32(1) +#define RNP_HW_L3_CKSUM_ERR RTE_BIT32(2) +#define RNP_HW_L4_CKSUM_ERR RTE_BIT32(3) +#define RNP_HW_SCTP_CKSUM_ERR RTE_BIT32(4) +#define RNP_HW_INNER_L3_CKSUM_ERR RTE_BIT32(5) +#define RNP_HW_INNER_L4_CKSUM_ERR RTE_BIT32(6) +#define RNP_HW_CKSUM_ERR_MASK RTE_GENMASK32(6, 2) +#define RNP_HW_CHECK_ERR_MASK RTE_GENMASK32(6, 0) +#define RNP_HW_ERR_RX_ALL_MASK RTE_GENMASK32(1, 0) /* max/min pkts length receive limit ctrl */ #define RNP_MIN_FRAME_CTRL _ETH_(0x80f0) #define RNP_MAX_FRAME_CTRL _ETH_(0x80f4) diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h index af930800c6..9cfc17b93c 100644 --- a/drivers/net/rnp/rnp.h +++ b/drivers/net/rnp/rnp.h @@ -42,6 +42,13 @@ RTE_ETH_RSS_NONFRAG_IPV6_UDP | \ RTE_ETH_RSS_IPV6_UDP_EX | \ RTE_ETH_RSS_NONFRAG_IPV6_SCTP) +/* rx checksum offload */ +#define RNP_RX_CHECKSUM_SUPPORT ( \ + RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | \ + RTE_ETH_RX_OFFLOAD_UDP_CKSUM | \ + RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \ + RTE_ETH_RX_OFFLOAD_SCTP_CKSUM | \ + RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) /* Ring info special */ #define RNP_MAX_BD_COUNT (4096) #define RNP_MIN_BD_COUNT (128) diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c index 2b66f572e7..b5d749e7a5 100644 --- a/drivers/net/rnp/rnp_ethdev.c +++ b/drivers/net/rnp/rnp_ethdev.c @@ -406,6 +406,67 @@ static int rnp_disable_all_tx_queue(struct rte_eth_dev *dev) return ret; } +static void rnp_set_rx_cksum_offload(struct rte_eth_dev *dev) +{ + struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev); + struct rnp_hw *hw = port->hw; + uint32_t cksum_ctrl; + uint64_t offloads; + + offloads = dev->data->dev_conf.rxmode.offloads; + cksum_ctrl = RNP_HW_CHECK_ERR_MASK; + /* enable rx checksum feature */ + if (!rnp_pf_is_multiple_ports(hw->device_id)) { + if (offloads & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) { + /* Tunnel Option Cksum L4_Option */ + cksum_ctrl &= ~RNP_HW_L4_CKSUM_ERR; + if (offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM | + RTE_ETH_RX_OFFLOAD_TCP_CKSUM)) + cksum_ctrl &= ~RNP_HW_INNER_L4_CKSUM_ERR; + else + cksum_ctrl |= RNP_HW_INNER_L4_CKSUM_ERR; + } else { + /* no tunnel option cksum l4_option */ + cksum_ctrl |= RNP_HW_INNER_L4_CKSUM_ERR; + if (offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM | + RTE_ETH_RX_OFFLOAD_TCP_CKSUM)) + cksum_ctrl &= ~RNP_HW_L4_CKSUM_ERR; + else + cksum_ctrl |= RNP_HW_L4_CKSUM_ERR; + } + if (offloads & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) { + /* tunnel option cksum l3_option */ + cksum_ctrl &= ~RNP_HW_L3_CKSUM_ERR; + if (offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) + cksum_ctrl &= ~RNP_HW_INNER_L3_CKSUM_ERR; + else + cksum_ctrl |= RNP_HW_INNER_L3_CKSUM_ERR; + } else { + /* no tunnel option cksum l3_option */ + cksum_ctrl |= RNP_HW_INNER_L3_CKSUM_ERR; + if (offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) + cksum_ctrl &= ~RNP_HW_L3_CKSUM_ERR; + else + cksum_ctrl |= RNP_HW_L3_CKSUM_ERR; + } + /* sctp option */ + if (offloads & RTE_ETH_RX_OFFLOAD_SCTP_CKSUM) { + cksum_ctrl &= ~RNP_HW_SCTP_CKSUM_ERR; + RNP_E_REG_WR(hw, RNP_HW_SCTP_CKSUM_CTRL, true); + } else { + RNP_E_REG_WR(hw, RNP_HW_SCTP_CKSUM_CTRL, false); + } + RNP_E_REG_WR(hw, RNP_HW_CHECK_ERR_CTRL, cksum_ctrl); + } else { + /* Enabled all support checksum features + * use software mode support per port rx checksum + * feature enabled/disabled for multiple port mode + */ + RNP_E_REG_WR(hw, RNP_HW_CHECK_ERR_CTRL, RNP_HW_ERR_RX_ALL_MASK); + RNP_E_REG_WR(hw, RNP_HW_SCTP_CKSUM_CTRL, true); + } +} + static int rnp_dev_configure(struct rte_eth_dev *eth_dev) { struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev); @@ -415,6 +476,7 @@ static int rnp_dev_configure(struct rte_eth_dev *eth_dev) else port->rxq_num_changed = false; port->last_rx_num = eth_dev->data->nb_rx_queues; + rnp_set_rx_cksum_offload(eth_dev); return 0; } @@ -587,7 +649,8 @@ static int rnp_dev_infos_get(struct rte_eth_dev *eth_dev, dev_info->reta_size = RNP_RSS_INDIR_SIZE; /* speed cap info */ dev_info->speed_capa = rnp_get_speed_caps(eth_dev); - + /* rx support offload cap */ + dev_info->rx_offload_capa = RNP_RX_CHECKSUM_SUPPORT; dev_info->default_rxconf = (struct rte_eth_rxconf) { .rx_drop_en = 0, .rx_thresh = { diff --git a/drivers/net/rnp/rnp_rxtx.c b/drivers/net/rnp/rnp_rxtx.c index bd9fc7f8c4..e0b2cc7a26 100644 --- a/drivers/net/rnp/rnp_rxtx.c +++ b/drivers/net/rnp/rnp_rxtx.c @@ -644,8 +644,102 @@ int rnp_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qidx) return 0; } +struct rnp_rx_cksum_parse { + uint64_t offloads; + uint64_t packet_type; + uint16_t hw_offload; + uint64_t good; + uint64_t bad; +}; + +#define RNP_RX_OFFLOAD_L4_CKSUM (RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \ + RTE_ETH_RX_OFFLOAD_UDP_CKSUM | \ + RTE_ETH_RX_OFFLOAD_SCTP_CKSUM) +static const struct rnp_rx_cksum_parse rnp_rx_cksum_tunnel[] = { + { RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM, + RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_MASK, RNP_RX_L3_ERR, + RTE_MBUF_F_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD + }, + { RTE_ETH_RX_OFFLOAD_IPV4_CKSUM, + RTE_PTYPE_L3_IPV4, RNP_RX_IN_L3_ERR, + RTE_MBUF_F_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_IP_CKSUM_BAD + }, + { RNP_RX_OFFLOAD_L4_CKSUM, RTE_PTYPE_L4_MASK, + RNP_RX_IN_L4_ERR | RNP_RX_SCTP_ERR, + RTE_MBUF_F_RX_L4_CKSUM_GOOD, RTE_MBUF_F_RX_L4_CKSUM_BAD + } +}; + +static const struct rnp_rx_cksum_parse rnp_rx_cksum[] = { + { RTE_ETH_RX_OFFLOAD_IPV4_CKSUM, + RTE_PTYPE_L3_IPV4, RNP_RX_L3_ERR, + RTE_MBUF_F_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_IP_CKSUM_BAD + }, + { RNP_RX_OFFLOAD_L4_CKSUM, + RTE_PTYPE_L4_MASK, RNP_RX_L4_ERR | RNP_RX_SCTP_ERR, + RTE_MBUF_F_RX_L4_CKSUM_GOOD, RTE_MBUF_F_RX_L4_CKSUM_BAD + } +}; + +static void +rnp_rx_parse_tunnel_cksum(struct rnp_rx_queue *rxq, + struct rte_mbuf *m, uint16_t cksum_cmd) +{ + uint16_t idx = 0; + + for (idx = 0; idx < RTE_DIM(rnp_rx_cksum_tunnel); idx++) { + if (rxq->rx_offloads & rnp_rx_cksum_tunnel[idx].offloads && + m->packet_type & rnp_rx_cksum_tunnel[idx].packet_type) { + if (cksum_cmd & rnp_rx_cksum_tunnel[idx].hw_offload) + m->ol_flags |= rnp_rx_cksum_tunnel[idx].bad; + else + m->ol_flags |= rnp_rx_cksum_tunnel[idx].good; + } + } +} + +static void +rnp_rx_parse_cksum(struct rnp_rx_queue *rxq, + struct rte_mbuf *m, uint16_t cksum_cmd) +{ + uint16_t idx = 0; + + for (idx = 0; idx < RTE_DIM(rnp_rx_cksum); idx++) { + if (rxq->rx_offloads & rnp_rx_cksum[idx].offloads && + m->packet_type & rnp_rx_cksum[idx].packet_type) { + if (cksum_cmd & rnp_rx_cksum[idx].hw_offload) + m->ol_flags |= rnp_rx_cksum[idx].bad; + else + m->ol_flags |= rnp_rx_cksum[idx].good; + } + } +} + +static __rte_always_inline void +rnp_dev_rx_offload(struct rnp_rx_queue *rxq, + struct rte_mbuf *m, + volatile struct rnp_rx_desc rxbd) +{ + uint32_t rss = rte_le_to_cpu_32(rxbd.wb.qword0.rss_hash); + uint16_t cmd = rxbd.wb.qword1.cmd; + + if (rxq->rx_offloads & RNP_RX_CHECKSUM_SUPPORT) { + if (m->packet_type & RTE_PTYPE_TUNNEL_MASK) { + rnp_rx_parse_tunnel_cksum(rxq, m, cmd); + } else { + if (m->packet_type & RTE_PTYPE_L3_MASK || + m->packet_type & RTE_PTYPE_L4_MASK) + rnp_rx_parse_cksum(rxq, m, cmd); + } + } + if (rxq->rx_offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH && rss) { + m->hash.rss = rss; + m->ol_flags |= RTE_MBUF_F_RX_RSS_HASH; + } +} + static __rte_always_inline void -rnp_dev_rx_parse(struct rnp_rx_queue *rxq __rte_unused, +rnp_dev_rx_parse(struct rnp_rx_queue *rxq, struct rte_mbuf *m, volatile struct rnp_rx_desc rxbd) { @@ -685,6 +779,7 @@ rnp_dev_rx_parse(struct rnp_rx_queue *rxq __rte_unused, } if (!(m->packet_type & RTE_PTYPE_L2_MASK)) m->packet_type |= RTE_PTYPE_L2_ETHER; + rnp_dev_rx_offload(rxq, m, rxbd); } #define RNP_CACHE_FETCH_RX (4) -- 2.34.1