From f5a2e3bad4860ae4e3be2bfe13cff20aa93e3ba1 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Fri, 12 Apr 2019 12:29:10 +0000 Subject: [PATCH] net/enetc: enable Rx checksum offload validation Checksum Validation on Rx is supported. Signed-off-by: Gagandeep Singh --- doc/guides/nics/features/enetc.ini | 2 + doc/guides/rel_notes/release_19_05.rst | 1 + drivers/net/enetc/base/enetc_hw.h | 5 ++ drivers/net/enetc/enetc_ethdev.c | 15 +++- drivers/net/enetc/enetc_rxtx.c | 107 ++++++++++++++++++++++--- 5 files changed, 116 insertions(+), 14 deletions(-) diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini index 101dc0a693..39a520172a 100644 --- a/doc/guides/nics/features/enetc.ini +++ b/doc/guides/nics/features/enetc.ini @@ -13,6 +13,8 @@ MTU update = Y Jumbo frame = Y Queue start/stop = Y CRC offload = Y +L3 checksum offload = P +L4 checksum offload = P Linux VFIO = Y ARMv8 = Y Usage doc = Y diff --git a/doc/guides/rel_notes/release_19_05.rst b/doc/guides/rel_notes/release_19_05.rst index 3312a87e28..25cd61ca23 100644 --- a/doc/guides/rel_notes/release_19_05.rst +++ b/doc/guides/rel_notes/release_19_05.rst @@ -154,6 +154,7 @@ New Features * Added jumbo frame support * Added queue start/stop * Added CRC offload support + * Added Rx checksum offload validation support * **Updated the QuickAssist Technology PMD.** diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h index 261ad157a2..ff2bda592f 100644 --- a/drivers/net/enetc/base/enetc_hw.h +++ b/drivers/net/enetc/base/enetc_hw.h @@ -99,6 +99,10 @@ enum enetc_bdr_type {TX, RX}; #define ENETC_PM0_RX_EN BIT(1) #define ENETC_PM0_CRC BIT(6) +#define ENETC_PAR_PORT_CFG 0x03050 +#define L3_CKSUM BIT(0) +#define L4_CKSUM BIT(1) + #define ENETC_PM0_MAXFRM 0x08014 #define ENETC_SET_TX_MTU(val) ((val) << 16) #define ENETC_SET_MAXFRM(val) ((val) & 0xffff) @@ -182,6 +186,7 @@ enum enetc_bdr_type {TX, RX}; #define ENETC_TXBD_FLAGS_F BIT(15) /* ENETC Parsed values (Little Endian) */ +#define ENETC_PARSE_ERROR 0x8000 #define ENETC_PKT_TYPE_ETHER 0x0060 #define ENETC_PKT_TYPE_IPV4 0x0000 #define ENETC_PKT_TYPE_IPV6 0x0020 diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c index ffae8ae25c..362e0740c2 100644 --- a/drivers/net/enetc/enetc_ethdev.c +++ b/drivers/net/enetc/enetc_ethdev.c @@ -163,7 +163,10 @@ enetc_dev_infos_get(struct rte_eth_dev *dev __rte_unused, dev_info->max_tx_queues = MAX_TX_RINGS; dev_info->max_rx_pktlen = ENETC_MAC_MAXFRM_SIZE; dev_info->rx_offload_capa = - (DEV_RX_OFFLOAD_KEEP_CRC | + (DEV_RX_OFFLOAD_IPV4_CKSUM | + DEV_RX_OFFLOAD_UDP_CKSUM | + DEV_RX_OFFLOAD_TCP_CKSUM | + DEV_RX_OFFLOAD_KEEP_CRC | DEV_RX_OFFLOAD_JUMBO_FRAME); } @@ -636,6 +639,7 @@ enetc_dev_configure(struct rte_eth_dev *dev) struct enetc_hw *enetc_hw = &hw->hw; struct rte_eth_conf *eth_conf = &dev->data->dev_conf; uint64_t rx_offloads = eth_conf->rxmode.offloads; + uint32_t checksum = L3_CKSUM | L4_CKSUM; PMD_INIT_FUNC_TRACE(); @@ -661,6 +665,15 @@ enetc_dev_configure(struct rte_eth_dev *dev) enetc_port_wr(enetc_hw, ENETC_PM0_CMD_CFG, config); } + if (rx_offloads & DEV_RX_OFFLOAD_IPV4_CKSUM) + checksum &= ~L3_CKSUM; + + if (rx_offloads & (DEV_RX_OFFLOAD_UDP_CKSUM | DEV_RX_OFFLOAD_TCP_CKSUM)) + checksum &= ~L4_CKSUM; + + enetc_port_wr(enetc_hw, ENETC_PAR_PORT_CFG, checksum); + + return 0; } diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c index 4a758d25a2..0ce7dbee7c 100644 --- a/drivers/net/enetc/enetc_rxtx.c +++ b/drivers/net/enetc/enetc_rxtx.c @@ -115,69 +115,150 @@ enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt) return j; } +static inline void enetc_slow_parsing(struct rte_mbuf *m, + uint64_t parse_results) +{ + m->ol_flags &= ~(PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_GOOD); + + switch (parse_results) { + case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV4: + m->packet_type = RTE_PTYPE_L2_ETHER | + RTE_PTYPE_L3_IPV4; + m->ol_flags |= PKT_RX_IP_CKSUM_BAD; + return; + case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV6: + m->packet_type = RTE_PTYPE_L2_ETHER | + RTE_PTYPE_L3_IPV6; + m->ol_flags |= PKT_RX_IP_CKSUM_BAD; + return; + case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV4_TCP: + m->packet_type = RTE_PTYPE_L2_ETHER | + RTE_PTYPE_L3_IPV4 | + RTE_PTYPE_L4_TCP; + m->ol_flags |= PKT_RX_IP_CKSUM_GOOD | + PKT_RX_L4_CKSUM_BAD; + return; + case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV6_TCP: + m->packet_type = RTE_PTYPE_L2_ETHER | + RTE_PTYPE_L3_IPV6 | + RTE_PTYPE_L4_TCP; + m->ol_flags |= PKT_RX_IP_CKSUM_GOOD | + PKT_RX_L4_CKSUM_BAD; + return; + case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV4_UDP: + m->packet_type = RTE_PTYPE_L2_ETHER | + RTE_PTYPE_L3_IPV4 | + RTE_PTYPE_L4_UDP; + m->ol_flags |= PKT_RX_IP_CKSUM_GOOD | + PKT_RX_L4_CKSUM_BAD; + return; + case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV6_UDP: + m->packet_type = RTE_PTYPE_L2_ETHER | + RTE_PTYPE_L3_IPV6 | + RTE_PTYPE_L4_UDP; + m->ol_flags |= PKT_RX_IP_CKSUM_GOOD | + PKT_RX_L4_CKSUM_BAD; + return; + case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV4_SCTP: + m->packet_type = RTE_PTYPE_L2_ETHER | + RTE_PTYPE_L3_IPV4 | + RTE_PTYPE_L4_SCTP; + m->ol_flags |= PKT_RX_IP_CKSUM_GOOD | + PKT_RX_L4_CKSUM_BAD; + return; + case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV6_SCTP: + m->packet_type = RTE_PTYPE_L2_ETHER | + RTE_PTYPE_L3_IPV6 | + RTE_PTYPE_L4_SCTP; + m->ol_flags |= PKT_RX_IP_CKSUM_GOOD | + PKT_RX_L4_CKSUM_BAD; + return; + case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV4_ICMP: + m->packet_type = RTE_PTYPE_L2_ETHER | + RTE_PTYPE_L3_IPV4 | + RTE_PTYPE_L4_ICMP; + m->ol_flags |= PKT_RX_IP_CKSUM_GOOD | + PKT_RX_L4_CKSUM_BAD; + return; + case ENETC_PARSE_ERROR | ENETC_PKT_TYPE_IPV6_ICMP: + m->packet_type = RTE_PTYPE_L2_ETHER | + RTE_PTYPE_L3_IPV6 | + RTE_PTYPE_L4_ICMP; + m->ol_flags |= PKT_RX_IP_CKSUM_GOOD | + PKT_RX_L4_CKSUM_BAD; + return; + /* More switch cases can be added */ + default: + m->packet_type = RTE_PTYPE_UNKNOWN; + m->ol_flags |= PKT_RX_IP_CKSUM_UNKNOWN | + PKT_RX_L4_CKSUM_UNKNOWN; + } +} + static inline void __attribute__((hot)) enetc_dev_rx_parse(struct rte_mbuf *m, uint16_t parse_results) { ENETC_PMD_DP_DEBUG("parse summary = 0x%x ", parse_results); + m->ol_flags |= PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_GOOD; - m->packet_type = RTE_PTYPE_UNKNOWN; switch (parse_results) { case ENETC_PKT_TYPE_ETHER: m->packet_type = RTE_PTYPE_L2_ETHER; - break; + return; case ENETC_PKT_TYPE_IPV4: m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4; - break; + return; case ENETC_PKT_TYPE_IPV6: m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6; - break; + return; case ENETC_PKT_TYPE_IPV4_TCP: m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP; - break; + return; case ENETC_PKT_TYPE_IPV6_TCP: m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP; - break; + return; case ENETC_PKT_TYPE_IPV4_UDP: m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP; - break; + return; case ENETC_PKT_TYPE_IPV6_UDP: m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP; - break; + return; case ENETC_PKT_TYPE_IPV4_SCTP: m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP; - break; + return; case ENETC_PKT_TYPE_IPV6_SCTP: m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_SCTP; - break; + return; case ENETC_PKT_TYPE_IPV4_ICMP: m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_ICMP; - break; + return; case ENETC_PKT_TYPE_IPV6_ICMP: m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_ICMP; - break; + return; /* More switch cases can be added */ default: - m->packet_type = RTE_PTYPE_UNKNOWN; + enetc_slow_parsing(m, parse_results); } + } static int -- 2.20.1