1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2020 Broadcom
12 #include "tf_msg_common.h"
13 #include "tf_device.h"
16 #include "tf_common.h"
17 #include "tf_session.h"
23 #define TF_RM_MSG_DEBUG 0
25 /* Specific msg size defines as we cannot use defines in tf.yaml. This
26 * means we have to manually sync hwrm with these defines if the
29 #define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE 16
30 #define TF_MSG_EM_INSERT_KEY_SIZE 64
31 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE 88
33 /* Compile check - Catch any msg changes that we depend on, like the
34 * defines listed above for array size checking.
36 * Checking array size is dangerous in that the type could change and
37 * we wouldn't be able to catch it. Thus we check if the complete msg
38 * changed instead. Best we can do.
40 * If failure is observed then both msg size (defines below) and the
41 * array size (define above) should be checked and compared.
43 #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56
44 static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
45 TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET,
46 "HWRM message size changed: hwrm_tf_global_cfg_set_input");
48 #define TF_MSG_SIZE_HWRM_TF_EM_INSERT 104
49 static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
50 TF_MSG_SIZE_HWRM_TF_EM_INSERT,
51 "HWRM message size changed: hwrm_tf_em_insert_input");
53 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET 128
54 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
55 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
56 "HWRM message size changed: hwrm_tf_tbl_type_set_input");
59 * This is the MAX data we can transport across regular HWRM
61 #define TF_PCI_BUF_SIZE_MAX 88
64 * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
66 struct tf_msg_dma_buf {
72 * Allocates a DMA buffer that can be used for message transfer.
75 * Pointer to DMA buffer structure
78 * Requested size of the buffer in bytes
82 * -ENOMEM - Unable to allocate buffer, no memory
85 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
87 struct tfp_calloc_parms alloc_parms;
90 /* Allocate session */
91 alloc_parms.nitems = 1;
92 alloc_parms.size = size;
93 alloc_parms.alignment = 4096;
94 rc = tfp_calloc(&alloc_parms);
98 buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
99 buf->va_addr = alloc_parms.mem_va;
105 * Free's a previous allocated DMA buffer.
108 * Pointer to DMA buffer structure
111 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
113 tfp_free(buf->va_addr);
116 /* HWRM Direct messages */
119 tf_msg_session_open(struct tf *tfp,
120 char *ctrl_chan_name,
121 uint8_t *fw_session_id,
122 uint8_t *fw_session_client_id)
125 struct hwrm_tf_session_open_input req = { 0 };
126 struct hwrm_tf_session_open_output resp = { 0 };
127 struct tfp_send_msg_parms parms = { 0 };
129 /* Populate the request */
130 tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
132 parms.tf_type = HWRM_TF_SESSION_OPEN;
133 parms.req_data = (uint32_t *)&req;
134 parms.req_size = sizeof(req);
135 parms.resp_data = (uint32_t *)&resp;
136 parms.resp_size = sizeof(resp);
137 parms.mailbox = TF_KONG_MB;
139 rc = tfp_send_msg_direct(tfp,
144 *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
145 *fw_session_client_id =
146 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
152 tf_msg_session_attach(struct tf *tfp __rte_unused,
153 char *ctrl_chan_name __rte_unused,
154 uint8_t tf_fw_session_id __rte_unused)
160 tf_msg_session_client_register(struct tf *tfp,
161 char *ctrl_channel_name,
162 uint8_t *fw_session_client_id)
165 struct hwrm_tf_session_register_input req = { 0 };
166 struct hwrm_tf_session_register_output resp = { 0 };
167 struct tfp_send_msg_parms parms = { 0 };
168 uint8_t fw_session_id;
170 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
173 "Unable to lookup FW id, rc:%s\n",
178 /* Populate the request */
179 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
180 tfp_memcpy(&req.session_client_name,
182 TF_SESSION_NAME_MAX);
184 parms.tf_type = HWRM_TF_SESSION_REGISTER;
185 parms.req_data = (uint32_t *)&req;
186 parms.req_size = sizeof(req);
187 parms.resp_data = (uint32_t *)&resp;
188 parms.resp_size = sizeof(resp);
189 parms.mailbox = TF_KONG_MB;
191 rc = tfp_send_msg_direct(tfp,
196 *fw_session_client_id =
197 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
203 tf_msg_session_client_unregister(struct tf *tfp,
204 uint8_t fw_session_client_id)
207 struct hwrm_tf_session_unregister_input req = { 0 };
208 struct hwrm_tf_session_unregister_output resp = { 0 };
209 struct tfp_send_msg_parms parms = { 0 };
210 uint8_t fw_session_id;
212 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
215 "Unable to lookup FW id, rc:%s\n",
220 /* Populate the request */
221 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
222 req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
224 parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
225 parms.req_data = (uint32_t *)&req;
226 parms.req_size = sizeof(req);
227 parms.resp_data = (uint32_t *)&resp;
228 parms.resp_size = sizeof(resp);
229 parms.mailbox = TF_KONG_MB;
231 rc = tfp_send_msg_direct(tfp,
238 tf_msg_session_close(struct tf *tfp)
241 struct hwrm_tf_session_close_input req = { 0 };
242 struct hwrm_tf_session_close_output resp = { 0 };
243 struct tfp_send_msg_parms parms = { 0 };
244 uint8_t fw_session_id;
246 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
249 "Unable to lookup FW id, rc:%s\n",
254 /* Populate the request */
255 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
257 parms.tf_type = HWRM_TF_SESSION_CLOSE;
258 parms.req_data = (uint32_t *)&req;
259 parms.req_size = sizeof(req);
260 parms.resp_data = (uint32_t *)&resp;
261 parms.resp_size = sizeof(resp);
262 parms.mailbox = TF_KONG_MB;
264 rc = tfp_send_msg_direct(tfp,
270 tf_msg_session_qcfg(struct tf *tfp)
273 struct hwrm_tf_session_qcfg_input req = { 0 };
274 struct hwrm_tf_session_qcfg_output resp = { 0 };
275 struct tfp_send_msg_parms parms = { 0 };
276 uint8_t fw_session_id;
278 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
281 "Unable to lookup FW id, rc:%s\n",
286 /* Populate the request */
287 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
289 parms.tf_type = HWRM_TF_SESSION_QCFG,
290 parms.req_data = (uint32_t *)&req;
291 parms.req_size = sizeof(req);
292 parms.resp_data = (uint32_t *)&resp;
293 parms.resp_size = sizeof(resp);
294 parms.mailbox = TF_KONG_MB;
296 rc = tfp_send_msg_direct(tfp,
302 tf_msg_session_resc_qcaps(struct tf *tfp,
305 struct tf_rm_resc_req_entry *query,
306 enum tf_rm_resc_resv_strategy *resv_strategy)
310 struct tfp_send_msg_parms parms = { 0 };
311 struct hwrm_tf_session_resc_qcaps_input req = { 0 };
312 struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
313 uint8_t fw_session_id;
314 struct tf_msg_dma_buf qcaps_buf = { 0 };
315 struct tf_rm_resc_req_entry *data;
318 TF_CHECK_PARMS3(tfp, query, resv_strategy);
320 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
323 "%s: Unable to lookup FW id, rc:%s\n",
329 /* Prepare DMA buffer */
330 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
331 rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
335 /* Populate the request */
336 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
337 req.flags = tfp_cpu_to_le_16(dir);
338 req.qcaps_size = size;
339 req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
341 parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
342 parms.req_data = (uint32_t *)&req;
343 parms.req_size = sizeof(req);
344 parms.resp_data = (uint32_t *)&resp;
345 parms.resp_size = sizeof(resp);
346 parms.mailbox = TF_KONG_MB;
348 rc = tfp_send_msg_direct(tfp, &parms);
352 /* Process the response
353 * Should always get expected number of entries
355 if (tfp_le_to_cpu_32(resp.size) != size) {
357 "%s: QCAPS message size error, rc:%s\n",
364 #if (TF_RM_MSG_DEBUG == 1)
365 printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
366 #endif /* (TF_RM_MSG_DEBUG == 1) */
368 /* Post process the response */
369 data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
371 #if (TF_RM_MSG_DEBUG == 1)
373 #endif /* (TF_RM_MSG_DEBUG == 1) */
374 for (i = 0; i < size; i++) {
375 query[i].type = tfp_le_to_cpu_32(data[i].type);
376 query[i].min = tfp_le_to_cpu_16(data[i].min);
377 query[i].max = tfp_le_to_cpu_16(data[i].max);
379 #if (TF_RM_MSG_DEBUG == 1)
380 printf("type: %d(0x%x) %d %d\n",
385 #endif /* (TF_RM_MSG_DEBUG == 1) */
389 *resv_strategy = resp.flags &
390 HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
393 tf_msg_free_dma_buf(&qcaps_buf);
399 tf_msg_session_resc_alloc(struct tf *tfp,
402 struct tf_rm_resc_req_entry *request,
403 struct tf_rm_resc_entry *resv)
407 struct tfp_send_msg_parms parms = { 0 };
408 struct hwrm_tf_session_resc_alloc_input req = { 0 };
409 struct hwrm_tf_session_resc_alloc_output resp = { 0 };
410 uint8_t fw_session_id;
411 struct tf_msg_dma_buf req_buf = { 0 };
412 struct tf_msg_dma_buf resv_buf = { 0 };
413 struct tf_rm_resc_req_entry *req_data;
414 struct tf_rm_resc_entry *resv_data;
417 TF_CHECK_PARMS3(tfp, request, resv);
419 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
422 "%s: Unable to lookup FW id, rc:%s\n",
428 /* Prepare DMA buffers */
429 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
430 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
434 dma_size = size * sizeof(struct tf_rm_resc_entry);
435 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
437 tf_msg_free_dma_buf(&req_buf);
441 /* Populate the request */
442 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
443 req.flags = tfp_cpu_to_le_16(dir);
446 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
447 for (i = 0; i < size; i++) {
448 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
449 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
450 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
453 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
454 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
456 parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
457 parms.req_data = (uint32_t *)&req;
458 parms.req_size = sizeof(req);
459 parms.resp_data = (uint32_t *)&resp;
460 parms.resp_size = sizeof(resp);
461 parms.mailbox = TF_KONG_MB;
463 rc = tfp_send_msg_direct(tfp, &parms);
467 /* Process the response
468 * Should always get expected number of entries
470 if (tfp_le_to_cpu_32(resp.size) != size) {
472 "%s: Alloc message size error, rc:%s\n",
479 #if (TF_RM_MSG_DEBUG == 1)
481 printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
482 #endif /* (TF_RM_MSG_DEBUG == 1) */
484 /* Post process the response */
485 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
486 for (i = 0; i < size; i++) {
487 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
488 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
489 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
491 #if (TF_RM_MSG_DEBUG == 1)
492 printf("%d type: %d(0x%x) %d %d\n",
498 #endif /* (TF_RM_MSG_DEBUG == 1) */
502 tf_msg_free_dma_buf(&req_buf);
503 tf_msg_free_dma_buf(&resv_buf);
509 tf_msg_session_resc_flush(struct tf *tfp,
512 struct tf_rm_resc_entry *resv)
516 struct tfp_send_msg_parms parms = { 0 };
517 struct hwrm_tf_session_resc_flush_input req = { 0 };
518 struct hwrm_tf_session_resc_flush_output resp = { 0 };
519 uint8_t fw_session_id;
520 struct tf_msg_dma_buf resv_buf = { 0 };
521 struct tf_rm_resc_entry *resv_data;
524 TF_CHECK_PARMS2(tfp, resv);
526 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
529 "%s: Unable to lookup FW id, rc:%s\n",
535 /* Prepare DMA buffers */
536 dma_size = size * sizeof(struct tf_rm_resc_entry);
537 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
541 /* Populate the request */
542 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
543 req.flags = tfp_cpu_to_le_16(dir);
544 req.flush_size = size;
546 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
547 for (i = 0; i < size; i++) {
548 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
549 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
550 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
553 req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
555 parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
556 parms.req_data = (uint32_t *)&req;
557 parms.req_size = sizeof(req);
558 parms.resp_data = (uint32_t *)&resp;
559 parms.resp_size = sizeof(resp);
560 parms.mailbox = TF_KONG_MB;
562 rc = tfp_send_msg_direct(tfp, &parms);
564 tf_msg_free_dma_buf(&resv_buf);
570 tf_msg_insert_em_internal_entry(struct tf *tfp,
571 struct tf_insert_em_entry_parms *em_parms,
572 uint16_t *rptr_index,
574 uint8_t *num_of_entries)
577 struct tfp_send_msg_parms parms = { 0 };
578 struct hwrm_tf_em_insert_input req = { 0 };
579 struct hwrm_tf_em_insert_output resp = { 0 };
580 struct tf_em_64b_entry *em_result =
581 (struct tf_em_64b_entry *)em_parms->em_record;
583 uint8_t fw_session_id;
584 uint8_t msg_key_size;
586 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
589 "%s: Unable to lookup FW id, rc:%s\n",
590 tf_dir_2_str(em_parms->dir),
595 /* Populate the request */
596 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
598 /* Check for key size conformity */
599 msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
600 if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
603 "%s: Invalid parameters for msg type, rc:%s\n",
604 tf_dir_2_str(em_parms->dir),
609 tfp_memcpy(req.em_key,
613 flags = (em_parms->dir == TF_DIR_TX ?
614 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
615 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
616 req.flags = tfp_cpu_to_le_16(flags);
617 req.strength = (em_result->hdr.word1 &
618 CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
619 CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
620 req.em_key_bitlen = em_parms->key_sz_in_bits;
621 req.action_ptr = em_result->hdr.pointer;
622 req.em_record_idx = *rptr_index;
624 parms.tf_type = HWRM_TF_EM_INSERT;
625 parms.req_data = (uint32_t *)&req;
626 parms.req_size = sizeof(req);
627 parms.resp_data = (uint32_t *)&resp;
628 parms.resp_size = sizeof(resp);
629 parms.mailbox = TF_KONG_MB;
631 rc = tfp_send_msg_direct(tfp,
636 *rptr_entry = resp.rptr_entry;
637 *rptr_index = resp.rptr_index;
638 *num_of_entries = resp.num_of_entries;
644 tf_msg_delete_em_entry(struct tf *tfp,
645 struct tf_delete_em_entry_parms *em_parms)
648 struct tfp_send_msg_parms parms = { 0 };
649 struct hwrm_tf_em_delete_input req = { 0 };
650 struct hwrm_tf_em_delete_output resp = { 0 };
652 uint8_t fw_session_id;
654 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
657 "%s: Unable to lookup FW id, rc:%s\n",
658 tf_dir_2_str(em_parms->dir),
663 /* Populate the request */
664 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
666 flags = (em_parms->dir == TF_DIR_TX ?
667 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
668 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
669 req.flags = tfp_cpu_to_le_16(flags);
670 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
672 parms.tf_type = HWRM_TF_EM_DELETE;
673 parms.req_data = (uint32_t *)&req;
674 parms.req_size = sizeof(req);
675 parms.resp_data = (uint32_t *)&resp;
676 parms.resp_size = sizeof(resp);
677 parms.mailbox = TF_KONG_MB;
679 rc = tfp_send_msg_direct(tfp,
684 em_parms->index = tfp_le_to_cpu_16(resp.em_index);
690 tf_msg_em_mem_rgtr(struct tf *tfp,
697 struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
698 struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
699 struct tfp_send_msg_parms parms = { 0 };
701 req.page_level = page_lvl;
702 req.page_size = page_size;
703 req.page_dir = tfp_cpu_to_le_64(dma_addr);
705 parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
706 parms.req_data = (uint32_t *)&req;
707 parms.req_size = sizeof(req);
708 parms.resp_data = (uint32_t *)&resp;
709 parms.resp_size = sizeof(resp);
710 parms.mailbox = TF_KONG_MB;
712 rc = tfp_send_msg_direct(tfp,
717 *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
723 tf_msg_em_mem_unrgtr(struct tf *tfp,
727 struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
728 struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
729 struct tfp_send_msg_parms parms = { 0 };
731 req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
733 parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
734 parms.req_data = (uint32_t *)&req;
735 parms.req_size = sizeof(req);
736 parms.resp_data = (uint32_t *)&resp;
737 parms.resp_size = sizeof(resp);
738 parms.mailbox = TF_KONG_MB;
740 rc = tfp_send_msg_direct(tfp,
746 tf_msg_em_qcaps(struct tf *tfp,
748 struct tf_em_caps *em_caps)
751 struct hwrm_tf_ext_em_qcaps_input req = {0};
752 struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
754 struct tfp_send_msg_parms parms = { 0 };
756 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
757 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
758 req.flags = tfp_cpu_to_le_32(flags);
760 parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
761 parms.req_data = (uint32_t *)&req;
762 parms.req_size = sizeof(req);
763 parms.resp_data = (uint32_t *)&resp;
764 parms.resp_size = sizeof(resp);
765 parms.mailbox = TF_KONG_MB;
767 rc = tfp_send_msg_direct(tfp,
772 em_caps->supported = tfp_le_to_cpu_32(resp.supported);
773 em_caps->max_entries_supported =
774 tfp_le_to_cpu_32(resp.max_entries_supported);
775 em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
776 em_caps->record_entry_size =
777 tfp_le_to_cpu_16(resp.record_entry_size);
778 em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
784 tf_msg_em_cfg(struct tf *tfp,
785 uint32_t num_entries,
786 uint16_t key0_ctx_id,
787 uint16_t key1_ctx_id,
788 uint16_t record_ctx_id,
790 uint8_t flush_interval,
794 struct hwrm_tf_ext_em_cfg_input req = {0};
795 struct hwrm_tf_ext_em_cfg_output resp = {0};
797 struct tfp_send_msg_parms parms = { 0 };
799 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
800 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
801 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
803 req.flags = tfp_cpu_to_le_32(flags);
804 req.num_entries = tfp_cpu_to_le_32(num_entries);
806 req.flush_interval = flush_interval;
808 req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
809 req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
810 req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
811 req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
813 parms.tf_type = HWRM_TF_EXT_EM_CFG;
814 parms.req_data = (uint32_t *)&req;
815 parms.req_size = sizeof(req);
816 parms.resp_data = (uint32_t *)&resp;
817 parms.resp_size = sizeof(resp);
818 parms.mailbox = TF_KONG_MB;
820 rc = tfp_send_msg_direct(tfp,
826 tf_msg_em_op(struct tf *tfp,
831 struct hwrm_tf_ext_em_op_input req = {0};
832 struct hwrm_tf_ext_em_op_output resp = {0};
834 struct tfp_send_msg_parms parms = { 0 };
836 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
837 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
838 req.flags = tfp_cpu_to_le_32(flags);
839 req.op = tfp_cpu_to_le_16(op);
841 parms.tf_type = HWRM_TF_EXT_EM_OP;
842 parms.req_data = (uint32_t *)&req;
843 parms.req_size = sizeof(req);
844 parms.resp_data = (uint32_t *)&resp;
845 parms.resp_size = sizeof(resp);
846 parms.mailbox = TF_KONG_MB;
848 rc = tfp_send_msg_direct(tfp,
854 tf_msg_tcam_entry_set(struct tf *tfp,
855 struct tf_tcam_set_parms *parms)
858 struct tfp_send_msg_parms mparms = { 0 };
859 struct hwrm_tf_tcam_set_input req = { 0 };
860 struct hwrm_tf_tcam_set_output resp = { 0 };
861 struct tf_msg_dma_buf buf = { 0 };
862 uint8_t *data = NULL;
864 uint8_t fw_session_id;
866 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
869 "%s: Unable to lookup FW id, rc:%s\n",
870 tf_dir_2_str(parms->dir),
875 /* Populate the request */
876 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
877 req.type = parms->hcapi_type;
878 req.idx = tfp_cpu_to_le_16(parms->idx);
879 if (parms->dir == TF_DIR_TX)
880 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
882 req.key_size = parms->key_size;
883 req.mask_offset = parms->key_size;
884 /* Result follows after key and mask, thus multiply by 2 */
885 req.result_offset = 2 * parms->key_size;
886 req.result_size = parms->result_size;
887 data_size = 2 * req.key_size + req.result_size;
889 if (data_size <= TF_PCI_BUF_SIZE_MAX) {
891 data = &req.dev_data[0];
894 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
895 rc = tf_msg_alloc_dma_buf(&buf, data_size);
899 tfp_memcpy(&req.dev_data[0],
901 sizeof(buf.pa_addr));
904 tfp_memcpy(&data[0], parms->key, parms->key_size);
905 tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
906 tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
908 mparms.tf_type = HWRM_TF_TCAM_SET;
909 mparms.req_data = (uint32_t *)&req;
910 mparms.req_size = sizeof(req);
911 mparms.resp_data = (uint32_t *)&resp;
912 mparms.resp_size = sizeof(resp);
913 mparms.mailbox = TF_KONG_MB;
915 rc = tfp_send_msg_direct(tfp,
919 tf_msg_free_dma_buf(&buf);
925 tf_msg_tcam_entry_free(struct tf *tfp,
926 struct tf_tcam_free_parms *in_parms)
929 struct hwrm_tf_tcam_free_input req = { 0 };
930 struct hwrm_tf_tcam_free_output resp = { 0 };
931 struct tfp_send_msg_parms parms = { 0 };
932 uint8_t fw_session_id;
934 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
937 "%s: Unable to lookup FW id, rc:%s\n",
938 tf_dir_2_str(in_parms->dir),
943 /* Populate the request */
944 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
945 req.type = in_parms->hcapi_type;
947 req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
948 if (in_parms->dir == TF_DIR_TX)
949 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
951 parms.tf_type = HWRM_TF_TCAM_FREE;
952 parms.req_data = (uint32_t *)&req;
953 parms.req_size = sizeof(req);
954 parms.resp_data = (uint32_t *)&resp;
955 parms.resp_size = sizeof(resp);
956 parms.mailbox = TF_KONG_MB;
958 rc = tfp_send_msg_direct(tfp,
964 tf_msg_set_tbl_entry(struct tf *tfp,
972 struct hwrm_tf_tbl_type_set_input req = { 0 };
973 struct hwrm_tf_tbl_type_set_output resp = { 0 };
974 struct tfp_send_msg_parms parms = { 0 };
975 uint8_t fw_session_id;
977 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
980 "%s: Unable to lookup FW id, rc:%s\n",
986 /* Populate the request */
987 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
988 req.flags = tfp_cpu_to_le_16(dir);
989 req.type = tfp_cpu_to_le_32(hcapi_type);
990 req.size = tfp_cpu_to_le_16(size);
991 req.index = tfp_cpu_to_le_32(index);
993 /* Check for data size conformity */
994 if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
997 "%s: Invalid parameters for msg type, rc:%s\n",
1003 tfp_memcpy(&req.data,
1007 parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1008 parms.req_data = (uint32_t *)&req;
1009 parms.req_size = sizeof(req);
1010 parms.resp_data = (uint32_t *)&resp;
1011 parms.resp_size = sizeof(resp);
1012 parms.mailbox = TF_KONG_MB;
1014 rc = tfp_send_msg_direct(tfp,
1019 return tfp_le_to_cpu_32(parms.tf_resp_code);
1023 tf_msg_get_tbl_entry(struct tf *tfp,
1025 uint16_t hcapi_type,
1031 struct hwrm_tf_tbl_type_get_input req = { 0 };
1032 struct hwrm_tf_tbl_type_get_output resp = { 0 };
1033 struct tfp_send_msg_parms parms = { 0 };
1034 uint8_t fw_session_id;
1036 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1039 "%s: Unable to lookup FW id, rc:%s\n",
1045 /* Populate the request */
1046 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1047 req.flags = tfp_cpu_to_le_16(dir);
1048 req.type = tfp_cpu_to_le_32(hcapi_type);
1049 req.index = tfp_cpu_to_le_32(index);
1051 parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1052 parms.req_data = (uint32_t *)&req;
1053 parms.req_size = sizeof(req);
1054 parms.resp_data = (uint32_t *)&resp;
1055 parms.resp_size = sizeof(resp);
1056 parms.mailbox = TF_KONG_MB;
1058 rc = tfp_send_msg_direct(tfp,
1063 /* Verify that we got enough buffer to return the requested data */
1064 if (tfp_le_to_cpu_32(resp.size) != size)
1071 return tfp_le_to_cpu_32(parms.tf_resp_code);
1074 /* HWRM Tunneled messages */
1077 tf_msg_get_global_cfg(struct tf *tfp,
1078 struct tf_dev_global_cfg_parms *params)
1081 struct tfp_send_msg_parms parms = { 0 };
1082 struct hwrm_tf_global_cfg_get_input req = { 0 };
1083 struct hwrm_tf_global_cfg_get_output resp = { 0 };
1085 uint8_t fw_session_id;
1086 uint16_t resp_size = 0;
1088 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1091 "%s: Unable to lookup FW id, rc:%s\n",
1092 tf_dir_2_str(params->dir),
1097 flags = (params->dir == TF_DIR_TX ?
1098 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1099 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1101 /* Populate the request */
1102 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1103 req.flags = tfp_cpu_to_le_32(flags);
1104 req.type = tfp_cpu_to_le_32(params->type);
1105 req.offset = tfp_cpu_to_le_32(params->offset);
1106 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1108 parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1109 parms.req_data = (uint32_t *)&req;
1110 parms.req_size = sizeof(req);
1111 parms.resp_data = (uint32_t *)&resp;
1112 parms.resp_size = sizeof(resp);
1113 parms.mailbox = TF_KONG_MB;
1115 rc = tfp_send_msg_direct(tfp, &parms);
1119 /* Verify that we got enough buffer to return the requested data */
1120 resp_size = tfp_le_to_cpu_16(resp.size);
1121 if (resp_size < params->config_sz_in_bytes)
1125 tfp_memcpy(params->config,
1131 return tfp_le_to_cpu_32(parms.tf_resp_code);
1135 tf_msg_set_global_cfg(struct tf *tfp,
1136 struct tf_dev_global_cfg_parms *params)
1139 struct tfp_send_msg_parms parms = { 0 };
1140 struct hwrm_tf_global_cfg_set_input req = { 0 };
1141 struct hwrm_tf_global_cfg_set_output resp = { 0 };
1143 uint8_t fw_session_id;
1145 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1148 "%s: Unable to lookup FW id, rc:%s\n",
1149 tf_dir_2_str(params->dir),
1154 flags = (params->dir == TF_DIR_TX ?
1155 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
1156 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
1158 /* Populate the request */
1159 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1160 req.flags = tfp_cpu_to_le_32(flags);
1161 req.type = tfp_cpu_to_le_32(params->type);
1162 req.offset = tfp_cpu_to_le_32(params->offset);
1164 /* Check for data size conformity */
1165 if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
1168 "%s: Invalid parameters for msg type, rc:%s\n",
1169 tf_dir_2_str(params->dir),
1174 tfp_memcpy(req.data, params->config,
1175 params->config_sz_in_bytes);
1176 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1178 parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
1179 parms.req_data = (uint32_t *)&req;
1180 parms.req_size = sizeof(req);
1181 parms.resp_data = (uint32_t *)&resp;
1182 parms.resp_size = sizeof(resp);
1183 parms.mailbox = TF_KONG_MB;
1185 rc = tfp_send_msg_direct(tfp, &parms);
1190 return tfp_le_to_cpu_32(parms.tf_resp_code);
1194 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
1196 uint16_t hcapi_type,
1197 uint32_t starting_idx,
1198 uint16_t num_entries,
1199 uint16_t entry_sz_in_bytes,
1200 uint64_t physical_mem_addr)
1203 struct tfp_send_msg_parms parms = { 0 };
1204 struct tf_tbl_type_bulk_get_input req = { 0 };
1205 struct tf_tbl_type_bulk_get_output resp = { 0 };
1207 uint8_t fw_session_id;
1209 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1212 "%s: Unable to lookup FW id, rc:%s\n",
1218 /* Populate the request */
1219 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1220 req.flags = tfp_cpu_to_le_16(dir);
1221 req.type = tfp_cpu_to_le_32(hcapi_type);
1222 req.start_index = tfp_cpu_to_le_32(starting_idx);
1223 req.num_entries = tfp_cpu_to_le_32(num_entries);
1225 data_size = num_entries * entry_sz_in_bytes;
1227 req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1232 HWRM_TFT_TBL_TYPE_BULK_GET,
1236 rc = tfp_send_msg_tunneled(tfp, &parms);
1240 /* Verify that we got enough buffer to return the requested data */
1241 if (tfp_le_to_cpu_32(resp.size) != data_size)
1244 return tfp_le_to_cpu_32(parms.tf_resp_code);
1248 tf_msg_get_if_tbl_entry(struct tf *tfp,
1249 struct tf_if_tbl_get_parms *params)
1252 struct tfp_send_msg_parms parms = { 0 };
1253 struct hwrm_tf_if_tbl_get_input req = { 0 };
1254 struct hwrm_tf_if_tbl_get_output resp = { 0 };
1256 struct tf_session *tfs;
1258 /* Retrieve the session information */
1259 rc = tf_session_get_session(tfp, &tfs);
1262 "%s: Failed to lookup session, rc:%s\n",
1263 tf_dir_2_str(params->dir),
1268 flags = (params->dir == TF_DIR_TX ?
1269 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
1270 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
1272 /* Populate the request */
1274 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1276 req.type = params->hcapi_type;
1277 req.index = tfp_cpu_to_le_16(params->idx);
1278 req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1280 parms.tf_type = HWRM_TF_IF_TBL_GET;
1281 parms.req_data = (uint32_t *)&req;
1282 parms.req_size = sizeof(req);
1283 parms.resp_data = (uint32_t *)&resp;
1284 parms.resp_size = sizeof(resp);
1285 parms.mailbox = TF_KONG_MB;
1287 rc = tfp_send_msg_direct(tfp, &parms);
1292 if (parms.tf_resp_code != 0)
1293 return tfp_le_to_cpu_32(parms.tf_resp_code);
1295 tfp_memcpy(¶ms->data[0], resp.data, req.size);
1297 return tfp_le_to_cpu_32(parms.tf_resp_code);
1301 tf_msg_set_if_tbl_entry(struct tf *tfp,
1302 struct tf_if_tbl_set_parms *params)
1305 struct tfp_send_msg_parms parms = { 0 };
1306 struct hwrm_tf_if_tbl_set_input req = { 0 };
1307 struct hwrm_tf_if_tbl_get_output resp = { 0 };
1309 struct tf_session *tfs;
1311 /* Retrieve the session information */
1312 rc = tf_session_get_session(tfp, &tfs);
1315 "%s: Failed to lookup session, rc:%s\n",
1316 tf_dir_2_str(params->dir),
1322 flags = (params->dir == TF_DIR_TX ?
1323 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1324 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1326 /* Populate the request */
1328 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1330 req.type = params->hcapi_type;
1331 req.index = tfp_cpu_to_le_32(params->idx);
1332 req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1333 tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1335 parms.tf_type = HWRM_TF_IF_TBL_SET;
1336 parms.req_data = (uint32_t *)&req;
1337 parms.req_size = sizeof(req);
1338 parms.resp_data = (uint32_t *)&resp;
1339 parms.resp_size = sizeof(resp);
1340 parms.mailbox = TF_KONG_MB;
1342 rc = tfp_send_msg_direct(tfp, &parms);
1347 return tfp_le_to_cpu_32(parms.tf_resp_code);