New upstream version 18.02
[deb_dpdk.git] / examples / ip_pipeline / pipeline / pipeline_actions_common.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2016 Intel Corporation
3  */
4 #ifndef __INCLUDE_PIPELINE_ACTIONS_COMMON_H__
5 #define __INCLUDE_PIPELINE_ACTIONS_COMMON_H__
6
7 #include <stdint.h>
8
9 #include <rte_common.h>
10 #include <rte_cycles.h>
11 #include <rte_mbuf.h>
12 #include <rte_pipeline.h>
13
14 #define PIPELINE_PORT_IN_AH(f_ah, f_pkt_work, f_pkt4_work)              \
15 static int                                                              \
16 f_ah(                                                                   \
17         __rte_unused struct rte_pipeline *p,                            \
18         struct rte_mbuf **pkts,                                         \
19         uint32_t n_pkts,                                                \
20         void *arg)                                                      \
21 {                                                                       \
22         uint32_t i;                                                     \
23                                                                         \
24         for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4)                   \
25                 f_pkt4_work(&pkts[i], arg);                             \
26                                                                         \
27         for ( ; i < n_pkts; i++)                                        \
28                 f_pkt_work(pkts[i], arg);                               \
29                                                                         \
30         return 0;                                                       \
31 }
32
33 #define PIPELINE_PORT_IN_AH_HIJACK_ALL(f_ah, f_pkt_work, f_pkt4_work) \
34 static int                                                              \
35 f_ah(                                                                   \
36         struct rte_pipeline *p,                         \
37         struct rte_mbuf **pkts,                                 \
38         uint32_t n_pkts,                                                \
39         void *arg)                                              \
40 {                                                                       \
41         uint64_t pkt_mask = RTE_LEN2MASK(n_pkts, uint64_t);     \
42         uint32_t i;                                                     \
43                                                                         \
44         rte_pipeline_ah_packet_hijack(p, pkt_mask);     \
45                                                                         \
46         for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4)   \
47                 f_pkt4_work(&pkts[i], arg);                             \
48                                                                         \
49         for ( ; i < n_pkts; i++)                                \
50                 f_pkt_work(pkts[i], arg);                       \
51                                                                         \
52         return 0;                                                       \
53 }
54
55 #define PIPELINE_TABLE_AH_HIT(f_ah, f_pkt_work, f_pkt4_work)            \
56 static int                                                              \
57 f_ah(                                                                   \
58         __rte_unused struct rte_pipeline *p,                            \
59         struct rte_mbuf **pkts,                                         \
60         uint64_t pkts_in_mask,                                          \
61         struct rte_pipeline_table_entry **entries,                      \
62         void *arg)                                                      \
63 {                                                                       \
64         if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {                 \
65                 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);   \
66                 uint32_t i;                                             \
67                                                                         \
68                 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4)           \
69                         f_pkt4_work(&pkts[i], &entries[i], arg);        \
70                                                                         \
71                 for ( ; i < n_pkts; i++)                                \
72                         f_pkt_work(pkts[i], entries[i], arg);           \
73         } else                                                          \
74                 for ( ; pkts_in_mask; ) {                               \
75                         uint32_t pos = __builtin_ctzll(pkts_in_mask);   \
76                         uint64_t pkt_mask = 1LLU << pos;                \
77                                                                         \
78                         pkts_in_mask &= ~pkt_mask;                      \
79                         f_pkt_work(pkts[pos], entries[pos], arg);       \
80                 }                                                       \
81                                                                         \
82         return 0;                                                       \
83 }
84
85 #define PIPELINE_TABLE_AH_MISS(f_ah, f_pkt_work, f_pkt4_work)           \
86 static int                                                              \
87 f_ah(                                                                   \
88         __rte_unused struct rte_pipeline *p,                            \
89         struct rte_mbuf **pkts,                                         \
90         uint64_t pkts_in_mask,                                          \
91         struct rte_pipeline_table_entry *entry,                         \
92         void *arg)                                                      \
93 {                                                                       \
94         if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {                 \
95                 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);   \
96                 uint32_t i;                                             \
97                                                                         \
98                 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4)           \
99                         f_pkt4_work(&pkts[i], entry, arg);              \
100                                                                         \
101                 for ( ; i < n_pkts; i++)                                \
102                         f_pkt_work(pkts[i], entry, arg);                \
103         } else                                                          \
104                 for ( ; pkts_in_mask; ) {                               \
105                         uint32_t pos = __builtin_ctzll(pkts_in_mask);   \
106                         uint64_t pkt_mask = 1LLU << pos;                \
107                                                                         \
108                         pkts_in_mask &= ~pkt_mask;                      \
109                         f_pkt_work(pkts[pos], entry, arg);              \
110                 }                                                       \
111                                                                         \
112         return 0;                                                       \
113 }
114
115 #define PIPELINE_TABLE_AH_HIT_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work)  \
116 static int                                                              \
117 f_ah(                                                                   \
118         struct rte_pipeline *p,                                         \
119         struct rte_mbuf **pkts,                                         \
120         uint64_t pkts_mask,                                             \
121         struct rte_pipeline_table_entry **entries,                      \
122         void *arg)                                                      \
123 {                                                                       \
124         uint64_t pkts_in_mask = pkts_mask;                              \
125         uint64_t pkts_out_mask = pkts_mask;                             \
126         uint64_t time = rte_rdtsc();                                    \
127                                                                         \
128         if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {                 \
129                 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);   \
130                 uint32_t i;                                             \
131                                                                         \
132                 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {         \
133                         uint64_t mask = f_pkt4_work(&pkts[i],           \
134                                 &entries[i], arg, time);                \
135                         pkts_out_mask ^= mask << i;                     \
136                 }                                                       \
137                                                                         \
138                 for ( ; i < n_pkts; i++) {                              \
139                         uint64_t mask = f_pkt_work(pkts[i],             \
140                                 entries[i], arg, time);                 \
141                         pkts_out_mask ^= mask << i;                     \
142                 }                                                       \
143         } else                                                          \
144                 for ( ; pkts_in_mask; ) {                               \
145                         uint32_t pos = __builtin_ctzll(pkts_in_mask);   \
146                         uint64_t pkt_mask = 1LLU << pos;                \
147                         uint64_t mask = f_pkt_work(pkts[pos],           \
148                                 entries[pos], arg, time);               \
149                                                                         \
150                         pkts_in_mask &= ~pkt_mask;                      \
151                         pkts_out_mask ^= mask << pos;                   \
152                 }                                                       \
153                                                                         \
154         rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask);      \
155                                                                         \
156         return 0;                                                       \
157 }
158
159 #define PIPELINE_TABLE_AH_MISS_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work) \
160 static int                                                              \
161 f_ah(                                                                   \
162         struct rte_pipeline *p,                                         \
163         struct rte_mbuf **pkts,                                         \
164         uint64_t pkts_mask,                                             \
165         struct rte_pipeline_table_entry *entry,                         \
166         void *arg)                                                      \
167 {                                                                       \
168         uint64_t pkts_in_mask = pkts_mask;                              \
169         uint64_t pkts_out_mask = pkts_mask;                             \
170         uint64_t time = rte_rdtsc();                                    \
171                                                                         \
172         if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {                 \
173                 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);   \
174                 uint32_t i;                                             \
175                                                                         \
176                 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {         \
177                         uint64_t mask = f_pkt4_work(&pkts[i],           \
178                                 entry, arg, time);                      \
179                         pkts_out_mask ^= mask << i;                     \
180                 }                                                       \
181                                                                         \
182                 for ( ; i < n_pkts; i++) {                              \
183                         uint64_t mask = f_pkt_work(pkts[i], entry, arg, time);\
184                         pkts_out_mask ^= mask << i;                     \
185                 }                                                       \
186         } else                                                          \
187                 for ( ; pkts_in_mask; ) {                               \
188                         uint32_t pos = __builtin_ctzll(pkts_in_mask);   \
189                         uint64_t pkt_mask = 1LLU << pos;                \
190                         uint64_t mask = f_pkt_work(pkts[pos],           \
191                                 entry, arg, time);              \
192                                                                         \
193                         pkts_in_mask &= ~pkt_mask;                      \
194                         pkts_out_mask ^= mask << pos;                   \
195                 }                                                       \
196                                                                         \
197         rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask);      \
198                                                                         \
199         return 0;                                                       \
200 }
201
202 #endif