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_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
ice_bit_rev_u16(u16 v,int len)146 static u16 ice_bit_rev_u16(u16 v, int len)
147 {
148 return bitrev16(v) >> (BITS_PER_TYPE(v) - len);
149 }
150
ice_bit_rev_u32(u32 v,int len)151 static u32 ice_bit_rev_u32(u32 v, int len)
152 {
153 return bitrev32(v) >> (BITS_PER_TYPE(v) - len);
154 }
155
ice_hv_bit_sel(struct ice_parser_rt * rt,int start,int len)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
ice_pk_build(struct ice_parser_rt * rt,struct ice_np_keybuilder * kb)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
ice_flag_get(struct ice_parser_rt * rt,unsigned int index)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
ice_imem_pgk_init(struct ice_parser_rt * rt,struct ice_imem_item * imem)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
ice_imem_alu0_set(struct ice_parser_rt * rt,struct ice_imem_item * imem)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
ice_imem_alu1_set(struct ice_parser_rt * rt,struct ice_imem_item * imem)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
ice_imem_alu2_set(struct ice_parser_rt * rt,struct ice_imem_item * imem)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
ice_imem_pgp_set(struct ice_parser_rt * rt,struct ice_imem_item * imem)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
ice_bst_pgk_init(struct ice_parser_rt * rt,struct ice_bst_tcam_item * bst)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
ice_bst_alu0_set(struct ice_parser_rt * rt,struct ice_bst_tcam_item * bst)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
ice_bst_alu1_set(struct ice_parser_rt * rt,struct ice_bst_tcam_item * bst)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
ice_bst_alu2_set(struct ice_parser_rt * rt,struct ice_bst_tcam_item * bst)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
ice_bst_pgp_set(struct ice_parser_rt * rt,struct ice_bst_tcam_item * bst)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
ice_rt_pg_cam_match(struct ice_parser_rt * rt)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
ice_rt_pg_nm_cam_match(struct ice_parser_rt * rt)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
ice_gpr_add(struct ice_parser_rt * rt,int idx,u16 val)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
ice_pg_exe(struct ice_parser_rt * rt)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
ice_flg_add(struct ice_parser_rt * rt,int idx,bool val)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
ice_flg_update(struct ice_parser_rt * rt,struct ice_alu * alu)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
ice_po_update(struct ice_parser_rt * rt,struct ice_alu * alu)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
ice_reg_bit_sel(struct ice_parser_rt * rt,int reg_idx,int start,int len)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
ice_err_add(struct ice_parser_rt * rt,int idx,bool val)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
ice_dst_reg_bit_set(struct ice_parser_rt * rt,struct ice_alu * alu,bool val)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
ice_alu_exe(struct ice_parser_rt * rt,struct ice_alu * alu)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
ice_alu0_exe(struct ice_parser_rt * rt)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
ice_alu1_exe(struct ice_parser_rt * rt)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
ice_alu2_exe(struct ice_parser_rt * rt)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
ice_pu_exe(struct ice_parser_rt * rt)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
ice_alu_pg_exe(struct ice_parser_rt * rt)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
ice_proto_off_update(struct ice_parser_rt * rt)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
ice_marker_set(struct ice_parser_rt * rt,int idx)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
ice_marker_update(struct ice_parser_rt * rt)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
ice_ptype_resolve(struct ice_parser_rt * rt)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
ice_proto_off_resolve(struct ice_parser_rt * rt,struct ice_parser_result * rslt)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
ice_result_resolve(struct ice_parser_rt * rt,struct ice_parser_result * rslt)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 */
ice_parser_rt_execute(struct ice_parser_rt * rt,struct ice_parser_result * rslt)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