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