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