xref: /dpdk/drivers/net/bnxt/tf_core/tf_msg.c (revision f5057be340e44f3edc0fe90fa875eb89a4c49b4f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 Broadcom
3  * All rights reserved.
4  */
5 
6 #include <assert.h>
7 #include <inttypes.h>
8 #include <stdbool.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include "tf_msg_common.h"
13 #include "tf_device.h"
14 #include "tf_msg.h"
15 #include "tf_util.h"
16 #include "tf_common.h"
17 #include "tf_session.h"
18 #include "tfp.h"
19 #include "hwrm_tf.h"
20 #include "tf_em.h"
21 
22 /* Logging defines */
23 #define TF_RM_MSG_DEBUG  0
24 
25 /* Specific msg size defines as we cannot use defines in tf.yaml. This
26  * means we have to manually sync hwrm with these defines if the
27  * tf.yaml changes.
28  */
29 #define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE  16
30 #define TF_MSG_EM_INSERT_KEY_SIZE        64
31 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE    88
32 
33 /* Compile check - Catch any msg changes that we depend on, like the
34  * defines listed above for array size checking.
35  *
36  * Checking array size is dangerous in that the type could change and
37  * we wouldn't be able to catch it. Thus we check if the complete msg
38  * changed instead. Best we can do.
39  *
40  * If failure is observed then both msg size (defines below) and the
41  * array size (define above) should be checked and compared.
42  */
43 #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56
44 static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
45 	      TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET,
46 	      "HWRM message size changed: hwrm_tf_global_cfg_set_input");
47 
48 #define TF_MSG_SIZE_HWRM_TF_EM_INSERT      104
49 static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
50 	      TF_MSG_SIZE_HWRM_TF_EM_INSERT,
51 	      "HWRM message size changed: hwrm_tf_em_insert_input");
52 
53 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET   128
54 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
55 	      TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
56 	      "HWRM message size changed: hwrm_tf_tbl_type_set_input");
57 
58 /**
59  * This is the MAX data we can transport across regular HWRM
60  */
61 #define TF_PCI_BUF_SIZE_MAX 88
62 
63 /**
64  * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
65  */
66 struct tf_msg_dma_buf {
67 	void *va_addr;
68 	uint64_t pa_addr;
69 };
70 
71 /**
72  * Allocates a DMA buffer that can be used for message transfer.
73  *
74  * [in] buf
75  *   Pointer to DMA buffer structure
76  *
77  * [in] size
78  *   Requested size of the buffer in bytes
79  *
80  * Returns:
81  *    0      - Success
82  *   -ENOMEM - Unable to allocate buffer, no memory
83  */
84 static int
85 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
86 {
87 	struct tfp_calloc_parms alloc_parms;
88 	int rc;
89 
90 	/* Allocate session */
91 	alloc_parms.nitems = 1;
92 	alloc_parms.size = size;
93 	alloc_parms.alignment = 4096;
94 	rc = tfp_calloc(&alloc_parms);
95 	if (rc)
96 		return -ENOMEM;
97 
98 	buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
99 	buf->va_addr = alloc_parms.mem_va;
100 
101 	return 0;
102 }
103 
104 /**
105  * Free's a previous allocated DMA buffer.
106  *
107  * [in] buf
108  *   Pointer to DMA buffer structure
109  */
110 static void
111 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
112 {
113 	tfp_free(buf->va_addr);
114 }
115 
116 /* HWRM Direct messages */
117 
118 int
119 tf_msg_session_open(struct tf *tfp,
120 		    char *ctrl_chan_name,
121 		    uint8_t *fw_session_id,
122 		    uint8_t *fw_session_client_id)
123 {
124 	int rc;
125 	struct hwrm_tf_session_open_input req = { 0 };
126 	struct hwrm_tf_session_open_output resp = { 0 };
127 	struct tfp_send_msg_parms parms = { 0 };
128 
129 	/* Populate the request */
130 	tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
131 
132 	parms.tf_type = HWRM_TF_SESSION_OPEN;
133 	parms.req_data = (uint32_t *)&req;
134 	parms.req_size = sizeof(req);
135 	parms.resp_data = (uint32_t *)&resp;
136 	parms.resp_size = sizeof(resp);
137 	parms.mailbox = TF_KONG_MB;
138 
139 	rc = tfp_send_msg_direct(tfp,
140 				 &parms);
141 	if (rc)
142 		return rc;
143 
144 	*fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
145 	*fw_session_client_id =
146 		(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
147 
148 	return rc;
149 }
150 
151 int
152 tf_msg_session_attach(struct tf *tfp __rte_unused,
153 		      char *ctrl_chan_name __rte_unused,
154 		      uint8_t tf_fw_session_id __rte_unused)
155 {
156 	return -1;
157 }
158 
159 int
160 tf_msg_session_client_register(struct tf *tfp,
161 			       char *ctrl_channel_name,
162 			       uint8_t *fw_session_client_id)
163 {
164 	int rc;
165 	struct hwrm_tf_session_register_input req = { 0 };
166 	struct hwrm_tf_session_register_output resp = { 0 };
167 	struct tfp_send_msg_parms parms = { 0 };
168 	uint8_t fw_session_id;
169 
170 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
171 	if (rc) {
172 		TFP_DRV_LOG(ERR,
173 			    "Unable to lookup FW id, rc:%s\n",
174 			    strerror(-rc));
175 		return rc;
176 	}
177 
178 	/* Populate the request */
179 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
180 	tfp_memcpy(&req.session_client_name,
181 		   ctrl_channel_name,
182 		   TF_SESSION_NAME_MAX);
183 
184 	parms.tf_type = HWRM_TF_SESSION_REGISTER;
185 	parms.req_data = (uint32_t *)&req;
186 	parms.req_size = sizeof(req);
187 	parms.resp_data = (uint32_t *)&resp;
188 	parms.resp_size = sizeof(resp);
189 	parms.mailbox = TF_KONG_MB;
190 
191 	rc = tfp_send_msg_direct(tfp,
192 				 &parms);
193 	if (rc)
194 		return rc;
195 
196 	*fw_session_client_id =
197 		(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
198 
199 	return rc;
200 }
201 
202 int
203 tf_msg_session_client_unregister(struct tf *tfp,
204 				 uint8_t fw_session_client_id)
205 {
206 	int rc;
207 	struct hwrm_tf_session_unregister_input req = { 0 };
208 	struct hwrm_tf_session_unregister_output resp = { 0 };
209 	struct tfp_send_msg_parms parms = { 0 };
210 	uint8_t fw_session_id;
211 
212 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
213 	if (rc) {
214 		TFP_DRV_LOG(ERR,
215 			    "Unable to lookup FW id, rc:%s\n",
216 			    strerror(-rc));
217 		return rc;
218 	}
219 
220 	/* Populate the request */
221 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
222 	req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
223 
224 	parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
225 	parms.req_data = (uint32_t *)&req;
226 	parms.req_size = sizeof(req);
227 	parms.resp_data = (uint32_t *)&resp;
228 	parms.resp_size = sizeof(resp);
229 	parms.mailbox = TF_KONG_MB;
230 
231 	rc = tfp_send_msg_direct(tfp,
232 				 &parms);
233 
234 	return rc;
235 }
236 
237 int
238 tf_msg_session_close(struct tf *tfp)
239 {
240 	int rc;
241 	struct hwrm_tf_session_close_input req = { 0 };
242 	struct hwrm_tf_session_close_output resp = { 0 };
243 	struct tfp_send_msg_parms parms = { 0 };
244 	uint8_t fw_session_id;
245 
246 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
247 	if (rc) {
248 		TFP_DRV_LOG(ERR,
249 			    "Unable to lookup FW id, rc:%s\n",
250 			    strerror(-rc));
251 		return rc;
252 	}
253 
254 	/* Populate the request */
255 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
256 
257 	parms.tf_type = HWRM_TF_SESSION_CLOSE;
258 	parms.req_data = (uint32_t *)&req;
259 	parms.req_size = sizeof(req);
260 	parms.resp_data = (uint32_t *)&resp;
261 	parms.resp_size = sizeof(resp);
262 	parms.mailbox = TF_KONG_MB;
263 
264 	rc = tfp_send_msg_direct(tfp,
265 				 &parms);
266 	return rc;
267 }
268 
269 int
270 tf_msg_session_qcfg(struct tf *tfp)
271 {
272 	int rc;
273 	struct hwrm_tf_session_qcfg_input req = { 0 };
274 	struct hwrm_tf_session_qcfg_output resp = { 0 };
275 	struct tfp_send_msg_parms parms = { 0 };
276 	uint8_t fw_session_id;
277 
278 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
279 	if (rc) {
280 		TFP_DRV_LOG(ERR,
281 			    "Unable to lookup FW id, rc:%s\n",
282 			    strerror(-rc));
283 		return rc;
284 	}
285 
286 	/* Populate the request */
287 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
288 
289 	parms.tf_type = HWRM_TF_SESSION_QCFG,
290 	parms.req_data = (uint32_t *)&req;
291 	parms.req_size = sizeof(req);
292 	parms.resp_data = (uint32_t *)&resp;
293 	parms.resp_size = sizeof(resp);
294 	parms.mailbox = TF_KONG_MB;
295 
296 	rc = tfp_send_msg_direct(tfp,
297 				 &parms);
298 	return rc;
299 }
300 
301 int
302 tf_msg_session_resc_qcaps(struct tf *tfp,
303 			  enum tf_dir dir,
304 			  uint16_t size,
305 			  struct tf_rm_resc_req_entry *query,
306 			  enum tf_rm_resc_resv_strategy *resv_strategy)
307 {
308 	int rc;
309 	int i;
310 	struct tfp_send_msg_parms parms = { 0 };
311 	struct hwrm_tf_session_resc_qcaps_input req = { 0 };
312 	struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
313 	uint8_t fw_session_id;
314 	struct tf_msg_dma_buf qcaps_buf = { 0 };
315 	struct tf_rm_resc_req_entry *data;
316 	int dma_size;
317 
318 	TF_CHECK_PARMS3(tfp, query, resv_strategy);
319 
320 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
321 	if (rc) {
322 		TFP_DRV_LOG(ERR,
323 			    "%s: Unable to lookup FW id, rc:%s\n",
324 			    tf_dir_2_str(dir),
325 			    strerror(-rc));
326 		return rc;
327 	}
328 
329 	/* Prepare DMA buffer */
330 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
331 	rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
332 	if (rc)
333 		return rc;
334 
335 	/* Populate the request */
336 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
337 	req.flags = tfp_cpu_to_le_16(dir);
338 	req.qcaps_size = size;
339 	req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
340 
341 	parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
342 	parms.req_data = (uint32_t *)&req;
343 	parms.req_size = sizeof(req);
344 	parms.resp_data = (uint32_t *)&resp;
345 	parms.resp_size = sizeof(resp);
346 	parms.mailbox = TF_KONG_MB;
347 
348 	rc = tfp_send_msg_direct(tfp, &parms);
349 	if (rc)
350 		goto cleanup;
351 
352 	/* Process the response
353 	 * Should always get expected number of entries
354 	 */
355 	if (tfp_le_to_cpu_32(resp.size) != size) {
356 		TFP_DRV_LOG(ERR,
357 			    "%s: QCAPS message size error, rc:%s\n",
358 			    tf_dir_2_str(dir),
359 			    strerror(EINVAL));
360 		rc = -EINVAL;
361 		goto cleanup;
362 	}
363 
364 #if (TF_RM_MSG_DEBUG == 1)
365 	printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
366 #endif /* (TF_RM_MSG_DEBUG == 1) */
367 
368 	/* Post process the response */
369 	data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
370 
371 #if (TF_RM_MSG_DEBUG == 1)
372 	printf("\nQCAPS\n");
373 #endif /* (TF_RM_MSG_DEBUG == 1) */
374 	for (i = 0; i < size; i++) {
375 		query[i].type = tfp_le_to_cpu_32(data[i].type);
376 		query[i].min = tfp_le_to_cpu_16(data[i].min);
377 		query[i].max = tfp_le_to_cpu_16(data[i].max);
378 
379 #if (TF_RM_MSG_DEBUG == 1)
380 		printf("type: %d(0x%x) %d %d\n",
381 		       query[i].type,
382 		       query[i].type,
383 		       query[i].min,
384 		       query[i].max);
385 #endif /* (TF_RM_MSG_DEBUG == 1) */
386 
387 	}
388 
389 	*resv_strategy = resp.flags &
390 	      HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
391 
392 cleanup:
393 	tf_msg_free_dma_buf(&qcaps_buf);
394 
395 	return rc;
396 }
397 
398 int
399 tf_msg_session_resc_alloc(struct tf *tfp,
400 			  enum tf_dir dir,
401 			  uint16_t size,
402 			  struct tf_rm_resc_req_entry *request,
403 			  struct tf_rm_resc_entry *resv)
404 {
405 	int rc;
406 	int i;
407 	struct tfp_send_msg_parms parms = { 0 };
408 	struct hwrm_tf_session_resc_alloc_input req = { 0 };
409 	struct hwrm_tf_session_resc_alloc_output resp = { 0 };
410 	uint8_t fw_session_id;
411 	struct tf_msg_dma_buf req_buf = { 0 };
412 	struct tf_msg_dma_buf resv_buf = { 0 };
413 	struct tf_rm_resc_req_entry *req_data;
414 	struct tf_rm_resc_entry *resv_data;
415 	int dma_size;
416 
417 	TF_CHECK_PARMS3(tfp, request, resv);
418 
419 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
420 	if (rc) {
421 		TFP_DRV_LOG(ERR,
422 			    "%s: Unable to lookup FW id, rc:%s\n",
423 			    tf_dir_2_str(dir),
424 			    strerror(-rc));
425 		return rc;
426 	}
427 
428 	/* Prepare DMA buffers */
429 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
430 	rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
431 	if (rc)
432 		return rc;
433 
434 	dma_size = size * sizeof(struct tf_rm_resc_entry);
435 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
436 	if (rc) {
437 		tf_msg_free_dma_buf(&req_buf);
438 		return rc;
439 	}
440 
441 	/* Populate the request */
442 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
443 	req.flags = tfp_cpu_to_le_16(dir);
444 	req.req_size = size;
445 
446 	req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
447 	for (i = 0; i < size; i++) {
448 		req_data[i].type = tfp_cpu_to_le_32(request[i].type);
449 		req_data[i].min = tfp_cpu_to_le_16(request[i].min);
450 		req_data[i].max = tfp_cpu_to_le_16(request[i].max);
451 	}
452 
453 	req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
454 	req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
455 
456 	parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
457 	parms.req_data = (uint32_t *)&req;
458 	parms.req_size = sizeof(req);
459 	parms.resp_data = (uint32_t *)&resp;
460 	parms.resp_size = sizeof(resp);
461 	parms.mailbox = TF_KONG_MB;
462 
463 	rc = tfp_send_msg_direct(tfp, &parms);
464 	if (rc)
465 		goto cleanup;
466 
467 	/* Process the response
468 	 * Should always get expected number of entries
469 	 */
470 	if (tfp_le_to_cpu_32(resp.size) != size) {
471 		TFP_DRV_LOG(ERR,
472 			    "%s: Alloc message size error, rc:%s\n",
473 			    tf_dir_2_str(dir),
474 			    strerror(EINVAL));
475 		rc = -EINVAL;
476 		goto cleanup;
477 	}
478 
479 #if (TF_RM_MSG_DEBUG == 1)
480 	printf("\nRESV\n");
481 	printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
482 #endif /* (TF_RM_MSG_DEBUG == 1) */
483 
484 	/* Post process the response */
485 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
486 	for (i = 0; i < size; i++) {
487 		resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
488 		resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
489 		resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
490 
491 #if (TF_RM_MSG_DEBUG == 1)
492 		printf("%d type: %d(0x%x) %d %d\n",
493 		       i,
494 		       resv[i].type,
495 		       resv[i].type,
496 		       resv[i].start,
497 		       resv[i].stride);
498 #endif /* (TF_RM_MSG_DEBUG == 1) */
499 	}
500 
501 cleanup:
502 	tf_msg_free_dma_buf(&req_buf);
503 	tf_msg_free_dma_buf(&resv_buf);
504 
505 	return rc;
506 }
507 
508 int
509 tf_msg_session_resc_flush(struct tf *tfp,
510 			  enum tf_dir dir,
511 			  uint16_t size,
512 			  struct tf_rm_resc_entry *resv)
513 {
514 	int rc;
515 	int i;
516 	struct tfp_send_msg_parms parms = { 0 };
517 	struct hwrm_tf_session_resc_flush_input req = { 0 };
518 	struct hwrm_tf_session_resc_flush_output resp = { 0 };
519 	uint8_t fw_session_id;
520 	struct tf_msg_dma_buf resv_buf = { 0 };
521 	struct tf_rm_resc_entry *resv_data;
522 	int dma_size;
523 
524 	TF_CHECK_PARMS2(tfp, resv);
525 
526 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
527 	if (rc) {
528 		TFP_DRV_LOG(ERR,
529 			    "%s: Unable to lookup FW id, rc:%s\n",
530 			    tf_dir_2_str(dir),
531 			    strerror(-rc));
532 		return rc;
533 	}
534 
535 	/* Prepare DMA buffers */
536 	dma_size = size * sizeof(struct tf_rm_resc_entry);
537 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
538 	if (rc)
539 		return rc;
540 
541 	/* Populate the request */
542 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
543 	req.flags = tfp_cpu_to_le_16(dir);
544 	req.flush_size = size;
545 
546 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
547 	for (i = 0; i < size; i++) {
548 		resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
549 		resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
550 		resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
551 	}
552 
553 	req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
554 
555 	parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
556 	parms.req_data = (uint32_t *)&req;
557 	parms.req_size = sizeof(req);
558 	parms.resp_data = (uint32_t *)&resp;
559 	parms.resp_size = sizeof(resp);
560 	parms.mailbox = TF_KONG_MB;
561 
562 	rc = tfp_send_msg_direct(tfp, &parms);
563 
564 	tf_msg_free_dma_buf(&resv_buf);
565 
566 	return rc;
567 }
568 
569 int
570 tf_msg_insert_em_internal_entry(struct tf *tfp,
571 				struct tf_insert_em_entry_parms *em_parms,
572 				uint16_t *rptr_index,
573 				uint8_t *rptr_entry,
574 				uint8_t *num_of_entries)
575 {
576 	int rc;
577 	struct tfp_send_msg_parms parms = { 0 };
578 	struct hwrm_tf_em_insert_input req = { 0 };
579 	struct hwrm_tf_em_insert_output resp = { 0 };
580 	struct tf_em_64b_entry *em_result =
581 		(struct tf_em_64b_entry *)em_parms->em_record;
582 	uint16_t flags;
583 	uint8_t fw_session_id;
584 	uint8_t msg_key_size;
585 
586 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
587 	if (rc) {
588 		TFP_DRV_LOG(ERR,
589 			    "%s: Unable to lookup FW id, rc:%s\n",
590 			    tf_dir_2_str(em_parms->dir),
591 			    strerror(-rc));
592 		return rc;
593 	}
594 
595 	/* Populate the request */
596 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
597 
598 	/* Check for key size conformity */
599 	msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
600 	if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
601 		rc = -EINVAL;
602 		TFP_DRV_LOG(ERR,
603 			    "%s: Invalid parameters for msg type, rc:%s\n",
604 			    tf_dir_2_str(em_parms->dir),
605 			    strerror(-rc));
606 		return rc;
607 	}
608 
609 	tfp_memcpy(req.em_key,
610 		   em_parms->key,
611 		   msg_key_size);
612 
613 	flags = (em_parms->dir == TF_DIR_TX ?
614 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
615 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
616 	req.flags = tfp_cpu_to_le_16(flags);
617 	req.strength = (em_result->hdr.word1 &
618 			CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
619 			CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
620 	req.em_key_bitlen = em_parms->key_sz_in_bits;
621 	req.action_ptr = em_result->hdr.pointer;
622 	req.em_record_idx = *rptr_index;
623 
624 	parms.tf_type = HWRM_TF_EM_INSERT;
625 	parms.req_data = (uint32_t *)&req;
626 	parms.req_size = sizeof(req);
627 	parms.resp_data = (uint32_t *)&resp;
628 	parms.resp_size = sizeof(resp);
629 	parms.mailbox = TF_KONG_MB;
630 
631 	rc = tfp_send_msg_direct(tfp,
632 				 &parms);
633 	if (rc)
634 		return rc;
635 
636 	*rptr_entry = resp.rptr_entry;
637 	*rptr_index = resp.rptr_index;
638 	*num_of_entries = resp.num_of_entries;
639 
640 	return 0;
641 }
642 
643 int
644 tf_msg_delete_em_entry(struct tf *tfp,
645 		       struct tf_delete_em_entry_parms *em_parms)
646 {
647 	int rc;
648 	struct tfp_send_msg_parms parms = { 0 };
649 	struct hwrm_tf_em_delete_input req = { 0 };
650 	struct hwrm_tf_em_delete_output resp = { 0 };
651 	uint16_t flags;
652 	uint8_t fw_session_id;
653 
654 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
655 	if (rc) {
656 		TFP_DRV_LOG(ERR,
657 			    "%s: Unable to lookup FW id, rc:%s\n",
658 			    tf_dir_2_str(em_parms->dir),
659 			    strerror(-rc));
660 		return rc;
661 	}
662 
663 	/* Populate the request */
664 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
665 
666 	flags = (em_parms->dir == TF_DIR_TX ?
667 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
668 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
669 	req.flags = tfp_cpu_to_le_16(flags);
670 	req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
671 
672 	parms.tf_type = HWRM_TF_EM_DELETE;
673 	parms.req_data = (uint32_t *)&req;
674 	parms.req_size = sizeof(req);
675 	parms.resp_data = (uint32_t *)&resp;
676 	parms.resp_size = sizeof(resp);
677 	parms.mailbox = TF_KONG_MB;
678 
679 	rc = tfp_send_msg_direct(tfp,
680 				 &parms);
681 	if (rc)
682 		return rc;
683 
684 	em_parms->index = tfp_le_to_cpu_16(resp.em_index);
685 
686 	return 0;
687 }
688 
689 int
690 tf_msg_em_mem_rgtr(struct tf *tfp,
691 		   int page_lvl,
692 		   int page_size,
693 		   uint64_t dma_addr,
694 		   uint16_t *ctx_id)
695 {
696 	int rc;
697 	struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
698 	struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
699 	struct tfp_send_msg_parms parms = { 0 };
700 
701 	req.page_level = page_lvl;
702 	req.page_size = page_size;
703 	req.page_dir = tfp_cpu_to_le_64(dma_addr);
704 
705 	parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
706 	parms.req_data = (uint32_t *)&req;
707 	parms.req_size = sizeof(req);
708 	parms.resp_data = (uint32_t *)&resp;
709 	parms.resp_size = sizeof(resp);
710 	parms.mailbox = TF_KONG_MB;
711 
712 	rc = tfp_send_msg_direct(tfp,
713 				 &parms);
714 	if (rc)
715 		return rc;
716 
717 	*ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
718 
719 	return rc;
720 }
721 
722 int
723 tf_msg_em_mem_unrgtr(struct tf *tfp,
724 		     uint16_t *ctx_id)
725 {
726 	int rc;
727 	struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
728 	struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
729 	struct tfp_send_msg_parms parms = { 0 };
730 
731 	req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
732 
733 	parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
734 	parms.req_data = (uint32_t *)&req;
735 	parms.req_size = sizeof(req);
736 	parms.resp_data = (uint32_t *)&resp;
737 	parms.resp_size = sizeof(resp);
738 	parms.mailbox = TF_KONG_MB;
739 
740 	rc = tfp_send_msg_direct(tfp,
741 				 &parms);
742 	return rc;
743 }
744 
745 int
746 tf_msg_em_qcaps(struct tf *tfp,
747 		int dir,
748 		struct tf_em_caps *em_caps)
749 {
750 	int rc;
751 	struct hwrm_tf_ext_em_qcaps_input  req = {0};
752 	struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
753 	uint32_t             flags;
754 	struct tfp_send_msg_parms parms = { 0 };
755 
756 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
757 		 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
758 	req.flags = tfp_cpu_to_le_32(flags);
759 
760 	parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
761 	parms.req_data = (uint32_t *)&req;
762 	parms.req_size = sizeof(req);
763 	parms.resp_data = (uint32_t *)&resp;
764 	parms.resp_size = sizeof(resp);
765 	parms.mailbox = TF_KONG_MB;
766 
767 	rc = tfp_send_msg_direct(tfp,
768 				 &parms);
769 	if (rc)
770 		return rc;
771 
772 	em_caps->supported = tfp_le_to_cpu_32(resp.supported);
773 	em_caps->max_entries_supported =
774 		tfp_le_to_cpu_32(resp.max_entries_supported);
775 	em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
776 	em_caps->record_entry_size =
777 		tfp_le_to_cpu_16(resp.record_entry_size);
778 	em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
779 
780 	return rc;
781 }
782 
783 int
784 tf_msg_em_cfg(struct tf *tfp,
785 	      uint32_t num_entries,
786 	      uint16_t key0_ctx_id,
787 	      uint16_t key1_ctx_id,
788 	      uint16_t record_ctx_id,
789 	      uint16_t efc_ctx_id,
790 	      uint8_t flush_interval,
791 	      int dir)
792 {
793 	int rc;
794 	struct hwrm_tf_ext_em_cfg_input  req = {0};
795 	struct hwrm_tf_ext_em_cfg_output resp = {0};
796 	uint32_t flags;
797 	struct tfp_send_msg_parms parms = { 0 };
798 
799 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
800 		 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
801 	flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
802 
803 	req.flags = tfp_cpu_to_le_32(flags);
804 	req.num_entries = tfp_cpu_to_le_32(num_entries);
805 
806 	req.flush_interval = flush_interval;
807 
808 	req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
809 	req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
810 	req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
811 	req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
812 
813 	parms.tf_type = HWRM_TF_EXT_EM_CFG;
814 	parms.req_data = (uint32_t *)&req;
815 	parms.req_size = sizeof(req);
816 	parms.resp_data = (uint32_t *)&resp;
817 	parms.resp_size = sizeof(resp);
818 	parms.mailbox = TF_KONG_MB;
819 
820 	rc = tfp_send_msg_direct(tfp,
821 				 &parms);
822 	return rc;
823 }
824 
825 int
826 tf_msg_em_op(struct tf *tfp,
827 	     int dir,
828 	     uint16_t op)
829 {
830 	int rc;
831 	struct hwrm_tf_ext_em_op_input req = {0};
832 	struct hwrm_tf_ext_em_op_output resp = {0};
833 	uint32_t flags;
834 	struct tfp_send_msg_parms parms = { 0 };
835 
836 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
837 		 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
838 	req.flags = tfp_cpu_to_le_32(flags);
839 	req.op = tfp_cpu_to_le_16(op);
840 
841 	parms.tf_type = HWRM_TF_EXT_EM_OP;
842 	parms.req_data = (uint32_t *)&req;
843 	parms.req_size = sizeof(req);
844 	parms.resp_data = (uint32_t *)&resp;
845 	parms.resp_size = sizeof(resp);
846 	parms.mailbox = TF_KONG_MB;
847 
848 	rc = tfp_send_msg_direct(tfp,
849 				 &parms);
850 	return rc;
851 }
852 
853 int
854 tf_msg_tcam_entry_set(struct tf *tfp,
855 		      struct tf_tcam_set_parms *parms)
856 {
857 	int rc;
858 	struct tfp_send_msg_parms mparms = { 0 };
859 	struct hwrm_tf_tcam_set_input req = { 0 };
860 	struct hwrm_tf_tcam_set_output resp = { 0 };
861 	struct tf_msg_dma_buf buf = { 0 };
862 	uint8_t *data = NULL;
863 	int data_size = 0;
864 	uint8_t fw_session_id;
865 
866 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
867 	if (rc) {
868 		TFP_DRV_LOG(ERR,
869 			    "%s: Unable to lookup FW id, rc:%s\n",
870 			    tf_dir_2_str(parms->dir),
871 			    strerror(-rc));
872 		return rc;
873 	}
874 
875 	/* Populate the request */
876 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
877 	req.type = parms->hcapi_type;
878 	req.idx = tfp_cpu_to_le_16(parms->idx);
879 	if (parms->dir == TF_DIR_TX)
880 		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
881 
882 	req.key_size = parms->key_size;
883 	req.mask_offset = parms->key_size;
884 	/* Result follows after key and mask, thus multiply by 2 */
885 	req.result_offset = 2 * parms->key_size;
886 	req.result_size = parms->result_size;
887 	data_size = 2 * req.key_size + req.result_size;
888 
889 	if (data_size <= TF_PCI_BUF_SIZE_MAX) {
890 		/* use pci buffer */
891 		data = &req.dev_data[0];
892 	} else {
893 		/* use dma buffer */
894 		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
895 		rc = tf_msg_alloc_dma_buf(&buf, data_size);
896 		if (rc)
897 			goto cleanup;
898 		data = buf.va_addr;
899 		tfp_memcpy(&req.dev_data[0],
900 			   &buf.pa_addr,
901 			   sizeof(buf.pa_addr));
902 	}
903 
904 	tfp_memcpy(&data[0], parms->key, parms->key_size);
905 	tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
906 	tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
907 
908 	mparms.tf_type = HWRM_TF_TCAM_SET;
909 	mparms.req_data = (uint32_t *)&req;
910 	mparms.req_size = sizeof(req);
911 	mparms.resp_data = (uint32_t *)&resp;
912 	mparms.resp_size = sizeof(resp);
913 	mparms.mailbox = TF_KONG_MB;
914 
915 	rc = tfp_send_msg_direct(tfp,
916 				 &mparms);
917 
918 cleanup:
919 	tf_msg_free_dma_buf(&buf);
920 
921 	return rc;
922 }
923 
924 int
925 tf_msg_tcam_entry_free(struct tf *tfp,
926 		       struct tf_tcam_free_parms *in_parms)
927 {
928 	int rc;
929 	struct hwrm_tf_tcam_free_input req =  { 0 };
930 	struct hwrm_tf_tcam_free_output resp = { 0 };
931 	struct tfp_send_msg_parms parms = { 0 };
932 	uint8_t fw_session_id;
933 
934 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
935 	if (rc) {
936 		TFP_DRV_LOG(ERR,
937 			    "%s: Unable to lookup FW id, rc:%s\n",
938 			    tf_dir_2_str(in_parms->dir),
939 			    strerror(-rc));
940 		return rc;
941 	}
942 
943 	/* Populate the request */
944 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
945 	req.type = in_parms->hcapi_type;
946 	req.count = 1;
947 	req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
948 	if (in_parms->dir == TF_DIR_TX)
949 		req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
950 
951 	parms.tf_type = HWRM_TF_TCAM_FREE;
952 	parms.req_data = (uint32_t *)&req;
953 	parms.req_size = sizeof(req);
954 	parms.resp_data = (uint32_t *)&resp;
955 	parms.resp_size = sizeof(resp);
956 	parms.mailbox = TF_KONG_MB;
957 
958 	rc = tfp_send_msg_direct(tfp,
959 				 &parms);
960 	return rc;
961 }
962 
963 int
964 tf_msg_set_tbl_entry(struct tf *tfp,
965 		     enum tf_dir dir,
966 		     uint16_t hcapi_type,
967 		     uint16_t size,
968 		     uint8_t *data,
969 		     uint32_t index)
970 {
971 	int rc;
972 	struct hwrm_tf_tbl_type_set_input req = { 0 };
973 	struct hwrm_tf_tbl_type_set_output resp = { 0 };
974 	struct tfp_send_msg_parms parms = { 0 };
975 	uint8_t fw_session_id;
976 
977 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
978 	if (rc) {
979 		TFP_DRV_LOG(ERR,
980 			    "%s: Unable to lookup FW id, rc:%s\n",
981 			    tf_dir_2_str(dir),
982 			    strerror(-rc));
983 		return rc;
984 	}
985 
986 	/* Populate the request */
987 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
988 	req.flags = tfp_cpu_to_le_16(dir);
989 	req.type = tfp_cpu_to_le_32(hcapi_type);
990 	req.size = tfp_cpu_to_le_16(size);
991 	req.index = tfp_cpu_to_le_32(index);
992 
993 	/* Check for data size conformity */
994 	if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
995 		rc = -EINVAL;
996 		TFP_DRV_LOG(ERR,
997 			    "%s: Invalid parameters for msg type, rc:%s\n",
998 			    tf_dir_2_str(dir),
999 			    strerror(-rc));
1000 		return rc;
1001 	}
1002 
1003 	tfp_memcpy(&req.data,
1004 		   data,
1005 		   size);
1006 
1007 	parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1008 	parms.req_data = (uint32_t *)&req;
1009 	parms.req_size = sizeof(req);
1010 	parms.resp_data = (uint32_t *)&resp;
1011 	parms.resp_size = sizeof(resp);
1012 	parms.mailbox = TF_KONG_MB;
1013 
1014 	rc = tfp_send_msg_direct(tfp,
1015 				 &parms);
1016 	if (rc)
1017 		return rc;
1018 
1019 	return tfp_le_to_cpu_32(parms.tf_resp_code);
1020 }
1021 
1022 int
1023 tf_msg_get_tbl_entry(struct tf *tfp,
1024 		     enum tf_dir dir,
1025 		     uint16_t hcapi_type,
1026 		     uint16_t size,
1027 		     uint8_t *data,
1028 		     uint32_t index)
1029 {
1030 	int rc;
1031 	struct hwrm_tf_tbl_type_get_input req = { 0 };
1032 	struct hwrm_tf_tbl_type_get_output resp = { 0 };
1033 	struct tfp_send_msg_parms parms = { 0 };
1034 	uint8_t fw_session_id;
1035 
1036 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1037 	if (rc) {
1038 		TFP_DRV_LOG(ERR,
1039 			    "%s: Unable to lookup FW id, rc:%s\n",
1040 			    tf_dir_2_str(dir),
1041 			    strerror(-rc));
1042 		return rc;
1043 	}
1044 
1045 	/* Populate the request */
1046 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1047 	req.flags = tfp_cpu_to_le_16(dir);
1048 	req.type = tfp_cpu_to_le_32(hcapi_type);
1049 	req.index = tfp_cpu_to_le_32(index);
1050 
1051 	parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1052 	parms.req_data = (uint32_t *)&req;
1053 	parms.req_size = sizeof(req);
1054 	parms.resp_data = (uint32_t *)&resp;
1055 	parms.resp_size = sizeof(resp);
1056 	parms.mailbox = TF_KONG_MB;
1057 
1058 	rc = tfp_send_msg_direct(tfp,
1059 				 &parms);
1060 	if (rc)
1061 		return rc;
1062 
1063 	/* Verify that we got enough buffer to return the requested data */
1064 	if (tfp_le_to_cpu_32(resp.size) != size)
1065 		return -EINVAL;
1066 
1067 	tfp_memcpy(data,
1068 		   &resp.data,
1069 		   size);
1070 
1071 	return tfp_le_to_cpu_32(parms.tf_resp_code);
1072 }
1073 
1074 /* HWRM Tunneled messages */
1075 
1076 int
1077 tf_msg_get_global_cfg(struct tf *tfp,
1078 		      struct tf_dev_global_cfg_parms *params)
1079 {
1080 	int rc = 0;
1081 	struct tfp_send_msg_parms parms = { 0 };
1082 	struct hwrm_tf_global_cfg_get_input req = { 0 };
1083 	struct hwrm_tf_global_cfg_get_output resp = { 0 };
1084 	uint32_t flags = 0;
1085 	uint8_t fw_session_id;
1086 	uint16_t resp_size = 0;
1087 
1088 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1089 	if (rc) {
1090 		TFP_DRV_LOG(ERR,
1091 			    "%s: Unable to lookup FW id, rc:%s\n",
1092 			    tf_dir_2_str(params->dir),
1093 			    strerror(-rc));
1094 		return rc;
1095 	}
1096 
1097 	flags = (params->dir == TF_DIR_TX ?
1098 		 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1099 		 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1100 
1101 	/* Populate the request */
1102 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1103 	req.flags = tfp_cpu_to_le_32(flags);
1104 	req.type = tfp_cpu_to_le_32(params->type);
1105 	req.offset = tfp_cpu_to_le_32(params->offset);
1106 	req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1107 
1108 	parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1109 	parms.req_data = (uint32_t *)&req;
1110 	parms.req_size = sizeof(req);
1111 	parms.resp_data = (uint32_t *)&resp;
1112 	parms.resp_size = sizeof(resp);
1113 	parms.mailbox = TF_KONG_MB;
1114 
1115 	rc = tfp_send_msg_direct(tfp, &parms);
1116 	if (rc != 0)
1117 		return rc;
1118 
1119 	/* Verify that we got enough buffer to return the requested data */
1120 	resp_size = tfp_le_to_cpu_16(resp.size);
1121 	if (resp_size < params->config_sz_in_bytes)
1122 		return -EINVAL;
1123 
1124 	if (params->config)
1125 		tfp_memcpy(params->config,
1126 			   resp.data,
1127 			   resp_size);
1128 	else
1129 		return -EFAULT;
1130 
1131 	return tfp_le_to_cpu_32(parms.tf_resp_code);
1132 }
1133 
1134 int
1135 tf_msg_set_global_cfg(struct tf *tfp,
1136 		      struct tf_dev_global_cfg_parms *params)
1137 {
1138 	int rc = 0;
1139 	struct tfp_send_msg_parms parms = { 0 };
1140 	struct hwrm_tf_global_cfg_set_input req = { 0 };
1141 	struct hwrm_tf_global_cfg_set_output resp = { 0 };
1142 	uint32_t flags = 0;
1143 	uint8_t fw_session_id;
1144 
1145 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1146 	if (rc) {
1147 		TFP_DRV_LOG(ERR,
1148 			    "%s: Unable to lookup FW id, rc:%s\n",
1149 			    tf_dir_2_str(params->dir),
1150 			    strerror(-rc));
1151 		return rc;
1152 	}
1153 
1154 	flags = (params->dir == TF_DIR_TX ?
1155 		 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
1156 		 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
1157 
1158 	/* Populate the request */
1159 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1160 	req.flags = tfp_cpu_to_le_32(flags);
1161 	req.type = tfp_cpu_to_le_32(params->type);
1162 	req.offset = tfp_cpu_to_le_32(params->offset);
1163 
1164 	/* Check for data size conformity */
1165 	if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
1166 		rc = -EINVAL;
1167 		TFP_DRV_LOG(ERR,
1168 			    "%s: Invalid parameters for msg type, rc:%s\n",
1169 			    tf_dir_2_str(params->dir),
1170 			    strerror(-rc));
1171 		return rc;
1172 	}
1173 
1174 	tfp_memcpy(req.data, params->config,
1175 		   params->config_sz_in_bytes);
1176 	req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1177 
1178 	parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
1179 	parms.req_data = (uint32_t *)&req;
1180 	parms.req_size = sizeof(req);
1181 	parms.resp_data = (uint32_t *)&resp;
1182 	parms.resp_size = sizeof(resp);
1183 	parms.mailbox = TF_KONG_MB;
1184 
1185 	rc = tfp_send_msg_direct(tfp, &parms);
1186 
1187 	if (rc != 0)
1188 		return rc;
1189 
1190 	return tfp_le_to_cpu_32(parms.tf_resp_code);
1191 }
1192 
1193 int
1194 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
1195 			  enum tf_dir dir,
1196 			  uint16_t hcapi_type,
1197 			  uint32_t starting_idx,
1198 			  uint16_t num_entries,
1199 			  uint16_t entry_sz_in_bytes,
1200 			  uint64_t physical_mem_addr)
1201 {
1202 	int rc;
1203 	struct tfp_send_msg_parms parms = { 0 };
1204 	struct tf_tbl_type_bulk_get_input req = { 0 };
1205 	struct tf_tbl_type_bulk_get_output resp = { 0 };
1206 	int data_size = 0;
1207 	uint8_t fw_session_id;
1208 
1209 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1210 	if (rc) {
1211 		TFP_DRV_LOG(ERR,
1212 			    "%s: Unable to lookup FW id, rc:%s\n",
1213 			    tf_dir_2_str(dir),
1214 			    strerror(-rc));
1215 		return rc;
1216 	}
1217 
1218 	/* Populate the request */
1219 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1220 	req.flags = tfp_cpu_to_le_16(dir);
1221 	req.type = tfp_cpu_to_le_32(hcapi_type);
1222 	req.start_index = tfp_cpu_to_le_32(starting_idx);
1223 	req.num_entries = tfp_cpu_to_le_32(num_entries);
1224 
1225 	data_size = num_entries * entry_sz_in_bytes;
1226 
1227 	req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1228 
1229 	MSG_PREP(parms,
1230 		 TF_KONG_MB,
1231 		 HWRM_TF,
1232 		 HWRM_TFT_TBL_TYPE_BULK_GET,
1233 		 req,
1234 		 resp);
1235 
1236 	rc = tfp_send_msg_tunneled(tfp, &parms);
1237 	if (rc)
1238 		return rc;
1239 
1240 	/* Verify that we got enough buffer to return the requested data */
1241 	if (tfp_le_to_cpu_32(resp.size) != data_size)
1242 		return -EINVAL;
1243 
1244 	return tfp_le_to_cpu_32(parms.tf_resp_code);
1245 }
1246 
1247 int
1248 tf_msg_get_if_tbl_entry(struct tf *tfp,
1249 			struct tf_if_tbl_get_parms *params)
1250 {
1251 	int rc = 0;
1252 	struct tfp_send_msg_parms parms = { 0 };
1253 	struct hwrm_tf_if_tbl_get_input req = { 0 };
1254 	struct hwrm_tf_if_tbl_get_output resp = { 0 };
1255 	uint32_t flags = 0;
1256 	struct tf_session *tfs;
1257 
1258 	/* Retrieve the session information */
1259 	rc = tf_session_get_session(tfp, &tfs);
1260 	if (rc) {
1261 		TFP_DRV_LOG(ERR,
1262 			    "%s: Failed to lookup session, rc:%s\n",
1263 			    tf_dir_2_str(params->dir),
1264 			    strerror(-rc));
1265 		return rc;
1266 	}
1267 
1268 	flags = (params->dir == TF_DIR_TX ?
1269 		HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
1270 		HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
1271 
1272 	/* Populate the request */
1273 	req.fw_session_id =
1274 		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1275 	req.flags = flags;
1276 	req.type = params->hcapi_type;
1277 	req.index = tfp_cpu_to_le_16(params->idx);
1278 	req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1279 
1280 	parms.tf_type = HWRM_TF_IF_TBL_GET;
1281 	parms.req_data = (uint32_t *)&req;
1282 	parms.req_size = sizeof(req);
1283 	parms.resp_data = (uint32_t *)&resp;
1284 	parms.resp_size = sizeof(resp);
1285 	parms.mailbox = TF_KONG_MB;
1286 
1287 	rc = tfp_send_msg_direct(tfp, &parms);
1288 
1289 	if (rc != 0)
1290 		return rc;
1291 
1292 	if (parms.tf_resp_code != 0)
1293 		return tfp_le_to_cpu_32(parms.tf_resp_code);
1294 
1295 	tfp_memcpy(&params->data[0], resp.data, req.size);
1296 
1297 	return tfp_le_to_cpu_32(parms.tf_resp_code);
1298 }
1299 
1300 int
1301 tf_msg_set_if_tbl_entry(struct tf *tfp,
1302 			struct tf_if_tbl_set_parms *params)
1303 {
1304 	int rc = 0;
1305 	struct tfp_send_msg_parms parms = { 0 };
1306 	struct hwrm_tf_if_tbl_set_input req = { 0 };
1307 	struct hwrm_tf_if_tbl_get_output resp = { 0 };
1308 	uint32_t flags = 0;
1309 	struct tf_session *tfs;
1310 
1311 	/* Retrieve the session information */
1312 	rc = tf_session_get_session(tfp, &tfs);
1313 	if (rc) {
1314 		TFP_DRV_LOG(ERR,
1315 			    "%s: Failed to lookup session, rc:%s\n",
1316 			    tf_dir_2_str(params->dir),
1317 			    strerror(-rc));
1318 		return rc;
1319 	}
1320 
1321 
1322 	flags = (params->dir == TF_DIR_TX ?
1323 		HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1324 		HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1325 
1326 	/* Populate the request */
1327 	req.fw_session_id =
1328 		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1329 	req.flags = flags;
1330 	req.type = params->hcapi_type;
1331 	req.index = tfp_cpu_to_le_32(params->idx);
1332 	req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1333 	tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1334 
1335 	parms.tf_type = HWRM_TF_IF_TBL_SET;
1336 	parms.req_data = (uint32_t *)&req;
1337 	parms.req_size = sizeof(req);
1338 	parms.resp_data = (uint32_t *)&resp;
1339 	parms.resp_size = sizeof(resp);
1340 	parms.mailbox = TF_KONG_MB;
1341 
1342 	rc = tfp_send_msg_direct(tfp, &parms);
1343 
1344 	if (rc != 0)
1345 		return rc;
1346 
1347 	return tfp_le_to_cpu_32(parms.tf_resp_code);
1348 }
1349