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