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