xref: /dpdk/examples/ipsec-secgw/ipsec_neon.h (revision 58e2cf4cf75b54f89c0cde772fe0edfc830ce8e2)
16eb3ba03SRahul Bhansali /* SPDX-License-Identifier: BSD-3-Clause
26eb3ba03SRahul Bhansali  * Copyright(C) 2022 Marvell.
36eb3ba03SRahul Bhansali  */
46eb3ba03SRahul Bhansali 
56eb3ba03SRahul Bhansali #ifndef IPSEC_NEON_H
66eb3ba03SRahul Bhansali #define IPSEC_NEON_H
76eb3ba03SRahul Bhansali 
86eb3ba03SRahul Bhansali #include "ipsec.h"
96eb3ba03SRahul Bhansali #include "neon/port_group.h"
106eb3ba03SRahul Bhansali 
116eb3ba03SRahul Bhansali #define MAX_TX_BURST	(MAX_PKT_BURST / 2)
126eb3ba03SRahul Bhansali 
136eb3ba03SRahul Bhansali extern xmm_t val_eth[RTE_MAX_ETHPORTS];
146eb3ba03SRahul Bhansali 
156eb3ba03SRahul Bhansali /*
166eb3ba03SRahul Bhansali  * Update source and destination MAC addresses in the ethernet header.
176eb3ba03SRahul Bhansali  */
186eb3ba03SRahul Bhansali static inline void
processx4_step3(struct rte_mbuf * pkts[FWDSTEP],uint16_t dst_port[FWDSTEP],uint64_t tx_offloads,bool ip_cksum,bool is_ipv4,uint8_t * l_pkt)196eb3ba03SRahul Bhansali processx4_step3(struct rte_mbuf *pkts[FWDSTEP], uint16_t dst_port[FWDSTEP],
20*58e2cf4cSNithin Dabilpuram 		uint64_t tx_offloads, bool ip_cksum, bool is_ipv4, uint8_t *l_pkt)
216eb3ba03SRahul Bhansali {
226eb3ba03SRahul Bhansali 	uint32x4_t te[FWDSTEP];
236eb3ba03SRahul Bhansali 	uint32x4_t ve[FWDSTEP];
246eb3ba03SRahul Bhansali 	uint32_t *p[FWDSTEP];
256eb3ba03SRahul Bhansali 	struct rte_mbuf *pkt;
26*58e2cf4cSNithin Dabilpuram 	uint32_t val;
276eb3ba03SRahul Bhansali 	uint8_t i;
286eb3ba03SRahul Bhansali 
296eb3ba03SRahul Bhansali 	for (i = 0; i < FWDSTEP; i++) {
306eb3ba03SRahul Bhansali 		pkt = pkts[i];
316eb3ba03SRahul Bhansali 
326eb3ba03SRahul Bhansali 		/* Check if it is a large packet */
336eb3ba03SRahul Bhansali 		if (pkt->pkt_len - RTE_ETHER_HDR_LEN > mtu_size)
346eb3ba03SRahul Bhansali 			*l_pkt |= 1;
356eb3ba03SRahul Bhansali 
366eb3ba03SRahul Bhansali 		p[i] = rte_pktmbuf_mtod(pkt, uint32_t *);
376eb3ba03SRahul Bhansali 		ve[i] = vreinterpretq_u32_s32(val_eth[dst_port[i]]);
386eb3ba03SRahul Bhansali 		te[i] = vld1q_u32(p[i]);
396eb3ba03SRahul Bhansali 
406eb3ba03SRahul Bhansali 		/* Update last 4 bytes */
41*58e2cf4cSNithin Dabilpuram 		val = vgetq_lane_u32(te[i], 3);
42*58e2cf4cSNithin Dabilpuram #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
43*58e2cf4cSNithin Dabilpuram 		val &= 0xFFFFUL << 16;
44*58e2cf4cSNithin Dabilpuram 		val |= rte_cpu_to_be_16(is_ipv4 ? RTE_ETHER_TYPE_IPV4 : RTE_ETHER_TYPE_IPV6);
45*58e2cf4cSNithin Dabilpuram #else
46*58e2cf4cSNithin Dabilpuram 		val &= 0xFFFFUL;
47*58e2cf4cSNithin Dabilpuram 		val |= rte_cpu_to_be_16(is_ipv4 ? RTE_ETHER_TYPE_IPV4 : RTE_ETHER_TYPE_IPV6) << 16;
48*58e2cf4cSNithin Dabilpuram #endif
49*58e2cf4cSNithin Dabilpuram 		ve[i] = vsetq_lane_u32(val, ve[i], 3);
506eb3ba03SRahul Bhansali 		vst1q_u32(p[i], ve[i]);
516eb3ba03SRahul Bhansali 
526eb3ba03SRahul Bhansali 		if (ip_cksum) {
536eb3ba03SRahul Bhansali 			struct rte_ipv4_hdr *ip;
546eb3ba03SRahul Bhansali 
556eb3ba03SRahul Bhansali 			pkt->ol_flags |= tx_offloads;
566eb3ba03SRahul Bhansali 
576eb3ba03SRahul Bhansali 			ip = (struct rte_ipv4_hdr *)
5879c322caSNithin Dabilpuram 				(((uintptr_t)p[i]) + RTE_ETHER_HDR_LEN);
596eb3ba03SRahul Bhansali 			ip->hdr_checksum = 0;
606eb3ba03SRahul Bhansali 
616eb3ba03SRahul Bhansali 			/* calculate IPv4 cksum in SW */
626eb3ba03SRahul Bhansali 			if ((pkt->ol_flags & RTE_MBUF_F_TX_IP_CKSUM) == 0)
636eb3ba03SRahul Bhansali 				ip->hdr_checksum = rte_ipv4_cksum(ip);
646eb3ba03SRahul Bhansali 		}
656eb3ba03SRahul Bhansali 
666eb3ba03SRahul Bhansali 	}
676eb3ba03SRahul Bhansali }
686eb3ba03SRahul Bhansali 
696eb3ba03SRahul Bhansali /**
706eb3ba03SRahul Bhansali  * Process single packet:
716eb3ba03SRahul Bhansali  * Update source and destination MAC addresses in the ethernet header.
726eb3ba03SRahul Bhansali  */
736eb3ba03SRahul Bhansali static inline void
process_packet(struct rte_mbuf * pkt,uint16_t * dst_port,uint64_t tx_offloads,bool ip_cksum,bool is_ipv4,uint8_t * l_pkt)746eb3ba03SRahul Bhansali process_packet(struct rte_mbuf *pkt, uint16_t *dst_port, uint64_t tx_offloads,
75*58e2cf4cSNithin Dabilpuram 	       bool ip_cksum, bool is_ipv4, uint8_t *l_pkt)
766eb3ba03SRahul Bhansali {
776eb3ba03SRahul Bhansali 	struct rte_ether_hdr *eth_hdr;
786eb3ba03SRahul Bhansali 	uint32x4_t te, ve;
79*58e2cf4cSNithin Dabilpuram 	uint32_t val;
806eb3ba03SRahul Bhansali 
816eb3ba03SRahul Bhansali 	/* Check if it is a large packet */
826eb3ba03SRahul Bhansali 	if (pkt->pkt_len - RTE_ETHER_HDR_LEN > mtu_size)
836eb3ba03SRahul Bhansali 		*l_pkt |= 1;
846eb3ba03SRahul Bhansali 
856eb3ba03SRahul Bhansali 	eth_hdr = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
866eb3ba03SRahul Bhansali 
876eb3ba03SRahul Bhansali 	te = vld1q_u32((uint32_t *)eth_hdr);
886eb3ba03SRahul Bhansali 	ve = vreinterpretq_u32_s32(val_eth[dst_port[0]]);
896eb3ba03SRahul Bhansali 
90*58e2cf4cSNithin Dabilpuram 	val = vgetq_lane_u32(te, 3);
91*58e2cf4cSNithin Dabilpuram #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
92*58e2cf4cSNithin Dabilpuram 	val &= 0xFFFFUL << 16;
93*58e2cf4cSNithin Dabilpuram 	val |= rte_cpu_to_be_16(is_ipv4 ? RTE_ETHER_TYPE_IPV4 : RTE_ETHER_TYPE_IPV6);
94*58e2cf4cSNithin Dabilpuram #else
95*58e2cf4cSNithin Dabilpuram 	val &= 0xFFFFUL;
96*58e2cf4cSNithin Dabilpuram 	val |= rte_cpu_to_be_16(is_ipv4 ? RTE_ETHER_TYPE_IPV4 : RTE_ETHER_TYPE_IPV6) << 16;
97*58e2cf4cSNithin Dabilpuram #endif
98*58e2cf4cSNithin Dabilpuram 	ve = vsetq_lane_u32(val, ve, 3);
996eb3ba03SRahul Bhansali 	vst1q_u32((uint32_t *)eth_hdr, ve);
1006eb3ba03SRahul Bhansali 
1016eb3ba03SRahul Bhansali 	if (ip_cksum) {
1026eb3ba03SRahul Bhansali 		struct rte_ipv4_hdr *ip;
1036eb3ba03SRahul Bhansali 
1046eb3ba03SRahul Bhansali 		pkt->ol_flags |= tx_offloads;
1056eb3ba03SRahul Bhansali 
1066eb3ba03SRahul Bhansali 		ip = (struct rte_ipv4_hdr *)(eth_hdr + 1);
1076eb3ba03SRahul Bhansali 		ip->hdr_checksum = 0;
1086eb3ba03SRahul Bhansali 
1096eb3ba03SRahul Bhansali 		/* calculate IPv4 cksum in SW */
1106eb3ba03SRahul Bhansali 		if ((pkt->ol_flags & RTE_MBUF_F_TX_IP_CKSUM) == 0)
1116eb3ba03SRahul Bhansali 			ip->hdr_checksum = rte_ipv4_cksum(ip);
1126eb3ba03SRahul Bhansali 	}
1136eb3ba03SRahul Bhansali }
1146eb3ba03SRahul Bhansali 
1156eb3ba03SRahul Bhansali static inline void
send_packets(struct rte_mbuf * m[],uint16_t port,uint32_t num,bool is_ipv4)1166eb3ba03SRahul Bhansali send_packets(struct rte_mbuf *m[], uint16_t port, uint32_t num, bool is_ipv4)
1176eb3ba03SRahul Bhansali {
1186eb3ba03SRahul Bhansali 	uint8_t proto;
1196eb3ba03SRahul Bhansali 	uint32_t i;
1206eb3ba03SRahul Bhansali 
1216eb3ba03SRahul Bhansali 	proto = is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6;
1226eb3ba03SRahul Bhansali 	for (i = 0; i < num; i++)
1236eb3ba03SRahul Bhansali 		send_single_packet(m[i], port, proto);
1246eb3ba03SRahul Bhansali }
1256eb3ba03SRahul Bhansali 
1266eb3ba03SRahul Bhansali static inline void
send_packetsx4(struct rte_mbuf * m[],uint16_t port,uint32_t num)1276eb3ba03SRahul Bhansali send_packetsx4(struct rte_mbuf *m[], uint16_t port, uint32_t num)
1286eb3ba03SRahul Bhansali {
1296eb3ba03SRahul Bhansali 	unsigned int lcoreid = rte_lcore_id();
1306eb3ba03SRahul Bhansali 	struct lcore_conf *qconf;
1316eb3ba03SRahul Bhansali 	uint32_t len, j, n;
1326eb3ba03SRahul Bhansali 
1336eb3ba03SRahul Bhansali 	qconf = &lcore_conf[lcoreid];
1346eb3ba03SRahul Bhansali 
1356eb3ba03SRahul Bhansali 	len = qconf->tx_mbufs[port].len;
1366eb3ba03SRahul Bhansali 
1376eb3ba03SRahul Bhansali 	/*
1386eb3ba03SRahul Bhansali 	 * If TX buffer for that queue is empty, and we have enough packets,
1396eb3ba03SRahul Bhansali 	 * then send them straightway.
1406eb3ba03SRahul Bhansali 	 */
1416eb3ba03SRahul Bhansali 	if (num >= MAX_TX_BURST && len == 0) {
1426eb3ba03SRahul Bhansali 		n = rte_eth_tx_burst(port, qconf->tx_queue_id[port], m, num);
1436eb3ba03SRahul Bhansali 		core_stats_update_tx(n);
1446eb3ba03SRahul Bhansali 		if (unlikely(n < num)) {
1456eb3ba03SRahul Bhansali 			do {
1466eb3ba03SRahul Bhansali 				rte_pktmbuf_free(m[n]);
1476eb3ba03SRahul Bhansali 			} while (++n < num);
1486eb3ba03SRahul Bhansali 		}
1496eb3ba03SRahul Bhansali 		return;
1506eb3ba03SRahul Bhansali 	}
1516eb3ba03SRahul Bhansali 
1526eb3ba03SRahul Bhansali 	/*
1536eb3ba03SRahul Bhansali 	 * Put packets into TX buffer for that queue.
1546eb3ba03SRahul Bhansali 	 */
1556eb3ba03SRahul Bhansali 
1566eb3ba03SRahul Bhansali 	n = len + num;
1576eb3ba03SRahul Bhansali 	n = (n > MAX_PKT_BURST) ? MAX_PKT_BURST - len : num;
1586eb3ba03SRahul Bhansali 
1596eb3ba03SRahul Bhansali 	j = 0;
1606eb3ba03SRahul Bhansali 	switch (n % FWDSTEP) {
1616eb3ba03SRahul Bhansali 	while (j < n) {
1626eb3ba03SRahul Bhansali 		case 0:
1636eb3ba03SRahul Bhansali 			qconf->tx_mbufs[port].m_table[len + j] = m[j];
1646eb3ba03SRahul Bhansali 			j++;
1656eb3ba03SRahul Bhansali 			/* fallthrough */
1666eb3ba03SRahul Bhansali 		case 3:
1676eb3ba03SRahul Bhansali 			qconf->tx_mbufs[port].m_table[len + j] = m[j];
1686eb3ba03SRahul Bhansali 			j++;
1696eb3ba03SRahul Bhansali 			/* fallthrough */
1706eb3ba03SRahul Bhansali 		case 2:
1716eb3ba03SRahul Bhansali 			qconf->tx_mbufs[port].m_table[len + j] = m[j];
1726eb3ba03SRahul Bhansali 			j++;
1736eb3ba03SRahul Bhansali 			/* fallthrough */
1746eb3ba03SRahul Bhansali 		case 1:
1756eb3ba03SRahul Bhansali 			qconf->tx_mbufs[port].m_table[len + j] = m[j];
1766eb3ba03SRahul Bhansali 			j++;
1776eb3ba03SRahul Bhansali 		}
1786eb3ba03SRahul Bhansali 	}
1796eb3ba03SRahul Bhansali 
1806eb3ba03SRahul Bhansali 	len += n;
1816eb3ba03SRahul Bhansali 
1826eb3ba03SRahul Bhansali 	/* enough pkts to be sent */
1836eb3ba03SRahul Bhansali 	if (unlikely(len == MAX_PKT_BURST)) {
1846eb3ba03SRahul Bhansali 
1856eb3ba03SRahul Bhansali 		send_burst(qconf, MAX_PKT_BURST, port);
1866eb3ba03SRahul Bhansali 
1876eb3ba03SRahul Bhansali 		/* copy rest of the packets into the TX buffer. */
1886eb3ba03SRahul Bhansali 		len = num - n;
1896eb3ba03SRahul Bhansali 		if (len == 0)
1906eb3ba03SRahul Bhansali 			goto exit;
1916eb3ba03SRahul Bhansali 
1926eb3ba03SRahul Bhansali 		j = 0;
1936eb3ba03SRahul Bhansali 		switch (len % FWDSTEP) {
1946eb3ba03SRahul Bhansali 		while (j < len) {
1956eb3ba03SRahul Bhansali 			case 0:
1966eb3ba03SRahul Bhansali 				qconf->tx_mbufs[port].m_table[j] = m[n + j];
1976eb3ba03SRahul Bhansali 				j++;
1986eb3ba03SRahul Bhansali 				/* fallthrough */
1996eb3ba03SRahul Bhansali 			case 3:
2006eb3ba03SRahul Bhansali 				qconf->tx_mbufs[port].m_table[j] = m[n + j];
2016eb3ba03SRahul Bhansali 				j++;
2026eb3ba03SRahul Bhansali 				/* fallthrough */
2036eb3ba03SRahul Bhansali 			case 2:
2046eb3ba03SRahul Bhansali 				qconf->tx_mbufs[port].m_table[j] = m[n + j];
2056eb3ba03SRahul Bhansali 				j++;
2066eb3ba03SRahul Bhansali 				/* fallthrough */
2076eb3ba03SRahul Bhansali 			case 1:
2086eb3ba03SRahul Bhansali 				qconf->tx_mbufs[port].m_table[j] = m[n + j];
2096eb3ba03SRahul Bhansali 				j++;
2106eb3ba03SRahul Bhansali 		}
2116eb3ba03SRahul Bhansali 		}
2126eb3ba03SRahul Bhansali 	}
2136eb3ba03SRahul Bhansali 
2146eb3ba03SRahul Bhansali exit:
2156eb3ba03SRahul Bhansali 	qconf->tx_mbufs[port].len = len;
2166eb3ba03SRahul Bhansali }
2176eb3ba03SRahul Bhansali 
2186eb3ba03SRahul Bhansali /**
2196eb3ba03SRahul Bhansali  * Send packets burst to the ports in dst_port array
2206eb3ba03SRahul Bhansali  */
2216eb3ba03SRahul Bhansali static __rte_always_inline void
send_multi_pkts(struct rte_mbuf ** pkts,uint16_t dst_port[MAX_PKT_BURST],int nb_rx,uint64_t tx_offloads,bool ip_cksum,bool is_ipv4)2226eb3ba03SRahul Bhansali send_multi_pkts(struct rte_mbuf **pkts, uint16_t dst_port[MAX_PKT_BURST],
2236eb3ba03SRahul Bhansali 		int nb_rx, uint64_t tx_offloads, bool ip_cksum, bool is_ipv4)
2246eb3ba03SRahul Bhansali {
2256eb3ba03SRahul Bhansali 	unsigned int lcoreid = rte_lcore_id();
2266eb3ba03SRahul Bhansali 	uint16_t pnum[MAX_PKT_BURST + 1];
2276eb3ba03SRahul Bhansali 	uint8_t l_pkt = 0;
2286eb3ba03SRahul Bhansali 	uint16_t dlp, *lp;
2296eb3ba03SRahul Bhansali 	int i = 0, k;
2306eb3ba03SRahul Bhansali 
2316eb3ba03SRahul Bhansali 	/*
2326eb3ba03SRahul Bhansali 	 * Finish packet processing and group consecutive
2336eb3ba03SRahul Bhansali 	 * packets with the same destination port.
2346eb3ba03SRahul Bhansali 	 */
2356eb3ba03SRahul Bhansali 	k = RTE_ALIGN_FLOOR(nb_rx, FWDSTEP);
2366eb3ba03SRahul Bhansali 
2376eb3ba03SRahul Bhansali 	if (k != 0) {
2386eb3ba03SRahul Bhansali 		uint16x8_t dp1, dp2;
2396eb3ba03SRahul Bhansali 
2406eb3ba03SRahul Bhansali 		lp = pnum;
2416eb3ba03SRahul Bhansali 		lp[0] = 1;
2426eb3ba03SRahul Bhansali 
243*58e2cf4cSNithin Dabilpuram 		processx4_step3(pkts, dst_port, tx_offloads, ip_cksum, is_ipv4, &l_pkt);
2446eb3ba03SRahul Bhansali 
2456eb3ba03SRahul Bhansali 		/* dp1: <d[0], d[1], d[2], d[3], ... > */
2466eb3ba03SRahul Bhansali 		dp1 = vld1q_u16(dst_port);
2476eb3ba03SRahul Bhansali 
2486eb3ba03SRahul Bhansali 		for (i = FWDSTEP; i != k; i += FWDSTEP) {
249*58e2cf4cSNithin Dabilpuram 			processx4_step3(&pkts[i], &dst_port[i], tx_offloads, ip_cksum, is_ipv4,
250*58e2cf4cSNithin Dabilpuram 					&l_pkt);
2516eb3ba03SRahul Bhansali 
2526eb3ba03SRahul Bhansali 			/*
2536eb3ba03SRahul Bhansali 			 * dp2:
2546eb3ba03SRahul Bhansali 			 * <d[j-3], d[j-2], d[j-1], d[j], ... >
2556eb3ba03SRahul Bhansali 			 */
2566eb3ba03SRahul Bhansali 			dp2 = vld1q_u16(&dst_port[i - FWDSTEP + 1]);
2576eb3ba03SRahul Bhansali 			lp  = port_groupx4(&pnum[i - FWDSTEP], lp, dp1, dp2);
2586eb3ba03SRahul Bhansali 
2596eb3ba03SRahul Bhansali 			/*
2606eb3ba03SRahul Bhansali 			 * dp1:
2616eb3ba03SRahul Bhansali 			 * <d[j], d[j+1], d[j+2], d[j+3], ... >
2626eb3ba03SRahul Bhansali 			 */
2636eb3ba03SRahul Bhansali 			dp1 = vextq_u16(dp2, dp1, FWDSTEP - 1);
2646eb3ba03SRahul Bhansali 		}
2656eb3ba03SRahul Bhansali 
2666eb3ba03SRahul Bhansali 		/*
2676eb3ba03SRahul Bhansali 		 * dp2: <d[j-3], d[j-2], d[j-1], d[j-1], ... >
2686eb3ba03SRahul Bhansali 		 */
2696eb3ba03SRahul Bhansali 		dp2 = vextq_u16(dp1, dp1, 1);
2706eb3ba03SRahul Bhansali 		dp2 = vsetq_lane_u16(vgetq_lane_u16(dp2, 2), dp2, 3);
2716eb3ba03SRahul Bhansali 		lp  = port_groupx4(&pnum[i - FWDSTEP], lp, dp1, dp2);
2726eb3ba03SRahul Bhansali 
2736eb3ba03SRahul Bhansali 		/*
2746eb3ba03SRahul Bhansali 		 * remove values added by the last repeated
2756eb3ba03SRahul Bhansali 		 * dst port.
2766eb3ba03SRahul Bhansali 		 */
2776eb3ba03SRahul Bhansali 		lp[0]--;
2786eb3ba03SRahul Bhansali 		dlp = dst_port[i - 1];
2796eb3ba03SRahul Bhansali 	} else {
2806eb3ba03SRahul Bhansali 		/* set dlp and lp to the never used values. */
2816eb3ba03SRahul Bhansali 		dlp = BAD_PORT - 1;
2826eb3ba03SRahul Bhansali 		lp = pnum + MAX_PKT_BURST;
2836eb3ba03SRahul Bhansali 	}
2846eb3ba03SRahul Bhansali 
2856eb3ba03SRahul Bhansali 	/* Process up to last 3 packets one by one. */
2866eb3ba03SRahul Bhansali 	switch (nb_rx % FWDSTEP) {
2876eb3ba03SRahul Bhansali 	case 3:
288*58e2cf4cSNithin Dabilpuram 		process_packet(pkts[i], dst_port + i, tx_offloads, ip_cksum, is_ipv4, &l_pkt);
2896eb3ba03SRahul Bhansali 		GROUP_PORT_STEP(dlp, dst_port, lp, pnum, i);
2906eb3ba03SRahul Bhansali 		i++;
2916eb3ba03SRahul Bhansali 		/* fallthrough */
2926eb3ba03SRahul Bhansali 	case 2:
293*58e2cf4cSNithin Dabilpuram 		process_packet(pkts[i], dst_port + i, tx_offloads, ip_cksum, is_ipv4, &l_pkt);
2946eb3ba03SRahul Bhansali 		GROUP_PORT_STEP(dlp, dst_port, lp, pnum, i);
2956eb3ba03SRahul Bhansali 		i++;
2966eb3ba03SRahul Bhansali 		/* fallthrough */
2976eb3ba03SRahul Bhansali 	case 1:
298*58e2cf4cSNithin Dabilpuram 		process_packet(pkts[i], dst_port + i, tx_offloads, ip_cksum, is_ipv4, &l_pkt);
2996eb3ba03SRahul Bhansali 		GROUP_PORT_STEP(dlp, dst_port, lp, pnum, i);
3006eb3ba03SRahul Bhansali 	}
3016eb3ba03SRahul Bhansali 
3026eb3ba03SRahul Bhansali 	/*
3036eb3ba03SRahul Bhansali 	 * Send packets out, through destination port.
3046eb3ba03SRahul Bhansali 	 * Consecutive packets with the same destination port
3056eb3ba03SRahul Bhansali 	 * are already grouped together.
3066eb3ba03SRahul Bhansali 	 * If destination port for the packet equals BAD_PORT,
3076eb3ba03SRahul Bhansali 	 * then free the packet without sending it out.
3086eb3ba03SRahul Bhansali 	 */
3096eb3ba03SRahul Bhansali 	for (i = 0; i < nb_rx; i += k) {
3106eb3ba03SRahul Bhansali 
3116eb3ba03SRahul Bhansali 		uint16_t pn;
3126eb3ba03SRahul Bhansali 
3136eb3ba03SRahul Bhansali 		pn = dst_port[i];
3146eb3ba03SRahul Bhansali 		k = pnum[i];
3156eb3ba03SRahul Bhansali 
3166eb3ba03SRahul Bhansali 		if (likely(pn != BAD_PORT)) {
3176eb3ba03SRahul Bhansali 			if (l_pkt)
3186eb3ba03SRahul Bhansali 				/* Large packet is present, need to send
3196eb3ba03SRahul Bhansali 				 * individual packets with fragment
3206eb3ba03SRahul Bhansali 				 */
3216eb3ba03SRahul Bhansali 				send_packets(pkts + i, pn, k, is_ipv4);
3226eb3ba03SRahul Bhansali 			else
3236eb3ba03SRahul Bhansali 				send_packetsx4(pkts + i, pn, k);
3246eb3ba03SRahul Bhansali 
3256eb3ba03SRahul Bhansali 		} else {
3266eb3ba03SRahul Bhansali 			free_pkts(&pkts[i], k);
3276eb3ba03SRahul Bhansali 			if (is_ipv4)
3286eb3ba03SRahul Bhansali 				core_statistics[lcoreid].lpm4.miss++;
3296eb3ba03SRahul Bhansali 			else
3306eb3ba03SRahul Bhansali 				core_statistics[lcoreid].lpm6.miss++;
3316eb3ba03SRahul Bhansali 		}
3326eb3ba03SRahul Bhansali 	}
3336eb3ba03SRahul Bhansali }
3346eb3ba03SRahul Bhansali 
3356eb3ba03SRahul Bhansali #endif /* IPSEC_NEON_H */
336