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