Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2001-2023 Intel Corporation
3 : : */
4 : :
5 : : #include "ice_common.h"
6 : :
7 : : #define GPR_HB_IDX 64
8 : : #define GPR_ERR_IDX 84
9 : : #define GPR_FLG_IDX 104
10 : : #define GPR_TSR_IDX 108
11 : : #define GPR_NN_IDX 109
12 : : #define GPR_HO_IDX 110
13 : : #define GPR_NP_IDX 111
14 : :
15 : : static void _rt_tsr_set(struct ice_parser_rt *rt, u16 tsr)
16 : : {
17 : 0 : rt->gpr[GPR_TSR_IDX] = tsr;
18 : : }
19 : :
20 : : static void _rt_ho_set(struct ice_parser_rt *rt, u16 ho)
21 : : {
22 : 0 : rt->gpr[GPR_HO_IDX] = ho;
23 : 0 : ice_memcpy(&rt->gpr[GPR_HB_IDX], &rt->pkt_buf[ho], 32,
24 : : ICE_NONDMA_TO_NONDMA);
25 : : }
26 : :
27 : : static void _rt_np_set(struct ice_parser_rt *rt, u16 pc)
28 : : {
29 : 0 : rt->gpr[GPR_NP_IDX] = pc;
30 : : }
31 : :
32 : : static void _rt_nn_set(struct ice_parser_rt *rt, u16 node)
33 : : {
34 : 0 : rt->gpr[GPR_NN_IDX] = node;
35 : : }
36 : :
37 : 0 : static void _rt_flag_set(struct ice_parser_rt *rt, int idx, bool val)
38 : : {
39 : 0 : int y = idx / 16;
40 : : int x = idx % 16;
41 : :
42 [ # # ]: 0 : if (val)
43 : 0 : rt->gpr[GPR_FLG_IDX + y] |= (u16)(1 << x);
44 : : else
45 : 0 : rt->gpr[GPR_FLG_IDX + y] &= ~(u16)(1 << x);
46 : :
47 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Set parser flag %d value %d\n",
48 : : idx, val);
49 : 0 : }
50 : :
51 : 0 : static void _rt_gpr_set(struct ice_parser_rt *rt, int idx, u16 val)
52 : : {
53 [ # # ]: 0 : if (idx == GPR_HO_IDX)
54 [ # # ]: 0 : _rt_ho_set(rt, val);
55 : : else
56 : 0 : rt->gpr[idx] = val;
57 : :
58 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Set GPR %d value %d\n",
59 : : idx, val);
60 : 0 : }
61 : :
62 : 0 : static void _rt_err_set(struct ice_parser_rt *rt, int idx, bool val)
63 : : {
64 [ # # ]: 0 : if (val)
65 : 0 : rt->gpr[GPR_ERR_IDX] |= (u16)(1 << idx);
66 : : else
67 : 0 : rt->gpr[GPR_ERR_IDX] &= ~(u16)(1 << idx);
68 : :
69 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Set parser error %d value %d\n",
70 : : idx, val);
71 : 0 : }
72 : :
73 : : /**
74 : : * ice_parser_rt_reset - reset the parser runtime
75 : : * @rt: pointer to the parser runtime
76 : : */
77 : 0 : void ice_parser_rt_reset(struct ice_parser_rt *rt)
78 : : {
79 : 0 : struct ice_parser *psr = rt->psr;
80 [ # # ]: 0 : struct ice_metainit_item *mi = &psr->mi_table[0];
81 : : int i;
82 : :
83 : : ice_memset(rt, 0, sizeof(*rt), ICE_NONDMA_MEM);
84 : :
85 : 0 : _rt_tsr_set(rt, mi->tsr);
86 [ # # ]: 0 : _rt_ho_set(rt, mi->ho);
87 : 0 : _rt_np_set(rt, mi->pc);
88 : 0 : _rt_nn_set(rt, mi->pg_rn);
89 : :
90 : 0 : rt->psr = psr;
91 : :
92 [ # # ]: 0 : for (i = 0; i < 64; i++) {
93 [ # # ]: 0 : if ((mi->flags & (1ul << i)) != 0ul)
94 : 0 : _rt_flag_set(rt, i, true);
95 : : }
96 : 0 : }
97 : :
98 : : /**
99 : : * ice_parser_rt_pktbuf_set - set a packet into parser runtime
100 : : * @rt: pointer to the parser runtime
101 : : * @pkt_buf: buffer with packet data
102 : : * @pkt_len: packet buffer length
103 : : */
104 : 0 : void ice_parser_rt_pktbuf_set(struct ice_parser_rt *rt, const u8 *pkt_buf,
105 : : int pkt_len)
106 : : {
107 : 0 : int len = min(ICE_PARSER_MAX_PKT_LEN, pkt_len);
108 : 0 : u16 ho = rt->gpr[GPR_HO_IDX];
109 : :
110 [ # # ]: 0 : ice_memcpy(rt->pkt_buf, pkt_buf, len, ICE_NONDMA_TO_NONDMA);
111 : 0 : rt->pkt_len = pkt_len;
112 : :
113 [ # # ]: 0 : ice_memcpy(&rt->gpr[GPR_HB_IDX], &rt->pkt_buf[ho],
114 : : ICE_PARSER_HDR_BUF_LEN, ICE_NONDMA_TO_NONDMA);
115 : 0 : }
116 : :
117 : 0 : static void _bst_key_init(struct ice_parser_rt *rt, struct ice_imem_item *imem)
118 : : {
119 : : int second_last_key_idx = ICE_PARSER_BST_KEY_LEN - 2;
120 : : int last_key_idx = ICE_PARSER_BST_KEY_LEN - 1;
121 : 0 : u8 tsr = (u8)rt->gpr[GPR_TSR_IDX];
122 : 0 : u16 ho = rt->gpr[GPR_HO_IDX];
123 : 0 : u8 *key = rt->bst_key;
124 : :
125 : : int i, j;
126 : :
127 [ # # ]: 0 : if (imem->b_kb.tsr_ctrl)
128 : 0 : key[last_key_idx] = (u8)tsr;
129 : : else
130 : 0 : key[last_key_idx] = imem->b_kb.priority;
131 : :
132 [ # # ]: 0 : for (i = second_last_key_idx; i >= 0; i--) {
133 : 0 : j = ho + second_last_key_idx - i;
134 [ # # ]: 0 : if (j < ICE_PARSER_MAX_PKT_LEN)
135 : 0 : key[i] = rt->pkt_buf[ho + second_last_key_idx - i];
136 : : else
137 : 0 : key[i] = 0;
138 : : }
139 : :
140 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Generated Boost TCAM Key:\n");
141 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
142 : : key[0], key[1], key[2], key[3], key[4],
143 : : key[5], key[6], key[7], key[8], key[9],
144 : : key[10], key[11], key[12], key[13], key[14],
145 : : key[15], key[16], key[17], key[18], key[19]);
146 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "\n");
147 : 0 : }
148 : :
149 : : static u8 _bit_rev_u8(u8 v)
150 : : {
151 : : u8 r = 0;
152 : : int i;
153 : :
154 [ # # # # : 0 : for (i = 0; i < 8; i++) {
# # # # #
# ]
155 : 0 : r |= (u8)((v & 0x1) << (7 - i));
156 : 0 : v >>= 1;
157 : : }
158 : :
159 : : return r;
160 : : }
161 : :
162 : : static u8 _bit_rev_u16(u16 v, int len)
163 : : {
164 : : u16 r = 0;
165 : : int i;
166 : :
167 [ # # ]: 0 : for (i = 0; i < len; i++) {
168 : 0 : r |= (u16)((v & 0x1) << (len - 1 - i));
169 : 0 : v >>= 1;
170 : : }
171 : :
172 : : return r;
173 : : }
174 : :
175 : : static u32 _bit_rev_u32(u32 v, int len)
176 : : {
177 : : u32 r = 0;
178 : : int i;
179 : :
180 [ # # ]: 0 : for (i = 0; i < len; i++) {
181 : 0 : r |= (u32)((v & 0x1) << (len - 1 - i));
182 : 0 : v >>= 1;
183 : : }
184 : :
185 : : return r;
186 : : }
187 : :
188 : 0 : static u32 _hv_bit_sel(struct ice_parser_rt *rt, int start, int len)
189 : : {
190 : : u64 msk;
191 : : union {
192 : : u64 d64;
193 : : u8 b[8];
194 : : } bit_sel;
195 : : int i;
196 : :
197 : 0 : int offset = GPR_HB_IDX + start / 16;
198 : :
199 [ # # ]: 0 : ice_memcpy(bit_sel.b, &rt->gpr[offset], 8, ICE_NONDMA_TO_NONDMA);
200 : :
201 [ # # ]: 0 : for (i = 0; i < 8; i++)
202 : 0 : bit_sel.b[i] = _bit_rev_u8(bit_sel.b[i]);
203 : :
204 : 0 : msk = (1ul << len) - 1;
205 : :
206 : 0 : return _bit_rev_u32((u32)((bit_sel.d64 >> (start % 16)) & msk), len);
207 : : }
208 : :
209 : 0 : static u32 _pk_build(struct ice_parser_rt *rt, struct ice_np_keybuilder *kb)
210 : : {
211 [ # # ]: 0 : if (kb->ops == 0)
212 : 0 : return _hv_bit_sel(rt, kb->start_or_reg0, kb->len_or_reg1);
213 [ # # ]: 0 : else if (kb->ops == 1)
214 : 0 : return rt->gpr[kb->start_or_reg0] |
215 : 0 : ((u32)rt->gpr[kb->len_or_reg1] << 16);
216 [ # # ]: 0 : else if (kb->ops == 2)
217 : : return 0;
218 : :
219 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Unsupported ops %d\n", kb->ops);
220 : : return 0xffffffff;
221 : : }
222 : :
223 : : static bool _flag_get(struct ice_parser_rt *rt, int index)
224 : : {
225 : 0 : int y = index / 16;
226 : : int x = index % 16;
227 : :
228 : 0 : return (rt->gpr[GPR_FLG_IDX + y] & (u16)(1 << x)) != 0;
229 : : }
230 : :
231 : 0 : static void _imem_pgk_init(struct ice_parser_rt *rt, struct ice_imem_item *imem)
232 : : {
233 : 0 : ice_memset(&rt->pg_key, 0, sizeof(rt->pg_key), ICE_NONDMA_MEM);
234 : 0 : rt->pg_key.next_proto = _pk_build(rt, &imem->np_kb);
235 : :
236 [ # # ]: 0 : if (imem->pg_kb.flag0_ena)
237 : 0 : rt->pg_key.flag0 = _flag_get(rt, imem->pg_kb.flag0_idx);
238 [ # # ]: 0 : if (imem->pg_kb.flag1_ena)
239 : 0 : rt->pg_key.flag1 = _flag_get(rt, imem->pg_kb.flag1_idx);
240 [ # # ]: 0 : if (imem->pg_kb.flag2_ena)
241 : 0 : rt->pg_key.flag2 = _flag_get(rt, imem->pg_kb.flag2_idx);
242 [ # # ]: 0 : if (imem->pg_kb.flag3_ena)
243 : 0 : rt->pg_key.flag3 = _flag_get(rt, imem->pg_kb.flag3_idx);
244 : :
245 : 0 : rt->pg_key.alu_reg = rt->gpr[imem->pg_kb.alu_reg_idx];
246 : 0 : rt->pg_key.node_id = rt->gpr[GPR_NN_IDX];
247 : :
248 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Generate Parse Graph Key: node_id(%d),flag0(%d), flag1(%d), flag2(%d), flag3(%d), boost_idx(%d), alu_reg(0x%04x), next_proto(0x%08x)\n",
249 : : rt->pg_key.node_id,
250 : : rt->pg_key.flag0,
251 : : rt->pg_key.flag1,
252 : : rt->pg_key.flag2,
253 : : rt->pg_key.flag3,
254 : : rt->pg_key.boost_idx,
255 : : rt->pg_key.alu_reg,
256 : : rt->pg_key.next_proto);
257 : 0 : }
258 : :
259 : 0 : static void _imem_alu0_set(struct ice_parser_rt *rt, struct ice_imem_item *imem)
260 : : {
261 : 0 : rt->alu0 = &imem->alu0;
262 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Load ALU0 from imem pc %d\n",
263 : : imem->idx);
264 : 0 : }
265 : :
266 : 0 : static void _imem_alu1_set(struct ice_parser_rt *rt, struct ice_imem_item *imem)
267 : : {
268 : 0 : rt->alu1 = &imem->alu1;
269 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Load ALU1 from imem pc %d\n",
270 : : imem->idx);
271 : 0 : }
272 : :
273 : 0 : static void _imem_alu2_set(struct ice_parser_rt *rt, struct ice_imem_item *imem)
274 : : {
275 : 0 : rt->alu2 = &imem->alu2;
276 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Load ALU2 from imem pc %d\n",
277 : : imem->idx);
278 : 0 : }
279 : :
280 : 0 : static void _imem_pgp_set(struct ice_parser_rt *rt, struct ice_imem_item *imem)
281 : : {
282 : 0 : rt->pg = imem->pg;
283 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Load PG priority %d from imem pc %d\n",
284 : : rt->pg, imem->idx);
285 : 0 : }
286 : :
287 : : static void
288 : 0 : _bst_pgk_init(struct ice_parser_rt *rt, struct ice_bst_tcam_item *bst)
289 : : {
290 : 0 : ice_memset(&rt->pg_key, 0, sizeof(rt->pg_key), ICE_NONDMA_MEM);
291 : 0 : rt->pg_key.boost_idx = bst->hit_idx_grp;
292 : 0 : rt->pg_key.next_proto = _pk_build(rt, &bst->np_kb);
293 : :
294 [ # # ]: 0 : if (bst->pg_kb.flag0_ena)
295 : 0 : rt->pg_key.flag0 = _flag_get(rt, bst->pg_kb.flag0_idx);
296 [ # # ]: 0 : if (bst->pg_kb.flag1_ena)
297 : 0 : rt->pg_key.flag1 = _flag_get(rt, bst->pg_kb.flag1_idx);
298 [ # # ]: 0 : if (bst->pg_kb.flag2_ena)
299 : 0 : rt->pg_key.flag2 = _flag_get(rt, bst->pg_kb.flag2_idx);
300 [ # # ]: 0 : if (bst->pg_kb.flag3_ena)
301 : 0 : rt->pg_key.flag3 = _flag_get(rt, bst->pg_kb.flag3_idx);
302 : :
303 : 0 : rt->pg_key.alu_reg = rt->gpr[bst->pg_kb.alu_reg_idx];
304 : 0 : rt->pg_key.node_id = rt->gpr[GPR_NN_IDX];
305 : :
306 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Generate Parse Graph Key: node_id(%d),flag0(%d), flag1(%d), flag2(%d), flag3(%d), boost_idx(%d), alu_reg(0x%04x), next_proto(0x%08x)\n",
307 : : rt->pg_key.node_id,
308 : : rt->pg_key.flag0,
309 : : rt->pg_key.flag1,
310 : : rt->pg_key.flag2,
311 : : rt->pg_key.flag3,
312 : : rt->pg_key.boost_idx,
313 : : rt->pg_key.alu_reg,
314 : : rt->pg_key.next_proto);
315 : 0 : }
316 : :
317 : 0 : static void _bst_alu0_set(struct ice_parser_rt *rt,
318 : : struct ice_bst_tcam_item *bst)
319 : : {
320 : 0 : rt->alu0 = &bst->alu0;
321 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Load ALU0 from boost address %d\n",
322 : : bst->address);
323 : 0 : }
324 : :
325 : 0 : static void _bst_alu1_set(struct ice_parser_rt *rt,
326 : : struct ice_bst_tcam_item *bst)
327 : : {
328 : 0 : rt->alu1 = &bst->alu1;
329 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Load ALU1 from boost address %d\n",
330 : : bst->address);
331 : 0 : }
332 : :
333 : 0 : static void _bst_alu2_set(struct ice_parser_rt *rt,
334 : : struct ice_bst_tcam_item *bst)
335 : : {
336 : 0 : rt->alu2 = &bst->alu2;
337 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Load ALU2 from boost address %d\n",
338 : : bst->address);
339 : 0 : }
340 : :
341 : 0 : static void _bst_pgp_set(struct ice_parser_rt *rt,
342 : : struct ice_bst_tcam_item *bst)
343 : : {
344 : 0 : rt->pg = bst->pg_pri;
345 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Load PG priority %d from boost address %d\n",
346 : : rt->pg, bst->address);
347 : 0 : }
348 : :
349 : 0 : static struct ice_pg_cam_item *_pg_cam_match(struct ice_parser_rt *rt)
350 : : {
351 : 0 : struct ice_parser *psr = rt->psr;
352 : : struct ice_pg_cam_item *item;
353 : :
354 : 0 : item = ice_pg_cam_match(psr->pg_cam_table, ICE_PG_CAM_TABLE_SIZE,
355 : : &rt->pg_key);
356 [ # # ]: 0 : if (item)
357 : : return item;
358 : :
359 : 0 : item = ice_pg_cam_match(psr->pg_sp_cam_table, ICE_PG_SP_CAM_TABLE_SIZE,
360 : : &rt->pg_key);
361 : 0 : return item;
362 : : }
363 : :
364 : 0 : static struct ice_pg_nm_cam_item *_pg_nm_cam_match(struct ice_parser_rt *rt)
365 : : {
366 : 0 : struct ice_parser *psr = rt->psr;
367 : : struct ice_pg_nm_cam_item *item;
368 : :
369 : 0 : item = ice_pg_nm_cam_match(psr->pg_nm_cam_table,
370 : : ICE_PG_NM_CAM_TABLE_SIZE, &rt->pg_key);
371 : :
372 [ # # ]: 0 : if (item)
373 : : return item;
374 : :
375 : 0 : item = ice_pg_nm_cam_match(psr->pg_nm_sp_cam_table,
376 : : ICE_PG_NM_SP_CAM_TABLE_SIZE,
377 : : &rt->pg_key);
378 : 0 : return item;
379 : : }
380 : :
381 : 0 : static void _gpr_add(struct ice_parser_rt *rt, int idx, u16 val)
382 : : {
383 : 0 : rt->pu.gpr_val_upd[idx] = true;
384 : 0 : rt->pu.gpr_val[idx] = val;
385 : :
386 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Pending update for register %d value %d\n",
387 : : idx, val);
388 : 0 : }
389 : :
390 : 0 : static void _pg_exe(struct ice_parser_rt *rt)
391 : : {
392 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Executing ParseGraph action ...\n");
393 : :
394 : 0 : _gpr_add(rt, GPR_NP_IDX, rt->action->next_pc);
395 : 0 : _gpr_add(rt, GPR_NN_IDX, rt->action->next_node);
396 : :
397 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Executing ParseGraph action done.\n");
398 : 0 : }
399 : :
400 : 0 : static void _flg_add(struct ice_parser_rt *rt, int idx, bool val)
401 : : {
402 : 0 : rt->pu.flg_msk |= (1ul << idx);
403 [ # # ]: 0 : if (val)
404 : 0 : rt->pu.flg_val |= (1ul << idx);
405 : : else
406 : 0 : rt->pu.flg_val &= ~(1ul << idx);
407 : :
408 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Pending update for flag %d value %d\n",
409 : : idx, val);
410 : 0 : }
411 : :
412 : 0 : static void _flg_update(struct ice_parser_rt *rt, struct ice_alu *alu)
413 : : {
414 : : int i;
415 : :
416 [ # # ]: 0 : if (alu->dedicate_flags_ena) {
417 [ # # ]: 0 : if (alu->flags_extr_imm) {
418 [ # # ]: 0 : for (i = 0; i < alu->dst_len; i++)
419 : 0 : _flg_add(rt, alu->dst_start + i,
420 : 0 : (alu->flags_start_imm &
421 : 0 : (1u << i)) != 0);
422 : : } else {
423 [ # # ]: 0 : for (i = 0; i < alu->dst_len; i++) {
424 : 0 : _flg_add(rt, alu->dst_start + i,
425 : 0 : _hv_bit_sel(rt,
426 : 0 : alu->flags_start_imm + i,
427 : : 1) != 0);
428 : : }
429 : : }
430 : : }
431 : 0 : }
432 : :
433 : 0 : static void _po_update(struct ice_parser_rt *rt, struct ice_alu *alu)
434 : : {
435 [ # # ]: 0 : if (alu->proto_offset_opc == 1)
436 : 0 : rt->po = (u16)(rt->gpr[GPR_HO_IDX] + alu->proto_offset);
437 [ # # ]: 0 : else if (alu->proto_offset_opc == 2)
438 : 0 : rt->po = (u16)(rt->gpr[GPR_HO_IDX] - alu->proto_offset);
439 [ # # ]: 0 : else if (alu->proto_offset_opc == 0)
440 : 0 : rt->po = rt->gpr[GPR_HO_IDX];
441 : :
442 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Update Protocol Offset = %d\n",
443 : : rt->po);
444 : 0 : }
445 : :
446 : 0 : static u16 _reg_bit_sel(struct ice_parser_rt *rt, int reg_idx,
447 : : int start, int len)
448 : : {
449 : : u32 msk;
450 : : union {
451 : : u32 d32;
452 : : u8 b[4];
453 : : } bit_sel;
454 : :
455 [ # # ]: 0 : ice_memcpy(bit_sel.b, &rt->gpr[reg_idx + start / 16], 4,
456 : : ICE_NONDMA_TO_NONDMA);
457 : :
458 : 0 : bit_sel.b[0] = _bit_rev_u8(bit_sel.b[0]);
459 : 0 : bit_sel.b[1] = _bit_rev_u8(bit_sel.b[1]);
460 : 0 : bit_sel.b[2] = _bit_rev_u8(bit_sel.b[2]);
461 : 0 : bit_sel.b[3] = _bit_rev_u8(bit_sel.b[3]);
462 : :
463 : 0 : msk = (1u << len) - 1;
464 : :
465 : 0 : return _bit_rev_u16((u16)((bit_sel.d32 >> (start % 16)) & msk), len);
466 : : }
467 : :
468 : 0 : static void _err_add(struct ice_parser_rt *rt, int idx, bool val)
469 : : {
470 : 0 : rt->pu.err_msk |= (u16)(1 << idx);
471 [ # # ]: 0 : if (val)
472 : 0 : rt->pu.flg_val |= (u16)(1 << idx);
473 : : else
474 : 0 : rt->pu.flg_val &= ~(u16)(1 << idx);
475 : :
476 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Pending update for error %d value %d\n",
477 : : idx, val);
478 : 0 : }
479 : :
480 : 0 : static void _dst_reg_bit_set(struct ice_parser_rt *rt, struct ice_alu *alu,
481 : : bool val)
482 : : {
483 : : u16 flg_idx;
484 : :
485 [ # # ]: 0 : if (alu->dedicate_flags_ena) {
486 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "DedicatedFlagsEnable should not be enabled in opcode %d\n",
487 : : alu->opc);
488 : 0 : return;
489 : : }
490 : :
491 [ # # ]: 0 : if (alu->dst_reg_id == GPR_ERR_IDX) {
492 [ # # ]: 0 : if (alu->dst_start >= 16) {
493 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Invalid error %d\n",
494 : : alu->dst_start);
495 : 0 : return;
496 : : }
497 : 0 : _err_add(rt, alu->dst_start, val);
498 [ # # ]: 0 : } else if (alu->dst_reg_id >= GPR_FLG_IDX) {
499 : 0 : flg_idx = (u16)(((alu->dst_reg_id - GPR_FLG_IDX) << 4) +
500 : 0 : alu->dst_start);
501 : :
502 [ # # ]: 0 : if (flg_idx >= 64) {
503 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Invalid flag %d\n",
504 : : flg_idx);
505 : 0 : return;
506 : : }
507 : 0 : _flg_add(rt, flg_idx, val);
508 : : } else {
509 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Unexpected Dest Register Bit set, RegisterID %d Start %d\n",
510 : : alu->dst_reg_id, alu->dst_start);
511 : : }
512 : : }
513 : :
514 : 0 : static void _alu_exe(struct ice_parser_rt *rt, struct ice_alu *alu)
515 : : {
516 : : u16 dst, src, shift, imm;
517 : :
518 [ # # ]: 0 : if (alu->shift_xlate_select) {
519 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "shift_xlate_select != 0 is not expected\n");
520 : 0 : return;
521 : : }
522 : :
523 : 0 : _po_update(rt, alu);
524 : 0 : _flg_update(rt, alu);
525 : :
526 : 0 : dst = rt->gpr[alu->dst_reg_id];
527 : 0 : src = _reg_bit_sel(rt, alu->src_reg_id, alu->src_start, alu->src_len);
528 : 0 : shift = alu->shift_xlate_key;
529 : 0 : imm = alu->imm;
530 : :
531 [ # # # # : 0 : switch (alu->opc) {
# # # # ]
532 : : case ICE_ALU_PARK:
533 : : break;
534 : 0 : case ICE_ALU_MOV_ADD:
535 : 0 : dst = (u16)((src << shift) + imm);
536 : 0 : _gpr_add(rt, alu->dst_reg_id, dst);
537 : 0 : break;
538 : 0 : case ICE_ALU_ADD:
539 : 0 : dst += (u16)((src << shift) + imm);
540 : 0 : _gpr_add(rt, alu->dst_reg_id, dst);
541 : 0 : break;
542 : 0 : case ICE_ALU_ORLT:
543 [ # # ]: 0 : if (src < imm)
544 : 0 : _dst_reg_bit_set(rt, alu, true);
545 : 0 : _gpr_add(rt, GPR_NP_IDX, alu->branch_addr);
546 : 0 : break;
547 : 0 : case ICE_ALU_OREQ:
548 [ # # ]: 0 : if (src == imm)
549 : 0 : _dst_reg_bit_set(rt, alu, true);
550 : 0 : _gpr_add(rt, GPR_NP_IDX, alu->branch_addr);
551 : 0 : break;
552 : 0 : case ICE_ALU_SETEQ:
553 [ # # ]: 0 : if (src == imm)
554 : 0 : _dst_reg_bit_set(rt, alu, true);
555 : : else
556 : 0 : _dst_reg_bit_set(rt, alu, false);
557 : 0 : _gpr_add(rt, GPR_NP_IDX, alu->branch_addr);
558 : 0 : break;
559 : 0 : case ICE_ALU_MOV_XOR:
560 : 0 : dst = (u16)((u16)(src << shift) ^ (u16)imm);
561 : 0 : _gpr_add(rt, alu->dst_reg_id, dst);
562 : 0 : break;
563 : 0 : default:
564 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Unsupported ALU instruction %d\n",
565 : : alu->opc);
566 : : break;
567 : : }
568 : : }
569 : :
570 : 0 : static void _alu0_exe(struct ice_parser_rt *rt)
571 : : {
572 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Executing ALU0 ...\n");
573 : 0 : _alu_exe(rt, rt->alu0);
574 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Executing ALU0 done.\n");
575 : 0 : }
576 : :
577 : 0 : static void _alu1_exe(struct ice_parser_rt *rt)
578 : : {
579 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Executing ALU1 ...\n");
580 : 0 : _alu_exe(rt, rt->alu1);
581 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Executing ALU1 done.\n");
582 : 0 : }
583 : :
584 : 0 : static void _alu2_exe(struct ice_parser_rt *rt)
585 : : {
586 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Executing ALU2 ...\n");
587 : 0 : _alu_exe(rt, rt->alu2);
588 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Executing ALU2 done.\n");
589 : 0 : }
590 : :
591 : 0 : static void _pu_exe(struct ice_parser_rt *rt)
592 : : {
593 : : struct ice_gpr_pu *pu = &rt->pu;
594 : : int i;
595 : :
596 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Updating Registers ...\n");
597 : :
598 [ # # ]: 0 : for (i = 0; i < ICE_PARSER_GPR_NUM; i++) {
599 [ # # ]: 0 : if (pu->gpr_val_upd[i])
600 : 0 : _rt_gpr_set(rt, i, pu->gpr_val[i]);
601 : : }
602 : :
603 [ # # ]: 0 : for (i = 0; i < 64; i++) {
604 [ # # ]: 0 : if (pu->flg_msk & (1ul << i))
605 : 0 : _rt_flag_set(rt, i, pu->flg_val & (1ul << i));
606 : : }
607 : :
608 [ # # ]: 0 : for (i = 0; i < 16; i++) {
609 [ # # ]: 0 : if (pu->err_msk & (1u << 1))
610 : 0 : _rt_err_set(rt, i, pu->err_val & (1u << i));
611 : : }
612 : :
613 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Updating Registers done.\n");
614 : 0 : }
615 : :
616 : 0 : static void _alu_pg_exe(struct ice_parser_rt *rt)
617 : : {
618 [ # # ]: 0 : ice_memset(&rt->pu, 0, sizeof(rt->pu), ICE_NONDMA_MEM);
619 : :
620 [ # # ]: 0 : if (rt->pg == 0) {
621 : 0 : _pg_exe(rt);
622 : 0 : _alu0_exe(rt);
623 : 0 : _alu1_exe(rt);
624 : 0 : _alu2_exe(rt);
625 [ # # ]: 0 : } else if (rt->pg == 1) {
626 : 0 : _alu0_exe(rt);
627 : 0 : _pg_exe(rt);
628 : 0 : _alu1_exe(rt);
629 : 0 : _alu2_exe(rt);
630 [ # # ]: 0 : } else if (rt->pg == 2) {
631 : 0 : _alu0_exe(rt);
632 : 0 : _alu1_exe(rt);
633 : 0 : _pg_exe(rt);
634 : 0 : _alu2_exe(rt);
635 [ # # ]: 0 : } else if (rt->pg == 3) {
636 : 0 : _alu0_exe(rt);
637 : 0 : _alu1_exe(rt);
638 : 0 : _alu2_exe(rt);
639 : 0 : _pg_exe(rt);
640 : : }
641 : :
642 : 0 : _pu_exe(rt);
643 : :
644 [ # # ]: 0 : if (rt->action->ho_inc == 0)
645 : : return;
646 : :
647 [ # # ]: 0 : if (rt->action->ho_polarity)
648 [ # # ]: 0 : _rt_ho_set(rt, rt->gpr[GPR_HO_IDX] + rt->action->ho_inc);
649 : : else
650 [ # # ]: 0 : _rt_ho_set(rt, rt->gpr[GPR_HO_IDX] - rt->action->ho_inc);
651 : : }
652 : :
653 : 0 : static void _proto_off_update(struct ice_parser_rt *rt)
654 : : {
655 : 0 : struct ice_parser *psr = rt->psr;
656 : : int i;
657 : :
658 [ # # ]: 0 : if (rt->action->is_pg) {
659 : 0 : struct ice_proto_grp_item *proto_grp =
660 : 0 : &psr->proto_grp_table[rt->action->proto_id];
661 : : u16 po;
662 : :
663 [ # # ]: 0 : for (i = 0; i < 8; i++) {
664 : : struct ice_proto_off *entry = &proto_grp->po[i];
665 : :
666 [ # # ]: 0 : if (entry->proto_id == 0xff)
667 : : break;
668 : :
669 [ # # ]: 0 : if (!entry->polarity)
670 : 0 : po = (u16)(rt->po + entry->offset);
671 : : else
672 : 0 : po = (u16)(rt->po - entry->offset);
673 : :
674 : 0 : rt->protocols[entry->proto_id] = true;
675 : 0 : rt->offsets[entry->proto_id] = po;
676 : :
677 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Set Protocol %d at offset %d\n",
678 : : entry->proto_id, po);
679 : : }
680 : : } else {
681 : 0 : rt->protocols[rt->action->proto_id] = true;
682 : 0 : rt->offsets[rt->action->proto_id] = rt->po;
683 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Set Protocol %d at offset %d\n",
684 : : rt->action->proto_id, rt->po);
685 : : }
686 : 0 : }
687 : :
688 : : static void _marker_set(struct ice_parser_rt *rt, int idx)
689 : : {
690 : 0 : int x = idx / 8;
691 : : int y = idx % 8;
692 : :
693 : 0 : rt->markers[x] |= (u8)(1u << y);
694 : 0 : }
695 : :
696 : 0 : static void _marker_update(struct ice_parser_rt *rt)
697 : : {
698 : 0 : struct ice_parser *psr = rt->psr;
699 : : int i;
700 : :
701 [ # # ]: 0 : if (rt->action->is_mg) {
702 : 0 : struct ice_mk_grp_item *mk_grp =
703 : 0 : &psr->mk_grp_table[rt->action->marker_id];
704 : :
705 [ # # ]: 0 : for (i = 0; i < 8; i++) {
706 : 0 : u8 marker = mk_grp->markers[i];
707 : :
708 [ # # ]: 0 : if (marker == 71)
709 : : break;
710 : :
711 : 0 : _marker_set(rt, marker);
712 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Set Marker %d\n",
713 : : marker);
714 : : }
715 : : } else {
716 [ # # ]: 0 : if (rt->action->marker_id != 71)
717 : 0 : _marker_set(rt, rt->action->marker_id);
718 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Set Marker %d\n",
719 : : rt->action->marker_id);
720 : : }
721 : 0 : }
722 : :
723 : : static u16 _ptype_resolve(struct ice_parser_rt *rt)
724 : : {
725 : 0 : struct ice_parser *psr = rt->psr;
726 : : struct ice_ptype_mk_tcam_item *item;
727 : :
728 : 0 : item = ice_ptype_mk_tcam_match(psr->ptype_mk_tcam_table,
729 : 0 : rt->markers, 9);
730 [ # # ]: 0 : if (item)
731 : 0 : return item->ptype;
732 : : return 0xffff;
733 : : }
734 : :
735 : : static void _proto_off_resolve(struct ice_parser_rt *rt,
736 : : struct ice_parser_result *rslt)
737 : : {
738 : : int i;
739 : :
740 [ # # ]: 0 : for (i = 0; i < 255; i++) {
741 [ # # ]: 0 : if (rt->protocols[i]) {
742 : 0 : rslt->po[rslt->po_num].proto_id = (u8)i;
743 : 0 : rslt->po[rslt->po_num].offset = rt->offsets[i];
744 : 0 : rslt->po_num++;
745 : : }
746 : : }
747 : : }
748 : :
749 : 0 : static void _result_resolve(struct ice_parser_rt *rt,
750 : : struct ice_parser_result *rslt)
751 : : {
752 : 0 : struct ice_parser *psr = rt->psr;
753 : :
754 : : ice_memset(rslt, 0, sizeof(*rslt), ICE_NONDMA_MEM);
755 : :
756 : 0 : rslt->ptype = _ptype_resolve(rt);
757 : :
758 [ # # ]: 0 : ice_memcpy(&rslt->flags_psr, &rt->gpr[GPR_FLG_IDX], 8,
759 : : ICE_NONDMA_TO_NONDMA);
760 : 0 : rslt->flags_pkt = ice_flg_redirect(psr->flg_rd_table, rslt->flags_psr);
761 : 0 : rslt->flags_sw = ice_xlt_kb_flag_get(psr->xlt_kb_sw, rslt->flags_pkt);
762 : 0 : rslt->flags_fd = ice_xlt_kb_flag_get(psr->xlt_kb_fd, rslt->flags_pkt);
763 : 0 : rslt->flags_rss = ice_xlt_kb_flag_get(psr->xlt_kb_rss, rslt->flags_pkt);
764 : :
765 : : _proto_off_resolve(rt, rslt);
766 : 0 : }
767 : :
768 : : /**
769 : : * ice_parser_rt_execute - parser execution routine
770 : : * @rt: pointer to the parser runtime
771 : : * @rslt: input/output parameter to save parser result
772 : : */
773 : 0 : enum ice_status ice_parser_rt_execute(struct ice_parser_rt *rt,
774 : : struct ice_parser_result *rslt)
775 : : {
776 : : enum ice_status status = ICE_SUCCESS;
777 : : struct ice_pg_nm_cam_item *pg_nm_cam;
778 : 0 : struct ice_parser *psr = rt->psr;
779 : : struct ice_pg_cam_item *pg_cam;
780 : : struct ice_bst_tcam_item *bst;
781 : : struct ice_imem_item *imem;
782 : : u16 node;
783 : : u16 pc;
784 : :
785 : 0 : node = rt->gpr[GPR_NN_IDX];
786 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Start with Node: %d\n", node);
787 : :
788 : : while (true) {
789 : 0 : pc = rt->gpr[GPR_NP_IDX];
790 : 0 : imem = &psr->imem_table[pc];
791 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Load imem at pc: %d\n",
792 : : pc);
793 : :
794 : 0 : _bst_key_init(rt, imem);
795 : 0 : bst = ice_bst_tcam_match(psr->bst_tcam_table, rt->bst_key);
796 : :
797 [ # # ]: 0 : if (!bst) {
798 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "No Boost TCAM Match\n");
799 : 0 : _imem_pgk_init(rt, imem);
800 : 0 : _imem_alu0_set(rt, imem);
801 : 0 : _imem_alu1_set(rt, imem);
802 : 0 : _imem_alu2_set(rt, imem);
803 : 0 : _imem_pgp_set(rt, imem);
804 : : } else {
805 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Boost TCAM Match address: %d\n",
806 : : bst->address);
807 [ # # ]: 0 : if (imem->b_m.pg) {
808 : 0 : _bst_pgk_init(rt, bst);
809 : 0 : _bst_pgp_set(rt, bst);
810 : : } else {
811 : 0 : _imem_pgk_init(rt, imem);
812 : 0 : _imem_pgp_set(rt, imem);
813 : : }
814 : :
815 [ # # ]: 0 : if (imem->b_m.al0)
816 : 0 : _bst_alu0_set(rt, bst);
817 : : else
818 : 0 : _imem_alu0_set(rt, imem);
819 : :
820 [ # # ]: 0 : if (imem->b_m.al1)
821 : 0 : _bst_alu1_set(rt, bst);
822 : : else
823 : 0 : _imem_alu1_set(rt, imem);
824 : :
825 [ # # ]: 0 : if (imem->b_m.al2)
826 : 0 : _bst_alu2_set(rt, bst);
827 : : else
828 : 0 : _imem_alu2_set(rt, imem);
829 : : }
830 : :
831 : 0 : rt->action = NULL;
832 : 0 : pg_cam = _pg_cam_match(rt);
833 [ # # ]: 0 : if (!pg_cam) {
834 : 0 : pg_nm_cam = _pg_nm_cam_match(rt);
835 [ # # ]: 0 : if (pg_nm_cam) {
836 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Match ParseGraph Nomatch CAM Address %d\n",
837 : : pg_nm_cam->idx);
838 : 0 : rt->action = &pg_nm_cam->action;
839 : : }
840 : : } else {
841 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Match ParseGraph CAM Address %d\n",
842 : : pg_cam->idx);
843 : 0 : rt->action = &pg_cam->action;
844 : : }
845 : :
846 [ # # ]: 0 : if (!rt->action) {
847 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Failed to match ParseGraph CAM, stop parsing.\n");
848 : : status = ICE_ERR_PARAM;
849 : : break;
850 : : }
851 : :
852 : 0 : _alu_pg_exe(rt);
853 : 0 : _marker_update(rt);
854 : 0 : _proto_off_update(rt);
855 : :
856 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Go to node %d\n",
857 : : rt->action->next_node);
858 : :
859 [ # # ]: 0 : if (rt->action->is_last_round) {
860 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Last Round in ParseGraph Action, stop parsing.\n");
861 : : break;
862 : : }
863 : :
864 [ # # ]: 0 : if (rt->gpr[GPR_HO_IDX] >= rt->pkt_len) {
865 [ # # ]: 0 : ice_debug(rt->psr->hw, ICE_DBG_PARSER, "Header Offset %d is larger than packet len %d, stop parsing\n",
866 : : rt->gpr[GPR_HO_IDX], rt->pkt_len);
867 : : break;
868 : : }
869 : : }
870 : :
871 : 0 : _result_resolve(rt, rslt);
872 : :
873 : 0 : return status;
874 : : }
|