1d81734caSHemant Agrawal /* SPDX-License-Identifier: BSD-3-Clause 237f9b54bSShreyansh Jain * 337f9b54bSShreyansh Jain * Copyright 2016 Freescale Semiconductor, Inc. All rights reserved. 4f191d5abSHemant Agrawal * Copyright 2017,2019-2021 NXP 537f9b54bSShreyansh Jain * 637f9b54bSShreyansh Jain */ 737f9b54bSShreyansh Jain 837f9b54bSShreyansh Jain /* System headers */ 937f9b54bSShreyansh Jain #include <inttypes.h> 1037f9b54bSShreyansh Jain #include <unistd.h> 1137f9b54bSShreyansh Jain #include <stdio.h> 1237f9b54bSShreyansh Jain #include <limits.h> 1337f9b54bSShreyansh Jain #include <sched.h> 1437f9b54bSShreyansh Jain #include <pthread.h> 1537f9b54bSShreyansh Jain 1637f9b54bSShreyansh Jain #include <rte_byteorder.h> 1737f9b54bSShreyansh Jain #include <rte_common.h> 1837f9b54bSShreyansh Jain #include <rte_interrupts.h> 1937f9b54bSShreyansh Jain #include <rte_log.h> 2037f9b54bSShreyansh Jain #include <rte_debug.h> 2137f9b54bSShreyansh Jain #include <rte_pci.h> 2237f9b54bSShreyansh Jain #include <rte_atomic.h> 2337f9b54bSShreyansh Jain #include <rte_branch_prediction.h> 2437f9b54bSShreyansh Jain #include <rte_memory.h> 2537f9b54bSShreyansh Jain #include <rte_tailq.h> 2637f9b54bSShreyansh Jain #include <rte_eal.h> 2737f9b54bSShreyansh Jain #include <rte_alarm.h> 2837f9b54bSShreyansh Jain #include <rte_ether.h> 29df96fd0dSBruce Richardson #include <ethdev_driver.h> 3037f9b54bSShreyansh Jain #include <rte_malloc.h> 3137f9b54bSShreyansh Jain #include <rte_ring.h> 3237f9b54bSShreyansh Jain #include <rte_ip.h> 3337f9b54bSShreyansh Jain #include <rte_tcp.h> 3437f9b54bSShreyansh Jain #include <rte_udp.h> 35d565c887SAshish Jain #include <rte_net.h> 365e745593SSunil Kumar Kori #include <rte_eventdev.h> 3737f9b54bSShreyansh Jain 3837f9b54bSShreyansh Jain #include "dpaa_ethdev.h" 3937f9b54bSShreyansh Jain #include "dpaa_rxtx.h" 40a2f1da7dSDavid Marchand #include <bus_dpaa_driver.h> 4137f9b54bSShreyansh Jain #include <dpaa_mempool.h> 4237f9b54bSShreyansh Jain 435e745593SSunil Kumar Kori #include <qman.h> 4437f9b54bSShreyansh Jain #include <fsl_usd.h> 4537f9b54bSShreyansh Jain #include <fsl_qman.h> 4637f9b54bSShreyansh Jain #include <fsl_bman.h> 478c83f28cSHemant Agrawal #include <dpaa_of.h> 4837f9b54bSShreyansh Jain #include <netcfg.h> 4937f9b54bSShreyansh Jain 5037f9b54bSShreyansh Jain #define DPAA_MBUF_TO_CONTIG_FD(_mbuf, _fd, _bpid) \ 5137f9b54bSShreyansh Jain do { \ 5237f9b54bSShreyansh Jain (_fd)->cmd = 0; \ 5337f9b54bSShreyansh Jain (_fd)->opaque_addr = 0; \ 5437f9b54bSShreyansh Jain (_fd)->opaque = QM_FD_CONTIG << DPAA_FD_FORMAT_SHIFT; \ 5537f9b54bSShreyansh Jain (_fd)->opaque |= ((_mbuf)->data_off) << DPAA_FD_OFFSET_SHIFT; \ 5637f9b54bSShreyansh Jain (_fd)->opaque |= (_mbuf)->pkt_len; \ 57455da545SSantosh Shukla (_fd)->addr = (_mbuf)->buf_iova; \ 5837f9b54bSShreyansh Jain (_fd)->bpid = _bpid; \ 5937f9b54bSShreyansh Jain } while (0) 6037f9b54bSShreyansh Jain 6177393f56SSachin Saxena #ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER 6277393f56SSachin Saxena #define DISPLAY_PRINT printf 6377393f56SSachin Saxena static void dpaa_display_frame_info(const struct qm_fd *fd, 6477393f56SSachin Saxena uint32_t fqid, bool rx) 6505ba55bcSShreyansh Jain { 6605ba55bcSShreyansh Jain int ii; 6705ba55bcSShreyansh Jain char *ptr; 6877393f56SSachin Saxena struct annotations_t *annot = rte_dpaa_mem_ptov(fd->addr); 6977393f56SSachin Saxena uint8_t format; 7005ba55bcSShreyansh Jain 7177393f56SSachin Saxena if (!fd->status) { 7277393f56SSachin Saxena /* Do not display correct packets.*/ 7377393f56SSachin Saxena return; 7405ba55bcSShreyansh Jain } 7577393f56SSachin Saxena 7677393f56SSachin Saxena format = (fd->opaque & DPAA_FD_FORMAT_MASK) >> 7777393f56SSachin Saxena DPAA_FD_FORMAT_SHIFT; 7877393f56SSachin Saxena 7977393f56SSachin Saxena DISPLAY_PRINT("fqid %d bpid %d addr 0x%lx, format %d\r\n", 8077393f56SSachin Saxena fqid, fd->bpid, (unsigned long)fd->addr, fd->format); 8177393f56SSachin Saxena DISPLAY_PRINT("off %d, len %d stat 0x%x\r\n", 8277393f56SSachin Saxena fd->offset, fd->length20, fd->status); 8377393f56SSachin Saxena if (rx) { 8477393f56SSachin Saxena ptr = (char *)&annot->parse; 8577393f56SSachin Saxena DISPLAY_PRINT("RX parser result:\r\n"); 8677393f56SSachin Saxena for (ii = 0; ii < (int)sizeof(struct dpaa_eth_parse_results_t); 8777393f56SSachin Saxena ii++) { 8877393f56SSachin Saxena DISPLAY_PRINT("%02x ", ptr[ii]); 8977393f56SSachin Saxena if (((ii + 1) % 16) == 0) 9077393f56SSachin Saxena DISPLAY_PRINT("\n"); 9177393f56SSachin Saxena } 9277393f56SSachin Saxena DISPLAY_PRINT("\n"); 9377393f56SSachin Saxena } 9477393f56SSachin Saxena 9577393f56SSachin Saxena if (unlikely(format == qm_fd_sg)) { 9677393f56SSachin Saxena /*TBD:S/G display: to be implemented*/ 9777393f56SSachin Saxena return; 9877393f56SSachin Saxena } 9977393f56SSachin Saxena 10077393f56SSachin Saxena DISPLAY_PRINT("Frame payload:\r\n"); 10177393f56SSachin Saxena ptr = (char *)annot; 10277393f56SSachin Saxena ptr += fd->offset; 10377393f56SSachin Saxena for (ii = 0; ii < fd->length20; ii++) { 10477393f56SSachin Saxena DISPLAY_PRINT("%02x ", ptr[ii]); 10577393f56SSachin Saxena if (((ii + 1) % 16) == 0) 10605ba55bcSShreyansh Jain printf("\n"); 10705ba55bcSShreyansh Jain } 10877393f56SSachin Saxena DISPLAY_PRINT("\n"); 10977393f56SSachin Saxena } 11005ba55bcSShreyansh Jain #else 11177393f56SSachin Saxena #define dpaa_display_frame_info(a, b, c) 11205ba55bcSShreyansh Jain #endif 11305ba55bcSShreyansh Jain 114a7bdc3bdSShreyansh Jain static inline void dpaa_slow_parsing(struct rte_mbuf *m __rte_unused, 115a7bdc3bdSShreyansh Jain uint64_t prs __rte_unused) 116a7bdc3bdSShreyansh Jain { 117a7bdc3bdSShreyansh Jain DPAA_DP_LOG(DEBUG, "Slow parsing"); 118a7bdc3bdSShreyansh Jain /*TBD:XXX: to be implemented*/ 119a7bdc3bdSShreyansh Jain } 120a7bdc3bdSShreyansh Jain 1210e5607e4SHemant Agrawal static inline void dpaa_eth_packet_info(struct rte_mbuf *m, void *fd_virt_addr) 122a7bdc3bdSShreyansh Jain { 123a7bdc3bdSShreyansh Jain struct annotations_t *annot = GET_ANNOTATIONS(fd_virt_addr); 1240e5607e4SHemant Agrawal uint64_t prs = *((uintptr_t *)(&annot->parse)) & DPAA_PARSE_MASK; 125a7bdc3bdSShreyansh Jain 126a7bdc3bdSShreyansh Jain DPAA_DP_LOG(DEBUG, " Parsing mbuf: %p with annotations: %p", m, annot); 127a7bdc3bdSShreyansh Jain 128daa02b5cSOlivier Matz m->ol_flags = RTE_MBUF_F_RX_RSS_HASH | RTE_MBUF_F_RX_IP_CKSUM_GOOD | 129daa02b5cSOlivier Matz RTE_MBUF_F_RX_L4_CKSUM_GOOD; 13095d226f0SNipun Gupta 131a7bdc3bdSShreyansh Jain switch (prs) { 132a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4: 133a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 134a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV4; 135a7bdc3bdSShreyansh Jain break; 136a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6: 137a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 138a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV6; 139a7bdc3bdSShreyansh Jain break; 1409ac71da4SNipun Gupta case DPAA_PKT_TYPE_ETHER: 1419ac71da4SNipun Gupta m->packet_type = RTE_PTYPE_L2_ETHER; 1429ac71da4SNipun Gupta break; 143a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4_FRAG: 144a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4_FRAG_UDP: 145a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4_FRAG_TCP: 146a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4_FRAG_SCTP: 147a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 148a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_FRAG; 149a7bdc3bdSShreyansh Jain break; 150a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6_FRAG: 151a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6_FRAG_UDP: 152a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6_FRAG_TCP: 153a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6_FRAG_SCTP: 154a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 155a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_FRAG; 156a7bdc3bdSShreyansh Jain break; 157a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4_EXT: 158a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 159a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV4_EXT; 160a7bdc3bdSShreyansh Jain break; 161a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6_EXT: 162a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 163a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV6_EXT; 164a7bdc3bdSShreyansh Jain break; 165a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4_TCP: 166a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 167a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP; 168a7bdc3bdSShreyansh Jain break; 169a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6_TCP: 170a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 171a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP; 172a7bdc3bdSShreyansh Jain break; 173a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4_UDP: 174a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 175a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP; 176a7bdc3bdSShreyansh Jain break; 177a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6_UDP: 178a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 179a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP; 180a7bdc3bdSShreyansh Jain break; 181e7524271SGagandeep Singh case DPAA_PKT_TYPE_IPSEC_IPV4: 182e7524271SGagandeep Singh if (*((uintptr_t *)&annot->parse) & DPAA_PARSE_ESP_MASK) 183e7524271SGagandeep Singh m->packet_type = RTE_PTYPE_L2_ETHER | 184e7524271SGagandeep Singh RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_ESP; 185e7524271SGagandeep Singh break; 186e7524271SGagandeep Singh case DPAA_PKT_TYPE_IPSEC_IPV6: 187e7524271SGagandeep Singh if (*((uintptr_t *)&annot->parse) & DPAA_PARSE_ESP_MASK) 188e7524271SGagandeep Singh m->packet_type = RTE_PTYPE_L2_ETHER | 189e7524271SGagandeep Singh RTE_PTYPE_L3_IPV6 | RTE_PTYPE_TUNNEL_ESP; 190e7524271SGagandeep Singh break; 191a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4_EXT_UDP: 192a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 193a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_UDP; 194a7bdc3bdSShreyansh Jain break; 195a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6_EXT_UDP: 196a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 197a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_UDP; 198a7bdc3bdSShreyansh Jain break; 199a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4_EXT_TCP: 200a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 201a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_TCP; 202a7bdc3bdSShreyansh Jain break; 203a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6_EXT_TCP: 204a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 205a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_TCP; 206a7bdc3bdSShreyansh Jain break; 207a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV4_SCTP: 208a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 209a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP; 210a7bdc3bdSShreyansh Jain break; 211a7bdc3bdSShreyansh Jain case DPAA_PKT_TYPE_IPV6_SCTP: 212a7bdc3bdSShreyansh Jain m->packet_type = RTE_PTYPE_L2_ETHER | 213a7bdc3bdSShreyansh Jain RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_SCTP; 214a7bdc3bdSShreyansh Jain break; 21595d226f0SNipun Gupta case DPAA_PKT_TYPE_IPV4_CSUM_ERR: 21695d226f0SNipun Gupta case DPAA_PKT_TYPE_IPV6_CSUM_ERR: 217daa02b5cSOlivier Matz m->ol_flags = RTE_MBUF_F_RX_RSS_HASH | RTE_MBUF_F_RX_IP_CKSUM_BAD; 21895d226f0SNipun Gupta break; 21995d226f0SNipun Gupta case DPAA_PKT_TYPE_IPV4_TCP_CSUM_ERR: 22095d226f0SNipun Gupta case DPAA_PKT_TYPE_IPV6_TCP_CSUM_ERR: 22195d226f0SNipun Gupta case DPAA_PKT_TYPE_IPV4_UDP_CSUM_ERR: 22295d226f0SNipun Gupta case DPAA_PKT_TYPE_IPV6_UDP_CSUM_ERR: 223daa02b5cSOlivier Matz m->ol_flags = RTE_MBUF_F_RX_RSS_HASH | RTE_MBUF_F_RX_L4_CKSUM_BAD; 22495d226f0SNipun Gupta break; 2259ac71da4SNipun Gupta case DPAA_PKT_TYPE_NONE: 2269ac71da4SNipun Gupta m->packet_type = 0; 2279ac71da4SNipun Gupta break; 228a7bdc3bdSShreyansh Jain /* More switch cases can be added */ 229a7bdc3bdSShreyansh Jain default: 230a7bdc3bdSShreyansh Jain dpaa_slow_parsing(m, prs); 231a7bdc3bdSShreyansh Jain } 232a7bdc3bdSShreyansh Jain 233a7bdc3bdSShreyansh Jain m->tx_offload = annot->parse.ip_off[0]; 234a7bdc3bdSShreyansh Jain m->tx_offload |= (annot->parse.l4_off - annot->parse.ip_off[0]) 235a7bdc3bdSShreyansh Jain << DPAA_PKT_L3_LEN_SHIFT; 236a7bdc3bdSShreyansh Jain 237a7bdc3bdSShreyansh Jain /* Set the hash values */ 2389ac71da4SNipun Gupta m->hash.rss = (uint32_t)(annot->hash); 239a7bdc3bdSShreyansh Jain 240a7bdc3bdSShreyansh Jain /* Check if Vlan is present */ 241a7bdc3bdSShreyansh Jain if (prs & DPAA_PARSE_VLAN_MASK) 242daa02b5cSOlivier Matz m->ol_flags |= RTE_MBUF_F_RX_VLAN; 243a7bdc3bdSShreyansh Jain /* Packet received without stripping the vlan */ 244a7bdc3bdSShreyansh Jain } 245a7bdc3bdSShreyansh Jain 2465a8cf1beSShreyansh Jain static inline void dpaa_checksum(struct rte_mbuf *mbuf) 2475a8cf1beSShreyansh Jain { 2486d13ea8eSOlivier Matz struct rte_ether_hdr *eth_hdr = 2496d13ea8eSOlivier Matz rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr *); 2505a8cf1beSShreyansh Jain char *l3_hdr = (char *)eth_hdr + mbuf->l2_len; 251a7c528e5SOlivier Matz struct rte_ipv4_hdr *ipv4_hdr = (struct rte_ipv4_hdr *)l3_hdr; 252a7c528e5SOlivier Matz struct rte_ipv6_hdr *ipv6_hdr = (struct rte_ipv6_hdr *)l3_hdr; 2535a8cf1beSShreyansh Jain 2545a8cf1beSShreyansh Jain DPAA_DP_LOG(DEBUG, "Calculating checksum for mbuf: %p", mbuf); 2555a8cf1beSShreyansh Jain 2565a8cf1beSShreyansh Jain if (((mbuf->packet_type & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_IPV4) || 2575a8cf1beSShreyansh Jain ((mbuf->packet_type & RTE_PTYPE_L3_MASK) == 2585a8cf1beSShreyansh Jain RTE_PTYPE_L3_IPV4_EXT)) { 259a7c528e5SOlivier Matz ipv4_hdr = (struct rte_ipv4_hdr *)l3_hdr; 2605a8cf1beSShreyansh Jain ipv4_hdr->hdr_checksum = 0; 2615a8cf1beSShreyansh Jain ipv4_hdr->hdr_checksum = rte_ipv4_cksum(ipv4_hdr); 2625a8cf1beSShreyansh Jain } else if (((mbuf->packet_type & RTE_PTYPE_L3_MASK) == 2635a8cf1beSShreyansh Jain RTE_PTYPE_L3_IPV6) || 2645a8cf1beSShreyansh Jain ((mbuf->packet_type & RTE_PTYPE_L3_MASK) == 2655a8cf1beSShreyansh Jain RTE_PTYPE_L3_IPV6_EXT)) 266a7c528e5SOlivier Matz ipv6_hdr = (struct rte_ipv6_hdr *)l3_hdr; 2675a8cf1beSShreyansh Jain 2685a8cf1beSShreyansh Jain if ((mbuf->packet_type & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_TCP) { 269f41b5156SOlivier Matz struct rte_tcp_hdr *tcp_hdr = (struct rte_tcp_hdr *)(l3_hdr + 2705a8cf1beSShreyansh Jain mbuf->l3_len); 2715a8cf1beSShreyansh Jain tcp_hdr->cksum = 0; 2720c9da755SDavid Marchand if (eth_hdr->ether_type == htons(RTE_ETHER_TYPE_IPV4)) 2735a8cf1beSShreyansh Jain tcp_hdr->cksum = rte_ipv4_udptcp_cksum(ipv4_hdr, 2745a8cf1beSShreyansh Jain tcp_hdr); 2750c9da755SDavid Marchand else /* assume ethertype == RTE_ETHER_TYPE_IPV6 */ 2765a8cf1beSShreyansh Jain tcp_hdr->cksum = rte_ipv6_udptcp_cksum(ipv6_hdr, 2775a8cf1beSShreyansh Jain tcp_hdr); 2785a8cf1beSShreyansh Jain } else if ((mbuf->packet_type & RTE_PTYPE_L4_MASK) == 2795a8cf1beSShreyansh Jain RTE_PTYPE_L4_UDP) { 280e73e3547SOlivier Matz struct rte_udp_hdr *udp_hdr = (struct rte_udp_hdr *)(l3_hdr + 2815a8cf1beSShreyansh Jain mbuf->l3_len); 2825a8cf1beSShreyansh Jain udp_hdr->dgram_cksum = 0; 2830c9da755SDavid Marchand if (eth_hdr->ether_type == htons(RTE_ETHER_TYPE_IPV4)) 2845a8cf1beSShreyansh Jain udp_hdr->dgram_cksum = rte_ipv4_udptcp_cksum(ipv4_hdr, 2855a8cf1beSShreyansh Jain udp_hdr); 2860c9da755SDavid Marchand else /* assume ethertype == RTE_ETHER_TYPE_IPV6 */ 2875a8cf1beSShreyansh Jain udp_hdr->dgram_cksum = rte_ipv6_udptcp_cksum(ipv6_hdr, 2885a8cf1beSShreyansh Jain udp_hdr); 2895a8cf1beSShreyansh Jain } 2905a8cf1beSShreyansh Jain } 2915a8cf1beSShreyansh Jain 2925a8cf1beSShreyansh Jain static inline void dpaa_checksum_offload(struct rte_mbuf *mbuf, 2935a8cf1beSShreyansh Jain struct qm_fd *fd, char *prs_buf) 2945a8cf1beSShreyansh Jain { 2955a8cf1beSShreyansh Jain struct dpaa_eth_parse_results_t *prs; 2965a8cf1beSShreyansh Jain 2975a8cf1beSShreyansh Jain DPAA_DP_LOG(DEBUG, " Offloading checksum for mbuf: %p", mbuf); 2985a8cf1beSShreyansh Jain 2995a8cf1beSShreyansh Jain prs = GET_TX_PRS(prs_buf); 3005a8cf1beSShreyansh Jain prs->l3r = 0; 3015a8cf1beSShreyansh Jain prs->l4r = 0; 3025a8cf1beSShreyansh Jain if (((mbuf->packet_type & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_IPV4) || 3035a8cf1beSShreyansh Jain ((mbuf->packet_type & RTE_PTYPE_L3_MASK) == 3045a8cf1beSShreyansh Jain RTE_PTYPE_L3_IPV4_EXT)) 3055a8cf1beSShreyansh Jain prs->l3r = DPAA_L3_PARSE_RESULT_IPV4; 3065a8cf1beSShreyansh Jain else if (((mbuf->packet_type & RTE_PTYPE_L3_MASK) == 3075a8cf1beSShreyansh Jain RTE_PTYPE_L3_IPV6) || 3085a8cf1beSShreyansh Jain ((mbuf->packet_type & RTE_PTYPE_L3_MASK) == 3095a8cf1beSShreyansh Jain RTE_PTYPE_L3_IPV6_EXT)) 3105a8cf1beSShreyansh Jain prs->l3r = DPAA_L3_PARSE_RESULT_IPV6; 3115a8cf1beSShreyansh Jain 3125a8cf1beSShreyansh Jain if ((mbuf->packet_type & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_TCP) 3135a8cf1beSShreyansh Jain prs->l4r = DPAA_L4_PARSE_RESULT_TCP; 3145a8cf1beSShreyansh Jain else if ((mbuf->packet_type & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_UDP) 3155a8cf1beSShreyansh Jain prs->l4r = DPAA_L4_PARSE_RESULT_UDP; 3165a8cf1beSShreyansh Jain 3175a8cf1beSShreyansh Jain prs->ip_off[0] = mbuf->l2_len; 3185a8cf1beSShreyansh Jain prs->l4_off = mbuf->l3_len + mbuf->l2_len; 3195a8cf1beSShreyansh Jain /* Enable L3 (and L4, if TCP or UDP) HW checksum*/ 3205a8cf1beSShreyansh Jain fd->cmd = DPAA_FD_CMD_RPD | DPAA_FD_CMD_DTC; 3215a8cf1beSShreyansh Jain } 3225a8cf1beSShreyansh Jain 3235e0789e9SNipun Gupta static inline void 3245e0789e9SNipun Gupta dpaa_unsegmented_checksum(struct rte_mbuf *mbuf, struct qm_fd *fd_arr) 3255e0789e9SNipun Gupta { 3265e0789e9SNipun Gupta if (!mbuf->packet_type) { 3275e0789e9SNipun Gupta struct rte_net_hdr_lens hdr_lens; 3285e0789e9SNipun Gupta 3295e0789e9SNipun Gupta mbuf->packet_type = rte_net_get_ptype(mbuf, &hdr_lens, 3305e0789e9SNipun Gupta RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK 3315e0789e9SNipun Gupta | RTE_PTYPE_L4_MASK); 3325e0789e9SNipun Gupta mbuf->l2_len = hdr_lens.l2_len; 3335e0789e9SNipun Gupta mbuf->l3_len = hdr_lens.l3_len; 3345e0789e9SNipun Gupta } 3355e0789e9SNipun Gupta if (mbuf->data_off < (DEFAULT_TX_ICEOF + 3365e0789e9SNipun Gupta sizeof(struct dpaa_eth_parse_results_t))) { 3375e0789e9SNipun Gupta DPAA_DP_LOG(DEBUG, "Checksum offload Err: " 3385e0789e9SNipun Gupta "Not enough Headroom " 3395e0789e9SNipun Gupta "space for correct Checksum offload." 3405e0789e9SNipun Gupta "So Calculating checksum in Software."); 3415e0789e9SNipun Gupta dpaa_checksum(mbuf); 3425e0789e9SNipun Gupta } else { 3435e0789e9SNipun Gupta dpaa_checksum_offload(mbuf, fd_arr, mbuf->buf_addr); 3445e0789e9SNipun Gupta } 3455e0789e9SNipun Gupta } 3465e0789e9SNipun Gupta 347f191d5abSHemant Agrawal static struct rte_mbuf * 3489ac71da4SNipun Gupta dpaa_eth_sg_to_mbuf(const struct qm_fd *fd, uint32_t ifid) 3498cffdcbeSShreyansh Jain { 3508cffdcbeSShreyansh Jain struct dpaa_bp_info *bp_info = DPAA_BPID_TO_POOL_INFO(fd->bpid); 3518cffdcbeSShreyansh Jain struct rte_mbuf *first_seg, *prev_seg, *cur_seg, *temp; 3528cffdcbeSShreyansh Jain struct qm_sg_entry *sgt, *sg_temp; 3538cffdcbeSShreyansh Jain void *vaddr, *sg_vaddr; 3548cffdcbeSShreyansh Jain int i = 0; 355287f4256SNipun Gupta uint16_t fd_offset = fd->offset; 3568cffdcbeSShreyansh Jain 35741c9ee8dSHemant Agrawal vaddr = DPAA_MEMPOOL_PTOV(bp_info, qm_fd_addr(fd)); 3588cffdcbeSShreyansh Jain if (!vaddr) { 3598cffdcbeSShreyansh Jain DPAA_PMD_ERR("unable to convert physical address"); 3608cffdcbeSShreyansh Jain return NULL; 3618cffdcbeSShreyansh Jain } 3628cffdcbeSShreyansh Jain sgt = vaddr + fd_offset; 3638cffdcbeSShreyansh Jain sg_temp = &sgt[i++]; 3648cffdcbeSShreyansh Jain hw_sg_to_cpu(sg_temp); 3658cffdcbeSShreyansh Jain temp = (struct rte_mbuf *)((char *)vaddr - bp_info->meta_data_size); 36641c9ee8dSHemant Agrawal sg_vaddr = DPAA_MEMPOOL_PTOV(bp_info, qm_sg_entry_get64(sg_temp)); 3678cffdcbeSShreyansh Jain 3688cffdcbeSShreyansh Jain first_seg = (struct rte_mbuf *)((char *)sg_vaddr - 3698cffdcbeSShreyansh Jain bp_info->meta_data_size); 3708cffdcbeSShreyansh Jain first_seg->data_off = sg_temp->offset; 3718cffdcbeSShreyansh Jain first_seg->data_len = sg_temp->length; 3728cffdcbeSShreyansh Jain first_seg->pkt_len = sg_temp->length; 3738cffdcbeSShreyansh Jain rte_mbuf_refcnt_set(first_seg, 1); 3748cffdcbeSShreyansh Jain 3758cffdcbeSShreyansh Jain first_seg->port = ifid; 3768cffdcbeSShreyansh Jain first_seg->nb_segs = 1; 3778cffdcbeSShreyansh Jain first_seg->ol_flags = 0; 3788cffdcbeSShreyansh Jain prev_seg = first_seg; 3798cffdcbeSShreyansh Jain while (i < DPAA_SGT_MAX_ENTRIES) { 3808cffdcbeSShreyansh Jain sg_temp = &sgt[i++]; 3818cffdcbeSShreyansh Jain hw_sg_to_cpu(sg_temp); 38241c9ee8dSHemant Agrawal sg_vaddr = DPAA_MEMPOOL_PTOV(bp_info, 38341c9ee8dSHemant Agrawal qm_sg_entry_get64(sg_temp)); 3848cffdcbeSShreyansh Jain cur_seg = (struct rte_mbuf *)((char *)sg_vaddr - 3858cffdcbeSShreyansh Jain bp_info->meta_data_size); 3868cffdcbeSShreyansh Jain cur_seg->data_off = sg_temp->offset; 3878cffdcbeSShreyansh Jain cur_seg->data_len = sg_temp->length; 3888cffdcbeSShreyansh Jain first_seg->pkt_len += sg_temp->length; 3898cffdcbeSShreyansh Jain first_seg->nb_segs += 1; 3908cffdcbeSShreyansh Jain rte_mbuf_refcnt_set(cur_seg, 1); 3918cffdcbeSShreyansh Jain prev_seg->next = cur_seg; 3928cffdcbeSShreyansh Jain if (sg_temp->final) { 3938cffdcbeSShreyansh Jain cur_seg->next = NULL; 3948cffdcbeSShreyansh Jain break; 3958cffdcbeSShreyansh Jain } 3968cffdcbeSShreyansh Jain prev_seg = cur_seg; 3978cffdcbeSShreyansh Jain } 39855576ac2SHemant Agrawal DPAA_DP_LOG(DEBUG, "Received an SG frame len =%d, num_sg =%d", 39955576ac2SHemant Agrawal first_seg->pkt_len, first_seg->nb_segs); 4008cffdcbeSShreyansh Jain 4010e5607e4SHemant Agrawal dpaa_eth_packet_info(first_seg, vaddr); 4028cffdcbeSShreyansh Jain rte_pktmbuf_free_seg(temp); 4038cffdcbeSShreyansh Jain 4048cffdcbeSShreyansh Jain return first_seg; 4058cffdcbeSShreyansh Jain } 4068cffdcbeSShreyansh Jain 4079ac71da4SNipun Gupta static inline struct rte_mbuf * 4089ac71da4SNipun Gupta dpaa_eth_fd_to_mbuf(const struct qm_fd *fd, uint32_t ifid) 40937f9b54bSShreyansh Jain { 41037f9b54bSShreyansh Jain struct rte_mbuf *mbuf; 4119ac71da4SNipun Gupta struct dpaa_bp_info *bp_info = DPAA_BPID_TO_POOL_INFO(fd->bpid); 41241c9ee8dSHemant Agrawal void *ptr; 4138cffdcbeSShreyansh Jain uint8_t format = 4148cffdcbeSShreyansh Jain (fd->opaque & DPAA_FD_FORMAT_MASK) >> DPAA_FD_FORMAT_SHIFT; 4159ac71da4SNipun Gupta uint16_t offset; 4169ac71da4SNipun Gupta uint32_t length; 41737f9b54bSShreyansh Jain 4188cffdcbeSShreyansh Jain if (unlikely(format == qm_fd_sg)) 4198cffdcbeSShreyansh Jain return dpaa_eth_sg_to_mbuf(fd, ifid); 4208cffdcbeSShreyansh Jain 4219ac71da4SNipun Gupta offset = (fd->opaque & DPAA_FD_OFFSET_MASK) >> DPAA_FD_OFFSET_SHIFT; 4229ac71da4SNipun Gupta length = fd->opaque & DPAA_FD_LENGTH_MASK; 4239ac71da4SNipun Gupta 42455576ac2SHemant Agrawal DPAA_DP_LOG(DEBUG, " FD--->MBUF off %d len = %d", offset, length); 42555576ac2SHemant Agrawal 42637f9b54bSShreyansh Jain /* Ignoring case when format != qm_fd_contig */ 4271ee09e39SHemant Agrawal ptr = DPAA_MEMPOOL_PTOV(bp_info, qm_fd_addr(fd)); 42837f9b54bSShreyansh Jain 42937f9b54bSShreyansh Jain mbuf = (struct rte_mbuf *)((char *)ptr - bp_info->meta_data_size); 4301ee09e39SHemant Agrawal /* Prefetch the Parse results and packet data to L1 */ 4311ee09e39SHemant Agrawal rte_prefetch0((void *)((uint8_t *)ptr + DEFAULT_RX_ICEOF)); 43237f9b54bSShreyansh Jain 43337f9b54bSShreyansh Jain mbuf->data_off = offset; 43437f9b54bSShreyansh Jain mbuf->data_len = length; 43537f9b54bSShreyansh Jain mbuf->pkt_len = length; 43637f9b54bSShreyansh Jain 43737f9b54bSShreyansh Jain mbuf->port = ifid; 43837f9b54bSShreyansh Jain mbuf->nb_segs = 1; 43937f9b54bSShreyansh Jain mbuf->ol_flags = 0; 44037f9b54bSShreyansh Jain mbuf->next = NULL; 44137f9b54bSShreyansh Jain rte_mbuf_refcnt_set(mbuf, 1); 4420e5607e4SHemant Agrawal dpaa_eth_packet_info(mbuf, mbuf->buf_addr); 44337f9b54bSShreyansh Jain 44437f9b54bSShreyansh Jain return mbuf; 44537f9b54bSShreyansh Jain } 44637f9b54bSShreyansh Jain 4479124e65dSGagandeep Singh uint16_t 4489124e65dSGagandeep Singh dpaa_free_mbuf(const struct qm_fd *fd) 4499124e65dSGagandeep Singh { 4509124e65dSGagandeep Singh struct rte_mbuf *mbuf; 4519124e65dSGagandeep Singh struct dpaa_bp_info *bp_info; 4529124e65dSGagandeep Singh uint8_t format; 4539124e65dSGagandeep Singh void *ptr; 4549124e65dSGagandeep Singh 4559124e65dSGagandeep Singh bp_info = DPAA_BPID_TO_POOL_INFO(fd->bpid); 4569124e65dSGagandeep Singh format = (fd->opaque & DPAA_FD_FORMAT_MASK) >> DPAA_FD_FORMAT_SHIFT; 4579124e65dSGagandeep Singh if (unlikely(format == qm_fd_sg)) { 458*0bf99a02SGagandeep Singh struct rte_mbuf *first_seg, *cur_seg; 4599124e65dSGagandeep Singh struct qm_sg_entry *sgt, *sg_temp; 4609124e65dSGagandeep Singh void *vaddr, *sg_vaddr; 4619124e65dSGagandeep Singh int i = 0; 4629124e65dSGagandeep Singh uint16_t fd_offset = fd->offset; 4639124e65dSGagandeep Singh 4649124e65dSGagandeep Singh vaddr = DPAA_MEMPOOL_PTOV(bp_info, qm_fd_addr(fd)); 4659124e65dSGagandeep Singh if (!vaddr) { 4669124e65dSGagandeep Singh DPAA_PMD_ERR("unable to convert physical address"); 4679124e65dSGagandeep Singh return -1; 4689124e65dSGagandeep Singh } 4699124e65dSGagandeep Singh sgt = vaddr + fd_offset; 4709124e65dSGagandeep Singh sg_temp = &sgt[i++]; 4719124e65dSGagandeep Singh hw_sg_to_cpu(sg_temp); 4729124e65dSGagandeep Singh sg_vaddr = DPAA_MEMPOOL_PTOV(bp_info, 4739124e65dSGagandeep Singh qm_sg_entry_get64(sg_temp)); 4749124e65dSGagandeep Singh first_seg = (struct rte_mbuf *)((char *)sg_vaddr - 4759124e65dSGagandeep Singh bp_info->meta_data_size); 4769124e65dSGagandeep Singh first_seg->nb_segs = 1; 4779124e65dSGagandeep Singh while (i < DPAA_SGT_MAX_ENTRIES) { 4789124e65dSGagandeep Singh sg_temp = &sgt[i++]; 4799124e65dSGagandeep Singh hw_sg_to_cpu(sg_temp); 480*0bf99a02SGagandeep Singh if (sg_temp->bpid != 0xFF) { 481*0bf99a02SGagandeep Singh bp_info = DPAA_BPID_TO_POOL_INFO(sg_temp->bpid); 4829124e65dSGagandeep Singh sg_vaddr = DPAA_MEMPOOL_PTOV(bp_info, 4839124e65dSGagandeep Singh qm_sg_entry_get64(sg_temp)); 4849124e65dSGagandeep Singh cur_seg = (struct rte_mbuf *)((char *)sg_vaddr - 4859124e65dSGagandeep Singh bp_info->meta_data_size); 486*0bf99a02SGagandeep Singh rte_pktmbuf_free_seg(cur_seg); 487*0bf99a02SGagandeep Singh } 488*0bf99a02SGagandeep Singh if (sg_temp->final) 4899124e65dSGagandeep Singh break; 4909124e65dSGagandeep Singh } 4919124e65dSGagandeep Singh rte_pktmbuf_free_seg(first_seg); 4929124e65dSGagandeep Singh return 0; 4939124e65dSGagandeep Singh } 4949124e65dSGagandeep Singh 4959124e65dSGagandeep Singh ptr = DPAA_MEMPOOL_PTOV(bp_info, qm_fd_addr(fd)); 4969124e65dSGagandeep Singh mbuf = (struct rte_mbuf *)((char *)ptr - bp_info->meta_data_size); 4979124e65dSGagandeep Singh 4989124e65dSGagandeep Singh rte_pktmbuf_free(mbuf); 4999124e65dSGagandeep Singh 5009124e65dSGagandeep Singh return 0; 5019124e65dSGagandeep Singh } 5029124e65dSGagandeep Singh 50319b4aba2SHemant Agrawal /* Specific for LS1043 */ 504b9083ea5SNipun Gupta void 50519b4aba2SHemant Agrawal dpaa_rx_cb_no_prefetch(struct qman_fq **fq, struct qm_dqrr_entry **dqrr, 506b9083ea5SNipun Gupta void **bufs, int num_bufs) 5070c504f69SHemant Agrawal { 508b9083ea5SNipun Gupta struct rte_mbuf *mbuf; 509b9083ea5SNipun Gupta struct dpaa_bp_info *bp_info; 510b9083ea5SNipun Gupta const struct qm_fd *fd; 511b9083ea5SNipun Gupta void *ptr; 512b9083ea5SNipun Gupta struct dpaa_if *dpaa_intf; 513b9083ea5SNipun Gupta uint16_t offset, i; 514b9083ea5SNipun Gupta uint32_t length; 515b9083ea5SNipun Gupta uint8_t format; 5160c504f69SHemant Agrawal 517b9083ea5SNipun Gupta bp_info = DPAA_BPID_TO_POOL_INFO(dqrr[0]->fd.bpid); 518b9083ea5SNipun Gupta ptr = rte_dpaa_mem_ptov(qm_fd_addr(&dqrr[0]->fd)); 519b9083ea5SNipun Gupta rte_prefetch0((void *)((uint8_t *)ptr + DEFAULT_RX_ICEOF)); 52019b4aba2SHemant Agrawal bufs[0] = (struct rte_mbuf *)((char *)ptr - bp_info->meta_data_size); 521b9083ea5SNipun Gupta 522b9083ea5SNipun Gupta for (i = 0; i < num_bufs; i++) { 52319b4aba2SHemant Agrawal if (i < num_bufs - 1) { 524b9083ea5SNipun Gupta bp_info = DPAA_BPID_TO_POOL_INFO(dqrr[i + 1]->fd.bpid); 525b9083ea5SNipun Gupta ptr = rte_dpaa_mem_ptov(qm_fd_addr(&dqrr[i + 1]->fd)); 526b9083ea5SNipun Gupta rte_prefetch0((void *)((uint8_t *)ptr + 527b9083ea5SNipun Gupta DEFAULT_RX_ICEOF)); 528b9083ea5SNipun Gupta bufs[i + 1] = (struct rte_mbuf *)((char *)ptr - 529b9083ea5SNipun Gupta bp_info->meta_data_size); 530b9083ea5SNipun Gupta } 531b9083ea5SNipun Gupta 532b9083ea5SNipun Gupta fd = &dqrr[i]->fd; 5339abdad12SHemant Agrawal dpaa_intf = fq[0]->dpaa_intf; 534b9083ea5SNipun Gupta format = (fd->opaque & DPAA_FD_FORMAT_MASK) >> 535b9083ea5SNipun Gupta DPAA_FD_FORMAT_SHIFT; 536b9083ea5SNipun Gupta if (unlikely(format == qm_fd_sg)) { 537b9083ea5SNipun Gupta bufs[i] = dpaa_eth_sg_to_mbuf(fd, dpaa_intf->ifid); 538b9083ea5SNipun Gupta continue; 539b9083ea5SNipun Gupta } 540b9083ea5SNipun Gupta 541b9083ea5SNipun Gupta offset = (fd->opaque & DPAA_FD_OFFSET_MASK) >> 542b9083ea5SNipun Gupta DPAA_FD_OFFSET_SHIFT; 543b9083ea5SNipun Gupta length = fd->opaque & DPAA_FD_LENGTH_MASK; 544b9083ea5SNipun Gupta 545b9083ea5SNipun Gupta mbuf = bufs[i]; 546b9083ea5SNipun Gupta mbuf->data_off = offset; 547b9083ea5SNipun Gupta mbuf->data_len = length; 548b9083ea5SNipun Gupta mbuf->pkt_len = length; 549b9083ea5SNipun Gupta mbuf->port = dpaa_intf->ifid; 550b9083ea5SNipun Gupta 551b9083ea5SNipun Gupta mbuf->nb_segs = 1; 552b9083ea5SNipun Gupta mbuf->ol_flags = 0; 553b9083ea5SNipun Gupta mbuf->next = NULL; 554b9083ea5SNipun Gupta rte_mbuf_refcnt_set(mbuf, 1); 5550e5607e4SHemant Agrawal dpaa_eth_packet_info(mbuf, mbuf->buf_addr); 55677393f56SSachin Saxena dpaa_display_frame_info(fd, fq[0]->fqid, true); 557b9083ea5SNipun Gupta } 558b9083ea5SNipun Gupta } 559b9083ea5SNipun Gupta 56019b4aba2SHemant Agrawal void 56119b4aba2SHemant Agrawal dpaa_rx_cb(struct qman_fq **fq, struct qm_dqrr_entry **dqrr, 56219b4aba2SHemant Agrawal void **bufs, int num_bufs) 56319b4aba2SHemant Agrawal { 56419b4aba2SHemant Agrawal struct rte_mbuf *mbuf; 56519b4aba2SHemant Agrawal const struct qm_fd *fd; 56619b4aba2SHemant Agrawal struct dpaa_if *dpaa_intf; 56719b4aba2SHemant Agrawal uint16_t offset, i; 56819b4aba2SHemant Agrawal uint32_t length; 56919b4aba2SHemant Agrawal uint8_t format; 57019b4aba2SHemant Agrawal 57119b4aba2SHemant Agrawal for (i = 0; i < num_bufs; i++) { 57219b4aba2SHemant Agrawal fd = &dqrr[i]->fd; 57319b4aba2SHemant Agrawal dpaa_intf = fq[0]->dpaa_intf; 57419b4aba2SHemant Agrawal format = (fd->opaque & DPAA_FD_FORMAT_MASK) >> 57519b4aba2SHemant Agrawal DPAA_FD_FORMAT_SHIFT; 57619b4aba2SHemant Agrawal if (unlikely(format == qm_fd_sg)) { 57719b4aba2SHemant Agrawal bufs[i] = dpaa_eth_sg_to_mbuf(fd, dpaa_intf->ifid); 57819b4aba2SHemant Agrawal continue; 57919b4aba2SHemant Agrawal } 58019b4aba2SHemant Agrawal 58119b4aba2SHemant Agrawal offset = (fd->opaque & DPAA_FD_OFFSET_MASK) >> 58219b4aba2SHemant Agrawal DPAA_FD_OFFSET_SHIFT; 58319b4aba2SHemant Agrawal length = fd->opaque & DPAA_FD_LENGTH_MASK; 58419b4aba2SHemant Agrawal 58519b4aba2SHemant Agrawal mbuf = bufs[i]; 58619b4aba2SHemant Agrawal mbuf->data_off = offset; 58719b4aba2SHemant Agrawal mbuf->data_len = length; 58819b4aba2SHemant Agrawal mbuf->pkt_len = length; 58919b4aba2SHemant Agrawal mbuf->port = dpaa_intf->ifid; 59019b4aba2SHemant Agrawal 59119b4aba2SHemant Agrawal mbuf->nb_segs = 1; 59219b4aba2SHemant Agrawal mbuf->ol_flags = 0; 59319b4aba2SHemant Agrawal mbuf->next = NULL; 59419b4aba2SHemant Agrawal rte_mbuf_refcnt_set(mbuf, 1); 59519b4aba2SHemant Agrawal dpaa_eth_packet_info(mbuf, mbuf->buf_addr); 59677393f56SSachin Saxena dpaa_display_frame_info(fd, fq[0]->fqid, true); 59719b4aba2SHemant Agrawal } 59819b4aba2SHemant Agrawal } 59919b4aba2SHemant Agrawal 600b9083ea5SNipun Gupta void dpaa_rx_cb_prepare(struct qm_dqrr_entry *dq, void **bufs) 601b9083ea5SNipun Gupta { 602b9083ea5SNipun Gupta struct dpaa_bp_info *bp_info = DPAA_BPID_TO_POOL_INFO(dq->fd.bpid); 603b9083ea5SNipun Gupta void *ptr = rte_dpaa_mem_ptov(qm_fd_addr(&dq->fd)); 604b9083ea5SNipun Gupta 605b9083ea5SNipun Gupta /* In case of LS1046, annotation stashing is disabled due to L2 cache 6067be78d02SJosh Soref * being bottleneck in case of multicore scenario for this platform. 6077be78d02SJosh Soref * So we prefetch the annotation beforehand, so that it is available 608b9083ea5SNipun Gupta * in cache when accessed. 609b9083ea5SNipun Gupta */ 610b9083ea5SNipun Gupta rte_prefetch0((void *)((uint8_t *)ptr + DEFAULT_RX_ICEOF)); 611b9083ea5SNipun Gupta 612b9083ea5SNipun Gupta *bufs = (struct rte_mbuf *)((char *)ptr - bp_info->meta_data_size); 6130c504f69SHemant Agrawal } 6140c504f69SHemant Agrawal 6150c504f69SHemant Agrawal static uint16_t 6160c504f69SHemant Agrawal dpaa_eth_queue_portal_rx(struct qman_fq *fq, 6170c504f69SHemant Agrawal struct rte_mbuf **bufs, 6180c504f69SHemant Agrawal uint16_t nb_bufs) 6190c504f69SHemant Agrawal { 6200c504f69SHemant Agrawal int ret; 6210c504f69SHemant Agrawal 622b9c94167SNipun Gupta if (unlikely(!fq->qp_initialized)) { 6230c504f69SHemant Agrawal ret = rte_dpaa_portal_fq_init((void *)0, fq); 6240c504f69SHemant Agrawal if (ret) { 6250c504f69SHemant Agrawal DPAA_PMD_ERR("Failure in affining portal %d", ret); 6260c504f69SHemant Agrawal return 0; 6270c504f69SHemant Agrawal } 628b9c94167SNipun Gupta fq->qp_initialized = 1; 6290c504f69SHemant Agrawal } 6300c504f69SHemant Agrawal 6310c504f69SHemant Agrawal return qman_portal_poll_rx(nb_bufs, (void **)bufs, fq->qp); 6320c504f69SHemant Agrawal } 6330c504f69SHemant Agrawal 6345e745593SSunil Kumar Kori enum qman_cb_dqrr_result 6355e745593SSunil Kumar Kori dpaa_rx_cb_parallel(void *event, 6365e745593SSunil Kumar Kori struct qman_portal *qm __always_unused, 6375e745593SSunil Kumar Kori struct qman_fq *fq, 6385e745593SSunil Kumar Kori const struct qm_dqrr_entry *dqrr, 6395e745593SSunil Kumar Kori void **bufs) 6405e745593SSunil Kumar Kori { 6415e745593SSunil Kumar Kori u32 ifid = ((struct dpaa_if *)fq->dpaa_intf)->ifid; 6425e745593SSunil Kumar Kori struct rte_mbuf *mbuf; 6435e745593SSunil Kumar Kori struct rte_event *ev = (struct rte_event *)event; 6445e745593SSunil Kumar Kori 6455e745593SSunil Kumar Kori mbuf = dpaa_eth_fd_to_mbuf(&dqrr->fd, ifid); 6465e745593SSunil Kumar Kori ev->event_ptr = (void *)mbuf; 6475e745593SSunil Kumar Kori ev->flow_id = fq->ev.flow_id; 6485e745593SSunil Kumar Kori ev->sub_event_type = fq->ev.sub_event_type; 6495e745593SSunil Kumar Kori ev->event_type = RTE_EVENT_TYPE_ETHDEV; 6505e745593SSunil Kumar Kori ev->op = RTE_EVENT_OP_NEW; 6515e745593SSunil Kumar Kori ev->sched_type = fq->ev.sched_type; 6525e745593SSunil Kumar Kori ev->queue_id = fq->ev.queue_id; 6535e745593SSunil Kumar Kori ev->priority = fq->ev.priority; 6545e745593SSunil Kumar Kori ev->impl_opaque = (uint8_t)DPAA_INVALID_MBUF_SEQN; 655c9a1c2e5SDavid Marchand *dpaa_seqn(mbuf) = DPAA_INVALID_MBUF_SEQN; 6565e745593SSunil Kumar Kori *bufs = mbuf; 6575e745593SSunil Kumar Kori 6585e745593SSunil Kumar Kori return qman_cb_dqrr_consume; 6595e745593SSunil Kumar Kori } 6605e745593SSunil Kumar Kori 6615e745593SSunil Kumar Kori enum qman_cb_dqrr_result 6625e745593SSunil Kumar Kori dpaa_rx_cb_atomic(void *event, 6635e745593SSunil Kumar Kori struct qman_portal *qm __always_unused, 6645e745593SSunil Kumar Kori struct qman_fq *fq, 6655e745593SSunil Kumar Kori const struct qm_dqrr_entry *dqrr, 6665e745593SSunil Kumar Kori void **bufs) 6675e745593SSunil Kumar Kori { 6685e745593SSunil Kumar Kori u8 index; 6695e745593SSunil Kumar Kori u32 ifid = ((struct dpaa_if *)fq->dpaa_intf)->ifid; 6705e745593SSunil Kumar Kori struct rte_mbuf *mbuf; 6715e745593SSunil Kumar Kori struct rte_event *ev = (struct rte_event *)event; 6725e745593SSunil Kumar Kori 6735e745593SSunil Kumar Kori mbuf = dpaa_eth_fd_to_mbuf(&dqrr->fd, ifid); 6745e745593SSunil Kumar Kori ev->event_ptr = (void *)mbuf; 6755e745593SSunil Kumar Kori ev->flow_id = fq->ev.flow_id; 6765e745593SSunil Kumar Kori ev->sub_event_type = fq->ev.sub_event_type; 6775e745593SSunil Kumar Kori ev->event_type = RTE_EVENT_TYPE_ETHDEV; 6785e745593SSunil Kumar Kori ev->op = RTE_EVENT_OP_NEW; 6795e745593SSunil Kumar Kori ev->sched_type = fq->ev.sched_type; 6805e745593SSunil Kumar Kori ev->queue_id = fq->ev.queue_id; 6815e745593SSunil Kumar Kori ev->priority = fq->ev.priority; 6825e745593SSunil Kumar Kori 6835e745593SSunil Kumar Kori /* Save active dqrr entries */ 6845e745593SSunil Kumar Kori index = DQRR_PTR2IDX(dqrr); 6855e745593SSunil Kumar Kori DPAA_PER_LCORE_DQRR_SIZE++; 6865e745593SSunil Kumar Kori DPAA_PER_LCORE_DQRR_HELD |= 1 << index; 6875e745593SSunil Kumar Kori DPAA_PER_LCORE_DQRR_MBUF(index) = mbuf; 6885e745593SSunil Kumar Kori ev->impl_opaque = index + 1; 689c9a1c2e5SDavid Marchand *dpaa_seqn(mbuf) = (uint32_t)index + 1; 6905e745593SSunil Kumar Kori *bufs = mbuf; 6915e745593SSunil Kumar Kori 6925e745593SSunil Kumar Kori return qman_cb_dqrr_defer; 6935e745593SSunil Kumar Kori } 6945e745593SSunil Kumar Kori 69577393f56SSachin Saxena #ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER 69677393f56SSachin Saxena static inline void dpaa_eth_err_queue(struct dpaa_if *dpaa_intf) 69777393f56SSachin Saxena { 69877393f56SSachin Saxena struct rte_mbuf *mbuf; 69977393f56SSachin Saxena struct qman_fq *debug_fq; 70077393f56SSachin Saxena int ret, i; 70177393f56SSachin Saxena struct qm_dqrr_entry *dq; 70277393f56SSachin Saxena struct qm_fd *fd; 70377393f56SSachin Saxena 70477393f56SSachin Saxena if (unlikely(!RTE_PER_LCORE(dpaa_io))) { 70577393f56SSachin Saxena ret = rte_dpaa_portal_init((void *)0); 70677393f56SSachin Saxena if (ret) { 70777393f56SSachin Saxena DPAA_PMD_ERR("Failure in affining portal"); 70877393f56SSachin Saxena return; 70977393f56SSachin Saxena } 71077393f56SSachin Saxena } 71177393f56SSachin Saxena for (i = 0; i <= DPAA_DEBUG_FQ_TX_ERROR; i++) { 71277393f56SSachin Saxena debug_fq = &dpaa_intf->debug_queues[i]; 71377393f56SSachin Saxena ret = qman_set_vdq(debug_fq, 4, QM_VDQCR_EXACT); 71477393f56SSachin Saxena if (ret) 71577393f56SSachin Saxena return; 71677393f56SSachin Saxena 71777393f56SSachin Saxena do { 71877393f56SSachin Saxena dq = qman_dequeue(debug_fq); 71977393f56SSachin Saxena if (!dq) 72077393f56SSachin Saxena continue; 72177393f56SSachin Saxena fd = &dq->fd; 72277393f56SSachin Saxena if (i == DPAA_DEBUG_FQ_RX_ERROR) 72377393f56SSachin Saxena DPAA_PMD_ERR("RX ERROR status: 0x%08x", 72477393f56SSachin Saxena fd->status); 72577393f56SSachin Saxena else 72677393f56SSachin Saxena DPAA_PMD_ERR("TX ERROR status: 0x%08x", 72777393f56SSachin Saxena fd->status); 72877393f56SSachin Saxena dpaa_display_frame_info(fd, debug_fq->fqid, 72977393f56SSachin Saxena i == DPAA_DEBUG_FQ_RX_ERROR); 73077393f56SSachin Saxena 73177393f56SSachin Saxena mbuf = dpaa_eth_fd_to_mbuf(fd, dpaa_intf->ifid); 73277393f56SSachin Saxena rte_pktmbuf_free(mbuf); 73377393f56SSachin Saxena qman_dqrr_consume(debug_fq, dq); 73477393f56SSachin Saxena } while (debug_fq->flags & QMAN_FQ_STATE_VDQCR); 73577393f56SSachin Saxena } 73677393f56SSachin Saxena } 73777393f56SSachin Saxena #endif 73877393f56SSachin Saxena 73937f9b54bSShreyansh Jain uint16_t dpaa_eth_queue_rx(void *q, 74037f9b54bSShreyansh Jain struct rte_mbuf **bufs, 74137f9b54bSShreyansh Jain uint16_t nb_bufs) 74237f9b54bSShreyansh Jain { 74337f9b54bSShreyansh Jain struct qman_fq *fq = q; 74437f9b54bSShreyansh Jain struct qm_dqrr_entry *dq; 74537f9b54bSShreyansh Jain uint32_t num_rx = 0, ifid = ((struct dpaa_if *)fq->dpaa_intf)->ifid; 746f40d5a53SNipun Gupta int num_rx_bufs, ret; 747f40d5a53SNipun Gupta uint32_t vdqcr_flags = 0; 74837f9b54bSShreyansh Jain 749e1797f4bSAkhil Goyal if (unlikely(rte_dpaa_bpid_info == NULL && 750e1797f4bSAkhil Goyal rte_eal_process_type() == RTE_PROC_SECONDARY)) 751e1797f4bSAkhil Goyal rte_dpaa_bpid_info = fq->bp_array; 752e1797f4bSAkhil Goyal 75377393f56SSachin Saxena #ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER 75477393f56SSachin Saxena if (fq->fqid == ((struct dpaa_if *)fq->dpaa_intf)->rx_queues[0].fqid) 75577393f56SSachin Saxena dpaa_eth_err_queue((struct dpaa_if *)fq->dpaa_intf); 75677393f56SSachin Saxena #endif 75777393f56SSachin Saxena 7580c504f69SHemant Agrawal if (likely(fq->is_static)) 7590c504f69SHemant Agrawal return dpaa_eth_queue_portal_rx(fq, bufs, nb_bufs); 7600c504f69SHemant Agrawal 761e5872221SRohit Raj if (unlikely(!DPAA_PER_LCORE_PORTAL)) { 76237f9b54bSShreyansh Jain ret = rte_dpaa_portal_init((void *)0); 76337f9b54bSShreyansh Jain if (ret) { 76437f9b54bSShreyansh Jain DPAA_PMD_ERR("Failure in affining portal"); 76537f9b54bSShreyansh Jain return 0; 76637f9b54bSShreyansh Jain } 7675d944582SNipun Gupta } 76837f9b54bSShreyansh Jain 769f40d5a53SNipun Gupta /* Until request for four buffers, we provide exact number of buffers. 770f40d5a53SNipun Gupta * Otherwise we do not set the QM_VDQCR_EXACT flag. 771f40d5a53SNipun Gupta * Not setting QM_VDQCR_EXACT flag can provide two more buffers than 772f40d5a53SNipun Gupta * requested, so we request two less in this case. 773f40d5a53SNipun Gupta */ 774f40d5a53SNipun Gupta if (nb_bufs < 4) { 775f40d5a53SNipun Gupta vdqcr_flags = QM_VDQCR_EXACT; 776f40d5a53SNipun Gupta num_rx_bufs = nb_bufs; 777f40d5a53SNipun Gupta } else { 778f40d5a53SNipun Gupta num_rx_bufs = nb_bufs > DPAA_MAX_DEQUEUE_NUM_FRAMES ? 779f40d5a53SNipun Gupta (DPAA_MAX_DEQUEUE_NUM_FRAMES - 2) : (nb_bufs - 2); 780f40d5a53SNipun Gupta } 781f40d5a53SNipun Gupta ret = qman_set_vdq(fq, num_rx_bufs, vdqcr_flags); 78237f9b54bSShreyansh Jain if (ret) 78337f9b54bSShreyansh Jain return 0; 78437f9b54bSShreyansh Jain 78537f9b54bSShreyansh Jain do { 78637f9b54bSShreyansh Jain dq = qman_dequeue(fq); 78737f9b54bSShreyansh Jain if (!dq) 78837f9b54bSShreyansh Jain continue; 78937f9b54bSShreyansh Jain bufs[num_rx++] = dpaa_eth_fd_to_mbuf(&dq->fd, ifid); 79077393f56SSachin Saxena dpaa_display_frame_info(&dq->fd, fq->fqid, true); 79137f9b54bSShreyansh Jain qman_dqrr_consume(fq, dq); 79237f9b54bSShreyansh Jain } while (fq->flags & QMAN_FQ_STATE_VDQCR); 79337f9b54bSShreyansh Jain 79437f9b54bSShreyansh Jain return num_rx; 79537f9b54bSShreyansh Jain } 79637f9b54bSShreyansh Jain 797f191d5abSHemant Agrawal static int 7988cffdcbeSShreyansh Jain dpaa_eth_mbuf_to_sg_fd(struct rte_mbuf *mbuf, 7998716c0ecSGagandeep Singh struct qm_fd *fd, 8008716c0ecSGagandeep Singh struct dpaa_sw_buf_free *free_buf, 8018716c0ecSGagandeep Singh uint32_t *free_count, 8028716c0ecSGagandeep Singh uint32_t pkt_id) 8038cffdcbeSShreyansh Jain { 8048716c0ecSGagandeep Singh struct rte_mbuf *cur_seg = mbuf; 8058cffdcbeSShreyansh Jain struct rte_mbuf *temp, *mi; 8068cffdcbeSShreyansh Jain struct qm_sg_entry *sg_temp, *sgt; 8078cffdcbeSShreyansh Jain int i = 0; 8088cffdcbeSShreyansh Jain 8098cffdcbeSShreyansh Jain DPAA_DP_LOG(DEBUG, "Creating SG FD to transmit"); 8108cffdcbeSShreyansh Jain 811533c31ccSGagandeep Singh temp = rte_pktmbuf_alloc(dpaa_tx_sg_pool); 8128cffdcbeSShreyansh Jain if (!temp) { 8138cffdcbeSShreyansh Jain DPAA_PMD_ERR("Failure in allocation of mbuf"); 8148cffdcbeSShreyansh Jain return -1; 8158cffdcbeSShreyansh Jain } 8168cffdcbeSShreyansh Jain if (temp->buf_len < ((mbuf->nb_segs * sizeof(struct qm_sg_entry)) 8178cffdcbeSShreyansh Jain + temp->data_off)) { 8188cffdcbeSShreyansh Jain DPAA_PMD_ERR("Insufficient space in mbuf for SG entries"); 8198cffdcbeSShreyansh Jain return -1; 8208cffdcbeSShreyansh Jain } 8218cffdcbeSShreyansh Jain 8228cffdcbeSShreyansh Jain fd->cmd = 0; 8238cffdcbeSShreyansh Jain fd->opaque_addr = 0; 8248cffdcbeSShreyansh Jain 8258cffdcbeSShreyansh Jain if (mbuf->ol_flags & DPAA_TX_CKSUM_OFFLOAD_MASK) { 826d565c887SAshish Jain if (!mbuf->packet_type) { 827d565c887SAshish Jain struct rte_net_hdr_lens hdr_lens; 828d565c887SAshish Jain 829d565c887SAshish Jain mbuf->packet_type = rte_net_get_ptype(mbuf, &hdr_lens, 830d565c887SAshish Jain RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK 831d565c887SAshish Jain | RTE_PTYPE_L4_MASK); 832d565c887SAshish Jain mbuf->l2_len = hdr_lens.l2_len; 833d565c887SAshish Jain mbuf->l3_len = hdr_lens.l3_len; 834d565c887SAshish Jain } 8358cffdcbeSShreyansh Jain if (temp->data_off < DEFAULT_TX_ICEOF 8368cffdcbeSShreyansh Jain + sizeof(struct dpaa_eth_parse_results_t)) 8378cffdcbeSShreyansh Jain temp->data_off = DEFAULT_TX_ICEOF 8388cffdcbeSShreyansh Jain + sizeof(struct dpaa_eth_parse_results_t); 8398cffdcbeSShreyansh Jain dcbz_64(temp->buf_addr); 8408cffdcbeSShreyansh Jain dpaa_checksum_offload(mbuf, fd, temp->buf_addr); 8418cffdcbeSShreyansh Jain } 8428cffdcbeSShreyansh Jain 8438cffdcbeSShreyansh Jain sgt = temp->buf_addr + temp->data_off; 8448cffdcbeSShreyansh Jain fd->format = QM_FD_SG; 845455da545SSantosh Shukla fd->addr = temp->buf_iova; 8468cffdcbeSShreyansh Jain fd->offset = temp->data_off; 847533c31ccSGagandeep Singh fd->bpid = DPAA_MEMPOOL_TO_BPID(dpaa_tx_sg_pool); 8488cffdcbeSShreyansh Jain fd->length20 = mbuf->pkt_len; 8498cffdcbeSShreyansh Jain 8508cffdcbeSShreyansh Jain while (i < DPAA_SGT_MAX_ENTRIES) { 8518cffdcbeSShreyansh Jain sg_temp = &sgt[i++]; 8528cffdcbeSShreyansh Jain sg_temp->opaque = 0; 8538cffdcbeSShreyansh Jain sg_temp->val = 0; 854455da545SSantosh Shukla sg_temp->addr = cur_seg->buf_iova; 8558cffdcbeSShreyansh Jain sg_temp->offset = cur_seg->data_off; 8568cffdcbeSShreyansh Jain sg_temp->length = cur_seg->data_len; 8578cffdcbeSShreyansh Jain if (RTE_MBUF_DIRECT(cur_seg)) { 8588cffdcbeSShreyansh Jain if (rte_mbuf_refcnt_read(cur_seg) > 1) { 8598cffdcbeSShreyansh Jain /*If refcnt > 1, invalid bpid is set to ensure 8608cffdcbeSShreyansh Jain * buffer is not freed by HW. 8618cffdcbeSShreyansh Jain */ 8628cffdcbeSShreyansh Jain sg_temp->bpid = 0xff; 8638cffdcbeSShreyansh Jain rte_mbuf_refcnt_update(cur_seg, -1); 8648cffdcbeSShreyansh Jain } else { 8658cffdcbeSShreyansh Jain sg_temp->bpid = 8668cffdcbeSShreyansh Jain DPAA_MEMPOOL_TO_BPID(cur_seg->pool); 8678cffdcbeSShreyansh Jain } 868f191d5abSHemant Agrawal } else if (RTE_MBUF_HAS_EXTBUF(cur_seg)) { 8698716c0ecSGagandeep Singh free_buf[*free_count].seg = cur_seg; 8708716c0ecSGagandeep Singh free_buf[*free_count].pkt_id = pkt_id; 8718716c0ecSGagandeep Singh ++*free_count; 872f191d5abSHemant Agrawal sg_temp->bpid = 0xff; 8738cffdcbeSShreyansh Jain } else { 8748cffdcbeSShreyansh Jain /* Get owner MBUF from indirect buffer */ 8758cffdcbeSShreyansh Jain mi = rte_mbuf_from_indirect(cur_seg); 8768cffdcbeSShreyansh Jain if (rte_mbuf_refcnt_read(mi) > 1) { 8778cffdcbeSShreyansh Jain /*If refcnt > 1, invalid bpid is set to ensure 8788cffdcbeSShreyansh Jain * owner buffer is not freed by HW. 8798cffdcbeSShreyansh Jain */ 8808cffdcbeSShreyansh Jain sg_temp->bpid = 0xff; 8818cffdcbeSShreyansh Jain } else { 8828cffdcbeSShreyansh Jain sg_temp->bpid = DPAA_MEMPOOL_TO_BPID(mi->pool); 8838cffdcbeSShreyansh Jain rte_mbuf_refcnt_update(mi, 1); 8848cffdcbeSShreyansh Jain } 8858716c0ecSGagandeep Singh free_buf[*free_count].seg = cur_seg; 8868716c0ecSGagandeep Singh free_buf[*free_count].pkt_id = pkt_id; 8878716c0ecSGagandeep Singh ++*free_count; 8888cffdcbeSShreyansh Jain } 8898716c0ecSGagandeep Singh cur_seg = cur_seg->next; 8908cffdcbeSShreyansh Jain if (cur_seg == NULL) { 8918cffdcbeSShreyansh Jain sg_temp->final = 1; 8928cffdcbeSShreyansh Jain cpu_to_hw_sg(sg_temp); 8938cffdcbeSShreyansh Jain break; 8948cffdcbeSShreyansh Jain } 8958cffdcbeSShreyansh Jain cpu_to_hw_sg(sg_temp); 8968cffdcbeSShreyansh Jain } 8978cffdcbeSShreyansh Jain return 0; 8988cffdcbeSShreyansh Jain } 8998cffdcbeSShreyansh Jain 90037f9b54bSShreyansh Jain /* Handle mbufs which are not segmented (non SG) */ 90137f9b54bSShreyansh Jain static inline void 90237f9b54bSShreyansh Jain tx_on_dpaa_pool_unsegmented(struct rte_mbuf *mbuf, 90337f9b54bSShreyansh Jain struct dpaa_bp_info *bp_info, 9048716c0ecSGagandeep Singh struct qm_fd *fd_arr, 9058716c0ecSGagandeep Singh struct dpaa_sw_buf_free *buf_to_free, 9068716c0ecSGagandeep Singh uint32_t *free_count, 9078716c0ecSGagandeep Singh uint32_t pkt_id) 90837f9b54bSShreyansh Jain { 90937f9b54bSShreyansh Jain struct rte_mbuf *mi = NULL; 91037f9b54bSShreyansh Jain 91137f9b54bSShreyansh Jain if (RTE_MBUF_DIRECT(mbuf)) { 91237f9b54bSShreyansh Jain if (rte_mbuf_refcnt_read(mbuf) > 1) { 91337f9b54bSShreyansh Jain /* In case of direct mbuf and mbuf being cloned, 91437f9b54bSShreyansh Jain * BMAN should _not_ release buffer. 91537f9b54bSShreyansh Jain */ 91637f9b54bSShreyansh Jain DPAA_MBUF_TO_CONTIG_FD(mbuf, fd_arr, 0xff); 91737f9b54bSShreyansh Jain /* Buffer should be releasd by EAL */ 91837f9b54bSShreyansh Jain rte_mbuf_refcnt_update(mbuf, -1); 91937f9b54bSShreyansh Jain } else { 92037f9b54bSShreyansh Jain /* In case of direct mbuf and no cloning, mbuf can be 92137f9b54bSShreyansh Jain * released by BMAN. 92237f9b54bSShreyansh Jain */ 92337f9b54bSShreyansh Jain DPAA_MBUF_TO_CONTIG_FD(mbuf, fd_arr, bp_info->bpid); 92437f9b54bSShreyansh Jain } 925f191d5abSHemant Agrawal } else if (RTE_MBUF_HAS_EXTBUF(mbuf)) { 9268716c0ecSGagandeep Singh buf_to_free[*free_count].seg = mbuf; 9278716c0ecSGagandeep Singh buf_to_free[*free_count].pkt_id = pkt_id; 9288716c0ecSGagandeep Singh ++*free_count; 929f191d5abSHemant Agrawal DPAA_MBUF_TO_CONTIG_FD(mbuf, fd_arr, 930f191d5abSHemant Agrawal bp_info ? bp_info->bpid : 0xff); 93137f9b54bSShreyansh Jain } else { 93237f9b54bSShreyansh Jain /* This is data-containing core mbuf: 'mi' */ 93337f9b54bSShreyansh Jain mi = rte_mbuf_from_indirect(mbuf); 93437f9b54bSShreyansh Jain if (rte_mbuf_refcnt_read(mi) > 1) { 93537f9b54bSShreyansh Jain /* In case of indirect mbuf, and mbuf being cloned, 93637f9b54bSShreyansh Jain * BMAN should _not_ release it and let EAL release 93737f9b54bSShreyansh Jain * it through pktmbuf_free below. 93837f9b54bSShreyansh Jain */ 93937f9b54bSShreyansh Jain DPAA_MBUF_TO_CONTIG_FD(mbuf, fd_arr, 0xff); 94037f9b54bSShreyansh Jain } else { 94137f9b54bSShreyansh Jain /* In case of indirect mbuf, and no cloning, core mbuf 94237f9b54bSShreyansh Jain * should be released by BMAN. 94337f9b54bSShreyansh Jain * Increate refcnt of core mbuf so that when 94437f9b54bSShreyansh Jain * pktmbuf_free is called and mbuf is released, EAL 94537f9b54bSShreyansh Jain * doesn't try to release core mbuf which would have 94637f9b54bSShreyansh Jain * been released by BMAN. 94737f9b54bSShreyansh Jain */ 94837f9b54bSShreyansh Jain rte_mbuf_refcnt_update(mi, 1); 949f191d5abSHemant Agrawal DPAA_MBUF_TO_CONTIG_FD(mbuf, fd_arr, 950f191d5abSHemant Agrawal bp_info ? bp_info->bpid : 0xff); 95137f9b54bSShreyansh Jain } 9528716c0ecSGagandeep Singh buf_to_free[*free_count].seg = mbuf; 9538716c0ecSGagandeep Singh buf_to_free[*free_count].pkt_id = pkt_id; 9548716c0ecSGagandeep Singh ++*free_count; 95537f9b54bSShreyansh Jain } 9565a8cf1beSShreyansh Jain 9575e0789e9SNipun Gupta if (mbuf->ol_flags & DPAA_TX_CKSUM_OFFLOAD_MASK) 9585e0789e9SNipun Gupta dpaa_unsegmented_checksum(mbuf, fd_arr); 95937f9b54bSShreyansh Jain } 96037f9b54bSShreyansh Jain 96137f9b54bSShreyansh Jain /* Handle all mbufs on dpaa BMAN managed pool */ 96237f9b54bSShreyansh Jain static inline uint16_t 96337f9b54bSShreyansh Jain tx_on_dpaa_pool(struct rte_mbuf *mbuf, 96437f9b54bSShreyansh Jain struct dpaa_bp_info *bp_info, 9658716c0ecSGagandeep Singh struct qm_fd *fd_arr, 9668716c0ecSGagandeep Singh struct dpaa_sw_buf_free *buf_to_free, 9678716c0ecSGagandeep Singh uint32_t *free_count, 9688716c0ecSGagandeep Singh uint32_t pkt_id) 96937f9b54bSShreyansh Jain { 97037f9b54bSShreyansh Jain DPAA_DP_LOG(DEBUG, "BMAN offloaded buffer, mbuf: %p", mbuf); 97137f9b54bSShreyansh Jain 97237f9b54bSShreyansh Jain if (mbuf->nb_segs == 1) { 97337f9b54bSShreyansh Jain /* Case for non-segmented buffers */ 9748716c0ecSGagandeep Singh tx_on_dpaa_pool_unsegmented(mbuf, bp_info, fd_arr, 9758716c0ecSGagandeep Singh buf_to_free, free_count, pkt_id); 9768cffdcbeSShreyansh Jain } else if (mbuf->nb_segs > 1 && 9778cffdcbeSShreyansh Jain mbuf->nb_segs <= DPAA_SGT_MAX_ENTRIES) { 9788716c0ecSGagandeep Singh if (dpaa_eth_mbuf_to_sg_fd(mbuf, fd_arr, buf_to_free, 9798716c0ecSGagandeep Singh free_count, pkt_id)) { 9808cffdcbeSShreyansh Jain DPAA_PMD_DEBUG("Unable to create Scatter Gather FD"); 9818cffdcbeSShreyansh Jain return 1; 9828cffdcbeSShreyansh Jain } 98337f9b54bSShreyansh Jain } else { 98437f9b54bSShreyansh Jain DPAA_PMD_DEBUG("Number of Segments not supported"); 98537f9b54bSShreyansh Jain return 1; 98637f9b54bSShreyansh Jain } 98737f9b54bSShreyansh Jain 98837f9b54bSShreyansh Jain return 0; 98937f9b54bSShreyansh Jain } 99037f9b54bSShreyansh Jain 99137f9b54bSShreyansh Jain /* Handle all mbufs on an external pool (non-dpaa) */ 992f8c7a17aSNipun Gupta static inline struct rte_mbuf * 993f8c7a17aSNipun Gupta reallocate_mbuf(struct qman_fq *txq, struct rte_mbuf *mbuf) 99437f9b54bSShreyansh Jain { 99537f9b54bSShreyansh Jain struct dpaa_if *dpaa_intf = txq->dpaa_intf; 996f8c7a17aSNipun Gupta struct dpaa_bp_info *bp_info = dpaa_intf->bp_info; 997f8c7a17aSNipun Gupta struct rte_mbuf *new_mbufs[DPAA_SGT_MAX_ENTRIES + 1] = {0}; 998f8c7a17aSNipun Gupta struct rte_mbuf *temp_mbuf; 999f8c7a17aSNipun Gupta int num_new_segs, mbuf_greater, ret, extra_seg = 0, i = 0; 1000f8c7a17aSNipun Gupta uint64_t mbufs_size, bytes_to_copy, offset1 = 0, offset2 = 0; 1001f8c7a17aSNipun Gupta char *data; 100237f9b54bSShreyansh Jain 1003f8c7a17aSNipun Gupta DPAA_DP_LOG(DEBUG, "Reallocating transmit buffer"); 1004f8c7a17aSNipun Gupta 1005f8c7a17aSNipun Gupta mbufs_size = bp_info->size - 1006f8c7a17aSNipun Gupta bp_info->meta_data_size - RTE_PKTMBUF_HEADROOM; 1007f8c7a17aSNipun Gupta extra_seg = !!(mbuf->pkt_len % mbufs_size); 1008f8c7a17aSNipun Gupta num_new_segs = (mbuf->pkt_len / mbufs_size) + extra_seg; 1009f8c7a17aSNipun Gupta 1010f8c7a17aSNipun Gupta ret = rte_pktmbuf_alloc_bulk(bp_info->mp, new_mbufs, num_new_segs); 1011f8c7a17aSNipun Gupta if (ret != 0) { 1012f8c7a17aSNipun Gupta DPAA_DP_LOG(DEBUG, "Allocation for new buffers failed"); 1013f8c7a17aSNipun Gupta return NULL; 101437f9b54bSShreyansh Jain } 101537f9b54bSShreyansh Jain 1016f8c7a17aSNipun Gupta temp_mbuf = mbuf; 101737f9b54bSShreyansh Jain 1018f8c7a17aSNipun Gupta while (temp_mbuf) { 1019f8c7a17aSNipun Gupta /* If mbuf data is less than new mbuf remaining memory */ 1020f8c7a17aSNipun Gupta if ((temp_mbuf->data_len - offset1) < (mbufs_size - offset2)) { 1021f8c7a17aSNipun Gupta bytes_to_copy = temp_mbuf->data_len - offset1; 1022f8c7a17aSNipun Gupta mbuf_greater = -1; 1023f8c7a17aSNipun Gupta /* If mbuf data is greater than new mbuf remaining memory */ 1024f8c7a17aSNipun Gupta } else if ((temp_mbuf->data_len - offset1) > 1025f8c7a17aSNipun Gupta (mbufs_size - offset2)) { 1026f8c7a17aSNipun Gupta bytes_to_copy = mbufs_size - offset2; 1027f8c7a17aSNipun Gupta mbuf_greater = 1; 1028f8c7a17aSNipun Gupta /* if mbuf data is equal to new mbuf remaining memory */ 1029f8c7a17aSNipun Gupta } else { 1030f8c7a17aSNipun Gupta bytes_to_copy = temp_mbuf->data_len - offset1; 1031f8c7a17aSNipun Gupta mbuf_greater = 0; 1032f8c7a17aSNipun Gupta } 1033f8c7a17aSNipun Gupta 1034f8c7a17aSNipun Gupta /* Copy the data */ 1035f8c7a17aSNipun Gupta data = rte_pktmbuf_append(new_mbufs[0], bytes_to_copy); 1036f8c7a17aSNipun Gupta 1037f8c7a17aSNipun Gupta rte_memcpy((uint8_t *)data, rte_pktmbuf_mtod_offset(mbuf, 1038f8c7a17aSNipun Gupta void *, offset1), bytes_to_copy); 1039f8c7a17aSNipun Gupta 1040f8c7a17aSNipun Gupta /* Set new offsets and the temp buffers */ 1041f8c7a17aSNipun Gupta if (mbuf_greater == -1) { 1042f8c7a17aSNipun Gupta offset1 = 0; 1043f8c7a17aSNipun Gupta offset2 += bytes_to_copy; 1044f8c7a17aSNipun Gupta temp_mbuf = temp_mbuf->next; 1045f8c7a17aSNipun Gupta } else if (mbuf_greater == 1) { 1046f8c7a17aSNipun Gupta offset2 = 0; 1047f8c7a17aSNipun Gupta offset1 += bytes_to_copy; 1048f8c7a17aSNipun Gupta new_mbufs[i]->next = new_mbufs[i + 1]; 1049f8c7a17aSNipun Gupta new_mbufs[0]->nb_segs++; 1050f8c7a17aSNipun Gupta i++; 1051f8c7a17aSNipun Gupta } else { 1052f8c7a17aSNipun Gupta offset1 = 0; 1053f8c7a17aSNipun Gupta offset2 = 0; 1054f8c7a17aSNipun Gupta temp_mbuf = temp_mbuf->next; 1055f8c7a17aSNipun Gupta new_mbufs[i]->next = new_mbufs[i + 1]; 1056f8c7a17aSNipun Gupta if (new_mbufs[i + 1]) 1057f8c7a17aSNipun Gupta new_mbufs[0]->nb_segs++; 1058f8c7a17aSNipun Gupta i++; 1059f8c7a17aSNipun Gupta } 1060f8c7a17aSNipun Gupta } 1061f8c7a17aSNipun Gupta 1062f8c7a17aSNipun Gupta /* Copy other required fields */ 1063f8c7a17aSNipun Gupta new_mbufs[0]->ol_flags = mbuf->ol_flags; 1064f8c7a17aSNipun Gupta new_mbufs[0]->packet_type = mbuf->packet_type; 1065f8c7a17aSNipun Gupta new_mbufs[0]->tx_offload = mbuf->tx_offload; 1066f8c7a17aSNipun Gupta 1067f8c7a17aSNipun Gupta rte_pktmbuf_free(mbuf); 1068f8c7a17aSNipun Gupta 1069f8c7a17aSNipun Gupta return new_mbufs[0]; 107037f9b54bSShreyansh Jain } 107137f9b54bSShreyansh Jain 107237f9b54bSShreyansh Jain uint16_t 107337f9b54bSShreyansh Jain dpaa_eth_queue_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) 107437f9b54bSShreyansh Jain { 107537f9b54bSShreyansh Jain struct rte_mbuf *mbuf, *mi = NULL; 107637f9b54bSShreyansh Jain struct rte_mempool *mp; 107737f9b54bSShreyansh Jain struct dpaa_bp_info *bp_info; 1078b0a87fe2SNipun Gupta struct qm_fd fd_arr[DPAA_TX_BURST_SIZE]; 10795e0789e9SNipun Gupta uint32_t frames_to_send, loop, sent = 0; 108037f9b54bSShreyansh Jain uint16_t state; 1081f8c7a17aSNipun Gupta int ret, realloc_mbuf = 0; 10825e745593SSunil Kumar Kori uint32_t seqn, index, flags[DPAA_TX_BURST_SIZE] = {0}; 10838716c0ecSGagandeep Singh struct dpaa_sw_buf_free buf_to_free[DPAA_MAX_SGS * DPAA_MAX_DEQUEUE_NUM_FRAMES]; 10848716c0ecSGagandeep Singh uint32_t free_count = 0; 108537f9b54bSShreyansh Jain 1086e5872221SRohit Raj if (unlikely(!DPAA_PER_LCORE_PORTAL)) { 108737f9b54bSShreyansh Jain ret = rte_dpaa_portal_init((void *)0); 108837f9b54bSShreyansh Jain if (ret) { 108937f9b54bSShreyansh Jain DPAA_PMD_ERR("Failure in affining portal"); 109037f9b54bSShreyansh Jain return 0; 109137f9b54bSShreyansh Jain } 10925d944582SNipun Gupta } 109337f9b54bSShreyansh Jain 109437f9b54bSShreyansh Jain DPAA_DP_LOG(DEBUG, "Transmitting %d buffers on queue: %p", nb_bufs, q); 109537f9b54bSShreyansh Jain 109637f9b54bSShreyansh Jain while (nb_bufs) { 1097b0a87fe2SNipun Gupta frames_to_send = (nb_bufs > DPAA_TX_BURST_SIZE) ? 1098b0a87fe2SNipun Gupta DPAA_TX_BURST_SIZE : nb_bufs; 10995e0789e9SNipun Gupta for (loop = 0; loop < frames_to_send; loop++) { 11005e0789e9SNipun Gupta mbuf = *(bufs++); 1101f8c7a17aSNipun Gupta /* In case the data offset is not multiple of 16, 1102f8c7a17aSNipun Gupta * FMAN can stall because of an errata. So reallocate 1103f8c7a17aSNipun Gupta * the buffer in such case. 1104f8c7a17aSNipun Gupta */ 1105f8c7a17aSNipun Gupta if (dpaa_svr_family == SVR_LS1043A_FAMILY && 110659267d7bSNipun Gupta (mbuf->data_off & 0x7F) != 0x0) 1107f8c7a17aSNipun Gupta realloc_mbuf = 1; 1108c9a1c2e5SDavid Marchand seqn = *dpaa_seqn(mbuf); 11099afce5aaSSunil Kumar Kori if (seqn != DPAA_INVALID_MBUF_SEQN) { 11109afce5aaSSunil Kumar Kori index = seqn - 1; 11119afce5aaSSunil Kumar Kori if (DPAA_PER_LCORE_DQRR_HELD & (1 << index)) { 11129afce5aaSSunil Kumar Kori flags[loop] = 11139afce5aaSSunil Kumar Kori ((index & QM_EQCR_DCA_IDXMASK) << 8); 11149afce5aaSSunil Kumar Kori flags[loop] |= QMAN_ENQUEUE_FLAG_DCA; 11159afce5aaSSunil Kumar Kori DPAA_PER_LCORE_DQRR_SIZE--; 11169afce5aaSSunil Kumar Kori DPAA_PER_LCORE_DQRR_HELD &= 11179afce5aaSSunil Kumar Kori ~(1 << index); 11189afce5aaSSunil Kumar Kori } 11199afce5aaSSunil Kumar Kori } 11209afce5aaSSunil Kumar Kori 11215e0789e9SNipun Gupta if (likely(RTE_MBUF_DIRECT(mbuf))) { 112237f9b54bSShreyansh Jain mp = mbuf->pool; 11235e0789e9SNipun Gupta bp_info = DPAA_MEMPOOL_TO_POOL_INFO(mp); 11245e0789e9SNipun Gupta if (likely(mp->ops_index == 11255e0789e9SNipun Gupta bp_info->dpaa_ops_index && 11265e0789e9SNipun Gupta mbuf->nb_segs == 1 && 1127f8c7a17aSNipun Gupta realloc_mbuf == 0 && 11285e0789e9SNipun Gupta rte_mbuf_refcnt_read(mbuf) == 1)) { 11295e0789e9SNipun Gupta DPAA_MBUF_TO_CONTIG_FD(mbuf, 11305e0789e9SNipun Gupta &fd_arr[loop], bp_info->bpid); 11315e0789e9SNipun Gupta if (mbuf->ol_flags & 11325e0789e9SNipun Gupta DPAA_TX_CKSUM_OFFLOAD_MASK) 11335e0789e9SNipun Gupta dpaa_unsegmented_checksum(mbuf, 11345e0789e9SNipun Gupta &fd_arr[loop]); 11355e0789e9SNipun Gupta continue; 11365e0789e9SNipun Gupta } 113737f9b54bSShreyansh Jain } else { 113837f9b54bSShreyansh Jain mi = rte_mbuf_from_indirect(mbuf); 113937f9b54bSShreyansh Jain mp = mi->pool; 114037f9b54bSShreyansh Jain } 114137f9b54bSShreyansh Jain 1142f191d5abSHemant Agrawal if (unlikely(RTE_MBUF_HAS_EXTBUF(mbuf))) { 1143f191d5abSHemant Agrawal bp_info = NULL; 1144f191d5abSHemant Agrawal goto indirect_buf; 1145f191d5abSHemant Agrawal } 1146f191d5abSHemant Agrawal 114737f9b54bSShreyansh Jain bp_info = DPAA_MEMPOOL_TO_POOL_INFO(mp); 1148f8c7a17aSNipun Gupta if (unlikely(mp->ops_index != bp_info->dpaa_ops_index || 1149f8c7a17aSNipun Gupta realloc_mbuf == 1)) { 1150f8c7a17aSNipun Gupta struct rte_mbuf *temp_mbuf; 1151f8c7a17aSNipun Gupta 1152f8c7a17aSNipun Gupta temp_mbuf = reallocate_mbuf(q, mbuf); 1153f8c7a17aSNipun Gupta if (!temp_mbuf) { 1154f8c7a17aSNipun Gupta /* Set frames_to_send & nb_bufs so 1155f8c7a17aSNipun Gupta * that packets are transmitted till 1156f8c7a17aSNipun Gupta * previous frame. 1157f8c7a17aSNipun Gupta */ 1158f8c7a17aSNipun Gupta frames_to_send = loop; 1159f8c7a17aSNipun Gupta nb_bufs = loop; 1160f8c7a17aSNipun Gupta goto send_pkts; 1161f8c7a17aSNipun Gupta } 1162f8c7a17aSNipun Gupta mbuf = temp_mbuf; 1163f8c7a17aSNipun Gupta realloc_mbuf = 0; 1164f8c7a17aSNipun Gupta } 1165f191d5abSHemant Agrawal indirect_buf: 116637f9b54bSShreyansh Jain state = tx_on_dpaa_pool(mbuf, bp_info, 11678716c0ecSGagandeep Singh &fd_arr[loop], 11688716c0ecSGagandeep Singh buf_to_free, 11698716c0ecSGagandeep Singh &free_count, 11708716c0ecSGagandeep Singh loop); 117137f9b54bSShreyansh Jain if (unlikely(state)) { 117237f9b54bSShreyansh Jain /* Set frames_to_send & nb_bufs so 117337f9b54bSShreyansh Jain * that packets are transmitted till 117437f9b54bSShreyansh Jain * previous frame. 117537f9b54bSShreyansh Jain */ 117637f9b54bSShreyansh Jain frames_to_send = loop; 117737f9b54bSShreyansh Jain nb_bufs = loop; 117837f9b54bSShreyansh Jain goto send_pkts; 117937f9b54bSShreyansh Jain } 118037f9b54bSShreyansh Jain } 118137f9b54bSShreyansh Jain 118237f9b54bSShreyansh Jain send_pkts: 118337f9b54bSShreyansh Jain loop = 0; 118437f9b54bSShreyansh Jain while (loop < frames_to_send) { 118537f9b54bSShreyansh Jain loop += qman_enqueue_multi(q, &fd_arr[loop], 11865e745593SSunil Kumar Kori &flags[loop], 118737f9b54bSShreyansh Jain frames_to_send - loop); 118837f9b54bSShreyansh Jain } 118937f9b54bSShreyansh Jain nb_bufs -= frames_to_send; 11905e0789e9SNipun Gupta sent += frames_to_send; 119137f9b54bSShreyansh Jain } 119237f9b54bSShreyansh Jain 11935e0789e9SNipun Gupta DPAA_DP_LOG(DEBUG, "Transmitted %d buffers on queue: %p", sent, q); 119437f9b54bSShreyansh Jain 11958716c0ecSGagandeep Singh for (loop = 0; loop < free_count; loop++) { 11968716c0ecSGagandeep Singh if (buf_to_free[loop].pkt_id < sent) 11978716c0ecSGagandeep Singh rte_pktmbuf_free_seg(buf_to_free[loop].seg); 1198f191d5abSHemant Agrawal } 1199f191d5abSHemant Agrawal 12005e0789e9SNipun Gupta return sent; 120137f9b54bSShreyansh Jain } 120237f9b54bSShreyansh Jain 12039124e65dSGagandeep Singh uint16_t 12049124e65dSGagandeep Singh dpaa_eth_queue_tx_slow(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) 12059124e65dSGagandeep Singh { 12069124e65dSGagandeep Singh qman_ern_poll_free(); 12079124e65dSGagandeep Singh 12089124e65dSGagandeep Singh return dpaa_eth_queue_tx(q, bufs, nb_bufs); 12099124e65dSGagandeep Singh } 12109124e65dSGagandeep Singh 121137f9b54bSShreyansh Jain uint16_t dpaa_eth_tx_drop_all(void *q __rte_unused, 121237f9b54bSShreyansh Jain struct rte_mbuf **bufs __rte_unused, 121337f9b54bSShreyansh Jain uint16_t nb_bufs __rte_unused) 121437f9b54bSShreyansh Jain { 121537f9b54bSShreyansh Jain DPAA_DP_LOG(DEBUG, "Drop all packets"); 121637f9b54bSShreyansh Jain 121737f9b54bSShreyansh Jain /* Drop all incoming packets. No need to free packets here 121837f9b54bSShreyansh Jain * because the rte_eth f/w frees up the packets through tx_buffer 121937f9b54bSShreyansh Jain * callback in case this functions returns count less than nb_bufs 122037f9b54bSShreyansh Jain */ 122137f9b54bSShreyansh Jain return 0; 122237f9b54bSShreyansh Jain } 1223