xref: /dpdk/drivers/net/bnxt/tf_core/tf_msg.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
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 {
385 	int rc;
386 	int i;
387 	struct tfp_send_msg_parms parms = { 0 };
388 	struct hwrm_tf_session_resc_qcaps_input req = { 0 };
389 	struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
390 	uint8_t fw_session_id;
391 	struct tf_msg_dma_buf qcaps_buf = { 0 };
392 	struct tf_rm_resc_req_entry *data;
393 	int dma_size;
394 	struct tf_session *tfs;
395 
396 	/* Retrieve the session information */
397 	rc = tf_session_get_session_internal(tfp, &tfs);
398 	if (rc) {
399 		TFP_DRV_LOG(ERR,
400 			    "Failed to lookup session, rc:%s\n",
401 			    strerror(-rc));
402 		return rc;
403 	}
404 
405 	TF_CHECK_PARMS3(tfp, query, resv_strategy);
406 
407 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
408 	if (rc) {
409 		TFP_DRV_LOG(ERR,
410 			    "%s: Unable to lookup FW id, rc:%s\n",
411 			    tf_dir_2_str(dir),
412 			    strerror(-rc));
413 		return rc;
414 	}
415 
416 	/* Prepare DMA buffer */
417 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
418 	rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
419 	if (rc)
420 		return rc;
421 
422 	/* Populate the request */
423 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
424 	req.flags = tfp_cpu_to_le_16(dir);
425 	req.qcaps_size = size;
426 	req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
427 
428 	parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
429 	parms.req_data = (uint32_t *)&req;
430 	parms.req_size = sizeof(req);
431 	parms.resp_data = (uint32_t *)&resp;
432 	parms.resp_size = sizeof(resp);
433 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
434 
435 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
436 	if (rc)
437 		goto cleanup;
438 
439 	/* Process the response
440 	 * Should always get expected number of entries
441 	 */
442 	if (tfp_le_to_cpu_32(resp.size) != size) {
443 		TFP_DRV_LOG(WARNING,
444 			    "%s: QCAPS message size error, rc:%s, request %d vs response %d\n",
445 			    tf_dir_2_str(dir),
446 			    strerror(EINVAL),
447 			    size,
448 			    resp.size);
449 	}
450 
451 	/* Post process the response */
452 	data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
453 
454 	for (i = 0; i < resp.size; i++) {
455 		query[i].type = tfp_le_to_cpu_32(data[i].type);
456 		query[i].min = tfp_le_to_cpu_16(data[i].min);
457 		query[i].max = tfp_le_to_cpu_16(data[i].max);
458 	}
459 
460 	*resv_strategy = resp.flags &
461 	      HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
462 
463 cleanup:
464 	tf_msg_free_dma_buf(&qcaps_buf);
465 
466 	return rc;
467 }
468 
469 int
470 tf_msg_session_resc_alloc(struct tf *tfp,
471 			  struct tf_dev_info *dev,
472 			  enum tf_dir dir,
473 			  uint16_t size,
474 			  struct tf_rm_resc_req_entry *request,
475 			  struct tf_rm_resc_entry *resv)
476 {
477 	int rc;
478 	int i;
479 	struct tfp_send_msg_parms parms = { 0 };
480 	struct hwrm_tf_session_resc_alloc_input req = { 0 };
481 	struct hwrm_tf_session_resc_alloc_output resp = { 0 };
482 	uint8_t fw_session_id;
483 	struct tf_msg_dma_buf req_buf = { 0 };
484 	struct tf_msg_dma_buf resv_buf = { 0 };
485 	struct tf_rm_resc_req_entry *req_data;
486 	struct tf_rm_resc_entry *resv_data;
487 	int dma_size;
488 	struct tf_session *tfs;
489 
490 	/* Retrieve the session information */
491 	rc = tf_session_get_session_internal(tfp, &tfs);
492 	if (rc) {
493 		TFP_DRV_LOG(ERR,
494 			    "Failed to lookup session, rc:%s\n",
495 			    strerror(-rc));
496 		return rc;
497 	}
498 
499 	TF_CHECK_PARMS3(tfp, request, resv);
500 
501 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
502 	if (rc) {
503 		TFP_DRV_LOG(ERR,
504 			    "%s: Unable to lookup FW id, rc:%s\n",
505 			    tf_dir_2_str(dir),
506 			    strerror(-rc));
507 		return rc;
508 	}
509 
510 	/* Prepare DMA buffers */
511 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
512 	rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
513 	if (rc)
514 		return rc;
515 
516 	dma_size = size * sizeof(struct tf_rm_resc_entry);
517 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
518 	if (rc) {
519 		tf_msg_free_dma_buf(&req_buf);
520 		return rc;
521 	}
522 
523 	/* Populate the request */
524 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
525 	req.flags = tfp_cpu_to_le_16(dir);
526 	req.req_size = size;
527 
528 	req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
529 	for (i = 0; i < size; i++) {
530 		req_data[i].type = tfp_cpu_to_le_32(request[i].type);
531 		req_data[i].min = tfp_cpu_to_le_16(request[i].min);
532 		req_data[i].max = tfp_cpu_to_le_16(request[i].max);
533 	}
534 
535 	req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
536 	req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
537 
538 	parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
539 	parms.req_data = (uint32_t *)&req;
540 	parms.req_size = sizeof(req);
541 	parms.resp_data = (uint32_t *)&resp;
542 	parms.resp_size = sizeof(resp);
543 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
544 
545 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
546 	if (rc)
547 		goto cleanup;
548 
549 	/* Process the response
550 	 * Should always get expected number of entries
551 	 */
552 	if (tfp_le_to_cpu_32(resp.size) != size) {
553 		TFP_DRV_LOG(ERR,
554 			    "%s: Alloc message size error, rc:%s\n",
555 			    tf_dir_2_str(dir),
556 			    strerror(EINVAL));
557 		rc = -EINVAL;
558 		goto cleanup;
559 	}
560 
561 	/* Post process the response */
562 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
563 	for (i = 0; i < size; i++) {
564 		resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
565 		resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
566 		resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
567 	}
568 
569 cleanup:
570 	tf_msg_free_dma_buf(&req_buf);
571 	tf_msg_free_dma_buf(&resv_buf);
572 
573 	return rc;
574 }
575 
576 int
577 tf_msg_session_resc_info(struct tf *tfp,
578 			 struct tf_dev_info *dev,
579 			 enum tf_dir dir,
580 			 uint16_t size,
581 			 struct tf_rm_resc_req_entry *request,
582 			 struct tf_rm_resc_entry *resv)
583 {
584 	int rc;
585 	int i;
586 	struct tfp_send_msg_parms parms = { 0 };
587 	struct hwrm_tf_session_resc_info_input req = { 0 };
588 	struct hwrm_tf_session_resc_info_output resp = { 0 };
589 	uint8_t fw_session_id;
590 	struct tf_msg_dma_buf req_buf = { 0 };
591 	struct tf_msg_dma_buf resv_buf = { 0 };
592 	struct tf_rm_resc_req_entry *req_data;
593 	struct tf_rm_resc_entry *resv_data;
594 	int dma_size;
595 	struct tf_session *tfs;
596 
597 	/* Retrieve the session information */
598 	rc = tf_session_get_session_internal(tfp, &tfs);
599 	if (rc) {
600 		TFP_DRV_LOG(ERR,
601 			    "Failed to lookup session, rc:%s\n",
602 			    strerror(-rc));
603 		return rc;
604 	}
605 
606 	TF_CHECK_PARMS3(tfp, request, resv);
607 
608 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
609 	if (rc) {
610 		TFP_DRV_LOG(ERR,
611 			    "%s: Unable to lookup FW id, rc:%s\n",
612 			    tf_dir_2_str(dir),
613 			    strerror(-rc));
614 		return rc;
615 	}
616 
617 	/* Prepare DMA buffers */
618 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
619 	rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
620 	if (rc)
621 		return rc;
622 
623 	dma_size = size * sizeof(struct tf_rm_resc_entry);
624 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
625 	if (rc) {
626 		tf_msg_free_dma_buf(&req_buf);
627 		return rc;
628 	}
629 
630 	/* Populate the request */
631 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
632 	req.flags = tfp_cpu_to_le_16(dir);
633 	req.req_size = size;
634 
635 	req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
636 	for (i = 0; i < size; i++) {
637 		req_data[i].type = tfp_cpu_to_le_32(request[i].type);
638 		req_data[i].min = tfp_cpu_to_le_16(request[i].min);
639 		req_data[i].max = tfp_cpu_to_le_16(request[i].max);
640 	}
641 
642 	req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
643 	req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
644 
645 	parms.tf_type = HWRM_TF_SESSION_RESC_INFO;
646 	parms.req_data = (uint32_t *)&req;
647 	parms.req_size = sizeof(req);
648 	parms.resp_data = (uint32_t *)&resp;
649 	parms.resp_size = sizeof(resp);
650 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
651 
652 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
653 	if (rc)
654 		goto cleanup;
655 
656 	/* Process the response
657 	 * Should always get expected number of entries
658 	 */
659 	if (tfp_le_to_cpu_32(resp.size) != size) {
660 		TFP_DRV_LOG(ERR,
661 			    "%s: Alloc message size error, rc:%s\n",
662 			    tf_dir_2_str(dir),
663 			    strerror(EINVAL));
664 		rc = -EINVAL;
665 		goto cleanup;
666 	}
667 
668 	/* Post process the response */
669 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
670 	for (i = 0; i < size; i++) {
671 		resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
672 		resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
673 		resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
674 	}
675 
676 cleanup:
677 	tf_msg_free_dma_buf(&req_buf);
678 	tf_msg_free_dma_buf(&resv_buf);
679 
680 	return rc;
681 }
682 
683 int
684 tf_msg_session_resc_flush(struct tf *tfp,
685 			  enum tf_dir dir,
686 			  uint16_t size,
687 			  struct tf_rm_resc_entry *resv)
688 {
689 	int rc;
690 	int i;
691 	struct tfp_send_msg_parms parms = { 0 };
692 	struct hwrm_tf_session_resc_flush_input req = { 0 };
693 	struct hwrm_tf_session_resc_flush_output resp = { 0 };
694 	uint8_t fw_session_id;
695 	struct tf_msg_dma_buf resv_buf = { 0 };
696 	struct tf_rm_resc_entry *resv_data;
697 	int dma_size;
698 	struct tf_dev_info *dev;
699 	struct tf_session *tfs;
700 
701 	TF_CHECK_PARMS2(tfp, resv);
702 
703 	/* Retrieve the session information */
704 	rc = tf_session_get_session_internal(tfp, &tfs);
705 	if (rc) {
706 		TFP_DRV_LOG(ERR,
707 			    "%s: Failed to lookup session, rc:%s\n",
708 			    tf_dir_2_str(dir),
709 			    strerror(-rc));
710 		return rc;
711 	}
712 
713 	/* Retrieve the device information */
714 	rc = tf_session_get_device(tfs, &dev);
715 	if (rc) {
716 		TFP_DRV_LOG(ERR,
717 			    "%s: Failed to lookup device, rc:%s\n",
718 			    tf_dir_2_str(dir),
719 			    strerror(-rc));
720 		return rc;
721 	}
722 
723 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
724 	if (rc) {
725 		TFP_DRV_LOG(ERR,
726 			    "%s: Unable to lookup FW id, rc:%s\n",
727 			    tf_dir_2_str(dir),
728 			    strerror(-rc));
729 		return rc;
730 	}
731 
732 	/* Prepare DMA buffers */
733 	dma_size = size * sizeof(struct tf_rm_resc_entry);
734 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
735 	if (rc)
736 		return rc;
737 
738 	/* Populate the request */
739 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
740 	req.flags = tfp_cpu_to_le_16(dir);
741 	req.flush_size = size;
742 
743 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
744 	for (i = 0; i < size; i++) {
745 		resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
746 		resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
747 		resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
748 	}
749 
750 	req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
751 
752 	parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
753 	parms.req_data = (uint32_t *)&req;
754 	parms.req_size = sizeof(req);
755 	parms.resp_data = (uint32_t *)&resp;
756 	parms.resp_size = sizeof(resp);
757 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
758 
759 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
760 
761 	tf_msg_free_dma_buf(&resv_buf);
762 
763 	return rc;
764 }
765 
766 int
767 tf_msg_insert_em_internal_entry(struct tf *tfp,
768 				struct tf_insert_em_entry_parms *em_parms,
769 				uint16_t *rptr_index,
770 				uint8_t *rptr_entry,
771 				uint8_t *num_of_entries)
772 {
773 	int rc;
774 	struct tfp_send_msg_parms parms = { 0 };
775 	struct hwrm_tf_em_insert_input req = { 0 };
776 	struct hwrm_tf_em_insert_output resp = { 0 };
777 	struct tf_em_64b_entry *em_result =
778 		(struct tf_em_64b_entry *)em_parms->em_record;
779 	uint16_t flags;
780 	uint8_t fw_session_id;
781 	uint8_t msg_key_size;
782 	struct tf_dev_info *dev;
783 	struct tf_session *tfs;
784 
785 	RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_em_insert_input) !=
786 			 TF_MSG_SIZE_HWRM_TF_EM_INSERT);
787 
788 	/* Retrieve the session information */
789 	rc = tf_session_get_session_internal(tfp, &tfs);
790 	if (rc) {
791 		TFP_DRV_LOG(ERR,
792 			    "%s: Failed to lookup session, rc:%s\n",
793 			    tf_dir_2_str(em_parms->dir),
794 			    strerror(-rc));
795 		return rc;
796 	}
797 
798 	/* Retrieve the device information */
799 	rc = tf_session_get_device(tfs, &dev);
800 	if (rc) {
801 		TFP_DRV_LOG(ERR,
802 			    "%s: Failed to lookup device, rc:%s\n",
803 			    tf_dir_2_str(em_parms->dir),
804 			    strerror(-rc));
805 		return rc;
806 	}
807 
808 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
809 	if (rc) {
810 		TFP_DRV_LOG(ERR,
811 			    "%s: Unable to lookup FW id, rc:%s\n",
812 			    tf_dir_2_str(em_parms->dir),
813 			    strerror(-rc));
814 		return rc;
815 	}
816 
817 	/* Populate the request */
818 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
819 
820 	/* Check for key size conformity */
821 	msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
822 	if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
823 		rc = -EINVAL;
824 		TFP_DRV_LOG(ERR,
825 			    "%s: Invalid parameters for msg type, rc:%s\n",
826 			    tf_dir_2_str(em_parms->dir),
827 			    strerror(-rc));
828 		return rc;
829 	}
830 
831 	tfp_memcpy(req.em_key,
832 		   em_parms->key,
833 		   msg_key_size);
834 
835 	flags = (em_parms->dir == TF_DIR_TX ?
836 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
837 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
838 	req.flags = tfp_cpu_to_le_16(flags);
839 	req.strength = (em_result->hdr.word1 &
840 			CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
841 			CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
842 	req.em_key_bitlen = em_parms->key_sz_in_bits;
843 	req.action_ptr = em_result->hdr.pointer;
844 	req.em_record_idx = *rptr_index;
845 
846 	parms.tf_type = HWRM_TF_EM_INSERT;
847 	parms.req_data = (uint32_t *)&req;
848 	parms.req_size = sizeof(req);
849 	parms.resp_data = (uint32_t *)&resp;
850 	parms.resp_size = sizeof(resp);
851 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
852 
853 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
854 				 &parms);
855 	if (rc)
856 		return rc;
857 
858 	*rptr_entry = resp.rptr_entry;
859 	*rptr_index = resp.rptr_index;
860 	*num_of_entries = resp.num_of_entries;
861 
862 	return 0;
863 }
864 
865 int
866 tf_msg_hash_insert_em_internal_entry(struct tf *tfp,
867 				     struct tf_insert_em_entry_parms *em_parms,
868 				     uint32_t key0_hash,
869 				     uint32_t key1_hash,
870 				     uint16_t *rptr_index,
871 				     uint8_t *rptr_entry,
872 				     uint8_t *num_of_entries)
873 {
874 	int rc;
875 	struct tfp_send_msg_parms parms = { 0 };
876 	struct hwrm_tf_em_hash_insert_input req = { 0 };
877 	struct hwrm_tf_em_hash_insert_output resp = { 0 };
878 	uint16_t flags;
879 	uint8_t fw_session_id;
880 	uint8_t msg_record_size;
881 	struct tf_dev_info *dev;
882 	struct tf_session *tfs;
883 
884 	/* Retrieve the session information */
885 	rc = tf_session_get_session_internal(tfp, &tfs);
886 	if (rc) {
887 		TFP_DRV_LOG(ERR,
888 			    "%s: Failed to lookup session, rc:%s\n",
889 			    tf_dir_2_str(em_parms->dir),
890 			    strerror(-rc));
891 		return rc;
892 	}
893 
894 	/* Retrieve the device information */
895 	rc = tf_session_get_device(tfs, &dev);
896 	if (rc) {
897 		TFP_DRV_LOG(ERR,
898 			    "%s: Failed to lookup device, rc:%s\n",
899 			    tf_dir_2_str(em_parms->dir),
900 			    strerror(-rc));
901 		return rc;
902 	}
903 
904 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
905 	if (rc) {
906 		TFP_DRV_LOG(ERR,
907 			    "%s: Unable to lookup FW id, rc:%s\n",
908 			    tf_dir_2_str(em_parms->dir),
909 			    strerror(-rc));
910 		return rc;
911 	}
912 
913 	/* Populate the request */
914 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
915 
916 	/* Check for key size conformity */
917 	msg_record_size = (em_parms->em_record_sz_in_bits + 7) / 8;
918 
919 	if (msg_record_size > TF_MSG_EM_INSERT_RECORD_SIZE) {
920 		rc = -EINVAL;
921 		TFP_DRV_LOG(ERR,
922 			    "%s: Record size to large, rc:%s\n",
923 			    tf_dir_2_str(em_parms->dir),
924 			    strerror(-rc));
925 		return rc;
926 	}
927 
928 	tfp_memcpy((char *)req.em_record,
929 		   em_parms->em_record,
930 		   msg_record_size);
931 
932 	flags = (em_parms->dir == TF_DIR_TX ?
933 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
934 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
935 	req.flags = tfp_cpu_to_le_16(flags);
936 	req.em_record_size_bits = em_parms->em_record_sz_in_bits;
937 	req.em_record_idx = *rptr_index;
938 	req.key0_hash = key0_hash;
939 	req.key1_hash = key1_hash;
940 
941 	parms.tf_type = HWRM_TF_EM_HASH_INSERT;
942 	parms.req_data = (uint32_t *)&req;
943 	parms.req_size = sizeof(req);
944 	parms.resp_data = (uint32_t *)&resp;
945 	parms.resp_size = sizeof(resp);
946 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
947 
948 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
949 				 &parms);
950 	if (rc)
951 		return rc;
952 
953 	*rptr_entry = resp.rptr_entry;
954 	*rptr_index = resp.rptr_index;
955 	*num_of_entries = resp.num_of_entries;
956 
957 	return 0;
958 }
959 
960 int
961 tf_msg_delete_em_entry(struct tf *tfp,
962 		       struct tf_delete_em_entry_parms *em_parms)
963 {
964 	int rc;
965 	struct tfp_send_msg_parms parms = { 0 };
966 	struct hwrm_tf_em_delete_input req = { 0 };
967 	struct hwrm_tf_em_delete_output resp = { 0 };
968 	uint16_t flags;
969 	uint8_t fw_session_id;
970 	struct tf_dev_info *dev;
971 	struct tf_session *tfs;
972 
973 	/* Retrieve the session information */
974 	rc = tf_session_get_session_internal(tfp, &tfs);
975 	if (rc) {
976 		TFP_DRV_LOG(ERR,
977 			    "%s: Failed to lookup session, rc:%s\n",
978 			    tf_dir_2_str(em_parms->dir),
979 			    strerror(-rc));
980 		return rc;
981 	}
982 
983 	/* Retrieve the device information */
984 	rc = tf_session_get_device(tfs, &dev);
985 	if (rc) {
986 		TFP_DRV_LOG(ERR,
987 			    "%s: Failed to lookup device, rc:%s\n",
988 			    tf_dir_2_str(em_parms->dir),
989 			    strerror(-rc));
990 		return rc;
991 	}
992 
993 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
994 	if (rc) {
995 		TFP_DRV_LOG(ERR,
996 			    "%s: Unable to lookup FW id, rc:%s\n",
997 			    tf_dir_2_str(em_parms->dir),
998 			    strerror(-rc));
999 		return rc;
1000 	}
1001 
1002 	/* Populate the request */
1003 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1004 
1005 	flags = (em_parms->dir == TF_DIR_TX ?
1006 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
1007 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
1008 	req.flags = tfp_cpu_to_le_16(flags);
1009 	req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
1010 
1011 	parms.tf_type = HWRM_TF_EM_DELETE;
1012 	parms.req_data = (uint32_t *)&req;
1013 	parms.req_size = sizeof(req);
1014 	parms.resp_data = (uint32_t *)&resp;
1015 	parms.resp_size = sizeof(resp);
1016 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1017 
1018 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1019 				 &parms);
1020 	if (rc)
1021 		return rc;
1022 
1023 	em_parms->index = tfp_le_to_cpu_16(resp.em_index);
1024 
1025 	return 0;
1026 }
1027 
1028 int
1029 tf_msg_move_em_entry(struct tf *tfp,
1030 		     struct tf_move_em_entry_parms *em_parms)
1031 {
1032 	int rc;
1033 	struct tfp_send_msg_parms parms = { 0 };
1034 	struct hwrm_tf_em_move_input req = { 0 };
1035 	struct hwrm_tf_em_move_output resp = { 0 };
1036 	uint16_t flags;
1037 	uint8_t fw_session_id;
1038 	struct tf_dev_info *dev;
1039 	struct tf_session *tfs;
1040 
1041 	/* Retrieve the session information */
1042 	rc = tf_session_get_session_internal(tfp, &tfs);
1043 	if (rc) {
1044 		TFP_DRV_LOG(ERR,
1045 			    "%s: Failed to lookup session, rc:%s\n",
1046 			    tf_dir_2_str(em_parms->dir),
1047 			    strerror(-rc));
1048 		return rc;
1049 	}
1050 
1051 	/* Retrieve the device information */
1052 	rc = tf_session_get_device(tfs, &dev);
1053 	if (rc) {
1054 		TFP_DRV_LOG(ERR,
1055 			    "%s: Failed to lookup device, rc:%s\n",
1056 			    tf_dir_2_str(em_parms->dir),
1057 			    strerror(-rc));
1058 		return rc;
1059 	}
1060 
1061 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1062 	if (rc) {
1063 		TFP_DRV_LOG(ERR,
1064 			    "%s: Unable to lookup FW id, rc:%s\n",
1065 			    tf_dir_2_str(em_parms->dir),
1066 			    strerror(-rc));
1067 		return rc;
1068 	}
1069 
1070 	/* Populate the request */
1071 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1072 
1073 	flags = (em_parms->dir == TF_DIR_TX ?
1074 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
1075 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
1076 	req.flags = tfp_cpu_to_le_16(flags);
1077 	req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
1078 	req.new_index = tfp_cpu_to_le_32(em_parms->new_index);
1079 
1080 	parms.tf_type = HWRM_TF_EM_MOVE;
1081 	parms.req_data = (uint32_t *)&req;
1082 	parms.req_size = sizeof(req);
1083 	parms.resp_data = (uint32_t *)&resp;
1084 	parms.resp_size = sizeof(resp);
1085 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1086 
1087 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1088 				 &parms);
1089 	if (rc)
1090 		return rc;
1091 
1092 	em_parms->index = tfp_le_to_cpu_16(resp.em_index);
1093 
1094 	return 0;
1095 }
1096 
1097 int tf_msg_ext_em_ctxt_mem_alloc(struct tf *tfp,
1098 				struct hcapi_cfa_em_table *tbl,
1099 				uint64_t *dma_addr,
1100 				uint32_t *page_lvl,
1101 				uint32_t *page_size)
1102 {
1103 	struct tfp_send_msg_parms parms = { 0 };
1104 	struct hwrm_tf_ctxt_mem_alloc_input req = {0};
1105 	struct hwrm_tf_ctxt_mem_alloc_output resp = {0};
1106 	uint32_t mem_size_k;
1107 	int rc = 0;
1108 	struct tf_dev_info *dev;
1109 	struct tf_session *tfs;
1110 	uint32_t fw_se_id;
1111 
1112 	/* Retrieve the session information */
1113 	rc = tf_session_get_session_internal(tfp, &tfs);
1114 	if (rc) {
1115 		TFP_DRV_LOG(ERR,
1116 			    "Failed to lookup session, rc:%s\n",
1117 			    strerror(-rc));
1118 		return rc;
1119 	}
1120 
1121 	/* Retrieve the device information */
1122 	rc = tf_session_get_device(tfs, &dev);
1123 	if (rc) {
1124 		TFP_DRV_LOG(ERR,
1125 			    "Failed to lookup device, rc:%s\n",
1126 			    strerror(-rc));
1127 		return rc;
1128 	}
1129 	/* Retrieve the session information */
1130 	fw_se_id = tfs->session_id.internal.fw_session_id;
1131 
1132 	if (tbl->num_entries && tbl->entry_size) {
1133 		/* unit: kbytes */
1134 		mem_size_k = (tbl->num_entries / TF_KILOBYTE) * tbl->entry_size;
1135 		req.mem_size = tfp_cpu_to_le_32(mem_size_k);
1136 		req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1137 		parms.tf_type = HWRM_TF_CTXT_MEM_ALLOC;
1138 		parms.req_data = (uint32_t *)&req;
1139 		parms.req_size = sizeof(req);
1140 		parms.resp_data = (uint32_t *)&resp;
1141 		parms.resp_size = sizeof(resp);
1142 		parms.mailbox = dev->ops->tf_dev_get_mailbox();
1143 		rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1144 		if (rc) {
1145 			TFP_DRV_LOG(ERR, "Failed ext_em_alloc error rc:%s\n",
1146 				strerror(-rc));
1147 			return rc;
1148 		}
1149 
1150 		*dma_addr = tfp_le_to_cpu_64(resp.page_dir);
1151 		*page_lvl = resp.page_level;
1152 		*page_size = resp.page_size;
1153 	}
1154 
1155 	return rc;
1156 }
1157 
1158 int tf_msg_ext_em_ctxt_mem_free(struct tf *tfp,
1159 				uint32_t mem_size_k,
1160 				uint64_t dma_addr,
1161 				uint8_t page_level,
1162 				uint8_t page_size)
1163 {
1164 	struct tfp_send_msg_parms parms = { 0 };
1165 	struct hwrm_tf_ctxt_mem_free_input req = {0};
1166 	struct hwrm_tf_ctxt_mem_free_output resp = {0};
1167 	int rc = 0;
1168 	struct tf_dev_info *dev;
1169 	struct tf_session *tfs;
1170 	uint32_t fw_se_id;
1171 
1172 	/* Retrieve the session information */
1173 	rc = tf_session_get_session_internal(tfp, &tfs);
1174 	if (rc) {
1175 		TFP_DRV_LOG(ERR,
1176 			    "Failed to lookup session, rc:%s\n",
1177 			    strerror(-rc));
1178 		return rc;
1179 	}
1180 
1181 	/* Retrieve the device information */
1182 	rc = tf_session_get_device(tfs, &dev);
1183 	if (rc) {
1184 		TFP_DRV_LOG(ERR,
1185 			    "Failed to lookup device, rc:%s\n",
1186 			    strerror(-rc));
1187 		return rc;
1188 	}
1189 	/* Retrieve the session information */
1190 	fw_se_id = tfs->session_id.internal.fw_session_id;
1191 
1192 	req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1193 	req.mem_size = tfp_cpu_to_le_32(mem_size_k);
1194 	req.page_dir = tfp_cpu_to_le_64(dma_addr);
1195 	req.page_level = page_level;
1196 	req.page_size = page_size;
1197 	parms.tf_type = HWRM_TF_CTXT_MEM_FREE;
1198 	parms.req_data = (uint32_t *)&req;
1199 	parms.req_size = sizeof(req);
1200 	parms.resp_data = (uint32_t *)&resp;
1201 	parms.resp_size = sizeof(resp);
1202 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1203 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1204 
1205 	return rc;
1206 }
1207 
1208 int
1209 tf_msg_em_mem_rgtr(struct tf *tfp,
1210 		   int page_lvl,
1211 		   int page_size,
1212 		   uint64_t dma_addr,
1213 		   uint16_t *ctx_id)
1214 {
1215 	int rc;
1216 	struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
1217 	struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
1218 	struct tfp_send_msg_parms parms = { 0 };
1219 	struct tf_dev_info *dev;
1220 	struct tf_session *tfs;
1221 	uint32_t fw_se_id;
1222 
1223 	/* Retrieve the session information */
1224 	rc = tf_session_get_session_internal(tfp, &tfs);
1225 	if (rc) {
1226 		TFP_DRV_LOG(ERR,
1227 			    "Failed to lookup session, rc:%s\n",
1228 			    strerror(-rc));
1229 		return rc;
1230 	}
1231 
1232 	/* Retrieve the device information */
1233 	rc = tf_session_get_device(tfs, &dev);
1234 	if (rc) {
1235 		TFP_DRV_LOG(ERR,
1236 			    "Failed to lookup device, rc:%s\n",
1237 			    strerror(-rc));
1238 		return rc;
1239 	}
1240 	fw_se_id = tfs->session_id.internal.fw_session_id;
1241 
1242 	req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1243 	req.page_level = page_lvl;
1244 	req.page_size = page_size;
1245 	req.page_dir = tfp_cpu_to_le_64(dma_addr);
1246 
1247 	parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
1248 	parms.req_data = (uint32_t *)&req;
1249 	parms.req_size = sizeof(req);
1250 	parms.resp_data = (uint32_t *)&resp;
1251 	parms.resp_size = sizeof(resp);
1252 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1253 
1254 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1255 				 &parms);
1256 	if (rc)
1257 		return rc;
1258 
1259 	*ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
1260 
1261 	return rc;
1262 }
1263 
1264 int
1265 tf_msg_em_mem_unrgtr(struct tf *tfp,
1266 		     uint16_t *ctx_id)
1267 {
1268 	int rc;
1269 	struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
1270 	struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
1271 	struct tfp_send_msg_parms parms = { 0 };
1272 	struct tf_dev_info *dev;
1273 	struct tf_session *tfs;
1274 	uint32_t fw_se_id;
1275 
1276 	/* Retrieve the session information */
1277 	rc = tf_session_get_session_internal(tfp, &tfs);
1278 	if (rc) {
1279 		TFP_DRV_LOG(ERR,
1280 			    "Failed to lookup session, rc:%s\n",
1281 			    strerror(-rc));
1282 		return rc;
1283 	}
1284 
1285 	/* Retrieve the device information */
1286 	rc = tf_session_get_device(tfs, &dev);
1287 	if (rc) {
1288 		TFP_DRV_LOG(ERR,
1289 			    "Failed to lookup device, rc:%s\n",
1290 			    strerror(-rc));
1291 		return rc;
1292 	}
1293 
1294 	fw_se_id = tfs->session_id.internal.fw_session_id;
1295 	req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1296 
1297 	req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
1298 
1299 	parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
1300 	parms.req_data = (uint32_t *)&req;
1301 	parms.req_size = sizeof(req);
1302 	parms.resp_data = (uint32_t *)&resp;
1303 	parms.resp_size = sizeof(resp);
1304 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1305 
1306 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1307 				 &parms);
1308 	return rc;
1309 }
1310 
1311 int
1312 tf_msg_em_qcaps(struct tf *tfp,
1313 		int dir,
1314 		struct tf_em_caps *em_caps)
1315 {
1316 	int rc;
1317 	struct hwrm_tf_ext_em_qcaps_input  req = {0};
1318 	struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
1319 	uint32_t             flags;
1320 	struct tfp_send_msg_parms parms = { 0 };
1321 	struct tf_dev_info *dev;
1322 	struct tf_session *tfs;
1323 	uint32_t fw_se_id;
1324 
1325 	/* Retrieve the session information */
1326 	rc = tf_session_get_session_internal(tfp, &tfs);
1327 	if (rc) {
1328 		TFP_DRV_LOG(ERR,
1329 			    "%s: Failed to lookup session, rc:%s\n",
1330 			    tf_dir_2_str(dir),
1331 			    strerror(-rc));
1332 		return rc;
1333 	}
1334 	fw_se_id = tfs->session_id.internal.fw_session_id;
1335 
1336 	/* Retrieve the device information */
1337 	rc = tf_session_get_device(tfs, &dev);
1338 	if (rc) {
1339 		TFP_DRV_LOG(ERR,
1340 			    "%s: Failed to lookup device, rc:%s\n",
1341 			    tf_dir_2_str(dir),
1342 			    strerror(-rc));
1343 		return rc;
1344 	}
1345 
1346 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
1347 		 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
1348 	req.flags = tfp_cpu_to_le_32(flags);
1349 
1350 	parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
1351 	req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1352 	parms.req_data = (uint32_t *)&req;
1353 	parms.req_size = sizeof(req);
1354 	parms.resp_data = (uint32_t *)&resp;
1355 	parms.resp_size = sizeof(resp);
1356 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1357 
1358 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1359 				 &parms);
1360 	if (rc)
1361 		return rc;
1362 
1363 	em_caps->supported = tfp_le_to_cpu_32(resp.supported);
1364 	em_caps->max_entries_supported =
1365 		tfp_le_to_cpu_32(resp.max_entries_supported);
1366 	em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
1367 	em_caps->record_entry_size =
1368 		tfp_le_to_cpu_16(resp.record_entry_size);
1369 	em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
1370 
1371 	return rc;
1372 }
1373 
1374 int
1375 tf_msg_em_cfg(struct tf *tfp,
1376 	      uint32_t num_entries,
1377 	      uint16_t key0_ctx_id,
1378 	      uint16_t key1_ctx_id,
1379 	      uint16_t record_ctx_id,
1380 	      uint16_t efc_ctx_id,
1381 	      uint8_t flush_interval,
1382 	      int dir)
1383 {
1384 	int rc;
1385 	struct hwrm_tf_ext_em_cfg_input  req = {0};
1386 	struct hwrm_tf_ext_em_cfg_output resp = {0};
1387 	uint32_t flags;
1388 	struct tfp_send_msg_parms parms = { 0 };
1389 	struct tf_dev_info *dev;
1390 	struct tf_session *tfs;
1391 
1392 	/* Retrieve the session information */
1393 	rc = tf_session_get_session_internal(tfp, &tfs);
1394 	if (rc) {
1395 		TFP_DRV_LOG(ERR,
1396 			    "%s: Failed to lookup session, rc:%s\n",
1397 			    tf_dir_2_str(dir),
1398 			    strerror(-rc));
1399 		return rc;
1400 	}
1401 
1402 	/* Retrieve the device information */
1403 	rc = tf_session_get_device(tfs, &dev);
1404 	if (rc) {
1405 		TFP_DRV_LOG(ERR,
1406 			    "%s: Failed to lookup device, rc:%s\n",
1407 			    tf_dir_2_str(dir),
1408 			    strerror(-rc));
1409 		return rc;
1410 	}
1411 
1412 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1413 		 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1414 	flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
1415 
1416 	req.flags = tfp_cpu_to_le_32(flags);
1417 	req.num_entries = tfp_cpu_to_le_32(num_entries);
1418 
1419 	req.flush_interval = flush_interval;
1420 
1421 	req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
1422 	req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
1423 	req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
1424 	req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
1425 
1426 	parms.tf_type = HWRM_TF_EXT_EM_CFG;
1427 	parms.req_data = (uint32_t *)&req;
1428 	parms.req_size = sizeof(req);
1429 	parms.resp_data = (uint32_t *)&resp;
1430 	parms.resp_size = sizeof(resp);
1431 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1432 
1433 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1434 				 &parms);
1435 	return rc;
1436 }
1437 
1438 int
1439 tf_msg_ext_em_cfg(struct tf *tfp,
1440 		  struct tf_tbl_scope_cb *tbl_scope_cb,
1441 		  uint32_t st_buckets,
1442 		  uint8_t flush_interval,
1443 		  enum tf_dir dir)
1444 {
1445 	struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir];
1446 	struct hcapi_cfa_em_table *lkup_tbl, *act_tbl;
1447 	struct hwrm_tf_ext_em_cfg_input  req = {0};
1448 	struct hwrm_tf_ext_em_cfg_output resp = {0};
1449 	struct tfp_send_msg_parms parms = { 0 };
1450 	uint32_t flags;
1451 	struct tf_dev_info *dev;
1452 	struct tf_session *tfs;
1453 	uint32_t fw_se_id;
1454 	int rc;
1455 
1456 	/* Retrieve the session information */
1457 	rc = tf_session_get_session_internal(tfp, &tfs);
1458 	if (rc) {
1459 		TFP_DRV_LOG(ERR,
1460 			    "%s: Failed to lookup session, rc:%s\n",
1461 			    tf_dir_2_str(dir),
1462 			    strerror(-rc));
1463 		return rc;
1464 	}
1465 
1466 	/* Retrieve the device information */
1467 	rc = tf_session_get_device(tfs, &dev);
1468 	if (rc) {
1469 		TFP_DRV_LOG(ERR,
1470 			    "%s: Failed to lookup device, rc:%s\n",
1471 			    tf_dir_2_str(dir),
1472 			    strerror(-rc));
1473 		return rc;
1474 	}
1475 	fw_se_id = tfs->session_id.internal.fw_session_id;
1476 
1477 	lkup_tbl = &ctxp->em_tables[TF_EM_LKUP_TABLE];
1478 	act_tbl = &ctxp->em_tables[TF_ACTION_TABLE];
1479 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1480 		 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1481 	flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
1482 
1483 	req.flags = tfp_cpu_to_le_32(flags);
1484 	req.num_entries = tfp_cpu_to_le_32(act_tbl->num_entries);
1485 	req.lkup_static_buckets = tfp_cpu_to_le_32(st_buckets);
1486 	req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1487 	req.flush_interval = flush_interval;
1488 	req.action_ctx_id = tfp_cpu_to_le_16(act_tbl->ctx_id);
1489 	req.action_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id);
1490 	req.lkup_ctx_id = tfp_cpu_to_le_16(lkup_tbl->ctx_id);
1491 	req.lkup_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id);
1492 
1493 	req.enables = (HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_CTX_ID |
1494 		       HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_TBL_SCOPE |
1495 		       HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_CTX_ID |
1496 		       HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_TBL_SCOPE |
1497 		       HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_STATIC_BUCKETS |
1498 		       HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_NUM_ENTRIES);
1499 
1500 	parms.tf_type = HWRM_TF_EXT_EM_CFG;
1501 	parms.req_data = (uint32_t *)&req;
1502 	parms.req_size = sizeof(req);
1503 	parms.resp_data = (uint32_t *)&resp;
1504 	parms.resp_size = sizeof(resp);
1505 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1506 
1507 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1508 				 &parms);
1509 	return rc;
1510 }
1511 
1512 int
1513 tf_msg_em_op(struct tf *tfp,
1514 	     int dir,
1515 	     uint16_t op)
1516 {
1517 	int rc;
1518 	struct hwrm_tf_ext_em_op_input req = {0};
1519 	struct hwrm_tf_ext_em_op_output resp = {0};
1520 	uint32_t flags;
1521 	struct tfp_send_msg_parms parms = { 0 };
1522 	struct tf_dev_info *dev;
1523 	struct tf_session *tfs;
1524 
1525 	/* Retrieve the session information */
1526 	rc = tf_session_get_session_internal(tfp, &tfs);
1527 	if (rc) {
1528 		TFP_DRV_LOG(ERR,
1529 			    "%s: Failed to lookup session, rc:%s\n",
1530 			    tf_dir_2_str(dir),
1531 			    strerror(-rc));
1532 		return rc;
1533 	}
1534 
1535 	/* Retrieve the device information */
1536 	rc = tf_session_get_device(tfs, &dev);
1537 	if (rc) {
1538 		TFP_DRV_LOG(ERR,
1539 			    "%s: Failed to lookup device, rc:%s\n",
1540 			    tf_dir_2_str(dir),
1541 			    strerror(-rc));
1542 		return rc;
1543 	}
1544 
1545 	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1546 		 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1547 	req.flags = tfp_cpu_to_le_32(flags);
1548 	req.op = tfp_cpu_to_le_16(op);
1549 
1550 	parms.tf_type = HWRM_TF_EXT_EM_OP;
1551 	parms.req_data = (uint32_t *)&req;
1552 	parms.req_size = sizeof(req);
1553 	parms.resp_data = (uint32_t *)&resp;
1554 	parms.resp_size = sizeof(resp);
1555 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1556 
1557 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1558 				 &parms);
1559 	return rc;
1560 }
1561 
1562 int
1563 tf_msg_tcam_entry_set(struct tf *tfp,
1564 		      struct tf_dev_info *dev,
1565 		      struct tf_tcam_set_parms *parms)
1566 {
1567 	int rc;
1568 	struct tfp_send_msg_parms mparms = { 0 };
1569 	struct hwrm_tf_tcam_set_input req = { 0 };
1570 	struct hwrm_tf_tcam_set_output resp = { 0 };
1571 	struct tf_msg_dma_buf buf = { 0 };
1572 	uint8_t *data = NULL;
1573 	int data_size = 0;
1574 	uint8_t fw_session_id;
1575 	struct tf_session *tfs;
1576 
1577 	/* Retrieve the session information */
1578 	rc = tf_session_get_session_internal(tfp, &tfs);
1579 	if (rc) {
1580 		TFP_DRV_LOG(ERR,
1581 			    "Failed to lookup session, rc:%s\n",
1582 			    strerror(-rc));
1583 		return rc;
1584 	}
1585 
1586 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1587 	if (rc) {
1588 		TFP_DRV_LOG(ERR,
1589 			    "%s: Unable to lookup FW id, rc:%s\n",
1590 			    tf_dir_2_str(parms->dir),
1591 			    strerror(-rc));
1592 		return rc;
1593 	}
1594 
1595 	/* Populate the request */
1596 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1597 	req.type = parms->hcapi_type;
1598 	req.idx = tfp_cpu_to_le_16(parms->idx);
1599 	if (parms->dir == TF_DIR_TX)
1600 		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
1601 
1602 	req.key_size = parms->key_size;
1603 	req.mask_offset = parms->key_size;
1604 	/* Result follows after key and mask, thus multiply by 2 */
1605 	req.result_offset = 2 * parms->key_size;
1606 	req.result_size = parms->result_size;
1607 	data_size = 2 * req.key_size + req.result_size;
1608 
1609 	if (data_size <= TF_PCI_BUF_SIZE_MAX) {
1610 		/* use pci buffer */
1611 		data = &req.dev_data[0];
1612 	} else {
1613 		/* use dma buffer */
1614 		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
1615 		rc = tf_msg_alloc_dma_buf(&buf, data_size);
1616 		if (rc)
1617 			goto cleanup;
1618 		data = buf.va_addr;
1619 		tfp_memcpy(&req.dev_data[0],
1620 			   &buf.pa_addr,
1621 			   sizeof(buf.pa_addr));
1622 	}
1623 
1624 	tfp_memcpy(&data[0], parms->key, parms->key_size);
1625 	tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
1626 	tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
1627 
1628 	mparms.tf_type = HWRM_TF_TCAM_SET;
1629 	mparms.req_data = (uint32_t *)&req;
1630 	mparms.req_size = sizeof(req);
1631 	mparms.resp_data = (uint32_t *)&resp;
1632 	mparms.resp_size = sizeof(resp);
1633 	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1634 
1635 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1636 				 &mparms);
1637 
1638 cleanup:
1639 	tf_msg_free_dma_buf(&buf);
1640 
1641 	return rc;
1642 }
1643 
1644 int
1645 tf_msg_tcam_entry_get(struct tf *tfp,
1646 		      struct tf_dev_info *dev,
1647 		      struct tf_tcam_get_parms *parms)
1648 {
1649 	int rc;
1650 	struct tfp_send_msg_parms mparms = { 0 };
1651 	struct hwrm_tf_tcam_get_input req = { 0 };
1652 	struct hwrm_tf_tcam_get_output resp = { 0 };
1653 	uint8_t fw_session_id;
1654 	struct tf_session *tfs;
1655 
1656 	/* Retrieve the session information */
1657 	rc = tf_session_get_session_internal(tfp, &tfs);
1658 	if (rc) {
1659 		TFP_DRV_LOG(ERR,
1660 			    "Failed to lookup session, rc:%s\n",
1661 			    strerror(-rc));
1662 		return rc;
1663 	}
1664 
1665 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1666 	if (rc) {
1667 		TFP_DRV_LOG(ERR,
1668 			    "%s: Unable to lookup FW id, rc:%s\n",
1669 			    tf_dir_2_str(parms->dir),
1670 			    strerror(-rc));
1671 		return rc;
1672 	}
1673 
1674 	/* Populate the request */
1675 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1676 	req.type = parms->hcapi_type;
1677 	req.idx = tfp_cpu_to_le_16(parms->idx);
1678 	if (parms->dir == TF_DIR_TX)
1679 		req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX;
1680 
1681 	mparms.tf_type = HWRM_TF_TCAM_GET;
1682 	mparms.req_data = (uint32_t *)&req;
1683 	mparms.req_size = sizeof(req);
1684 	mparms.resp_data = (uint32_t *)&resp;
1685 	mparms.resp_size = sizeof(resp);
1686 	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1687 
1688 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1689 				 &mparms);
1690 
1691 	if (rc != 0)
1692 		return rc;
1693 
1694 	if (parms->key_size < resp.key_size ||
1695 	    parms->result_size < resp.result_size) {
1696 		rc = -EINVAL;
1697 		TFP_DRV_LOG(ERR,
1698 			    "%s: Key buffer(%d) is smaller than the key(%d), rc:%s\n",
1699 			    tf_dir_2_str(parms->dir),
1700 			    parms->key_size,
1701 			    resp.key_size,
1702 			    strerror(-rc));
1703 		return rc;
1704 	}
1705 	parms->key_size = resp.key_size;
1706 	parms->result_size = resp.result_size;
1707 	tfp_memcpy(parms->key, resp.dev_data, resp.key_size);
1708 	tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size);
1709 	tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size);
1710 
1711 	return 0;
1712 }
1713 
1714 int
1715 tf_msg_tcam_entry_free(struct tf *tfp,
1716 		       struct tf_dev_info *dev,
1717 		       struct tf_tcam_free_parms *in_parms)
1718 {
1719 	int rc;
1720 	struct hwrm_tf_tcam_free_input req =  { 0 };
1721 	struct hwrm_tf_tcam_free_output resp = { 0 };
1722 	struct tfp_send_msg_parms parms = { 0 };
1723 	uint8_t fw_session_id;
1724 	struct tf_session *tfs;
1725 
1726 	/* Retrieve the session information */
1727 	rc = tf_session_get_session_internal(tfp, &tfs);
1728 	if (rc) {
1729 		TFP_DRV_LOG(ERR,
1730 			    "Failed to lookup session, rc:%s\n",
1731 			    strerror(-rc));
1732 		return rc;
1733 	}
1734 
1735 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1736 	if (rc) {
1737 		TFP_DRV_LOG(ERR,
1738 			    "%s: Unable to lookup FW id, rc:%s\n",
1739 			    tf_dir_2_str(in_parms->dir),
1740 			    strerror(-rc));
1741 		return rc;
1742 	}
1743 
1744 	/* Populate the request */
1745 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1746 	req.type = in_parms->hcapi_type;
1747 	req.count = 1;
1748 	req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
1749 	if (in_parms->dir == TF_DIR_TX)
1750 		req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
1751 
1752 	parms.tf_type = HWRM_TF_TCAM_FREE;
1753 	parms.req_data = (uint32_t *)&req;
1754 	parms.req_size = sizeof(req);
1755 	parms.resp_data = (uint32_t *)&resp;
1756 	parms.resp_size = sizeof(resp);
1757 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1758 
1759 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1760 				 &parms);
1761 	return rc;
1762 }
1763 
1764 int
1765 tf_msg_set_tbl_entry(struct tf *tfp,
1766 		     enum tf_dir dir,
1767 		     uint16_t hcapi_type,
1768 		     uint16_t size,
1769 		     uint8_t *data,
1770 		     uint32_t index)
1771 {
1772 	int rc;
1773 	struct hwrm_tf_tbl_type_set_input req = { 0 };
1774 	struct hwrm_tf_tbl_type_set_output resp = { 0 };
1775 	struct tfp_send_msg_parms parms = { 0 };
1776 	uint8_t fw_session_id;
1777 	struct tf_dev_info *dev;
1778 	struct tf_session *tfs;
1779 
1780 	RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_tbl_type_set_input) !=
1781 			 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET);
1782 
1783 	/* Retrieve the session information */
1784 	rc = tf_session_get_session_internal(tfp, &tfs);
1785 	if (rc) {
1786 		TFP_DRV_LOG(ERR,
1787 			    "%s: Failed to lookup session, rc:%s\n",
1788 			    tf_dir_2_str(dir),
1789 			    strerror(-rc));
1790 		return rc;
1791 	}
1792 
1793 	/* Retrieve the device information */
1794 	rc = tf_session_get_device(tfs, &dev);
1795 	if (rc) {
1796 		TFP_DRV_LOG(ERR,
1797 			    "%s: Failed to lookup device, rc:%s\n",
1798 			    tf_dir_2_str(dir),
1799 			    strerror(-rc));
1800 		return rc;
1801 	}
1802 
1803 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1804 	if (rc) {
1805 		TFP_DRV_LOG(ERR,
1806 			    "%s: Unable to lookup FW id, rc:%s\n",
1807 			    tf_dir_2_str(dir),
1808 			    strerror(-rc));
1809 		return rc;
1810 	}
1811 
1812 	/* Populate the request */
1813 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1814 	req.flags = tfp_cpu_to_le_16(dir);
1815 	req.type = tfp_cpu_to_le_32(hcapi_type);
1816 	req.size = tfp_cpu_to_le_16(size);
1817 	req.index = tfp_cpu_to_le_32(index);
1818 
1819 	/* Check for data size conformity */
1820 	if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
1821 		rc = -EINVAL;
1822 		TFP_DRV_LOG(ERR,
1823 			    "%s: Invalid parameters for msg type, rc:%s\n",
1824 			    tf_dir_2_str(dir),
1825 			    strerror(-rc));
1826 		return rc;
1827 	}
1828 
1829 	tfp_memcpy(&req.data,
1830 		   data,
1831 		   size);
1832 
1833 	parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1834 	parms.req_data = (uint32_t *)&req;
1835 	parms.req_size = sizeof(req);
1836 	parms.resp_data = (uint32_t *)&resp;
1837 	parms.resp_size = sizeof(resp);
1838 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1839 
1840 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1841 				 &parms);
1842 	if (rc)
1843 		return rc;
1844 
1845 	return 0;
1846 }
1847 
1848 int
1849 tf_msg_get_tbl_entry(struct tf *tfp,
1850 		     enum tf_dir dir,
1851 		     uint16_t hcapi_type,
1852 		     uint16_t size,
1853 		     uint8_t *data,
1854 		     uint32_t index)
1855 {
1856 	int rc;
1857 	struct hwrm_tf_tbl_type_get_input req = { 0 };
1858 	struct hwrm_tf_tbl_type_get_output resp = { 0 };
1859 	struct tfp_send_msg_parms parms = { 0 };
1860 	uint8_t fw_session_id;
1861 	struct tf_dev_info *dev;
1862 	struct tf_session *tfs;
1863 
1864 	/* Retrieve the session information */
1865 	rc = tf_session_get_session_internal(tfp, &tfs);
1866 	if (rc) {
1867 		TFP_DRV_LOG(ERR,
1868 			    "%s: Failed to lookup session, rc:%s\n",
1869 			    tf_dir_2_str(dir),
1870 			    strerror(-rc));
1871 		return rc;
1872 	}
1873 
1874 	/* Retrieve the device information */
1875 	rc = tf_session_get_device(tfs, &dev);
1876 	if (rc) {
1877 		TFP_DRV_LOG(ERR,
1878 			    "%s: Failed to lookup device, rc:%s\n",
1879 			    tf_dir_2_str(dir),
1880 			    strerror(-rc));
1881 		return rc;
1882 	}
1883 
1884 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1885 	if (rc) {
1886 		TFP_DRV_LOG(ERR,
1887 			    "%s: Unable to lookup FW id, rc:%s\n",
1888 			    tf_dir_2_str(dir),
1889 			    strerror(-rc));
1890 		return rc;
1891 	}
1892 
1893 	/* Populate the request */
1894 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1895 	req.flags = tfp_cpu_to_le_16(dir);
1896 	req.type = tfp_cpu_to_le_32(hcapi_type);
1897 	req.index = tfp_cpu_to_le_32(index);
1898 
1899 	parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1900 	parms.req_data = (uint32_t *)&req;
1901 	parms.req_size = sizeof(req);
1902 	parms.resp_data = (uint32_t *)&resp;
1903 	parms.resp_size = sizeof(resp);
1904 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1905 
1906 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1907 				 &parms);
1908 	if (rc)
1909 		return rc;
1910 
1911 	/*
1912 	 * The response will be 64 bytes long, the response size will
1913 	 * be in words (16). All we can test for is that the response
1914 	 * size is < to the requested size.
1915 	 */
1916 	if ((tfp_le_to_cpu_32(resp.size) * 4) < size)
1917 		return -EINVAL;
1918 
1919 	/*
1920 	 * Copy the requested number of bytes
1921 	 */
1922 	tfp_memcpy(data,
1923 		   &resp.data,
1924 		   size);
1925 
1926 	return 0;
1927 }
1928 
1929 /* HWRM Tunneled messages */
1930 
1931 int
1932 tf_msg_get_global_cfg(struct tf *tfp,
1933 		      struct tf_global_cfg_parms *params)
1934 {
1935 	int rc = 0;
1936 	struct tfp_send_msg_parms parms = { 0 };
1937 	struct hwrm_tf_global_cfg_get_input req = { 0 };
1938 	struct hwrm_tf_global_cfg_get_output resp = { 0 };
1939 	uint32_t flags = 0;
1940 	uint8_t fw_session_id;
1941 	uint16_t resp_size = 0;
1942 	struct tf_dev_info *dev;
1943 	struct tf_session *tfs;
1944 
1945 	/* Retrieve the session information */
1946 	rc = tf_session_get_session_internal(tfp, &tfs);
1947 	if (rc) {
1948 		TFP_DRV_LOG(ERR,
1949 			    "%s: Failed to lookup session, rc:%s\n",
1950 			    tf_dir_2_str(params->dir),
1951 			    strerror(-rc));
1952 		return rc;
1953 	}
1954 
1955 	/* Retrieve the device information */
1956 	rc = tf_session_get_device(tfs, &dev);
1957 	if (rc) {
1958 		TFP_DRV_LOG(ERR,
1959 			    "%s: Failed to lookup device, rc:%s\n",
1960 			    tf_dir_2_str(params->dir),
1961 			    strerror(-rc));
1962 		return rc;
1963 	}
1964 
1965 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1966 	if (rc) {
1967 		TFP_DRV_LOG(ERR,
1968 			    "%s: Unable to lookup FW id, rc:%s\n",
1969 			    tf_dir_2_str(params->dir),
1970 			    strerror(-rc));
1971 		return rc;
1972 	}
1973 
1974 	flags = (params->dir == TF_DIR_TX ?
1975 		 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1976 		 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1977 
1978 	/* Populate the request */
1979 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1980 	req.flags = tfp_cpu_to_le_32(flags);
1981 	req.type = tfp_cpu_to_le_32(params->type);
1982 	req.offset = tfp_cpu_to_le_32(params->offset);
1983 	req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1984 
1985 	parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1986 	parms.req_data = (uint32_t *)&req;
1987 	parms.req_size = sizeof(req);
1988 	parms.resp_data = (uint32_t *)&resp;
1989 	parms.resp_size = sizeof(resp);
1990 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1991 
1992 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1993 	if (rc != 0)
1994 		return rc;
1995 
1996 	/* Verify that we got enough buffer to return the requested data */
1997 	resp_size = tfp_le_to_cpu_16(resp.size);
1998 	if (resp_size < params->config_sz_in_bytes)
1999 		return -EINVAL;
2000 
2001 	if (params->config)
2002 		tfp_memcpy(params->config,
2003 			   resp.data,
2004 			   resp_size);
2005 	else
2006 		return -EFAULT;
2007 
2008 	return 0;
2009 }
2010 
2011 int
2012 tf_msg_set_global_cfg(struct tf *tfp,
2013 		      struct tf_global_cfg_parms *params)
2014 {
2015 	int rc = 0;
2016 	struct tfp_send_msg_parms parms = { 0 };
2017 	struct hwrm_tf_global_cfg_set_input req = { 0 };
2018 	struct hwrm_tf_global_cfg_set_output resp = { 0 };
2019 	uint32_t flags = 0;
2020 	uint8_t fw_session_id;
2021 	struct tf_dev_info *dev;
2022 	struct tf_session *tfs;
2023 
2024 	/* Retrieve the session information */
2025 	rc = tf_session_get_session_internal(tfp, &tfs);
2026 	if (rc) {
2027 		TFP_DRV_LOG(ERR,
2028 			    "%s: Failed to lookup session, rc:%s\n",
2029 			    tf_dir_2_str(params->dir),
2030 			    strerror(-rc));
2031 		return rc;
2032 	}
2033 
2034 	/* Retrieve the device information */
2035 	rc = tf_session_get_device(tfs, &dev);
2036 	if (rc) {
2037 		TFP_DRV_LOG(ERR,
2038 			    "%s: Failed to lookup device, rc:%s\n",
2039 			    tf_dir_2_str(params->dir),
2040 			    strerror(-rc));
2041 		return rc;
2042 	}
2043 
2044 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2045 	if (rc) {
2046 		TFP_DRV_LOG(ERR,
2047 			    "%s: Unable to lookup FW id, rc:%s\n",
2048 			    tf_dir_2_str(params->dir),
2049 			    strerror(-rc));
2050 		return rc;
2051 	}
2052 
2053 	flags = (params->dir == TF_DIR_TX ?
2054 		 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
2055 		 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
2056 
2057 	/* Populate the request */
2058 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2059 	req.flags = tfp_cpu_to_le_32(flags);
2060 	req.type = tfp_cpu_to_le_32(params->type);
2061 	req.offset = tfp_cpu_to_le_32(params->offset);
2062 
2063 	/* Check for data size conformity */
2064 	if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
2065 		rc = -EINVAL;
2066 		TFP_DRV_LOG(ERR,
2067 			    "%s: Invalid parameters for msg type, rc:%s\n",
2068 			    tf_dir_2_str(params->dir),
2069 			    strerror(-rc));
2070 		return rc;
2071 	}
2072 
2073 	tfp_memcpy(req.data, params->config,
2074 		   params->config_sz_in_bytes);
2075 
2076 	/* Only set mask if pointer is provided
2077 	 */
2078 	if (params->config_mask) {
2079 		tfp_memcpy(req.mask,
2080 			   params->config_mask,
2081 			   params->config_sz_in_bytes);
2082 	}
2083 
2084 	req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
2085 
2086 	parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
2087 	parms.req_data = (uint32_t *)&req;
2088 	parms.req_size = sizeof(req);
2089 	parms.resp_data = (uint32_t *)&resp;
2090 	parms.resp_size = sizeof(resp);
2091 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2092 
2093 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2094 
2095 	if (rc != 0)
2096 		return rc;
2097 
2098 	return 0;
2099 }
2100 
2101 int
2102 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
2103 			  enum tf_dir dir,
2104 			  uint16_t hcapi_type,
2105 			  uint32_t starting_idx,
2106 			  uint16_t num_entries,
2107 			  uint16_t entry_sz_in_bytes,
2108 			  uint64_t physical_mem_addr)
2109 {
2110 	int rc;
2111 	struct tfp_send_msg_parms parms = { 0 };
2112 	struct hwrm_tf_tbl_type_bulk_get_input req = { 0 };
2113 	struct hwrm_tf_tbl_type_bulk_get_output resp = { 0 };
2114 	int data_size = 0;
2115 	uint8_t fw_session_id;
2116 	struct tf_dev_info *dev;
2117 	struct tf_session *tfs;
2118 
2119 	/* Retrieve the session information */
2120 	rc = tf_session_get_session(tfp, &tfs);
2121 	if (rc) {
2122 		TFP_DRV_LOG(ERR,
2123 			    "%s: Failed to lookup session, rc:%s\n",
2124 			    tf_dir_2_str(dir),
2125 			    strerror(-rc));
2126 		return rc;
2127 	}
2128 
2129 	/* Retrieve the device information */
2130 	rc = tf_session_get_device(tfs, &dev);
2131 	if (rc) {
2132 		TFP_DRV_LOG(ERR,
2133 			    "%s: Failed to lookup device, rc:%s\n",
2134 			    tf_dir_2_str(dir),
2135 			    strerror(-rc));
2136 		return rc;
2137 	}
2138 
2139 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2140 	if (rc) {
2141 		TFP_DRV_LOG(ERR,
2142 			    "%s: Unable to lookup FW id, rc:%s\n",
2143 			    tf_dir_2_str(dir),
2144 			    strerror(-rc));
2145 		return rc;
2146 	}
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(dir);
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