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