Linux Audio

Check our new training course

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