1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2024 Intel Corporation */ 3 4 #include "ice_common.h" 5 6 static void ice_rt_tsr_set(struct ice_parser_rt *rt, u16 tsr) 7 { 8 rt->gpr[ICE_GPR_TSR_IDX] = tsr; 9 } 10 11 static 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 17 static void ice_rt_np_set(struct ice_parser_rt *rt, u16 pc) 18 { 19 rt->gpr[ICE_GPR_NP_IDX] = pc; 20 } 21 22 static void ice_rt_nn_set(struct ice_parser_rt *rt, u16 node) 23 { 24 rt->gpr[ICE_GPR_NN_IDX] = node; 25 } 26 27 static void 28 ice_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 45 static 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 57 static 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 */ 74 void 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 */ 102 void 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 114 static 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_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 else 136 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 146 static u16 ice_bit_rev_u16(u16 v, int len) 147 { 148 return bitrev16(v) >> (BITS_PER_TYPE(v) - len); 149 } 150 151 static u32 ice_bit_rev_u32(u32 v, int len) 152 { 153 return bitrev32(v) >> (BITS_PER_TYPE(v) - len); 154 } 155 156 static 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 175 static 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 191 static 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 199 static 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 232 static 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 240 static 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 248 static 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 256 static 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 264 static 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 298 static 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 306 static 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 314 static 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 322 static 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 330 static 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 343 static 344 struct 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 359 static 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 368 static 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 378 static 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 else 384 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 390 static 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 412 static 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 425 static 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 441 static 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 else 447 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 453 static 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 487 static 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 541 static 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 548 static 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 555 static 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 562 static 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 587 static 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 else 626 ice_rt_ho_set(rt, rt->gpr[ICE_GPR_HO_IDX] - rt->action->ho_inc); 627 } 628 629 static 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 else 648 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 665 static 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 673 static 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 701 static 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 715 static 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 729 static 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 routine 749 * @rt: pointer to the parser runtime 750 * @rslt: input/output parameter to save parser result 751 * 752 * Return: 0 on success or errno. 753 */ 754 int 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 else 805 ice_imem_alu0_set(rt, imem); 806 807 if (imem->b_m.alu1) 808 ice_bst_alu1_set(rt, bst); 809 else 810 ice_imem_alu1_set(rt, imem); 811 812 if (imem->b_m.alu2) 813 ice_bst_alu2_set(rt, bst); 814 else 815 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