brintos

brintos / linux-shallow public Read only

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