1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
8 * Resolve priority for multiple results (scalar version).
9 * This consists comparing the priority of the current traversal with the
10 * running set of results for the packet.
11 * For each result, keep a running array of the result (rule number) and
12 * its priority for each category.
15 resolve_priority_scalar(uint64_t transition
, int n
,
16 const struct rte_acl_ctx
*ctx
, struct parms
*parms
,
17 const struct rte_acl_match_results
*p
, uint32_t categories
)
20 int32_t *saved_priority
;
21 uint32_t *saved_results
;
22 const int32_t *priority
;
23 const uint32_t *results
;
25 saved_results
= parms
[n
].cmplt
->results
;
26 saved_priority
= parms
[n
].cmplt
->priority
;
28 /* results and priorities for completed trie */
29 results
= p
[transition
].results
;
30 priority
= p
[transition
].priority
;
32 /* if this is not the first completed trie */
33 if (parms
[n
].cmplt
->count
!= ctx
->num_tries
) {
34 for (i
= 0; i
< categories
; i
+= RTE_ACL_RESULTS_MULTIPLIER
) {
36 if (saved_priority
[i
] <= priority
[i
]) {
37 saved_priority
[i
] = priority
[i
];
38 saved_results
[i
] = results
[i
];
40 if (saved_priority
[i
+ 1] <= priority
[i
+ 1]) {
41 saved_priority
[i
+ 1] = priority
[i
+ 1];
42 saved_results
[i
+ 1] = results
[i
+ 1];
44 if (saved_priority
[i
+ 2] <= priority
[i
+ 2]) {
45 saved_priority
[i
+ 2] = priority
[i
+ 2];
46 saved_results
[i
+ 2] = results
[i
+ 2];
48 if (saved_priority
[i
+ 3] <= priority
[i
+ 3]) {
49 saved_priority
[i
+ 3] = priority
[i
+ 3];
50 saved_results
[i
+ 3] = results
[i
+ 3];
54 for (i
= 0; i
< categories
; i
+= RTE_ACL_RESULTS_MULTIPLIER
) {
55 saved_priority
[i
] = priority
[i
];
56 saved_priority
[i
+ 1] = priority
[i
+ 1];
57 saved_priority
[i
+ 2] = priority
[i
+ 2];
58 saved_priority
[i
+ 3] = priority
[i
+ 3];
60 saved_results
[i
] = results
[i
];
61 saved_results
[i
+ 1] = results
[i
+ 1];
62 saved_results
[i
+ 2] = results
[i
+ 2];
63 saved_results
[i
+ 3] = results
[i
+ 3];
68 static inline uint32_t
69 scan_forward(uint32_t input
, uint32_t max
)
71 return (input
== 0) ? max
: rte_bsf32(input
);
74 static inline uint64_t
75 scalar_transition(const uint64_t *trans_table
, uint64_t transition
,
78 uint32_t addr
, index
, ranges
, x
, a
, b
, c
;
80 /* break transition into component parts */
81 ranges
= transition
>> (sizeof(index
) * CHAR_BIT
);
82 index
= transition
& ~RTE_ACL_NODE_INDEX
;
83 addr
= transition
^ index
;
85 if (index
!= RTE_ACL_NODE_DFA
) {
86 /* calc address for a QRANGE/SINGLE node */
87 c
= (uint32_t)input
* SCALAR_QRANGE_MULT
;
88 a
= ranges
| SCALAR_QRANGE_MIN
;
89 a
-= (c
& SCALAR_QRANGE_MASK
);
90 b
= c
& SCALAR_QRANGE_MIN
;
91 a
&= SCALAR_QRANGE_MIN
;
92 a
^= (ranges
^ b
) & (a
^ b
);
93 x
= scan_forward(a
, 32) >> 3;
95 /* calc address for a DFA node */
96 x
= ranges
>> (input
/
97 RTE_ACL_DFA_GR64_SIZE
* RTE_ACL_DFA_GR64_BIT
);
104 /* pickup next transition */
105 transition
= *(trans_table
+ addr
);
110 rte_acl_classify_scalar(const struct rte_acl_ctx
*ctx
, const uint8_t **data
,
111 uint32_t *results
, uint32_t num
, uint32_t categories
)
114 uint64_t transition0
, transition1
;
115 uint32_t input0
, input1
;
116 struct acl_flow_data flows
;
117 uint64_t index_array
[MAX_SEARCHES_SCALAR
];
118 struct completion cmplt
[MAX_SEARCHES_SCALAR
];
119 struct parms parms
[MAX_SEARCHES_SCALAR
];
121 acl_set_flow(&flows
, cmplt
, RTE_DIM(cmplt
), data
, results
, num
,
122 categories
, ctx
->trans_table
);
124 for (n
= 0; n
< MAX_SEARCHES_SCALAR
; n
++) {
126 index_array
[n
] = acl_start_next_trie(&flows
, parms
, n
, ctx
);
129 transition0
= index_array
[0];
130 transition1
= index_array
[1];
132 while ((transition0
| transition1
) & RTE_ACL_NODE_MATCH
) {
133 transition0
= acl_match_check(transition0
,
134 0, ctx
, parms
, &flows
, resolve_priority_scalar
);
135 transition1
= acl_match_check(transition1
,
136 1, ctx
, parms
, &flows
, resolve_priority_scalar
);
139 while (flows
.started
> 0) {
141 input0
= GET_NEXT_4BYTES(parms
, 0);
142 input1
= GET_NEXT_4BYTES(parms
, 1);
144 for (n
= 0; n
< 4; n
++) {
146 transition0
= scalar_transition(flows
.trans
,
147 transition0
, (uint8_t)input0
);
150 transition1
= scalar_transition(flows
.trans
,
151 transition1
, (uint8_t)input1
);
155 while ((transition0
| transition1
) & RTE_ACL_NODE_MATCH
) {
156 transition0
= acl_match_check(transition0
,
157 0, ctx
, parms
, &flows
, resolve_priority_scalar
);
158 transition1
= acl_match_check(transition1
,
159 1, ctx
, parms
, &flows
, resolve_priority_scalar
);