xref: /linux/drivers/net/ethernet/intel/ice/ice_parser_rt.c (revision 9410645520e9b820069761f3450ef6661418e279)
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