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 CD4F3A0C47; Wed, 3 Nov 2021 20:21:33 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4B1B74115A; Wed, 3 Nov 2021 20:21:09 +0100 (CET) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by mails.dpdk.org (Postfix) with ESMTP id DDE9D41152 for ; Wed, 3 Nov 2021 20:21:07 +0100 (CET) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id AE86E1A0718; Wed, 3 Nov 2021 20:21:07 +0100 (CET) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 4A3E11A0716; Wed, 3 Nov 2021 20:21:07 +0100 (CET) Received: from lsv03186.swis.in-blr01.nxp.com (lsv03186.swis.in-blr01.nxp.com [92.120.146.182]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 43FB8183AC8B; Thu, 4 Nov 2021 03:21:06 +0800 (+08) From: Apeksha Gupta To: david.marchand@redhat.com, ferruh.yigit@intel.com, andrew.rybchenko@oktetlabs.ru Cc: dev@dpdk.org, sachin.saxena@nxp.com, hemant.agrawal@nxp.com, Apeksha Gupta Date: Thu, 4 Nov 2021 00:50:45 +0530 Message-Id: <20211103192045.22240-6-apeksha.gupta@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211103192045.22240-1-apeksha.gupta@nxp.com> References: <20211021044700.12370-2-apeksha.gupta@nxp.com> <20211103192045.22240-1-apeksha.gupta@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v7 5/5] net/enetfec: add features 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 Sender: "dev" This patch adds checksum and VLAN offloads in enetfec network poll mode driver. Signed-off-by: Sachin Saxena Signed-off-by: Apeksha Gupta --- doc/guides/nics/enetfec.rst | 2 + doc/guides/nics/features/enetfec.ini | 3 ++ drivers/net/enetfec/enet_ethdev.c | 17 ++++++++- drivers/net/enetfec/enet_ethdev.h | 1 + drivers/net/enetfec/enet_regs.h | 10 +++++ drivers/net/enetfec/enet_rxtx.c | 56 +++++++++++++++++++++++++++- 6 files changed, 87 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/enetfec.rst b/doc/guides/nics/enetfec.rst index 47836630b6..132f0209e5 100644 --- a/doc/guides/nics/enetfec.rst +++ b/doc/guides/nics/enetfec.rst @@ -84,6 +84,8 @@ ENETFEC Features - Basic stats - Promiscuous +- VLAN offload +- L3/L4 checksum offload - Linux - ARMv8 diff --git a/doc/guides/nics/features/enetfec.ini b/doc/guides/nics/features/enetfec.ini index 3d8aa5b627..2a34351b43 100644 --- a/doc/guides/nics/features/enetfec.ini +++ b/doc/guides/nics/features/enetfec.ini @@ -5,6 +5,9 @@ ; [Features] Promiscuous mode = Y +VLAN offload = Y +L3 checksum offload = Y +L4 checksum offload = Y Basic stats = Y Linux = Y ARMv8 = Y diff --git a/drivers/net/enetfec/enet_ethdev.c b/drivers/net/enetfec/enet_ethdev.c index 42b6cac26f..026752fa91 100644 --- a/drivers/net/enetfec/enet_ethdev.c +++ b/drivers/net/enetfec/enet_ethdev.c @@ -106,7 +106,11 @@ enetfec_restart(struct rte_eth_dev *dev) val = rte_read32((uint8_t *)fep->hw_baseaddr_v + ENETFEC_RACC); /* align IP header */ val |= ENETFEC_RACC_SHIFT16; - val &= ~ENETFEC_RACC_OPTIONS; + if (fep->flag_csum & RX_FLAG_CSUM_EN) + /* set RX checksum */ + val |= ENETFEC_RACC_OPTIONS; + else + val &= ~ENETFEC_RACC_OPTIONS; rte_write32(rte_cpu_to_le_32(val), (uint8_t *)fep->hw_baseaddr_v + ENETFEC_RACC); rte_write32(rte_cpu_to_le_32(PKT_MAX_BUF_SIZE), @@ -597,9 +601,20 @@ static int enetfec_eth_init(struct rte_eth_dev *dev) { struct enetfec_private *fep = dev->data->dev_private; + struct rte_eth_conf *eth_conf = &fep->dev->data->dev_conf; + uint64_t rx_offloads = eth_conf->rxmode.offloads; fep->full_duplex = FULL_DUPLEX; dev->dev_ops = &enetfec_ops; + if (fep->quirks & QUIRK_VLAN) + /* enable hw VLAN support */ + rx_offloads |= DEV_RX_OFFLOAD_VLAN; + + if (fep->quirks & QUIRK_CSUM) { + /* enable hw accelerator */ + rx_offloads |= DEV_RX_OFFLOAD_CHECKSUM; + fep->flag_csum |= RX_FLAG_CSUM_EN; + } rte_eth_dev_probing_finish(dev); return 0; diff --git a/drivers/net/enetfec/enet_ethdev.h b/drivers/net/enetfec/enet_ethdev.h index e48f958ad9..e4cb8ef5a5 100644 --- a/drivers/net/enetfec/enet_ethdev.h +++ b/drivers/net/enetfec/enet_ethdev.h @@ -11,6 +11,7 @@ #define BD_LEN 49152 #define ENETFEC_TX_FR_SIZE 2048 #define ETH_HLEN RTE_ETHER_HDR_LEN +#define VLAN_HLEN 4 /* full duplex or half duplex */ #define HALF_DUPLEX 0x00 diff --git a/drivers/net/enetfec/enet_regs.h b/drivers/net/enetfec/enet_regs.h index 5415ed77ea..a300c6f8bc 100644 --- a/drivers/net/enetfec/enet_regs.h +++ b/drivers/net/enetfec/enet_regs.h @@ -27,6 +27,12 @@ #define RX_BD_EMPTY ((ushort)0x8000) /* BD is empty */ #define RX_BD_STATS ((ushort)0x013f) /* All buffer descriptor status bits */ +/* Ethernet receive use control and status of enhanced buffer descriptor */ +#define BD_ENETFEC_RX_VLAN 0x00000004 + +#define RX_FLAG_CSUM_EN (RX_BD_ICE | RX_BD_PCR) +#define RX_FLAG_CSUM_ERR (RX_BD_ICE | RX_BD_PCR) + /* Ethernet transmit use control and status of buffer descriptor */ #define TX_BD_TC ((ushort)0x0400) /* Transmit CRC */ #define TX_BD_LAST ((ushort)0x0800) /* Last in frame */ @@ -56,6 +62,10 @@ #define QUIRK_HAS_ENETFEC_MAC (1 << 0) /* GBIT supported in controller */ #define QUIRK_GBIT (1 << 3) +/* Controller support hardware checksum */ +#define QUIRK_CSUM (1 << 5) +/* Controller support hardware vlan */ +#define QUIRK_VLAN (1 << 6) /* RACC register supported by controller */ #define QUIRK_RACC (1 << 12) /* i.MX8 ENETFEC IP version added the feature to generate the delayed TXC or diff --git a/drivers/net/enetfec/enet_rxtx.c b/drivers/net/enetfec/enet_rxtx.c index 6ac4624553..3c110fa824 100644 --- a/drivers/net/enetfec/enet_rxtx.c +++ b/drivers/net/enetfec/enet_rxtx.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "enet_regs.h" #include "enet_ethdev.h" #include "enet_pmd_logs.h" @@ -245,11 +246,17 @@ enetfec_recv_pkts(void *rxq1, __rte_unused struct rte_mbuf **rx_pkts, unsigned short status; unsigned short pkt_len; int pkt_received = 0, index = 0; - void *data; + void *data, *mbuf_data; + uint16_t vlan_tag; + struct bufdesc_ex *ebdp = NULL; + bool vlan_packet_rcvd = false; struct enetfec_priv_rx_q *rxq = (struct enetfec_priv_rx_q *)rxq1; struct rte_eth_stats *stats = &rxq->fep->stats; + struct rte_eth_conf *eth_conf = &rxq->fep->dev->data->dev_conf; + uint64_t rx_offloads = eth_conf->rxmode.offloads; pool = rxq->pool; bdp = rxq->bd.cur; + #if ENETFEC_LOOPBACK enetfec_lb_rxtx(rxq1); #endif @@ -302,6 +309,7 @@ enetfec_recv_pkts(void *rxq1, __rte_unused struct rte_mbuf **rx_pkts, mbuf = rxq->rx_mbuf[index]; data = rte_pktmbuf_mtod(mbuf, uint8_t *); + mbuf_data = data; rte_prefetch0(data); rte_pktmbuf_append((struct rte_mbuf *)mbuf, pkt_len - 4); @@ -311,6 +319,48 @@ enetfec_recv_pkts(void *rxq1, __rte_unused struct rte_mbuf **rx_pkts, rx_pkts[pkt_received] = mbuf; pkt_received++; + + /* Extract the enhanced buffer descriptor */ + ebdp = NULL; + if (rxq->fep->bufdesc_ex) + ebdp = (struct bufdesc_ex *)bdp; + + /* If this is a VLAN packet remove the VLAN Tag */ + vlan_packet_rcvd = false; + if ((rx_offloads & DEV_RX_OFFLOAD_VLAN) && + rxq->fep->bufdesc_ex && + (rte_read32(&ebdp->bd_esc) & + rte_cpu_to_le_32(BD_ENETFEC_RX_VLAN))) { + /* Push and remove the vlan tag */ + struct rte_vlan_hdr *vlan_header = + (struct rte_vlan_hdr *) + ((uint8_t *)data + ETH_HLEN); + vlan_tag = rte_be_to_cpu_16(vlan_header->vlan_tci); + + vlan_packet_rcvd = true; + memmove((uint8_t *)mbuf_data + VLAN_HLEN, + data, ETH_ALEN * 2); + rte_pktmbuf_adj(mbuf, VLAN_HLEN); + } + + if (rxq->fep->bufdesc_ex && + (rxq->fep->flag_csum & RX_FLAG_CSUM_EN)) { + if ((rte_read32(&ebdp->bd_esc) & + rte_cpu_to_le_32(RX_FLAG_CSUM_ERR)) == 0) { + /* don't check it */ + mbuf->ol_flags = RTE_MBUF_F_RX_IP_CKSUM_BAD; + } else { + mbuf->ol_flags = RTE_MBUF_F_RX_IP_CKSUM_GOOD; + } + } + + /* Handle received VLAN packets */ + if (vlan_packet_rcvd) { + mbuf->vlan_tci = vlan_tag; + mbuf->ol_flags |= RTE_MBUF_F_RX_VLAN_STRIPPED + | RTE_MBUF_F_RX_VLAN; + } + rxq->rx_mbuf[index] = new_mbuf; rte_write32(rte_cpu_to_le_32(rte_pktmbuf_iova(new_mbuf)), &bdp->bd_bufaddr); @@ -411,6 +461,10 @@ enetfec_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) if (txq->fep->bufdesc_ex) { struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp; + + if (mbuf->ol_flags == RTE_MBUF_F_RX_IP_CKSUM_GOOD) + estatus |= TX_BD_PINS | TX_BD_IINS; + rte_write32(0, &ebdp->bd_bdu); rte_write32(rte_cpu_to_le_32(estatus), &ebdp->bd_esc); -- 2.17.1