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