xref: /dpdk/drivers/net/bnxt/tf_core/tf_msg.c (revision 19f3ac618ab2d309e24a3034fcfdacaa6f31c718)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2023 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_em_common.h"
13 #include "tf_msg_common.h"
14 #include "tf_device.h"
15 #include "tf_msg.h"
16 #include "tf_util.h"
17 #include "tf_common.h"
18 #include "tf_session.h"
19 #include "tfp.h"
20 #include "tf_em.h"
21 
22 /* Specific msg size defines as we cannot use defines in tf.yaml. This
23  * means we have to manually sync hwrm with these defines if the
24  * tf.yaml changes.
25  */
26 #define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE  16
27 #define TF_MSG_EM_INSERT_KEY_SIZE        64
28 #define TF_MSG_EM_INSERT_RECORD_SIZE     96
29 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE    88
30 
31 /* Compile check - Catch any msg changes that we depend on, like the
32  * defines listed above for array size checking.
33  *
34  * Checking array size is dangerous in that the type could change and
35  * we wouldn't be able to catch it. Thus we check if the complete msg
36  * changed instead. Best we can do.
37  *
38  * If failure is observed then both msg size (defines below) and the
39  * array size (define above) should be checked and compared.
40  */
41 #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56
42 static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
43 	      TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET,
44 	      "HWRM message size changed: hwrm_tf_global_cfg_set_input");
45 
46 #define TF_MSG_SIZE_HWRM_TF_EM_INSERT      104
47 static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
48 	      TF_MSG_SIZE_HWRM_TF_EM_INSERT,
49 	      "HWRM message size changed: hwrm_tf_em_insert_input");
50 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET   128
51 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
52 	      TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
53 	      "HWRM message size changed: hwrm_tf_tbl_type_set_input");
54 
55 /**
56  * This is the MAX data we can transport across regular HWRM
57  */
58 #define TF_PCI_BUF_SIZE_MAX 88
59 
60 /**
61  * This is the length of shared session name "tf_share"
62  */
63 #define TF_SHARED_SESSION_NAME_LEN 9
64 
65 /**
66  * This is the length of tcam shared session name "tf_shared-wc_tcam"
67  */
68 #define TF_TCAM_SHARED_SESSION_NAME_LEN 17
69 
70 /**
71  * This is the length of tcam shared session name "tf_shared-poolx"
72  */
73 #define TF_POOL_SHARED_SESSION_NAME_LEN 16
74 
75 /**
76  * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
77  */
78 struct tf_msg_dma_buf {
79 	void *va_addr;
80 	uint64_t pa_addr;
81 };
82 
83 /**
84  * Allocates a DMA buffer that can be used for message transfer.
85  *
86  * [in] buf
87  *   Pointer to DMA buffer structure
88  *
89  * [in] size
90  *   Requested size of the buffer in bytes
91  *
92  * Returns:
93  *    0      - Success
94  *   -ENOMEM - Unable to allocate buffer, no memory
95  */
96 static int
97 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
98 {
99 	struct tfp_calloc_parms alloc_parms;
100 	int rc;
101 
102 	/* Allocate session */
103 	alloc_parms.nitems = 1;
104 	alloc_parms.size = size;
105 	alloc_parms.alignment = 4096;
106 	rc = tfp_calloc(&alloc_parms);
107 	if (rc)
108 		return -ENOMEM;
109 
110 	buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
111 	buf->va_addr = alloc_parms.mem_va;
112 
113 	return 0;
114 }
115 
116 /**
117  * Free's a previous allocated DMA buffer.
118  *
119  * [in] buf
120  *   Pointer to DMA buffer structure
121  */
122 static void
123 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
124 {
125 	tfp_free(buf->va_addr);
126 }
127 
128 /* HWRM Direct messages */
129 
130 int
131 tf_msg_session_open(struct bnxt *bp,
132 		    char *ctrl_chan_name,
133 		    uint8_t *fw_session_id,
134 		    uint8_t *fw_session_client_id,
135 		    struct tf_dev_info *dev,
136 		    bool *shared_session_creator)
137 {
138 	int rc;
139 	struct hwrm_tf_session_open_input req = { 0 };
140 	struct hwrm_tf_session_open_output resp = { 0 };
141 	struct tfp_send_msg_parms parms = { 0 };
142 	char *session_name;
143 	char *tcam_session_name;
144 	char *pool_session_name;
145 
146 	/*
147 	 * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0.
148 	 * "tf_shared-pool" is defined for version 1.0.1.
149 	 * "tf_shared" is used by both verions.
150 	 */
151 	tcam_session_name = strstr(ctrl_chan_name, "tf_shared-wc_tcam");
152 	pool_session_name = strstr(ctrl_chan_name, "tf_shared-pool");
153 	session_name = strstr(ctrl_chan_name, "tf_shared");
154 	if (tcam_session_name)
155 		tfp_memcpy(&req.session_name,
156 			   tcam_session_name,
157 			   TF_TCAM_SHARED_SESSION_NAME_LEN);
158 	else if (pool_session_name)
159 		tfp_memcpy(&req.session_name,
160 			   pool_session_name,
161 			   TF_POOL_SHARED_SESSION_NAME_LEN);
162 	else if (session_name)
163 		tfp_memcpy(&req.session_name,
164 			   session_name,
165 			   TF_SHARED_SESSION_NAME_LEN);
166 	else
167 		tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
168 
169 	parms.tf_type = HWRM_TF_SESSION_OPEN;
170 	parms.req_data = (uint32_t *)&req;
171 	parms.req_size = sizeof(req);
172 	parms.resp_data = (uint32_t *)&resp;
173 	parms.resp_size = sizeof(resp);
174 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
175 
176 	rc = tfp_send_msg_direct(bp,
177 				 &parms);
178 	if (rc)
179 		return rc;
180 
181 	*fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
182 	*fw_session_client_id =
183 		(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
184 	*shared_session_creator = (bool)tfp_le_to_cpu_32(resp.flags
185 		& HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR);
186 
187 	return rc;
188 }
189 
190 int
191 tf_msg_session_attach(struct tf *tfp __rte_unused,
192 		      char *ctrl_chan_name __rte_unused,
193 		      uint8_t tf_fw_session_id __rte_unused)
194 {
195 	return -1;
196 }
197 
198 int
199 tf_msg_session_client_register(struct tf *tfp,
200 			       struct tf_session *tfs,
201 			       char *ctrl_channel_name,
202 			       uint8_t *fw_session_client_id)
203 {
204 	int rc;
205 	struct hwrm_tf_session_register_input req = { 0 };
206 	struct hwrm_tf_session_register_output resp = { 0 };
207 	struct tfp_send_msg_parms parms = { 0 };
208 	uint8_t fw_session_id;
209 	struct tf_dev_info *dev;
210 	char *session_name;
211 	char *tcam_session_name;
212 	char *pool_session_name;
213 
214 	/* Retrieve the device information */
215 	rc = tf_session_get_device(tfs, &dev);
216 	if (rc) {
217 		TFP_DRV_LOG(ERR,
218 			    "Failed to lookup device, rc:%s\n",
219 			    strerror(-rc));
220 		return rc;
221 	}
222 
223 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
224 	if (rc) {
225 		TFP_DRV_LOG(ERR,
226 			    "Unable to lookup FW id, rc:%s\n",
227 			    strerror(-rc));
228 		return rc;
229 	}
230 
231 	/* Populate the request */
232 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
233 
234 	/*
235 	 * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0.
236 	 * "tf_shared-pool" is defined for version 1.0.1.
237 	 * "tf_shared" is used by both verions.
238 	 */
239 	tcam_session_name = strstr(ctrl_channel_name, "tf_shared-wc_tcam");
240 	pool_session_name = strstr(ctrl_channel_name, "tf_shared-pool");
241 	session_name = strstr(ctrl_channel_name, "tf_shared");
242 	if (tcam_session_name)
243 		tfp_memcpy(&req.session_client_name,
244 			   tcam_session_name,
245 			   TF_TCAM_SHARED_SESSION_NAME_LEN);
246 	else if (pool_session_name)
247 		tfp_memcpy(&req.session_client_name,
248 			   pool_session_name,
249 			   TF_POOL_SHARED_SESSION_NAME_LEN);
250 	else if (session_name)
251 		tfp_memcpy(&req.session_client_name,
252 			   session_name,
253 			   TF_SHARED_SESSION_NAME_LEN);
254 	else
255 		tfp_memcpy(&req.session_client_name,
256 			   ctrl_channel_name,
257 			   TF_SESSION_NAME_MAX);
258 
259 	parms.tf_type = HWRM_TF_SESSION_REGISTER;
260 	parms.req_data = (uint32_t *)&req;
261 	parms.req_size = sizeof(req);
262 	parms.resp_data = (uint32_t *)&resp;
263 	parms.resp_size = sizeof(resp);
264 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
265 
266 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
267 				 &parms);
268 	if (rc)
269 		return rc;
270 
271 	*fw_session_client_id =
272 		(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
273 
274 	return rc;
275 }
276 
277 int
278 tf_msg_session_client_unregister(struct tf *tfp,
279 				 struct tf_session *tfs,
280 				 uint8_t fw_session_client_id)
281 {
282 	int rc;
283 	struct hwrm_tf_session_unregister_input req = { 0 };
284 	struct hwrm_tf_session_unregister_output resp = { 0 };
285 	struct tfp_send_msg_parms parms = { 0 };
286 	uint8_t fw_session_id;
287 	struct tf_dev_info *dev;
288 
289 	/* Retrieve the device information */
290 	rc = tf_session_get_device(tfs, &dev);
291 	if (rc) {
292 		TFP_DRV_LOG(ERR,
293 			    "Failed to lookup device, rc:%s\n",
294 			    strerror(-rc));
295 		return rc;
296 	}
297 
298 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
299 	if (rc) {
300 		TFP_DRV_LOG(ERR,
301 			    "Unable to lookup FW id, rc:%s\n",
302 			    strerror(-rc));
303 		return rc;
304 	}
305 
306 	/* Populate the request */
307 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
308 	req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
309 
310 	parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
311 	parms.req_data = (uint32_t *)&req;
312 	parms.req_size = sizeof(req);
313 	parms.resp_data = (uint32_t *)&resp;
314 	parms.resp_size = sizeof(resp);
315 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
316 
317 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
318 				 &parms);
319 
320 	return rc;
321 }
322 
323 int
324 tf_msg_session_close(struct tf *tfp,
325 		     uint8_t fw_session_id,
326 		     int mailbox)
327 {
328 	int rc;
329 	struct hwrm_tf_session_close_input req = { 0 };
330 	struct hwrm_tf_session_close_output resp = { 0 };
331 	struct tfp_send_msg_parms parms = { 0 };
332 
333 	/* Populate the request */
334 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
335 
336 	parms.tf_type = HWRM_TF_SESSION_CLOSE;
337 	parms.req_data = (uint32_t *)&req;
338 	parms.req_size = sizeof(req);
339 	parms.resp_data = (uint32_t *)&resp;
340 	parms.resp_size = sizeof(resp);
341 	parms.mailbox = mailbox;
342 
343 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
344 				 &parms);
345 	return rc;
346 }
347 
348 int
349 tf_msg_session_qcfg(struct tf *tfp)
350 {
351 	int rc;
352 	struct hwrm_tf_session_qcfg_input req = { 0 };
353 	struct hwrm_tf_session_qcfg_output resp = { 0 };
354 	struct tfp_send_msg_parms parms = { 0 };
355 	uint8_t fw_session_id;
356 	struct tf_dev_info *dev;
357 	struct tf_session *tfs;
358 
359 	/* Retrieve the session information */
360 	rc = tf_session_get_session_internal(tfp, &tfs);
361 	if (rc) {
362 		TFP_DRV_LOG(ERR,
363 			    "Failed to lookup session, rc:%s\n",
364 			    strerror(-rc));
365 		return rc;
366 	}
367 
368 	/* Retrieve the device information */
369 	rc = tf_session_get_device(tfs, &dev);
370 	if (rc) {
371 		TFP_DRV_LOG(ERR,
372 			    "Failed to lookup device, rc:%s\n",
373 			    strerror(-rc));
374 		return rc;
375 	}
376 
377 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
378 	if (rc) {
379 		TFP_DRV_LOG(ERR,
380 			    "Unable to lookup FW id, rc:%s\n",
381 			    strerror(-rc));
382 		return rc;
383 	}
384 
385 	/* Populate the request */
386 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
387 
388 	parms.tf_type = HWRM_TF_SESSION_QCFG,
389 	parms.req_data = (uint32_t *)&req;
390 	parms.req_size = sizeof(req);
391 	parms.resp_data = (uint32_t *)&resp;
392 	parms.resp_size = sizeof(resp);
393 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
394 
395 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
396 				 &parms);
397 	return rc;
398 }
399 
400 int
401 tf_msg_session_resc_qcaps(struct tf *tfp,
402 			  struct tf_dev_info *dev,
403 			  enum tf_dir dir,
404 			  uint16_t size,
405 			  struct tf_rm_resc_req_entry *query,
406 			  enum tf_rm_resc_resv_strategy *resv_strategy,
407 			  uint8_t *sram_profile)
408 {
409 	int rc;
410 	int i;
411 	struct tfp_send_msg_parms parms = { 0 };
412 	struct hwrm_tf_session_resc_qcaps_input req = { 0 };
413 	struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
414 	struct tf_msg_dma_buf qcaps_buf = { 0 };
415 	struct tf_rm_resc_req_entry *data;
416 	int dma_size;
417 
418 	TF_CHECK_PARMS3(tfp, query, resv_strategy);
419 
420 	/* Prepare DMA buffer */
421 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
422 	rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
423 	if (rc)
424 		return rc;
425 
426 	/* Populate the request */
427 	req.fw_session_id = 0;
428 	req.flags = tfp_cpu_to_le_16(dir);
429 	req.qcaps_size = size;
430 	req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
431 
432 	parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
433 	parms.req_data = (uint32_t *)&req;
434 	parms.req_size = sizeof(req);
435 	parms.resp_data = (uint32_t *)&resp;
436 	parms.resp_size = sizeof(resp);
437 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
438 
439 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
440 	if (rc)
441 		goto cleanup;
442 
443 	/* Process the response
444 	 * Should always get expected number of entries
445 	 */
446 	if (tfp_le_to_cpu_32(resp.size) != size) {
447 		TFP_DRV_LOG(WARNING,
448 			    "%s: QCAPS message size error, rc:%s, request %d vs response %d\n",
449 			    tf_dir_2_str(dir),
450 			    strerror(EINVAL),
451 			    size,
452 			    resp.size);
453 	}
454 
455 	/* Post process the response */
456 	data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
457 	for (i = 0; i < resp.size; i++) {
458 		query[i].type = tfp_le_to_cpu_32(data[i].type);
459 		query[i].min = tfp_le_to_cpu_16(data[i].min);
460 		query[i].max = tfp_le_to_cpu_16(data[i].max);
461 	}
462 
463 	*resv_strategy = resp.flags &
464 	      HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
465 
466 	if (sram_profile != NULL)
467 		*sram_profile = resp.sram_profile;
468 
469 cleanup:
470 	tf_msg_free_dma_buf(&qcaps_buf);
471 
472 	return rc;
473 }
474 
475 int
476 tf_msg_session_resc_alloc(struct tf *tfp,
477 			  struct tf_dev_info *dev,
478 			  enum tf_dir dir,
479 			  uint16_t size,
480 			  struct tf_rm_resc_req_entry *request,
481 			  struct tf_rm_resc_entry *resv)
482 {
483 	int rc;
484 	int i;
485 	struct tfp_send_msg_parms parms = { 0 };
486 	struct hwrm_tf_session_resc_alloc_input req = { 0 };
487 	struct hwrm_tf_session_resc_alloc_output resp = { 0 };
488 	uint8_t fw_session_id;
489 	struct tf_msg_dma_buf req_buf = { 0 };
490 	struct tf_msg_dma_buf resv_buf = { 0 };
491 	struct tf_rm_resc_req_entry *req_data;
492 	struct tf_rm_resc_entry *resv_data;
493 	int dma_size;
494 	struct tf_session *tfs;
495 
496 	/* Retrieve the session information */
497 	rc = tf_session_get_session_internal(tfp, &tfs);
498 	if (rc) {
499 		TFP_DRV_LOG(ERR,
500 			    "Failed to lookup session, rc:%s\n",
501 			    strerror(-rc));
502 		return rc;
503 	}
504 
505 	TF_CHECK_PARMS3(tfp, request, resv);
506 
507 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
508 	if (rc) {
509 		TFP_DRV_LOG(ERR,
510 			    "%s: Unable to lookup FW id, rc:%s\n",
511 			    tf_dir_2_str(dir),
512 			    strerror(-rc));
513 		return rc;
514 	}
515 
516 	/* Prepare DMA buffers */
517 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
518 	rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
519 	if (rc)
520 		return rc;
521 
522 	dma_size = size * sizeof(struct tf_rm_resc_entry);
523 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
524 	if (rc) {
525 		tf_msg_free_dma_buf(&req_buf);
526 		return rc;
527 	}
528 
529 	/* Populate the request */
530 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
531 	req.flags = tfp_cpu_to_le_16(dir);
532 	req.req_size = size;
533 
534 	req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
535 	for (i = 0; i < size; i++) {
536 		req_data[i].type = tfp_cpu_to_le_32(request[i].type);
537 		req_data[i].min = tfp_cpu_to_le_16(request[i].min);
538 		req_data[i].max = tfp_cpu_to_le_16(request[i].max);
539 	}
540 
541 	req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
542 	req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
543 
544 	parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
545 	parms.req_data = (uint32_t *)&req;
546 	parms.req_size = sizeof(req);
547 	parms.resp_data = (uint32_t *)&resp;
548 	parms.resp_size = sizeof(resp);
549 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
550 
551 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
552 	if (rc)
553 		goto cleanup;
554 
555 	/* Process the response
556 	 * Should always get expected number of entries
557 	 */
558 	if (tfp_le_to_cpu_32(resp.size) != size) {
559 		TFP_DRV_LOG(ERR,
560 			    "%s: Alloc message size error, rc:%s\n",
561 			    tf_dir_2_str(dir),
562 			    strerror(EINVAL));
563 		rc = -EINVAL;
564 		goto cleanup;
565 	}
566 
567 	/* Post process the response */
568 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
569 	for (i = 0; i < size; i++) {
570 		resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
571 		resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
572 		resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
573 	}
574 
575 cleanup:
576 	tf_msg_free_dma_buf(&req_buf);
577 	tf_msg_free_dma_buf(&resv_buf);
578 
579 	return rc;
580 }
581 
582 int
583 tf_msg_session_resc_info(struct tf *tfp,
584 			 struct tf_dev_info *dev,
585 			 enum tf_dir dir,
586 			 uint16_t size,
587 			 struct tf_rm_resc_req_entry *request,
588 			 struct tf_rm_resc_entry *resv)
589 {
590 	int rc;
591 	int i;
592 	struct tfp_send_msg_parms parms = { 0 };
593 	struct hwrm_tf_session_resc_info_input req = { 0 };
594 	struct hwrm_tf_session_resc_info_output resp = { 0 };
595 	uint8_t fw_session_id;
596 	struct tf_msg_dma_buf req_buf = { 0 };
597 	struct tf_msg_dma_buf resv_buf = { 0 };
598 	struct tf_rm_resc_req_entry *req_data;
599 	struct tf_rm_resc_entry *resv_data;
600 	int dma_size;
601 	struct tf_session *tfs;
602 
603 	/* Retrieve the session information */
604 	rc = tf_session_get_session_internal(tfp, &tfs);
605 	if (rc) {
606 		TFP_DRV_LOG(ERR,
607 			    "Failed to lookup session, rc:%s\n",
608 			    strerror(-rc));
609 		return rc;
610 	}
611 
612 	TF_CHECK_PARMS3(tfp, request, resv);
613 
614 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
615 	if (rc) {
616 		TFP_DRV_LOG(ERR,
617 			    "%s: Unable to lookup FW id, rc:%s\n",
618 			    tf_dir_2_str(dir),
619 			    strerror(-rc));
620 		return rc;
621 	}
622 
623 	/* Prepare DMA buffers */
624 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
625 	rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
626 	if (rc)
627 		return rc;
628 
629 	dma_size = size * sizeof(struct tf_rm_resc_entry);
630 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
631 	if (rc) {
632 		tf_msg_free_dma_buf(&req_buf);
633 		return rc;
634 	}
635 
636 	/* Populate the request */
637 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
638 	req.flags = tfp_cpu_to_le_16(dir);
639 	req.req_size = size;
640 
641 	req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
642 	for (i = 0; i < size; i++) {
643 		req_data[i].type = tfp_cpu_to_le_32(request[i].type);
644 		req_data[i].min = tfp_cpu_to_le_16(request[i].min);
645 		req_data[i].max = tfp_cpu_to_le_16(request[i].max);
646 	}
647 
648 	req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
649 	req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
650 
651 	parms.tf_type = HWRM_TF_SESSION_RESC_INFO;
652 	parms.req_data = (uint32_t *)&req;
653 	parms.req_size = sizeof(req);
654 	parms.resp_data = (uint32_t *)&resp;
655 	parms.resp_size = sizeof(resp);
656 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
657 
658 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
659 	if (rc)
660 		goto cleanup;
661 
662 	/* Process the response
663 	 * Should always get expected number of entries
664 	 */
665 	if (tfp_le_to_cpu_32(resp.size) != size) {
666 		TFP_DRV_LOG(ERR,
667 			    "%s: Alloc message size error, rc:%s\n",
668 			    tf_dir_2_str(dir),
669 			    strerror(EINVAL));
670 		rc = -EINVAL;
671 		goto cleanup;
672 	}
673 
674 	/* Post process the response */
675 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
676 	for (i = 0; i < size; i++) {
677 		resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
678 		resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
679 		resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
680 	}
681 
682 cleanup:
683 	tf_msg_free_dma_buf(&req_buf);
684 	tf_msg_free_dma_buf(&resv_buf);
685 
686 	return rc;
687 }
688 
689 int
690 tf_msg_session_resc_flush(struct tf *tfp,
691 			  enum tf_dir dir,
692 			  uint16_t size,
693 			  struct tf_rm_resc_entry *resv)
694 {
695 	int rc;
696 	int i;
697 	struct tfp_send_msg_parms parms = { 0 };
698 	struct hwrm_tf_session_resc_flush_input req = { 0 };
699 	struct hwrm_tf_session_resc_flush_output resp = { 0 };
700 	uint8_t fw_session_id;
701 	struct tf_msg_dma_buf resv_buf = { 0 };
702 	struct tf_rm_resc_entry *resv_data;
703 	int dma_size;
704 	struct tf_dev_info *dev;
705 	struct tf_session *tfs;
706 
707 	TF_CHECK_PARMS2(tfp, resv);
708 
709 	/* Retrieve the session information */
710 	rc = tf_session_get_session_internal(tfp, &tfs);
711 	if (rc) {
712 		TFP_DRV_LOG(ERR,
713 			    "%s: Failed to lookup session, rc:%s\n",
714 			    tf_dir_2_str(dir),
715 			    strerror(-rc));
716 		return rc;
717 	}
718 
719 	/* Retrieve the device information */
720 	rc = tf_session_get_device(tfs, &dev);
721 	if (rc) {
722 		TFP_DRV_LOG(ERR,
723 			    "%s: Failed to lookup device, rc:%s\n",
724 			    tf_dir_2_str(dir),
725 			    strerror(-rc));
726 		return rc;
727 	}
728 
729 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
730 	if (rc) {
731 		TFP_DRV_LOG(ERR,
732 			    "%s: Unable to lookup FW id, rc:%s\n",
733 			    tf_dir_2_str(dir),
734 			    strerror(-rc));
735 		return rc;
736 	}
737 
738 	/* Prepare DMA buffers */
739 	dma_size = size * sizeof(struct tf_rm_resc_entry);
740 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
741 	if (rc)
742 		return rc;
743 
744 	/* Populate the request */
745 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
746 	req.flags = tfp_cpu_to_le_16(dir);
747 	req.flush_size = size;
748 
749 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
750 	for (i = 0; i < size; i++) {
751 		resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
752 		resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
753 		resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
754 	}
755 
756 	req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
757 
758 	parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
759 	parms.req_data = (uint32_t *)&req;
760 	parms.req_size = sizeof(req);
761 	parms.resp_data = (uint32_t *)&resp;
762 	parms.resp_size = sizeof(resp);
763 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
764 
765 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
766 
767 	tf_msg_free_dma_buf(&resv_buf);
768 
769 	return rc;
770 }
771 
772 int
773 tf_msg_insert_em_internal_entry(struct tf *tfp,
774 				struct tf_insert_em_entry_parms *em_parms,
775 				uint16_t *rptr_index,
776 				uint8_t *rptr_entry,
777 				uint8_t *num_of_entries)
778 {
779 	int rc;
780 	struct tfp_send_msg_parms parms = { 0 };
781 	struct hwrm_tf_em_insert_input req = { 0 };
782 	struct hwrm_tf_em_insert_output resp = { 0 };
783 	struct tf_em_64b_entry *em_result =
784 		(struct tf_em_64b_entry *)em_parms->em_record;
785 	uint16_t flags;
786 	uint8_t fw_session_id;
787 	uint8_t msg_key_size;
788 	struct tf_dev_info *dev;
789 	struct tf_session *tfs;
790 
791 	RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_em_insert_input) !=
792 			 TF_MSG_SIZE_HWRM_TF_EM_INSERT);
793 
794 	/* Retrieve the session information */
795 	rc = tf_session_get_session_internal(tfp, &tfs);
796 	if (rc) {
797 		TFP_DRV_LOG(ERR,
798 			    "%s: Failed to lookup session, rc:%s\n",
799 			    tf_dir_2_str(em_parms->dir),
800 			    strerror(-rc));
801 		return rc;
802 	}
803 
804 	/* Retrieve the device information */
805 	rc = tf_session_get_device(tfs, &dev);
806 	if (rc) {
807 		TFP_DRV_LOG(ERR,
808 			    "%s: Failed to lookup device, rc:%s\n",
809 			    tf_dir_2_str(em_parms->dir),
810 			    strerror(-rc));
811 		return rc;
812 	}
813 
814 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
815 	if (rc) {
816 		TFP_DRV_LOG(ERR,
817 			    "%s: Unable to lookup FW id, rc:%s\n",
818 			    tf_dir_2_str(em_parms->dir),
819 			    strerror(-rc));
820 		return rc;
821 	}
822 
823 	/* Populate the request */
824 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
825 
826 	/* Check for key size conformity */
827 	msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
828 	if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
829 		rc = -EINVAL;
830 		TFP_DRV_LOG(ERR,
831 			    "%s: Invalid parameters for msg type, rc:%s\n",
832 			    tf_dir_2_str(em_parms->dir),
833 			    strerror(-rc));
834 		return rc;
835 	}
836 
837 	tfp_memcpy(req.em_key,
838 		   em_parms->key,
839 		   msg_key_size);
840 
841 	flags = (em_parms->dir == TF_DIR_TX ?
842 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
843 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
844 	req.flags = tfp_cpu_to_le_16(flags);
845 	req.strength = (em_result->hdr.word1 &
846 			CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
847 			CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
848 	req.em_key_bitlen = em_parms->key_sz_in_bits;
849 	req.action_ptr = em_result->hdr.pointer;
850 	req.em_record_idx = *rptr_index;
851 
852 	parms.tf_type = HWRM_TF_EM_INSERT;
853 	parms.req_data = (uint32_t *)&req;
854 	parms.req_size = sizeof(req);
855 	parms.resp_data = (uint32_t *)&resp;
856 	parms.resp_size = sizeof(resp);
857 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
858 
859 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
860 				 &parms);
861 	if (rc)
862 		return rc;
863 
864 	*rptr_entry = resp.rptr_entry;
865 	*rptr_index = resp.rptr_index;
866 	*num_of_entries = resp.num_of_entries;
867 
868 	return 0;
869 }
870 
871 int
872 tf_msg_hash_insert_em_internal_entry(struct tf *tfp,
873 				     struct tf_insert_em_entry_parms *em_parms,
874 				     uint32_t key0_hash,
875 				     uint32_t key1_hash,
876 				     uint16_t *rptr_index,
877 				     uint8_t *rptr_entry,
878 				     uint8_t *num_of_entries)
879 {
880 	int rc;
881 	struct tfp_send_msg_parms parms = { 0 };
882 	struct hwrm_tf_em_hash_insert_input req = { 0 };
883 	struct hwrm_tf_em_hash_insert_output resp = { 0 };
884 	uint16_t flags;
885 	uint8_t fw_session_id;
886 	uint8_t msg_record_size;
887 	struct tf_dev_info *dev;
888 	struct tf_session *tfs;
889 
890 	/* Retrieve the session information */
891 	rc = tf_session_get_session_internal(tfp, &tfs);
892 	if (rc) {
893 		TFP_DRV_LOG(ERR,
894 			    "%s: Failed to lookup session, rc:%s\n",
895 			    tf_dir_2_str(em_parms->dir),
896 			    strerror(-rc));
897 		return rc;
898 	}
899 
900 	/* Retrieve the device information */
901 	rc = tf_session_get_device(tfs, &dev);
902 	if (rc) {
903 		TFP_DRV_LOG(ERR,
904 			    "%s: Failed to lookup device, rc:%s\n",
905 			    tf_dir_2_str(em_parms->dir),
906 			    strerror(-rc));
907 		return rc;
908 	}
909 
910 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
911 	if (rc) {
912 		TFP_DRV_LOG(ERR,
913 			    "%s: Unable to lookup FW id, rc:%s\n",
914 			    tf_dir_2_str(em_parms->dir),
915 			    strerror(-rc));
916 		return rc;
917 	}
918 
919 	/* Populate the request */
920 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
921 
922 	/* Check for key size conformity */
923 	msg_record_size = (em_parms->em_record_sz_in_bits + 7) / 8;
924 
925 	if (msg_record_size > TF_MSG_EM_INSERT_RECORD_SIZE) {
926 		rc = -EINVAL;
927 		TFP_DRV_LOG(ERR,
928 			    "%s: Record size too large, rc:%s\n",
929 			    tf_dir_2_str(em_parms->dir),
930 			    strerror(-rc));
931 		return rc;
932 	}
933 
934 	tfp_memcpy((char *)req.em_record,
935 		   em_parms->em_record,
936 		   msg_record_size);
937 
938 	flags = (em_parms->dir == TF_DIR_TX ?
939 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
940 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
941 	req.flags = tfp_cpu_to_le_16(flags);
942 	req.em_record_size_bits = em_parms->em_record_sz_in_bits;
943 	req.em_record_idx = *rptr_index;
944 	req.key0_hash = key0_hash;
945 	req.key1_hash = key1_hash;
946 
947 	parms.tf_type = HWRM_TF_EM_HASH_INSERT;
948 	parms.req_data = (uint32_t *)&req;
949 	parms.req_size = sizeof(req);
950 	parms.resp_data = (uint32_t *)&resp;
951 	parms.resp_size = sizeof(resp);
952 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
953 
954 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
955 				 &parms);
956 	if (rc)
957 		return rc;
958 
959 	*rptr_entry = resp.rptr_entry;
960 	*rptr_index = resp.rptr_index;
961 	*num_of_entries = resp.num_of_entries;
962 
963 	return 0;
964 }
965 
966 int
967 tf_msg_delete_em_entry(struct tf *tfp,
968 		       struct tf_delete_em_entry_parms *em_parms)
969 {
970 	int rc;
971 	struct tfp_send_msg_parms parms = { 0 };
972 	struct hwrm_tf_em_delete_input req = { 0 };
973 	struct hwrm_tf_em_delete_output resp = { 0 };
974 	uint16_t flags;
975 	uint8_t fw_session_id;
976 	struct tf_dev_info *dev;
977 	struct tf_session *tfs;
978 
979 	/* Retrieve the session information */
980 	rc = tf_session_get_session_internal(tfp, &tfs);
981 	if (rc) {
982 		TFP_DRV_LOG(ERR,
983 			    "%s: Failed to lookup session, rc:%s\n",
984 			    tf_dir_2_str(em_parms->dir),
985 			    strerror(-rc));
986 		return rc;
987 	}
988 
989 	/* Retrieve the device information */
990 	rc = tf_session_get_device(tfs, &dev);
991 	if (rc) {
992 		TFP_DRV_LOG(ERR,
993 			    "%s: Failed to lookup device, rc:%s\n",
994 			    tf_dir_2_str(em_parms->dir),
995 			    strerror(-rc));
996 		return rc;
997 	}
998 
999 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1000 	if (rc) {
1001 		TFP_DRV_LOG(ERR,
1002 			    "%s: Unable to lookup FW id, rc:%s\n",
1003 			    tf_dir_2_str(em_parms->dir),
1004 			    strerror(-rc));
1005 		return rc;
1006 	}
1007 
1008 	/* Populate the request */
1009 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1010 
1011 	flags = (em_parms->dir == TF_DIR_TX ?
1012 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
1013 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
1014 	req.flags = tfp_cpu_to_le_16(flags);
1015 	req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
1016 
1017 	parms.tf_type = HWRM_TF_EM_DELETE;
1018 	parms.req_data = (uint32_t *)&req;
1019 	parms.req_size = sizeof(req);
1020 	parms.resp_data = (uint32_t *)&resp;
1021 	parms.resp_size = sizeof(resp);
1022 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1023 
1024 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1025 				 &parms);
1026 	if (rc)
1027 		return rc;
1028 
1029 	em_parms->index = tfp_le_to_cpu_16(resp.em_index);
1030 
1031 	return 0;
1032 }
1033 
1034 int
1035 tf_msg_move_em_entry(struct tf *tfp,
1036 		     struct tf_move_em_entry_parms *em_parms)
1037 {
1038 	int rc;
1039 	struct tfp_send_msg_parms parms = { 0 };
1040 	struct hwrm_tf_em_move_input req = { 0 };
1041 	struct hwrm_tf_em_move_output resp = { 0 };
1042 	uint16_t flags;
1043 	uint8_t fw_session_id;
1044 	struct tf_dev_info *dev;
1045 	struct tf_session *tfs;
1046 
1047 	/* Retrieve the session information */
1048 	rc = tf_session_get_session_internal(tfp, &tfs);
1049 	if (rc) {
1050 		TFP_DRV_LOG(ERR,
1051 			    "%s: Failed to lookup session, rc:%s\n",
1052 			    tf_dir_2_str(em_parms->dir),
1053 			    strerror(-rc));
1054 		return rc;
1055 	}
1056 
1057 	/* Retrieve the device information */
1058 	rc = tf_session_get_device(tfs, &dev);
1059 	if (rc) {
1060 		TFP_DRV_LOG(ERR,
1061 			    "%s: Failed to lookup device, rc:%s\n",
1062 			    tf_dir_2_str(em_parms->dir),
1063 			    strerror(-rc));
1064 		return rc;
1065 	}
1066 
1067 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1068 	if (rc) {
1069 		TFP_DRV_LOG(ERR,
1070 			    "%s: Unable to lookup FW id, rc:%s\n",
1071 			    tf_dir_2_str(em_parms->dir),
1072 			    strerror(-rc));
1073 		return rc;
1074 	}
1075 
1076 	/* Populate the request */
1077 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1078 
1079 	flags = (em_parms->dir == TF_DIR_TX ?
1080 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
1081 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
1082 	req.flags = tfp_cpu_to_le_16(flags);
1083 	req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
1084 	req.new_index = tfp_cpu_to_le_32(em_parms->new_index);
1085 
1086 	parms.tf_type = HWRM_TF_EM_MOVE;
1087 	parms.req_data = (uint32_t *)&req;
1088 	parms.req_size = sizeof(req);
1089 	parms.resp_data = (uint32_t *)&resp;
1090 	parms.resp_size = sizeof(resp);
1091 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1092 
1093 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1094 				 &parms);
1095 	if (rc)
1096 		return rc;
1097 
1098 	em_parms->index = tfp_le_to_cpu_16(resp.em_index);
1099 
1100 	return 0;
1101 }
1102 
1103 int
1104 tf_msg_tcam_entry_set(struct tf *tfp,
1105 		      struct tf_dev_info *dev,
1106 		      struct tf_tcam_set_parms *parms)
1107 {
1108 	int rc;
1109 	struct tfp_send_msg_parms mparms = { 0 };
1110 	struct hwrm_tf_tcam_set_input req = { 0 };
1111 	struct hwrm_tf_tcam_set_output resp = { 0 };
1112 	struct tf_msg_dma_buf buf = { 0 };
1113 	uint8_t *data = NULL;
1114 	int data_size = 0;
1115 	uint8_t fw_session_id;
1116 	struct tf_session *tfs;
1117 
1118 	/* Retrieve the session information */
1119 	rc = tf_session_get_session_internal(tfp, &tfs);
1120 	if (rc) {
1121 		TFP_DRV_LOG(ERR,
1122 			    "Failed to lookup session, rc:%s\n",
1123 			    strerror(-rc));
1124 		return rc;
1125 	}
1126 
1127 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1128 	if (rc) {
1129 		TFP_DRV_LOG(ERR,
1130 			    "%s: Unable to lookup FW id, rc:%s\n",
1131 			    tf_dir_2_str(parms->dir),
1132 			    strerror(-rc));
1133 		return rc;
1134 	}
1135 
1136 	/* Populate the request */
1137 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1138 	req.type = parms->hcapi_type;
1139 	req.idx = tfp_cpu_to_le_16(parms->idx);
1140 	if (parms->dir == TF_DIR_TX)
1141 		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
1142 
1143 	req.key_size = parms->key_size;
1144 	req.mask_offset = parms->key_size;
1145 	/* Result follows after key and mask, thus multiply by 2 */
1146 	req.result_offset = 2 * parms->key_size;
1147 	req.result_size = parms->result_size;
1148 	data_size = 2 * req.key_size + req.result_size;
1149 
1150 	/*
1151 	 * Always use dma buffer, as the delete multi slice
1152 	 * tcam entries not support with HWRM request buffer
1153 	 * only DMA'ed buffer can update the mode bits for
1154 	 * the delete to work
1155 	 */
1156 	req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
1157 	rc = tf_msg_alloc_dma_buf(&buf, data_size);
1158 	if (rc)
1159 		goto cleanup;
1160 	data = buf.va_addr;
1161 	tfp_memcpy(&req.dev_data[0],
1162 		   &buf.pa_addr,
1163 		   sizeof(buf.pa_addr));
1164 
1165 	tfp_memcpy(&data[0], parms->key, parms->key_size);
1166 	tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
1167 	tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
1168 
1169 	mparms.tf_type = HWRM_TF_TCAM_SET;
1170 	mparms.req_data = (uint32_t *)&req;
1171 	mparms.req_size = sizeof(req);
1172 	mparms.resp_data = (uint32_t *)&resp;
1173 	mparms.resp_size = sizeof(resp);
1174 	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1175 
1176 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1177 				 &mparms);
1178 
1179 cleanup:
1180 	tf_msg_free_dma_buf(&buf);
1181 
1182 	return rc;
1183 }
1184 
1185 int
1186 tf_msg_tcam_entry_get(struct tf *tfp,
1187 		      struct tf_dev_info *dev,
1188 		      struct tf_tcam_get_parms *parms)
1189 {
1190 	int rc;
1191 	struct tfp_send_msg_parms mparms = { 0 };
1192 	struct hwrm_tf_tcam_get_input req = { 0 };
1193 	struct hwrm_tf_tcam_get_output resp = { 0 };
1194 	uint8_t fw_session_id;
1195 	struct tf_session *tfs;
1196 
1197 	/* Retrieve the session information */
1198 	rc = tf_session_get_session_internal(tfp, &tfs);
1199 	if (rc) {
1200 		TFP_DRV_LOG(ERR,
1201 			    "Failed to lookup session, rc:%s\n",
1202 			    strerror(-rc));
1203 		return rc;
1204 	}
1205 
1206 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1207 	if (rc) {
1208 		TFP_DRV_LOG(ERR,
1209 			    "%s: Unable to lookup FW id, rc:%s\n",
1210 			    tf_dir_2_str(parms->dir),
1211 			    strerror(-rc));
1212 		return rc;
1213 	}
1214 
1215 	/* Populate the request */
1216 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1217 	req.type = parms->hcapi_type;
1218 	req.idx = tfp_cpu_to_le_16(parms->idx);
1219 	if (parms->dir == TF_DIR_TX)
1220 		req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX;
1221 
1222 	mparms.tf_type = HWRM_TF_TCAM_GET;
1223 	mparms.req_data = (uint32_t *)&req;
1224 	mparms.req_size = sizeof(req);
1225 	mparms.resp_data = (uint32_t *)&resp;
1226 	mparms.resp_size = sizeof(resp);
1227 	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1228 
1229 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1230 				 &mparms);
1231 
1232 	if (rc != 0)
1233 		return rc;
1234 
1235 	if (parms->key_size < resp.key_size ||
1236 	    parms->result_size < resp.result_size) {
1237 		rc = -EINVAL;
1238 		TFP_DRV_LOG(ERR,
1239 			    "%s: Key buffer(%d) is smaller than the key(%d), rc:%s\n",
1240 			    tf_dir_2_str(parms->dir),
1241 			    parms->key_size,
1242 			    resp.key_size,
1243 			    strerror(-rc));
1244 		return rc;
1245 	}
1246 	parms->key_size = resp.key_size;
1247 	parms->result_size = resp.result_size;
1248 	tfp_memcpy(parms->key, resp.dev_data, resp.key_size);
1249 	tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size);
1250 	tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size);
1251 
1252 	return 0;
1253 }
1254 
1255 int
1256 tf_msg_tcam_entry_free(struct tf *tfp,
1257 		       struct tf_dev_info *dev,
1258 		       struct tf_tcam_free_parms *in_parms)
1259 {
1260 	int rc;
1261 	struct hwrm_tf_tcam_free_input req =  { 0 };
1262 	struct hwrm_tf_tcam_free_output resp = { 0 };
1263 	struct tfp_send_msg_parms parms = { 0 };
1264 	uint8_t fw_session_id;
1265 	struct tf_session *tfs;
1266 
1267 	/* Retrieve the session information */
1268 	rc = tf_session_get_session_internal(tfp, &tfs);
1269 	if (rc) {
1270 		TFP_DRV_LOG(ERR,
1271 			    "Failed to lookup session, rc:%s\n",
1272 			    strerror(-rc));
1273 		return rc;
1274 	}
1275 
1276 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1277 	if (rc) {
1278 		TFP_DRV_LOG(ERR,
1279 			    "%s: Unable to lookup FW id, rc:%s\n",
1280 			    tf_dir_2_str(in_parms->dir),
1281 			    strerror(-rc));
1282 		return rc;
1283 	}
1284 
1285 	/* Populate the request */
1286 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1287 	req.type = in_parms->hcapi_type;
1288 	req.count = 1;
1289 	req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
1290 	if (in_parms->dir == TF_DIR_TX)
1291 		req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
1292 
1293 	parms.tf_type = HWRM_TF_TCAM_FREE;
1294 	parms.req_data = (uint32_t *)&req;
1295 	parms.req_size = sizeof(req);
1296 	parms.resp_data = (uint32_t *)&resp;
1297 	parms.resp_size = sizeof(resp);
1298 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1299 
1300 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1301 				 &parms);
1302 	return rc;
1303 }
1304 
1305 int
1306 tf_msg_set_tbl_entry(struct tf *tfp,
1307 		     enum tf_dir dir,
1308 		     uint16_t hcapi_type,
1309 		     uint16_t size,
1310 		     uint8_t *data,
1311 		     uint32_t index)
1312 {
1313 	int rc;
1314 	struct hwrm_tf_tbl_type_set_input req = { 0 };
1315 	struct hwrm_tf_tbl_type_set_output resp = { 0 };
1316 	struct tfp_send_msg_parms parms = { 0 };
1317 	struct tf_msg_dma_buf buf = { 0 };
1318 	uint8_t fw_session_id;
1319 	struct tf_dev_info *dev;
1320 	struct tf_session *tfs;
1321 
1322 	RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_tbl_type_set_input) !=
1323 			 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET);
1324 
1325 	/* Retrieve the session information */
1326 	rc = tf_session_get_session_internal(tfp, &tfs);
1327 	if (rc) {
1328 		TFP_DRV_LOG(ERR,
1329 			    "%s: Failed to lookup session, rc:%s\n",
1330 			    tf_dir_2_str(dir),
1331 			    strerror(-rc));
1332 		return rc;
1333 	}
1334 
1335 	/* Retrieve the device information */
1336 	rc = tf_session_get_device(tfs, &dev);
1337 	if (rc) {
1338 		TFP_DRV_LOG(ERR,
1339 			    "%s: Failed to lookup device, rc:%s\n",
1340 			    tf_dir_2_str(dir),
1341 			    strerror(-rc));
1342 		return rc;
1343 	}
1344 
1345 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1346 	if (rc) {
1347 		TFP_DRV_LOG(ERR,
1348 			    "%s: Unable to lookup FW id, rc:%s\n",
1349 			    tf_dir_2_str(dir),
1350 			    strerror(-rc));
1351 		return rc;
1352 	}
1353 
1354 	/* Populate the request */
1355 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1356 	req.flags = tfp_cpu_to_le_16(dir);
1357 	req.type = tfp_cpu_to_le_32(hcapi_type);
1358 	req.size = tfp_cpu_to_le_16(size);
1359 	req.index = tfp_cpu_to_le_32(index);
1360 
1361 	/* Check for data size conformity */
1362 	if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
1363 		/* use dma buffer */
1364 		req.flags |= HWRM_TF_TBL_TYPE_SET_INPUT_FLAGS_DMA;
1365 		rc = tf_msg_alloc_dma_buf(&buf, size);
1366 		if (rc)
1367 			goto cleanup;
1368 		tfp_memcpy(buf.va_addr, data, size);
1369 		tfp_memcpy(&req.data[0],
1370 			   &buf.pa_addr,
1371 			   sizeof(buf.pa_addr));
1372 	} else {
1373 		tfp_memcpy(&req.data, data, size);
1374 	}
1375 
1376 	parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1377 	parms.req_data = (uint32_t *)&req;
1378 	parms.req_size = sizeof(req);
1379 	parms.resp_data = (uint32_t *)&resp;
1380 	parms.resp_size = sizeof(resp);
1381 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1382 
1383 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1384 				 &parms);
1385 cleanup:
1386 	tf_msg_free_dma_buf(&buf);
1387 
1388 	return rc;
1389 }
1390 
1391 int
1392 tf_msg_get_tbl_entry(struct tf *tfp,
1393 		     enum tf_dir dir,
1394 		     uint16_t hcapi_type,
1395 		     uint16_t size,
1396 		     uint8_t *data,
1397 		     uint32_t index,
1398 		     bool clear_on_read)
1399 {
1400 	int rc;
1401 	struct hwrm_tf_tbl_type_get_input req = { 0 };
1402 	struct hwrm_tf_tbl_type_get_output resp = { 0 };
1403 	struct tfp_send_msg_parms parms = { 0 };
1404 	uint8_t fw_session_id;
1405 	struct tf_dev_info *dev;
1406 	struct tf_session *tfs;
1407 	uint32_t flags = 0;
1408 
1409 	/* Retrieve the session information */
1410 	rc = tf_session_get_session_internal(tfp, &tfs);
1411 	if (rc) {
1412 		TFP_DRV_LOG(ERR,
1413 			    "%s: Failed to lookup session, rc:%s\n",
1414 			    tf_dir_2_str(dir),
1415 			    strerror(-rc));
1416 		return rc;
1417 	}
1418 
1419 	/* Retrieve the device information */
1420 	rc = tf_session_get_device(tfs, &dev);
1421 	if (rc) {
1422 		TFP_DRV_LOG(ERR,
1423 			    "%s: Failed to lookup device, rc:%s\n",
1424 			    tf_dir_2_str(dir),
1425 			    strerror(-rc));
1426 		return rc;
1427 	}
1428 
1429 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1430 	if (rc) {
1431 		TFP_DRV_LOG(ERR,
1432 			    "%s: Unable to lookup FW id, rc:%s\n",
1433 			    tf_dir_2_str(dir),
1434 			    strerror(-rc));
1435 		return rc;
1436 	}
1437 	flags = (dir == TF_DIR_TX ?
1438 		 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_TX :
1439 		 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_RX);
1440 
1441 	if (clear_on_read)
1442 		flags |= HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_CLEAR_ON_READ;
1443 
1444 	/* Populate the request */
1445 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1446 	req.flags = tfp_cpu_to_le_16(flags);
1447 	req.type = tfp_cpu_to_le_32(hcapi_type);
1448 	req.index = tfp_cpu_to_le_32(index);
1449 
1450 	parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1451 	parms.req_data = (uint32_t *)&req;
1452 	parms.req_size = sizeof(req);
1453 	parms.resp_data = (uint32_t *)&resp;
1454 	parms.resp_size = sizeof(resp);
1455 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1456 
1457 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1458 				 &parms);
1459 	if (rc)
1460 		return rc;
1461 
1462 	/*
1463 	 * The response will be 64 bytes long, the response size will
1464 	 * be in words (16). All we can test for is that the response
1465 	 * size is < to the requested size.
1466 	 */
1467 	if ((tfp_le_to_cpu_32(resp.size) * 4) < size)
1468 		return -EINVAL;
1469 
1470 	/*
1471 	 * Copy the requested number of bytes
1472 	 */
1473 	tfp_memcpy(data,
1474 		   &resp.data,
1475 		   size);
1476 
1477 	return 0;
1478 }
1479 
1480 /* HWRM Tunneled messages */
1481 
1482 int
1483 tf_msg_get_global_cfg(struct tf *tfp,
1484 		      struct tf_global_cfg_parms *params)
1485 {
1486 	int rc = 0;
1487 	struct tfp_send_msg_parms parms = { 0 };
1488 	struct hwrm_tf_global_cfg_get_input req = { 0 };
1489 	struct hwrm_tf_global_cfg_get_output resp = { 0 };
1490 	uint32_t flags = 0;
1491 	uint8_t fw_session_id;
1492 	uint16_t resp_size = 0;
1493 	struct tf_dev_info *dev;
1494 	struct tf_session *tfs;
1495 
1496 	/* Retrieve the session information */
1497 	rc = tf_session_get_session_internal(tfp, &tfs);
1498 	if (rc) {
1499 		TFP_DRV_LOG(ERR,
1500 			    "%s: Failed to lookup session, rc:%s\n",
1501 			    tf_dir_2_str(params->dir),
1502 			    strerror(-rc));
1503 		return rc;
1504 	}
1505 
1506 	/* Retrieve the device information */
1507 	rc = tf_session_get_device(tfs, &dev);
1508 	if (rc) {
1509 		TFP_DRV_LOG(ERR,
1510 			    "%s: Failed to lookup device, rc:%s\n",
1511 			    tf_dir_2_str(params->dir),
1512 			    strerror(-rc));
1513 		return rc;
1514 	}
1515 
1516 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1517 	if (rc) {
1518 		TFP_DRV_LOG(ERR,
1519 			    "%s: Unable to lookup FW id, rc:%s\n",
1520 			    tf_dir_2_str(params->dir),
1521 			    strerror(-rc));
1522 		return rc;
1523 	}
1524 
1525 	flags = (params->dir == TF_DIR_TX ?
1526 		 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1527 		 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1528 
1529 	/* Populate the request */
1530 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1531 	req.flags = tfp_cpu_to_le_32(flags);
1532 	req.type = tfp_cpu_to_le_32(params->type);
1533 	req.offset = tfp_cpu_to_le_32(params->offset);
1534 	req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1535 
1536 	parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1537 	parms.req_data = (uint32_t *)&req;
1538 	parms.req_size = sizeof(req);
1539 	parms.resp_data = (uint32_t *)&resp;
1540 	parms.resp_size = sizeof(resp);
1541 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1542 
1543 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1544 	if (rc != 0)
1545 		return rc;
1546 
1547 	/* Verify that we got enough buffer to return the requested data */
1548 	resp_size = tfp_le_to_cpu_16(resp.size);
1549 	if (resp_size < params->config_sz_in_bytes)
1550 		return -EINVAL;
1551 
1552 	if (params->config)
1553 		tfp_memcpy(params->config,
1554 			   resp.data,
1555 			   resp_size);
1556 	else
1557 		return -EFAULT;
1558 
1559 	return 0;
1560 }
1561 
1562 int
1563 tf_msg_set_global_cfg(struct tf *tfp,
1564 		      struct tf_global_cfg_parms *params)
1565 {
1566 	int rc = 0;
1567 	struct tfp_send_msg_parms parms = { 0 };
1568 	struct hwrm_tf_global_cfg_set_input req = { 0 };
1569 	struct hwrm_tf_global_cfg_set_output resp = { 0 };
1570 	uint32_t flags = 0;
1571 	uint8_t fw_session_id;
1572 	struct tf_dev_info *dev;
1573 	struct tf_session *tfs;
1574 
1575 	/* Retrieve the session information */
1576 	rc = tf_session_get_session_internal(tfp, &tfs);
1577 	if (rc) {
1578 		TFP_DRV_LOG(ERR,
1579 			    "%s: Failed to lookup session, rc:%s\n",
1580 			    tf_dir_2_str(params->dir),
1581 			    strerror(-rc));
1582 		return rc;
1583 	}
1584 
1585 	/* Retrieve the device information */
1586 	rc = tf_session_get_device(tfs, &dev);
1587 	if (rc) {
1588 		TFP_DRV_LOG(ERR,
1589 			    "%s: Failed to lookup device, rc:%s\n",
1590 			    tf_dir_2_str(params->dir),
1591 			    strerror(-rc));
1592 		return rc;
1593 	}
1594 
1595 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1596 	if (rc) {
1597 		TFP_DRV_LOG(ERR,
1598 			    "%s: Unable to lookup FW id, rc:%s\n",
1599 			    tf_dir_2_str(params->dir),
1600 			    strerror(-rc));
1601 		return rc;
1602 	}
1603 
1604 	flags = (params->dir == TF_DIR_TX ?
1605 		 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
1606 		 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
1607 
1608 	/* Populate the request */
1609 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1610 	req.flags = tfp_cpu_to_le_32(flags);
1611 	req.type = tfp_cpu_to_le_32(params->type);
1612 	req.offset = tfp_cpu_to_le_32(params->offset);
1613 
1614 	/* Check for data size conformity */
1615 	if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
1616 		rc = -EINVAL;
1617 		TFP_DRV_LOG(ERR,
1618 			    "%s: Invalid parameters for msg type, rc:%s\n",
1619 			    tf_dir_2_str(params->dir),
1620 			    strerror(-rc));
1621 		return rc;
1622 	}
1623 
1624 	tfp_memcpy(req.data, params->config,
1625 		   params->config_sz_in_bytes);
1626 
1627 	/* Only set mask if pointer is provided
1628 	 */
1629 	if (params->config_mask) {
1630 		tfp_memcpy(req.mask,
1631 			   params->config_mask,
1632 			   params->config_sz_in_bytes);
1633 	}
1634 
1635 	req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1636 
1637 	parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
1638 	parms.req_data = (uint32_t *)&req;
1639 	parms.req_size = sizeof(req);
1640 	parms.resp_data = (uint32_t *)&resp;
1641 	parms.resp_size = sizeof(resp);
1642 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1643 
1644 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1645 
1646 	if (rc != 0)
1647 		return rc;
1648 
1649 	return 0;
1650 }
1651 
1652 int
1653 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
1654 			  enum tf_dir dir,
1655 			  uint16_t hcapi_type,
1656 			  uint32_t starting_idx,
1657 			  uint16_t num_entries,
1658 			  uint16_t entry_sz_in_bytes,
1659 			  uint64_t physical_mem_addr,
1660 			  bool clear_on_read)
1661 {
1662 	int rc;
1663 	struct tfp_send_msg_parms parms = { 0 };
1664 	struct hwrm_tf_tbl_type_bulk_get_input req = { 0 };
1665 	struct hwrm_tf_tbl_type_bulk_get_output resp = { 0 };
1666 	int data_size = 0;
1667 	uint8_t fw_session_id;
1668 	struct tf_dev_info *dev;
1669 	struct tf_session *tfs;
1670 	uint32_t flags = 0;
1671 
1672 	/* Retrieve the session information */
1673 	rc = tf_session_get_session(tfp, &tfs);
1674 	if (rc) {
1675 		TFP_DRV_LOG(ERR,
1676 			    "%s: Failed to lookup session, rc:%s\n",
1677 			    tf_dir_2_str(dir),
1678 			    strerror(-rc));
1679 		return rc;
1680 	}
1681 
1682 	/* Retrieve the device information */
1683 	rc = tf_session_get_device(tfs, &dev);
1684 	if (rc) {
1685 		TFP_DRV_LOG(ERR,
1686 			    "%s: Failed to lookup device, rc:%s\n",
1687 			    tf_dir_2_str(dir),
1688 			    strerror(-rc));
1689 		return rc;
1690 	}
1691 
1692 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1693 	if (rc) {
1694 		TFP_DRV_LOG(ERR,
1695 			    "%s: Unable to lookup FW id, rc:%s\n",
1696 			    tf_dir_2_str(dir),
1697 			    strerror(-rc));
1698 		return rc;
1699 	}
1700 	flags = (dir == TF_DIR_TX ?
1701 		 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_TX :
1702 		 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_RX);
1703 
1704 	if (clear_on_read)
1705 		flags |= HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_CLEAR_ON_READ;
1706 
1707 	/* Populate the request */
1708 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1709 	req.flags = tfp_cpu_to_le_16(flags);
1710 	req.type = tfp_cpu_to_le_32(hcapi_type);
1711 	req.start_index = tfp_cpu_to_le_32(starting_idx);
1712 	req.num_entries = tfp_cpu_to_le_32(num_entries);
1713 
1714 	data_size = num_entries * entry_sz_in_bytes;
1715 
1716 	req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1717 
1718 	parms.tf_type = HWRM_TF_TBL_TYPE_BULK_GET;
1719 	parms.req_data = (uint32_t *)&req;
1720 	parms.req_size = sizeof(req);
1721 	parms.resp_data = (uint32_t *)&resp;
1722 	parms.resp_size = sizeof(resp);
1723 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1724 
1725 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1726 				 &parms);
1727 	if (rc)
1728 		return rc;
1729 
1730 	/* Verify that we got enough buffer to return the requested data */
1731 	if (tfp_le_to_cpu_32(resp.size) != data_size)
1732 		return -EINVAL;
1733 
1734 	return 0;
1735 }
1736 
1737 int
1738 tf_msg_get_if_tbl_entry(struct tf *tfp,
1739 			struct tf_if_tbl_get_parms *params)
1740 {
1741 	int rc = 0;
1742 	struct tfp_send_msg_parms parms = { 0 };
1743 	struct hwrm_tf_if_tbl_get_input req = { 0 };
1744 	struct hwrm_tf_if_tbl_get_output resp = { 0 };
1745 	uint32_t flags = 0;
1746 	struct tf_dev_info *dev;
1747 	struct tf_session *tfs;
1748 
1749 	/* Retrieve the session information */
1750 	rc = tf_session_get_session(tfp, &tfs);
1751 	if (rc) {
1752 		TFP_DRV_LOG(ERR,
1753 			    "%s: Failed to lookup session, rc:%s\n",
1754 			    tf_dir_2_str(params->dir),
1755 			    strerror(-rc));
1756 		return rc;
1757 	}
1758 
1759 	/* Retrieve the device information */
1760 	rc = tf_session_get_device(tfs, &dev);
1761 	if (rc) {
1762 		TFP_DRV_LOG(ERR,
1763 			    "%s: Failed to lookup device, rc:%s\n",
1764 			    tf_dir_2_str(params->dir),
1765 			    strerror(-rc));
1766 		return rc;
1767 	}
1768 
1769 	flags = (params->dir == TF_DIR_TX ?
1770 		HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
1771 		HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
1772 
1773 	/* Populate the request */
1774 	req.fw_session_id =
1775 		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1776 	req.flags = flags;
1777 	req.type = params->hcapi_type;
1778 	req.index = tfp_cpu_to_le_16(params->idx);
1779 	req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1780 
1781 	parms.tf_type = HWRM_TF_IF_TBL_GET;
1782 	parms.req_data = (uint32_t *)&req;
1783 	parms.req_size = sizeof(req);
1784 	parms.resp_data = (uint32_t *)&resp;
1785 	parms.resp_size = sizeof(resp);
1786 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1787 
1788 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1789 
1790 	if (rc != 0)
1791 		return rc;
1792 
1793 	tfp_memcpy(&params->data[0], resp.data, req.size);
1794 
1795 	return 0;
1796 }
1797 
1798 int
1799 tf_msg_set_if_tbl_entry(struct tf *tfp,
1800 			struct tf_if_tbl_set_parms *params)
1801 {
1802 	int rc = 0;
1803 	struct tfp_send_msg_parms parms = { 0 };
1804 	struct hwrm_tf_if_tbl_set_input req = { 0 };
1805 	struct hwrm_tf_if_tbl_get_output resp = { 0 };
1806 	uint32_t flags = 0;
1807 	struct tf_dev_info *dev;
1808 	struct tf_session *tfs;
1809 
1810 	/* Retrieve the session information */
1811 	rc = tf_session_get_session(tfp, &tfs);
1812 	if (rc) {
1813 		TFP_DRV_LOG(ERR,
1814 			    "%s: Failed to lookup session, rc:%s\n",
1815 			    tf_dir_2_str(params->dir),
1816 			    strerror(-rc));
1817 		return rc;
1818 	}
1819 
1820 	/* Retrieve the device information */
1821 	rc = tf_session_get_device(tfs, &dev);
1822 	if (rc)
1823 		return rc;
1824 
1825 	flags = (params->dir == TF_DIR_TX ?
1826 		HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1827 		HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1828 
1829 	/* Populate the request */
1830 	req.fw_session_id =
1831 		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1832 	req.flags = flags;
1833 	req.type = params->hcapi_type;
1834 	req.index = tfp_cpu_to_le_32(params->idx);
1835 	req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1836 	tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1837 
1838 	parms.tf_type = HWRM_TF_IF_TBL_SET;
1839 	parms.req_data = (uint32_t *)&req;
1840 	parms.req_size = sizeof(req);
1841 	parms.resp_data = (uint32_t *)&resp;
1842 	parms.resp_size = sizeof(resp);
1843 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1844 
1845 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1846 
1847 	if (rc != 0)
1848 		return rc;
1849 
1850 	return 0;
1851 }
1852 
1853 int
1854 tf_msg_get_version(struct bnxt *bp,
1855 		   struct tf_dev_info *dev,
1856 		   struct tf_get_version_parms *params)
1857 
1858 {
1859 	int rc;
1860 	struct hwrm_tf_version_get_input req = { 0 };
1861 	struct hwrm_tf_version_get_output resp = { 0 };
1862 	struct tfp_send_msg_parms parms = { 0 };
1863 
1864 	/* Populate the request */
1865 	parms.tf_type = HWRM_TF_VERSION_GET,
1866 	parms.req_data = (uint32_t *)&req;
1867 	parms.req_size = sizeof(req);
1868 	parms.resp_data = (uint32_t *)&resp;
1869 	parms.resp_size = sizeof(resp);
1870 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1871 
1872 	rc = tfp_send_msg_direct(bp,
1873 				 &parms);
1874 
1875 	params->major = resp.major;
1876 	params->minor = resp.minor;
1877 	params->update = resp.update;
1878 
1879 	dev->ops->tf_dev_map_hcapi_caps(resp.dev_caps_cfg,
1880 					&params->dev_ident_caps,
1881 					&params->dev_tcam_caps,
1882 					&params->dev_tbl_caps,
1883 					&params->dev_em_caps);
1884 
1885 	return rc;
1886 }
1887 
1888 int
1889 tf_msg_session_set_hotup_state(struct tf *tfp, uint16_t state)
1890 {
1891 	int rc;
1892 	struct hwrm_tf_session_hotup_state_set_input req = { 0 };
1893 	struct hwrm_tf_session_hotup_state_set_output resp = { 0 };
1894 	struct tfp_send_msg_parms parms = { 0 };
1895 	uint8_t fw_session_id;
1896 	struct tf_dev_info *dev;
1897 	struct tf_session *tfs;
1898 
1899 	/* Retrieve the session information */
1900 	rc = tf_session_get_session_internal(tfp, &tfs);
1901 	if (rc) {
1902 		TFP_DRV_LOG(ERR,
1903 			    "Failed to lookup session, rc:%s\n",
1904 			    strerror(-rc));
1905 		return rc;
1906 	}
1907 
1908 	/* Retrieve the device information */
1909 	rc = tf_session_get_device(tfs, &dev);
1910 	if (rc) {
1911 		TFP_DRV_LOG(ERR,
1912 			    "Failed to lookup device, rc:%s\n",
1913 			    strerror(-rc));
1914 		return rc;
1915 	}
1916 
1917 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1918 	if (rc) {
1919 		TFP_DRV_LOG(ERR,
1920 			    "Unable to lookup FW id, rc:%s\n",
1921 			    strerror(-rc));
1922 		return rc;
1923 	}
1924 
1925 	/* Populate the request */
1926 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1927 	req.state = tfp_cpu_to_le_16(state);
1928 
1929 	parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_SET;
1930 	parms.req_data = (uint32_t *)&req;
1931 	parms.req_size = sizeof(req);
1932 	parms.resp_data = (uint32_t *)&resp;
1933 	parms.resp_size = sizeof(resp);
1934 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1935 
1936 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1937 				 &parms);
1938 	return rc;
1939 }
1940 
1941 int
1942 tf_msg_session_get_hotup_state(struct tf *tfp,
1943 			       uint16_t *state,
1944 			       uint16_t *ref_cnt)
1945 {
1946 	int rc;
1947 	struct hwrm_tf_session_hotup_state_get_input req = { 0 };
1948 	struct hwrm_tf_session_hotup_state_get_output resp = { 0 };
1949 	struct tfp_send_msg_parms parms = { 0 };
1950 	uint8_t fw_session_id;
1951 	struct tf_dev_info *dev;
1952 	struct tf_session *tfs;
1953 
1954 	/* Retrieve the session information */
1955 	rc = tf_session_get_session_internal(tfp, &tfs);
1956 	if (rc) {
1957 		TFP_DRV_LOG(ERR,
1958 			    "Failed to lookup session, rc:%s\n",
1959 			    strerror(-rc));
1960 		return rc;
1961 	}
1962 
1963 	/* Retrieve the device information */
1964 	rc = tf_session_get_device(tfs, &dev);
1965 	if (rc) {
1966 		TFP_DRV_LOG(ERR,
1967 			    "Failed to lookup device, rc:%s\n",
1968 			    strerror(-rc));
1969 		return rc;
1970 	}
1971 
1972 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1973 	if (rc) {
1974 		TFP_DRV_LOG(ERR,
1975 			    "Unable to lookup FW id, rc:%s\n",
1976 			    strerror(-rc));
1977 		return rc;
1978 	}
1979 
1980 	/* Populate the request */
1981 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1982 
1983 	parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_GET;
1984 	parms.req_data = (uint32_t *)&req;
1985 	parms.req_size = sizeof(req);
1986 	parms.resp_data = (uint32_t *)&resp;
1987 	parms.resp_size = sizeof(resp);
1988 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1989 
1990 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1991 				 &parms);
1992 
1993 	*state = tfp_le_to_cpu_16(resp.state);
1994 	*ref_cnt = tfp_le_to_cpu_16(resp.ref_cnt);
1995 
1996 	return rc;
1997 }
1998 
1999 #ifdef TF_FLOW_SCALE_QUERY
2000 /* Send set resource usage request to the firmware. */
2001 int
2002 tf_msg_set_resc_usage(struct tf *tfp,
2003 		      enum tf_dir dir,
2004 		      uint32_t resc_types,
2005 		      uint32_t size,
2006 		      uint8_t *data)
2007 {
2008 	int rc;
2009 	struct hwrm_tf_resc_usage_set_input req = { 0 };
2010 	struct hwrm_tf_resc_usage_set_output resp = { 0 };
2011 	struct tfp_send_msg_parms parms = { 0 };
2012 	struct tf_msg_dma_buf buf = { 0 };
2013 	uint8_t fw_session_id;
2014 	struct tf_dev_info *dev;
2015 	struct tf_session *tfs;
2016 
2017 	/* Retrieve the session information */
2018 	rc = tf_session_get_session_internal(tfp, &tfs);
2019 	if (rc) {
2020 		TFP_DRV_LOG(ERR,
2021 			    "%s: Failed to lookup session, rc:%s\n",
2022 			    tf_dir_2_str(dir),
2023 			    strerror(-rc));
2024 		return rc;
2025 	}
2026 
2027 	/* Retrieve the device information */
2028 	rc = tf_session_get_device(tfs, &dev);
2029 	if (rc) {
2030 		TFP_DRV_LOG(ERR,
2031 			    "%s: Failed to lookup device, rc:%s\n",
2032 			    tf_dir_2_str(dir),
2033 			    strerror(-rc));
2034 		return rc;
2035 	}
2036 
2037 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2038 	if (rc) {
2039 		TFP_DRV_LOG(ERR,
2040 			    "%s: Unable to lookup FW id, rc:%s\n",
2041 			    tf_dir_2_str(dir),
2042 			    strerror(-rc));
2043 		return rc;
2044 	}
2045 
2046 	/* Populate the request */
2047 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2048 	req.flags = tfp_cpu_to_le_16(dir);
2049 	req.types = tfp_cpu_to_le_32(resc_types);
2050 	req.size = tfp_cpu_to_le_16(size);
2051 #if (TF_RM_MSG_DEBUG == 1)
2052 	/* Dump data */
2053 	dump_tf_resc_usage(dir, data, size);
2054 #endif /* (TF_RM_MSG_DEBUG == 1) */
2055 	/* Check for data size conformity */
2056 	if (size > sizeof(req.data)) {
2057 		/* use dma buffer */
2058 		req.flags |= HWRM_TF_RESC_USAGE_SET_INPUT_FLAGS_DMA;
2059 		rc = tf_msg_alloc_dma_buf(&buf, size);
2060 		if (rc)
2061 			goto exit;
2062 		tfp_memcpy(buf.va_addr, data, size);
2063 		tfp_memcpy(&req.data[0],
2064 			   &buf.pa_addr,
2065 			   sizeof(buf.pa_addr));
2066 	} else {
2067 		tfp_memcpy(&req.data, data, size);
2068 	}
2069 
2070 	parms.tf_type = HWRM_TF_RESC_USAGE_SET;
2071 	parms.req_data = (uint32_t *)&req;
2072 	parms.req_size = sizeof(req);
2073 	parms.resp_data = (uint32_t *)&resp;
2074 	parms.resp_size = sizeof(resp);
2075 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2076 
2077 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
2078 				 &parms);
2079 
2080 	/* Free dma buffer */
2081 	if (size > sizeof(req.data))
2082 		tf_msg_free_dma_buf(&buf);
2083 exit:
2084 	return rc;
2085 }
2086 
2087 /* Send query resource usage request to the firmware. */
2088 int tf_msg_query_resc_usage(struct tf *tfp,
2089 			    enum tf_dir dir,
2090 			    uint32_t resc_types,
2091 			    uint32_t *size,
2092 			    uint8_t *data)
2093 {
2094 	int rc;
2095 	struct hwrm_tf_resc_usage_query_input req = { 0 };
2096 	struct hwrm_tf_resc_usage_query_output resp = { 0 };
2097 	struct tfp_send_msg_parms parms = { 0 };
2098 	uint8_t fw_session_id;
2099 	struct tf_dev_info *dev;
2100 	struct tf_session *tfs;
2101 	uint32_t flags = 0;
2102 
2103 	/* Retrieve the session information */
2104 	rc = tf_session_get_session_internal(tfp, &tfs);
2105 	if (rc) {
2106 		TFP_DRV_LOG(ERR,
2107 			    "%s: Failed to lookup session, rc:%s\n",
2108 			    tf_dir_2_str(dir),
2109 			    strerror(-rc));
2110 		return rc;
2111 	}
2112 
2113 	/* Retrieve the device information */
2114 	rc = tf_session_get_device(tfs, &dev);
2115 	if (rc) {
2116 		TFP_DRV_LOG(ERR,
2117 			    "%s: Failed to lookup device, rc:%s\n",
2118 			    tf_dir_2_str(dir),
2119 			    strerror(-rc));
2120 		return rc;
2121 	}
2122 
2123 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2124 	if (rc) {
2125 		TFP_DRV_LOG(ERR,
2126 			    "%s: Unable to lookup FW id, rc:%s\n",
2127 			    tf_dir_2_str(dir),
2128 			    strerror(-rc));
2129 		return rc;
2130 	}
2131 	flags = (dir == TF_DIR_TX ?
2132 		 HWRM_TF_RESC_USAGE_QUERY_INPUT_FLAGS_DIR_TX :
2133 		 HWRM_TF_RESC_USAGE_QUERY_INPUT_FLAGS_DIR_RX);
2134 
2135 	/* Populate the request */
2136 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2137 	req.flags = tfp_cpu_to_le_16(flags);
2138 	req.types = tfp_cpu_to_le_32(resc_types);
2139 
2140 	parms.tf_type = HWRM_TF_RESC_USAGE_QUERY;
2141 	parms.req_data = (uint32_t *)&req;
2142 	parms.req_size = sizeof(req);
2143 	parms.resp_data = (uint32_t *)&resp;
2144 	parms.resp_size = sizeof(resp);
2145 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2146 
2147 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
2148 				 &parms);
2149 	if (rc)
2150 		return rc;
2151 
2152 	/* The response size should be less than or equal to (<=) the input buffer size. */
2153 	if (resp.size > *size)
2154 		return -EINVAL;
2155 
2156 	*size = resp.size;
2157 
2158 	/*
2159 	 * Copy the requested number of bytes
2160 	 */
2161 	tfp_memcpy(data,
2162 		   &resp.data,
2163 		   resp.size);
2164 
2165 #if (TF_RM_MSG_DEBUG == 1)
2166 	/* dump data */
2167 	dump_tf_resc_usage(dir, data, resp.size);
2168 #endif /* (TF_RM_MSG_DEBUG == 1) */
2169 
2170 	return 0;
2171 }
2172 #endif /* TF_FLOW_SCALE_QUERY */
2173