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