xref: /dpdk/drivers/net/bnxt/tf_core/tf_msg.c (revision 7917b0d38e92e8b9ec5a870415b791420e10f11a)
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     80
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 to 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 tf_msg_ext_em_ctxt_mem_alloc(struct tf *tfp,
1104 				struct hcapi_cfa_em_table *tbl,
1105 				uint64_t *dma_addr,
1106 				uint32_t *page_lvl,
1107 				uint32_t *page_size)
1108 {
1109 	struct tfp_send_msg_parms parms = { 0 };
1110 	struct hwrm_tf_ctxt_mem_alloc_input req = {0};
1111 	struct hwrm_tf_ctxt_mem_alloc_output resp = {0};
1112 	uint32_t mem_size_k;
1113 	int rc = 0;
1114 	struct tf_dev_info *dev;
1115 	struct tf_session *tfs;
1116 	uint32_t fw_se_id;
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 	/* Retrieve the device information */
1128 	rc = tf_session_get_device(tfs, &dev);
1129 	if (rc) {
1130 		TFP_DRV_LOG(ERR,
1131 			    "Failed to lookup device, rc:%s\n",
1132 			    strerror(-rc));
1133 		return rc;
1134 	}
1135 	/* Retrieve the session information */
1136 	fw_se_id = tfs->session_id.internal.fw_session_id;
1137 
1138 	if (tbl->num_entries && tbl->entry_size) {
1139 		/* unit: kbytes */
1140 		mem_size_k = (tbl->num_entries / TF_KILOBYTE) * tbl->entry_size;
1141 		req.mem_size = tfp_cpu_to_le_32(mem_size_k);
1142 		req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1143 		parms.tf_type = HWRM_TF_CTXT_MEM_ALLOC;
1144 		parms.req_data = (uint32_t *)&req;
1145 		parms.req_size = sizeof(req);
1146 		parms.resp_data = (uint32_t *)&resp;
1147 		parms.resp_size = sizeof(resp);
1148 		parms.mailbox = dev->ops->tf_dev_get_mailbox();
1149 		rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1150 		if (rc) {
1151 			TFP_DRV_LOG(ERR, "Failed ext_em_alloc error rc:%s\n",
1152 				strerror(-rc));
1153 			return rc;
1154 		}
1155 
1156 		*dma_addr = tfp_le_to_cpu_64(resp.page_dir);
1157 		*page_lvl = resp.page_level;
1158 		*page_size = resp.page_size;
1159 	}
1160 
1161 	return rc;
1162 }
1163 
1164 int tf_msg_ext_em_ctxt_mem_free(struct tf *tfp,
1165 				uint32_t mem_size_k,
1166 				uint64_t dma_addr,
1167 				uint8_t page_level,
1168 				uint8_t page_size)
1169 {
1170 	struct tfp_send_msg_parms parms = { 0 };
1171 	struct hwrm_tf_ctxt_mem_free_input req = {0};
1172 	struct hwrm_tf_ctxt_mem_free_output resp = {0};
1173 	int rc = 0;
1174 	struct tf_dev_info *dev;
1175 	struct tf_session *tfs;
1176 	uint32_t fw_se_id;
1177 
1178 	/* Retrieve the session information */
1179 	rc = tf_session_get_session_internal(tfp, &tfs);
1180 	if (rc) {
1181 		TFP_DRV_LOG(ERR,
1182 			    "Failed to lookup session, rc:%s\n",
1183 			    strerror(-rc));
1184 		return rc;
1185 	}
1186 
1187 	/* Retrieve the device information */
1188 	rc = tf_session_get_device(tfs, &dev);
1189 	if (rc) {
1190 		TFP_DRV_LOG(ERR,
1191 			    "Failed to lookup device, rc:%s\n",
1192 			    strerror(-rc));
1193 		return rc;
1194 	}
1195 	/* Retrieve the session information */
1196 	fw_se_id = tfs->session_id.internal.fw_session_id;
1197 
1198 	req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1199 	req.mem_size = tfp_cpu_to_le_32(mem_size_k);
1200 	req.page_dir = tfp_cpu_to_le_64(dma_addr);
1201 	req.page_level = page_level;
1202 	req.page_size = page_size;
1203 	parms.tf_type = HWRM_TF_CTXT_MEM_FREE;
1204 	parms.req_data = (uint32_t *)&req;
1205 	parms.req_size = sizeof(req);
1206 	parms.resp_data = (uint32_t *)&resp;
1207 	parms.resp_size = sizeof(resp);
1208 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1209 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1210 
1211 	return rc;
1212 }
1213 
1214 int
1215 tf_msg_em_mem_rgtr(struct tf *tfp,
1216 		   int page_lvl,
1217 		   int page_size,
1218 		   uint64_t dma_addr,
1219 		   uint16_t *ctx_id)
1220 {
1221 	int rc;
1222 	struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
1223 	struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
1224 	struct tfp_send_msg_parms parms = { 0 };
1225 	struct tf_dev_info *dev;
1226 	struct tf_session *tfs;
1227 	uint32_t fw_se_id;
1228 
1229 	/* Retrieve the session information */
1230 	rc = tf_session_get_session_internal(tfp, &tfs);
1231 	if (rc) {
1232 		TFP_DRV_LOG(ERR,
1233 			    "Failed to lookup session, rc:%s\n",
1234 			    strerror(-rc));
1235 		return rc;
1236 	}
1237 
1238 	/* Retrieve the device information */
1239 	rc = tf_session_get_device(tfs, &dev);
1240 	if (rc) {
1241 		TFP_DRV_LOG(ERR,
1242 			    "Failed to lookup device, rc:%s\n",
1243 			    strerror(-rc));
1244 		return rc;
1245 	}
1246 	fw_se_id = tfs->session_id.internal.fw_session_id;
1247 
1248 	req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1249 	req.page_level = page_lvl;
1250 	req.page_size = page_size;
1251 	req.page_dir = tfp_cpu_to_le_64(dma_addr);
1252 
1253 	parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
1254 	parms.req_data = (uint32_t *)&req;
1255 	parms.req_size = sizeof(req);
1256 	parms.resp_data = (uint32_t *)&resp;
1257 	parms.resp_size = sizeof(resp);
1258 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1259 
1260 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1261 				 &parms);
1262 	if (rc)
1263 		return rc;
1264 
1265 	*ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
1266 
1267 	return rc;
1268 }
1269 
1270 int
1271 tf_msg_em_mem_unrgtr(struct tf *tfp,
1272 		     uint16_t *ctx_id)
1273 {
1274 	int rc;
1275 	struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
1276 	struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
1277 	struct tfp_send_msg_parms parms = { 0 };
1278 	struct tf_dev_info *dev;
1279 	struct tf_session *tfs;
1280 	uint32_t fw_se_id;
1281 
1282 	/* Retrieve the session information */
1283 	rc = tf_session_get_session_internal(tfp, &tfs);
1284 	if (rc) {
1285 		TFP_DRV_LOG(ERR,
1286 			    "Failed to lookup session, rc:%s\n",
1287 			    strerror(-rc));
1288 		return rc;
1289 	}
1290 
1291 	/* Retrieve the device information */
1292 	rc = tf_session_get_device(tfs, &dev);
1293 	if (rc) {
1294 		TFP_DRV_LOG(ERR,
1295 			    "Failed to lookup device, rc:%s\n",
1296 			    strerror(-rc));
1297 		return rc;
1298 	}
1299 
1300 	fw_se_id = tfs->session_id.internal.fw_session_id;
1301 	req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1302 
1303 	req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
1304 
1305 	parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
1306 	parms.req_data = (uint32_t *)&req;
1307 	parms.req_size = sizeof(req);
1308 	parms.resp_data = (uint32_t *)&resp;
1309 	parms.resp_size = sizeof(resp);
1310 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1311 
1312 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1313 				 &parms);
1314 	return rc;
1315 }
1316 
1317 int
1318 tf_msg_em_qcaps(struct tf *tfp,
1319 		int dir,
1320 		struct tf_em_caps *em_caps)
1321 {
1322 	int rc;
1323 	struct hwrm_tf_ext_em_qcaps_input  req = {0};
1324 	struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
1325 	uint32_t             flags;
1326 	struct tfp_send_msg_parms parms = { 0 };
1327 	struct tf_dev_info *dev;
1328 	struct tf_session *tfs;
1329 	uint32_t fw_se_id;
1330 
1331 	/* Retrieve the session information */
1332 	rc = tf_session_get_session_internal(tfp, &tfs);
1333 	if (rc) {
1334 		TFP_DRV_LOG(ERR,
1335 			    "%s: Failed to lookup session, rc:%s\n",
1336 			    tf_dir_2_str(dir),
1337 			    strerror(-rc));
1338 		return rc;
1339 	}
1340 	fw_se_id = tfs->session_id.internal.fw_session_id;
1341 
1342 	/* Retrieve the device information */
1343 	rc = tf_session_get_device(tfs, &dev);
1344 	if (rc) {
1345 		TFP_DRV_LOG(ERR,
1346 			    "%s: Failed to lookup device, rc:%s\n",
1347 			    tf_dir_2_str(dir),
1348 			    strerror(-rc));
1349 		return rc;
1350 	}
1351 
1352 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
1353 		 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
1354 	req.flags = tfp_cpu_to_le_32(flags);
1355 
1356 	parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
1357 	req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1358 	parms.req_data = (uint32_t *)&req;
1359 	parms.req_size = sizeof(req);
1360 	parms.resp_data = (uint32_t *)&resp;
1361 	parms.resp_size = sizeof(resp);
1362 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1363 
1364 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1365 				 &parms);
1366 	if (rc)
1367 		return rc;
1368 
1369 	em_caps->supported = tfp_le_to_cpu_32(resp.supported);
1370 	em_caps->max_entries_supported =
1371 		tfp_le_to_cpu_32(resp.max_entries_supported);
1372 	em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
1373 	em_caps->record_entry_size =
1374 		tfp_le_to_cpu_16(resp.record_entry_size);
1375 	em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
1376 
1377 	return rc;
1378 }
1379 
1380 int
1381 tf_msg_em_cfg(struct tf *tfp,
1382 	      uint32_t num_entries,
1383 	      uint16_t key0_ctx_id,
1384 	      uint16_t key1_ctx_id,
1385 	      uint16_t record_ctx_id,
1386 	      uint16_t efc_ctx_id,
1387 	      uint8_t flush_interval,
1388 	      int dir)
1389 {
1390 	int rc;
1391 	struct hwrm_tf_ext_em_cfg_input  req = {0};
1392 	struct hwrm_tf_ext_em_cfg_output resp = {0};
1393 	uint32_t flags;
1394 	struct tfp_send_msg_parms parms = { 0 };
1395 	struct tf_dev_info *dev;
1396 	struct tf_session *tfs;
1397 
1398 	/* Retrieve the session information */
1399 	rc = tf_session_get_session_internal(tfp, &tfs);
1400 	if (rc) {
1401 		TFP_DRV_LOG(ERR,
1402 			    "%s: Failed to lookup session, rc:%s\n",
1403 			    tf_dir_2_str(dir),
1404 			    strerror(-rc));
1405 		return rc;
1406 	}
1407 
1408 	/* Retrieve the device information */
1409 	rc = tf_session_get_device(tfs, &dev);
1410 	if (rc) {
1411 		TFP_DRV_LOG(ERR,
1412 			    "%s: Failed to lookup device, rc:%s\n",
1413 			    tf_dir_2_str(dir),
1414 			    strerror(-rc));
1415 		return rc;
1416 	}
1417 
1418 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1419 		 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1420 	flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
1421 
1422 	req.flags = tfp_cpu_to_le_32(flags);
1423 	req.num_entries = tfp_cpu_to_le_32(num_entries);
1424 
1425 	req.flush_interval = flush_interval;
1426 
1427 	req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
1428 	req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
1429 	req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
1430 	req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
1431 
1432 	parms.tf_type = HWRM_TF_EXT_EM_CFG;
1433 	parms.req_data = (uint32_t *)&req;
1434 	parms.req_size = sizeof(req);
1435 	parms.resp_data = (uint32_t *)&resp;
1436 	parms.resp_size = sizeof(resp);
1437 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1438 
1439 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1440 				 &parms);
1441 	return rc;
1442 }
1443 
1444 int
1445 tf_msg_ext_em_cfg(struct tf *tfp,
1446 		  struct tf_tbl_scope_cb *tbl_scope_cb,
1447 		  uint32_t st_buckets,
1448 		  uint8_t flush_interval,
1449 		  enum tf_dir dir)
1450 {
1451 	struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir];
1452 	struct hcapi_cfa_em_table *lkup_tbl, *act_tbl;
1453 	struct hwrm_tf_ext_em_cfg_input  req = {0};
1454 	struct hwrm_tf_ext_em_cfg_output resp = {0};
1455 	struct tfp_send_msg_parms parms = { 0 };
1456 	uint32_t flags;
1457 	struct tf_dev_info *dev;
1458 	struct tf_session *tfs;
1459 	uint32_t fw_se_id;
1460 	int rc;
1461 
1462 	/* Retrieve the session information */
1463 	rc = tf_session_get_session_internal(tfp, &tfs);
1464 	if (rc) {
1465 		TFP_DRV_LOG(ERR,
1466 			    "%s: Failed to lookup session, rc:%s\n",
1467 			    tf_dir_2_str(dir),
1468 			    strerror(-rc));
1469 		return rc;
1470 	}
1471 
1472 	/* Retrieve the device information */
1473 	rc = tf_session_get_device(tfs, &dev);
1474 	if (rc) {
1475 		TFP_DRV_LOG(ERR,
1476 			    "%s: Failed to lookup device, rc:%s\n",
1477 			    tf_dir_2_str(dir),
1478 			    strerror(-rc));
1479 		return rc;
1480 	}
1481 	fw_se_id = tfs->session_id.internal.fw_session_id;
1482 
1483 	lkup_tbl = &ctxp->em_tables[TF_EM_LKUP_TABLE];
1484 	act_tbl = &ctxp->em_tables[TF_ACTION_TABLE];
1485 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1486 		 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1487 	flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
1488 
1489 	req.flags = tfp_cpu_to_le_32(flags);
1490 	req.num_entries = tfp_cpu_to_le_32(act_tbl->num_entries);
1491 	req.lkup_static_buckets = tfp_cpu_to_le_32(st_buckets);
1492 	req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1493 	req.flush_interval = flush_interval;
1494 	req.action_ctx_id = tfp_cpu_to_le_16(act_tbl->ctx_id);
1495 	req.action_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id);
1496 	req.lkup_ctx_id = tfp_cpu_to_le_16(lkup_tbl->ctx_id);
1497 	req.lkup_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id);
1498 
1499 	req.enables = (HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_CTX_ID |
1500 		       HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_TBL_SCOPE |
1501 		       HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_CTX_ID |
1502 		       HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_TBL_SCOPE |
1503 		       HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_STATIC_BUCKETS |
1504 		       HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_NUM_ENTRIES);
1505 
1506 	parms.tf_type = HWRM_TF_EXT_EM_CFG;
1507 	parms.req_data = (uint32_t *)&req;
1508 	parms.req_size = sizeof(req);
1509 	parms.resp_data = (uint32_t *)&resp;
1510 	parms.resp_size = sizeof(resp);
1511 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1512 
1513 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1514 				 &parms);
1515 	return rc;
1516 }
1517 
1518 int
1519 tf_msg_em_op(struct tf *tfp,
1520 	     int dir,
1521 	     uint16_t op)
1522 {
1523 	int rc;
1524 	struct hwrm_tf_ext_em_op_input req = {0};
1525 	struct hwrm_tf_ext_em_op_output resp = {0};
1526 	uint32_t flags;
1527 	struct tfp_send_msg_parms parms = { 0 };
1528 	struct tf_dev_info *dev;
1529 	struct tf_session *tfs;
1530 
1531 	/* Retrieve the session information */
1532 	rc = tf_session_get_session_internal(tfp, &tfs);
1533 	if (rc) {
1534 		TFP_DRV_LOG(ERR,
1535 			    "%s: Failed to lookup session, rc:%s\n",
1536 			    tf_dir_2_str(dir),
1537 			    strerror(-rc));
1538 		return rc;
1539 	}
1540 
1541 	/* Retrieve the device information */
1542 	rc = tf_session_get_device(tfs, &dev);
1543 	if (rc) {
1544 		TFP_DRV_LOG(ERR,
1545 			    "%s: Failed to lookup device, rc:%s\n",
1546 			    tf_dir_2_str(dir),
1547 			    strerror(-rc));
1548 		return rc;
1549 	}
1550 
1551 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1552 		 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1553 	req.flags = tfp_cpu_to_le_32(flags);
1554 	req.op = tfp_cpu_to_le_16(op);
1555 
1556 	parms.tf_type = HWRM_TF_EXT_EM_OP;
1557 	parms.req_data = (uint32_t *)&req;
1558 	parms.req_size = sizeof(req);
1559 	parms.resp_data = (uint32_t *)&resp;
1560 	parms.resp_size = sizeof(resp);
1561 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1562 
1563 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1564 				 &parms);
1565 	return rc;
1566 }
1567 
1568 int
1569 tf_msg_tcam_entry_set(struct tf *tfp,
1570 		      struct tf_dev_info *dev,
1571 		      struct tf_tcam_set_parms *parms)
1572 {
1573 	int rc;
1574 	struct tfp_send_msg_parms mparms = { 0 };
1575 	struct hwrm_tf_tcam_set_input req = { 0 };
1576 	struct hwrm_tf_tcam_set_output resp = { 0 };
1577 	struct tf_msg_dma_buf buf = { 0 };
1578 	uint8_t *data = NULL;
1579 	int data_size = 0;
1580 	uint8_t fw_session_id;
1581 	struct tf_session *tfs;
1582 
1583 	/* Retrieve the session information */
1584 	rc = tf_session_get_session_internal(tfp, &tfs);
1585 	if (rc) {
1586 		TFP_DRV_LOG(ERR,
1587 			    "Failed to lookup session, rc:%s\n",
1588 			    strerror(-rc));
1589 		return rc;
1590 	}
1591 
1592 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1593 	if (rc) {
1594 		TFP_DRV_LOG(ERR,
1595 			    "%s: Unable to lookup FW id, rc:%s\n",
1596 			    tf_dir_2_str(parms->dir),
1597 			    strerror(-rc));
1598 		return rc;
1599 	}
1600 
1601 	/* Populate the request */
1602 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1603 	req.type = parms->hcapi_type;
1604 	req.idx = tfp_cpu_to_le_16(parms->idx);
1605 	if (parms->dir == TF_DIR_TX)
1606 		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
1607 
1608 	req.key_size = parms->key_size;
1609 	req.mask_offset = parms->key_size;
1610 	/* Result follows after key and mask, thus multiply by 2 */
1611 	req.result_offset = 2 * parms->key_size;
1612 	req.result_size = parms->result_size;
1613 	data_size = 2 * req.key_size + req.result_size;
1614 
1615 	if (data_size <= TF_PCI_BUF_SIZE_MAX) {
1616 		/* use pci buffer */
1617 		data = &req.dev_data[0];
1618 	} else {
1619 		/* use dma buffer */
1620 		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
1621 		rc = tf_msg_alloc_dma_buf(&buf, data_size);
1622 		if (rc)
1623 			goto cleanup;
1624 		data = buf.va_addr;
1625 		tfp_memcpy(&req.dev_data[0],
1626 			   &buf.pa_addr,
1627 			   sizeof(buf.pa_addr));
1628 	}
1629 
1630 	tfp_memcpy(&data[0], parms->key, parms->key_size);
1631 	tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
1632 	tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
1633 
1634 	mparms.tf_type = HWRM_TF_TCAM_SET;
1635 	mparms.req_data = (uint32_t *)&req;
1636 	mparms.req_size = sizeof(req);
1637 	mparms.resp_data = (uint32_t *)&resp;
1638 	mparms.resp_size = sizeof(resp);
1639 	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1640 
1641 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1642 				 &mparms);
1643 
1644 cleanup:
1645 	tf_msg_free_dma_buf(&buf);
1646 
1647 	return rc;
1648 }
1649 
1650 int
1651 tf_msg_tcam_entry_get(struct tf *tfp,
1652 		      struct tf_dev_info *dev,
1653 		      struct tf_tcam_get_parms *parms)
1654 {
1655 	int rc;
1656 	struct tfp_send_msg_parms mparms = { 0 };
1657 	struct hwrm_tf_tcam_get_input req = { 0 };
1658 	struct hwrm_tf_tcam_get_output resp = { 0 };
1659 	uint8_t fw_session_id;
1660 	struct tf_session *tfs;
1661 
1662 	/* Retrieve the session information */
1663 	rc = tf_session_get_session_internal(tfp, &tfs);
1664 	if (rc) {
1665 		TFP_DRV_LOG(ERR,
1666 			    "Failed to lookup session, rc:%s\n",
1667 			    strerror(-rc));
1668 		return rc;
1669 	}
1670 
1671 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1672 	if (rc) {
1673 		TFP_DRV_LOG(ERR,
1674 			    "%s: Unable to lookup FW id, rc:%s\n",
1675 			    tf_dir_2_str(parms->dir),
1676 			    strerror(-rc));
1677 		return rc;
1678 	}
1679 
1680 	/* Populate the request */
1681 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1682 	req.type = parms->hcapi_type;
1683 	req.idx = tfp_cpu_to_le_16(parms->idx);
1684 	if (parms->dir == TF_DIR_TX)
1685 		req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX;
1686 
1687 	mparms.tf_type = HWRM_TF_TCAM_GET;
1688 	mparms.req_data = (uint32_t *)&req;
1689 	mparms.req_size = sizeof(req);
1690 	mparms.resp_data = (uint32_t *)&resp;
1691 	mparms.resp_size = sizeof(resp);
1692 	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1693 
1694 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1695 				 &mparms);
1696 
1697 	if (rc != 0)
1698 		return rc;
1699 
1700 	if (parms->key_size < resp.key_size ||
1701 	    parms->result_size < resp.result_size) {
1702 		rc = -EINVAL;
1703 		TFP_DRV_LOG(ERR,
1704 			    "%s: Key buffer(%d) is smaller than the key(%d), rc:%s\n",
1705 			    tf_dir_2_str(parms->dir),
1706 			    parms->key_size,
1707 			    resp.key_size,
1708 			    strerror(-rc));
1709 		return rc;
1710 	}
1711 	parms->key_size = resp.key_size;
1712 	parms->result_size = resp.result_size;
1713 	tfp_memcpy(parms->key, resp.dev_data, resp.key_size);
1714 	tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size);
1715 	tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size);
1716 
1717 	return 0;
1718 }
1719 
1720 int
1721 tf_msg_tcam_entry_free(struct tf *tfp,
1722 		       struct tf_dev_info *dev,
1723 		       struct tf_tcam_free_parms *in_parms)
1724 {
1725 	int rc;
1726 	struct hwrm_tf_tcam_free_input req =  { 0 };
1727 	struct hwrm_tf_tcam_free_output resp = { 0 };
1728 	struct tfp_send_msg_parms parms = { 0 };
1729 	uint8_t fw_session_id;
1730 	struct tf_session *tfs;
1731 
1732 	/* Retrieve the session information */
1733 	rc = tf_session_get_session_internal(tfp, &tfs);
1734 	if (rc) {
1735 		TFP_DRV_LOG(ERR,
1736 			    "Failed to lookup session, rc:%s\n",
1737 			    strerror(-rc));
1738 		return rc;
1739 	}
1740 
1741 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1742 	if (rc) {
1743 		TFP_DRV_LOG(ERR,
1744 			    "%s: Unable to lookup FW id, rc:%s\n",
1745 			    tf_dir_2_str(in_parms->dir),
1746 			    strerror(-rc));
1747 		return rc;
1748 	}
1749 
1750 	/* Populate the request */
1751 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1752 	req.type = in_parms->hcapi_type;
1753 	req.count = 1;
1754 	req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
1755 	if (in_parms->dir == TF_DIR_TX)
1756 		req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
1757 
1758 	parms.tf_type = HWRM_TF_TCAM_FREE;
1759 	parms.req_data = (uint32_t *)&req;
1760 	parms.req_size = sizeof(req);
1761 	parms.resp_data = (uint32_t *)&resp;
1762 	parms.resp_size = sizeof(resp);
1763 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1764 
1765 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1766 				 &parms);
1767 	return rc;
1768 }
1769 
1770 int
1771 tf_msg_set_tbl_entry(struct tf *tfp,
1772 		     enum tf_dir dir,
1773 		     uint16_t hcapi_type,
1774 		     uint16_t size,
1775 		     uint8_t *data,
1776 		     uint32_t index)
1777 {
1778 	int rc;
1779 	struct hwrm_tf_tbl_type_set_input req = { 0 };
1780 	struct hwrm_tf_tbl_type_set_output resp = { 0 };
1781 	struct tfp_send_msg_parms parms = { 0 };
1782 	struct tf_msg_dma_buf buf = { 0 };
1783 	uint8_t fw_session_id;
1784 	struct tf_dev_info *dev;
1785 	struct tf_session *tfs;
1786 
1787 	RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_tbl_type_set_input) !=
1788 			 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET);
1789 
1790 	/* Retrieve the session information */
1791 	rc = tf_session_get_session_internal(tfp, &tfs);
1792 	if (rc) {
1793 		TFP_DRV_LOG(ERR,
1794 			    "%s: Failed to lookup session, rc:%s\n",
1795 			    tf_dir_2_str(dir),
1796 			    strerror(-rc));
1797 		return rc;
1798 	}
1799 
1800 	/* Retrieve the device information */
1801 	rc = tf_session_get_device(tfs, &dev);
1802 	if (rc) {
1803 		TFP_DRV_LOG(ERR,
1804 			    "%s: Failed to lookup device, rc:%s\n",
1805 			    tf_dir_2_str(dir),
1806 			    strerror(-rc));
1807 		return rc;
1808 	}
1809 
1810 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1811 	if (rc) {
1812 		TFP_DRV_LOG(ERR,
1813 			    "%s: Unable to lookup FW id, rc:%s\n",
1814 			    tf_dir_2_str(dir),
1815 			    strerror(-rc));
1816 		return rc;
1817 	}
1818 
1819 	/* Populate the request */
1820 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1821 	req.flags = tfp_cpu_to_le_16(dir);
1822 	req.type = tfp_cpu_to_le_32(hcapi_type);
1823 	req.size = tfp_cpu_to_le_16(size);
1824 	req.index = tfp_cpu_to_le_32(index);
1825 
1826 	/* Check for data size conformity */
1827 	if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
1828 		/* use dma buffer */
1829 		req.flags |= HWRM_TF_TBL_TYPE_SET_INPUT_FLAGS_DMA;
1830 		rc = tf_msg_alloc_dma_buf(&buf, size);
1831 		if (rc)
1832 			goto cleanup;
1833 		tfp_memcpy(buf.va_addr, data, size);
1834 		tfp_memcpy(&req.data[0],
1835 			   &buf.pa_addr,
1836 			   sizeof(buf.pa_addr));
1837 	} else {
1838 		tfp_memcpy(&req.data, data, size);
1839 	}
1840 
1841 	parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1842 	parms.req_data = (uint32_t *)&req;
1843 	parms.req_size = sizeof(req);
1844 	parms.resp_data = (uint32_t *)&resp;
1845 	parms.resp_size = sizeof(resp);
1846 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1847 
1848 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1849 				 &parms);
1850 cleanup:
1851 	tf_msg_free_dma_buf(&buf);
1852 
1853 	return rc;
1854 }
1855 
1856 int
1857 tf_msg_get_tbl_entry(struct tf *tfp,
1858 		     enum tf_dir dir,
1859 		     uint16_t hcapi_type,
1860 		     uint16_t size,
1861 		     uint8_t *data,
1862 		     uint32_t index,
1863 		     bool clear_on_read)
1864 {
1865 	int rc;
1866 	struct hwrm_tf_tbl_type_get_input req = { 0 };
1867 	struct hwrm_tf_tbl_type_get_output resp = { 0 };
1868 	struct tfp_send_msg_parms parms = { 0 };
1869 	uint8_t fw_session_id;
1870 	struct tf_dev_info *dev;
1871 	struct tf_session *tfs;
1872 	uint32_t flags = 0;
1873 
1874 	/* Retrieve the session information */
1875 	rc = tf_session_get_session_internal(tfp, &tfs);
1876 	if (rc) {
1877 		TFP_DRV_LOG(ERR,
1878 			    "%s: Failed to lookup session, rc:%s\n",
1879 			    tf_dir_2_str(dir),
1880 			    strerror(-rc));
1881 		return rc;
1882 	}
1883 
1884 	/* Retrieve the device information */
1885 	rc = tf_session_get_device(tfs, &dev);
1886 	if (rc) {
1887 		TFP_DRV_LOG(ERR,
1888 			    "%s: Failed to lookup device, rc:%s\n",
1889 			    tf_dir_2_str(dir),
1890 			    strerror(-rc));
1891 		return rc;
1892 	}
1893 
1894 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1895 	if (rc) {
1896 		TFP_DRV_LOG(ERR,
1897 			    "%s: Unable to lookup FW id, rc:%s\n",
1898 			    tf_dir_2_str(dir),
1899 			    strerror(-rc));
1900 		return rc;
1901 	}
1902 	flags = (dir == TF_DIR_TX ?
1903 		 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_TX :
1904 		 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_RX);
1905 
1906 	if (clear_on_read)
1907 		flags |= HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_CLEAR_ON_READ;
1908 
1909 	/* Populate the request */
1910 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1911 	req.flags = tfp_cpu_to_le_16(flags);
1912 	req.type = tfp_cpu_to_le_32(hcapi_type);
1913 	req.index = tfp_cpu_to_le_32(index);
1914 
1915 	parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1916 	parms.req_data = (uint32_t *)&req;
1917 	parms.req_size = sizeof(req);
1918 	parms.resp_data = (uint32_t *)&resp;
1919 	parms.resp_size = sizeof(resp);
1920 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1921 
1922 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1923 				 &parms);
1924 	if (rc)
1925 		return rc;
1926 
1927 	/*
1928 	 * The response will be 64 bytes long, the response size will
1929 	 * be in words (16). All we can test for is that the response
1930 	 * size is < to the requested size.
1931 	 */
1932 	if ((tfp_le_to_cpu_32(resp.size) * 4) < size)
1933 		return -EINVAL;
1934 
1935 	/*
1936 	 * Copy the requested number of bytes
1937 	 */
1938 	tfp_memcpy(data,
1939 		   &resp.data,
1940 		   size);
1941 
1942 	return 0;
1943 }
1944 
1945 /* HWRM Tunneled messages */
1946 
1947 int
1948 tf_msg_get_global_cfg(struct tf *tfp,
1949 		      struct tf_global_cfg_parms *params)
1950 {
1951 	int rc = 0;
1952 	struct tfp_send_msg_parms parms = { 0 };
1953 	struct hwrm_tf_global_cfg_get_input req = { 0 };
1954 	struct hwrm_tf_global_cfg_get_output resp = { 0 };
1955 	uint32_t flags = 0;
1956 	uint8_t fw_session_id;
1957 	uint16_t resp_size = 0;
1958 	struct tf_dev_info *dev;
1959 	struct tf_session *tfs;
1960 
1961 	/* Retrieve the session information */
1962 	rc = tf_session_get_session_internal(tfp, &tfs);
1963 	if (rc) {
1964 		TFP_DRV_LOG(ERR,
1965 			    "%s: Failed to lookup session, rc:%s\n",
1966 			    tf_dir_2_str(params->dir),
1967 			    strerror(-rc));
1968 		return rc;
1969 	}
1970 
1971 	/* Retrieve the device information */
1972 	rc = tf_session_get_device(tfs, &dev);
1973 	if (rc) {
1974 		TFP_DRV_LOG(ERR,
1975 			    "%s: Failed to lookup device, rc:%s\n",
1976 			    tf_dir_2_str(params->dir),
1977 			    strerror(-rc));
1978 		return rc;
1979 	}
1980 
1981 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1982 	if (rc) {
1983 		TFP_DRV_LOG(ERR,
1984 			    "%s: Unable to lookup FW id, rc:%s\n",
1985 			    tf_dir_2_str(params->dir),
1986 			    strerror(-rc));
1987 		return rc;
1988 	}
1989 
1990 	flags = (params->dir == TF_DIR_TX ?
1991 		 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1992 		 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1993 
1994 	/* Populate the request */
1995 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1996 	req.flags = tfp_cpu_to_le_32(flags);
1997 	req.type = tfp_cpu_to_le_32(params->type);
1998 	req.offset = tfp_cpu_to_le_32(params->offset);
1999 	req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
2000 
2001 	parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
2002 	parms.req_data = (uint32_t *)&req;
2003 	parms.req_size = sizeof(req);
2004 	parms.resp_data = (uint32_t *)&resp;
2005 	parms.resp_size = sizeof(resp);
2006 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2007 
2008 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2009 	if (rc != 0)
2010 		return rc;
2011 
2012 	/* Verify that we got enough buffer to return the requested data */
2013 	resp_size = tfp_le_to_cpu_16(resp.size);
2014 	if (resp_size < params->config_sz_in_bytes)
2015 		return -EINVAL;
2016 
2017 	if (params->config)
2018 		tfp_memcpy(params->config,
2019 			   resp.data,
2020 			   resp_size);
2021 	else
2022 		return -EFAULT;
2023 
2024 	return 0;
2025 }
2026 
2027 int
2028 tf_msg_set_global_cfg(struct tf *tfp,
2029 		      struct tf_global_cfg_parms *params)
2030 {
2031 	int rc = 0;
2032 	struct tfp_send_msg_parms parms = { 0 };
2033 	struct hwrm_tf_global_cfg_set_input req = { 0 };
2034 	struct hwrm_tf_global_cfg_set_output resp = { 0 };
2035 	uint32_t flags = 0;
2036 	uint8_t fw_session_id;
2037 	struct tf_dev_info *dev;
2038 	struct tf_session *tfs;
2039 
2040 	/* Retrieve the session information */
2041 	rc = tf_session_get_session_internal(tfp, &tfs);
2042 	if (rc) {
2043 		TFP_DRV_LOG(ERR,
2044 			    "%s: Failed to lookup session, rc:%s\n",
2045 			    tf_dir_2_str(params->dir),
2046 			    strerror(-rc));
2047 		return rc;
2048 	}
2049 
2050 	/* Retrieve the device information */
2051 	rc = tf_session_get_device(tfs, &dev);
2052 	if (rc) {
2053 		TFP_DRV_LOG(ERR,
2054 			    "%s: Failed to lookup device, rc:%s\n",
2055 			    tf_dir_2_str(params->dir),
2056 			    strerror(-rc));
2057 		return rc;
2058 	}
2059 
2060 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2061 	if (rc) {
2062 		TFP_DRV_LOG(ERR,
2063 			    "%s: Unable to lookup FW id, rc:%s\n",
2064 			    tf_dir_2_str(params->dir),
2065 			    strerror(-rc));
2066 		return rc;
2067 	}
2068 
2069 	flags = (params->dir == TF_DIR_TX ?
2070 		 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
2071 		 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
2072 
2073 	/* Populate the request */
2074 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2075 	req.flags = tfp_cpu_to_le_32(flags);
2076 	req.type = tfp_cpu_to_le_32(params->type);
2077 	req.offset = tfp_cpu_to_le_32(params->offset);
2078 
2079 	/* Check for data size conformity */
2080 	if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
2081 		rc = -EINVAL;
2082 		TFP_DRV_LOG(ERR,
2083 			    "%s: Invalid parameters for msg type, rc:%s\n",
2084 			    tf_dir_2_str(params->dir),
2085 			    strerror(-rc));
2086 		return rc;
2087 	}
2088 
2089 	tfp_memcpy(req.data, params->config,
2090 		   params->config_sz_in_bytes);
2091 
2092 	/* Only set mask if pointer is provided
2093 	 */
2094 	if (params->config_mask) {
2095 		tfp_memcpy(req.mask,
2096 			   params->config_mask,
2097 			   params->config_sz_in_bytes);
2098 	}
2099 
2100 	req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
2101 
2102 	parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
2103 	parms.req_data = (uint32_t *)&req;
2104 	parms.req_size = sizeof(req);
2105 	parms.resp_data = (uint32_t *)&resp;
2106 	parms.resp_size = sizeof(resp);
2107 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2108 
2109 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2110 
2111 	if (rc != 0)
2112 		return rc;
2113 
2114 	return 0;
2115 }
2116 
2117 int
2118 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
2119 			  enum tf_dir dir,
2120 			  uint16_t hcapi_type,
2121 			  uint32_t starting_idx,
2122 			  uint16_t num_entries,
2123 			  uint16_t entry_sz_in_bytes,
2124 			  uint64_t physical_mem_addr,
2125 			  bool clear_on_read)
2126 {
2127 	int rc;
2128 	struct tfp_send_msg_parms parms = { 0 };
2129 	struct hwrm_tf_tbl_type_bulk_get_input req = { 0 };
2130 	struct hwrm_tf_tbl_type_bulk_get_output resp = { 0 };
2131 	int data_size = 0;
2132 	uint8_t fw_session_id;
2133 	struct tf_dev_info *dev;
2134 	struct tf_session *tfs;
2135 	uint32_t flags = 0;
2136 
2137 	/* Retrieve the session information */
2138 	rc = tf_session_get_session(tfp, &tfs);
2139 	if (rc) {
2140 		TFP_DRV_LOG(ERR,
2141 			    "%s: Failed to lookup session, rc:%s\n",
2142 			    tf_dir_2_str(dir),
2143 			    strerror(-rc));
2144 		return rc;
2145 	}
2146 
2147 	/* Retrieve the device information */
2148 	rc = tf_session_get_device(tfs, &dev);
2149 	if (rc) {
2150 		TFP_DRV_LOG(ERR,
2151 			    "%s: Failed to lookup device, rc:%s\n",
2152 			    tf_dir_2_str(dir),
2153 			    strerror(-rc));
2154 		return rc;
2155 	}
2156 
2157 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2158 	if (rc) {
2159 		TFP_DRV_LOG(ERR,
2160 			    "%s: Unable to lookup FW id, rc:%s\n",
2161 			    tf_dir_2_str(dir),
2162 			    strerror(-rc));
2163 		return rc;
2164 	}
2165 	flags = (dir == TF_DIR_TX ?
2166 		 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_TX :
2167 		 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_RX);
2168 
2169 	if (clear_on_read)
2170 		flags |= HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_CLEAR_ON_READ;
2171 
2172 	/* Populate the request */
2173 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2174 	req.flags = tfp_cpu_to_le_16(flags);
2175 	req.type = tfp_cpu_to_le_32(hcapi_type);
2176 	req.start_index = tfp_cpu_to_le_32(starting_idx);
2177 	req.num_entries = tfp_cpu_to_le_32(num_entries);
2178 
2179 	data_size = num_entries * entry_sz_in_bytes;
2180 
2181 	req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
2182 
2183 	parms.tf_type = HWRM_TF_TBL_TYPE_BULK_GET;
2184 	parms.req_data = (uint32_t *)&req;
2185 	parms.req_size = sizeof(req);
2186 	parms.resp_data = (uint32_t *)&resp;
2187 	parms.resp_size = sizeof(resp);
2188 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2189 
2190 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
2191 				 &parms);
2192 	if (rc)
2193 		return rc;
2194 
2195 	/* Verify that we got enough buffer to return the requested data */
2196 	if (tfp_le_to_cpu_32(resp.size) != data_size)
2197 		return -EINVAL;
2198 
2199 	return 0;
2200 }
2201 
2202 int
2203 tf_msg_get_if_tbl_entry(struct tf *tfp,
2204 			struct tf_if_tbl_get_parms *params)
2205 {
2206 	int rc = 0;
2207 	struct tfp_send_msg_parms parms = { 0 };
2208 	struct hwrm_tf_if_tbl_get_input req = { 0 };
2209 	struct hwrm_tf_if_tbl_get_output resp = { 0 };
2210 	uint32_t flags = 0;
2211 	struct tf_dev_info *dev;
2212 	struct tf_session *tfs;
2213 
2214 	/* Retrieve the session information */
2215 	rc = tf_session_get_session(tfp, &tfs);
2216 	if (rc) {
2217 		TFP_DRV_LOG(ERR,
2218 			    "%s: Failed to lookup session, rc:%s\n",
2219 			    tf_dir_2_str(params->dir),
2220 			    strerror(-rc));
2221 		return rc;
2222 	}
2223 
2224 	/* Retrieve the device information */
2225 	rc = tf_session_get_device(tfs, &dev);
2226 	if (rc) {
2227 		TFP_DRV_LOG(ERR,
2228 			    "%s: Failed to lookup device, rc:%s\n",
2229 			    tf_dir_2_str(params->dir),
2230 			    strerror(-rc));
2231 		return rc;
2232 	}
2233 
2234 	flags = (params->dir == TF_DIR_TX ?
2235 		HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
2236 		HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
2237 
2238 	/* Populate the request */
2239 	req.fw_session_id =
2240 		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
2241 	req.flags = flags;
2242 	req.type = params->hcapi_type;
2243 	req.index = tfp_cpu_to_le_16(params->idx);
2244 	req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
2245 
2246 	parms.tf_type = HWRM_TF_IF_TBL_GET;
2247 	parms.req_data = (uint32_t *)&req;
2248 	parms.req_size = sizeof(req);
2249 	parms.resp_data = (uint32_t *)&resp;
2250 	parms.resp_size = sizeof(resp);
2251 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2252 
2253 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2254 
2255 	if (rc != 0)
2256 		return rc;
2257 
2258 	tfp_memcpy(&params->data[0], resp.data, req.size);
2259 
2260 	return 0;
2261 }
2262 
2263 int
2264 tf_msg_set_if_tbl_entry(struct tf *tfp,
2265 			struct tf_if_tbl_set_parms *params)
2266 {
2267 	int rc = 0;
2268 	struct tfp_send_msg_parms parms = { 0 };
2269 	struct hwrm_tf_if_tbl_set_input req = { 0 };
2270 	struct hwrm_tf_if_tbl_get_output resp = { 0 };
2271 	uint32_t flags = 0;
2272 	struct tf_dev_info *dev;
2273 	struct tf_session *tfs;
2274 
2275 	/* Retrieve the session information */
2276 	rc = tf_session_get_session(tfp, &tfs);
2277 	if (rc) {
2278 		TFP_DRV_LOG(ERR,
2279 			    "%s: Failed to lookup session, rc:%s\n",
2280 			    tf_dir_2_str(params->dir),
2281 			    strerror(-rc));
2282 		return rc;
2283 	}
2284 
2285 	/* Retrieve the device information */
2286 	rc = tf_session_get_device(tfs, &dev);
2287 	if (rc)
2288 		return rc;
2289 
2290 	flags = (params->dir == TF_DIR_TX ?
2291 		HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
2292 		HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
2293 
2294 	/* Populate the request */
2295 	req.fw_session_id =
2296 		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
2297 	req.flags = flags;
2298 	req.type = params->hcapi_type;
2299 	req.index = tfp_cpu_to_le_32(params->idx);
2300 	req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
2301 	tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
2302 
2303 	parms.tf_type = HWRM_TF_IF_TBL_SET;
2304 	parms.req_data = (uint32_t *)&req;
2305 	parms.req_size = sizeof(req);
2306 	parms.resp_data = (uint32_t *)&resp;
2307 	parms.resp_size = sizeof(resp);
2308 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2309 
2310 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2311 
2312 	if (rc != 0)
2313 		return rc;
2314 
2315 	return 0;
2316 }
2317 
2318 int
2319 tf_msg_get_version(struct bnxt *bp,
2320 		   struct tf_dev_info *dev,
2321 		   struct tf_get_version_parms *params)
2322 
2323 {
2324 	int rc;
2325 	struct hwrm_tf_version_get_input req = { 0 };
2326 	struct hwrm_tf_version_get_output resp = { 0 };
2327 	struct tfp_send_msg_parms parms = { 0 };
2328 
2329 	/* Populate the request */
2330 	parms.tf_type = HWRM_TF_VERSION_GET,
2331 	parms.req_data = (uint32_t *)&req;
2332 	parms.req_size = sizeof(req);
2333 	parms.resp_data = (uint32_t *)&resp;
2334 	parms.resp_size = sizeof(resp);
2335 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2336 
2337 	rc = tfp_send_msg_direct(bp,
2338 				 &parms);
2339 
2340 	params->major = resp.major;
2341 	params->minor = resp.minor;
2342 	params->update = resp.update;
2343 
2344 	dev->ops->tf_dev_map_hcapi_caps(resp.dev_caps_cfg,
2345 					&params->dev_ident_caps,
2346 					&params->dev_tcam_caps,
2347 					&params->dev_tbl_caps,
2348 					&params->dev_em_caps);
2349 
2350 	return rc;
2351 }
2352 
2353 int
2354 tf_msg_session_set_hotup_state(struct tf *tfp, uint16_t state)
2355 {
2356 	int rc;
2357 	struct hwrm_tf_session_hotup_state_set_input req = { 0 };
2358 	struct hwrm_tf_session_hotup_state_set_output resp = { 0 };
2359 	struct tfp_send_msg_parms parms = { 0 };
2360 	uint8_t fw_session_id;
2361 	struct tf_dev_info *dev;
2362 	struct tf_session *tfs;
2363 
2364 	/* Retrieve the session information */
2365 	rc = tf_session_get_session_internal(tfp, &tfs);
2366 	if (rc) {
2367 		TFP_DRV_LOG(ERR,
2368 			    "Failed to lookup session, rc:%s\n",
2369 			    strerror(-rc));
2370 		return rc;
2371 	}
2372 
2373 	/* Retrieve the device information */
2374 	rc = tf_session_get_device(tfs, &dev);
2375 	if (rc) {
2376 		TFP_DRV_LOG(ERR,
2377 			    "Failed to lookup device, rc:%s\n",
2378 			    strerror(-rc));
2379 		return rc;
2380 	}
2381 
2382 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2383 	if (rc) {
2384 		TFP_DRV_LOG(ERR,
2385 			    "Unable to lookup FW id, rc:%s\n",
2386 			    strerror(-rc));
2387 		return rc;
2388 	}
2389 
2390 	/* Populate the request */
2391 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2392 	req.state = tfp_cpu_to_le_16(state);
2393 
2394 	parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_SET;
2395 	parms.req_data = (uint32_t *)&req;
2396 	parms.req_size = sizeof(req);
2397 	parms.resp_data = (uint32_t *)&resp;
2398 	parms.resp_size = sizeof(resp);
2399 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2400 
2401 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
2402 				 &parms);
2403 	return rc;
2404 }
2405 
2406 int
2407 tf_msg_session_get_hotup_state(struct tf *tfp,
2408 			       uint16_t *state,
2409 			       uint16_t *ref_cnt)
2410 {
2411 	int rc;
2412 	struct hwrm_tf_session_hotup_state_get_input req = { 0 };
2413 	struct hwrm_tf_session_hotup_state_get_output resp = { 0 };
2414 	struct tfp_send_msg_parms parms = { 0 };
2415 	uint8_t fw_session_id;
2416 	struct tf_dev_info *dev;
2417 	struct tf_session *tfs;
2418 
2419 	/* Retrieve the session information */
2420 	rc = tf_session_get_session_internal(tfp, &tfs);
2421 	if (rc) {
2422 		TFP_DRV_LOG(ERR,
2423 			    "Failed to lookup session, rc:%s\n",
2424 			    strerror(-rc));
2425 		return rc;
2426 	}
2427 
2428 	/* Retrieve the device information */
2429 	rc = tf_session_get_device(tfs, &dev);
2430 	if (rc) {
2431 		TFP_DRV_LOG(ERR,
2432 			    "Failed to lookup device, rc:%s\n",
2433 			    strerror(-rc));
2434 		return rc;
2435 	}
2436 
2437 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2438 	if (rc) {
2439 		TFP_DRV_LOG(ERR,
2440 			    "Unable to lookup FW id, rc:%s\n",
2441 			    strerror(-rc));
2442 		return rc;
2443 	}
2444 
2445 	/* Populate the request */
2446 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2447 
2448 	parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_GET;
2449 	parms.req_data = (uint32_t *)&req;
2450 	parms.req_size = sizeof(req);
2451 	parms.resp_data = (uint32_t *)&resp;
2452 	parms.resp_size = sizeof(resp);
2453 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2454 
2455 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
2456 				 &parms);
2457 
2458 	*state = tfp_le_to_cpu_16(resp.state);
2459 	*ref_cnt = tfp_le_to_cpu_16(resp.ref_cnt);
2460 
2461 	return rc;
2462 }
2463