1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2016 Intel Corporation.
3 * Copyright(c) 2017 IBM Corporation.
4 * Copyright(C) 2022 Marvell.
5 */
6
7 #ifndef PORT_GROUP_H
8 #define PORT_GROUP_H
9
10 #include "pkt_group.h"
11
12 /*
13 * Group consecutive packets with the same destination port in bursts of 4.
14 * Suppose we have array of destination ports:
15 * dst_port[] = {a, b, c, d,, e, ... }
16 * dp1 should contain: <a, b, c, d>, dp2: <b, c, d, e>.
17 * We doing 4 comparisons at once and the result is 4 bit mask.
18 * This mask is used as an index into prebuild array of pnum values.
19 */
20 static inline uint16_t *
port_groupx4(uint16_t pn[FWDSTEP+1],uint16_t * lp,__vector unsigned short dp1,__vector unsigned short dp2)21 port_groupx4(uint16_t pn[FWDSTEP + 1], uint16_t *lp,
22 __vector unsigned short dp1,
23 __vector unsigned short dp2)
24 {
25 union {
26 uint16_t u16[FWDSTEP + 1];
27 uint64_t u64;
28 } *pnum = (void *)pn;
29 __vector unsigned long long result;
30 const __vector unsigned int perm_mask = {0x00204060, 0x80808080,
31 0x80808080, 0x80808080};
32 int32_t v;
33
34 dp1 = (__vector unsigned short)vec_cmpeq(dp1, dp2);
35 dp1 = vec_mergeh(dp1, dp1);
36 result = (__vector unsigned long long)vec_vbpermq(
37 (__vector unsigned char)dp1, (__vector unsigned char)perm_mask);
38
39 v = result[1];
40 /* update last port counter. */
41 lp[0] += gptbl[v].lpv;
42
43 /* if dest port value has changed. */
44 if (v != GRPMSK) {
45 pnum->u64 = gptbl[v].pnum;
46 pnum->u16[FWDSTEP] = 1;
47 lp = pnum->u16 + gptbl[v].idx;
48 }
49
50 return lp;
51 }
52
53 #endif /* PORT_GROUP_H */
54