1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2020 Broadcom
11 #include "tf_msg_common.h"
12 #include "tf_device.h"
15 #include "tf_common.h"
16 #include "tf_session.h"
22 #define TF_RM_MSG_DEBUG 0
25 * This is the MAX data we can transport across regular HWRM
27 #define TF_PCI_BUF_SIZE_MAX 88
30 * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
32 struct tf_msg_dma_buf {
38 * Allocates a DMA buffer that can be used for message transfer.
41 * Pointer to DMA buffer structure
44 * Requested size of the buffer in bytes
48 * -ENOMEM - Unable to allocate buffer, no memory
51 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
53 struct tfp_calloc_parms alloc_parms;
56 /* Allocate session */
57 alloc_parms.nitems = 1;
58 alloc_parms.size = size;
59 alloc_parms.alignment = 4096;
60 rc = tfp_calloc(&alloc_parms);
64 buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
65 buf->va_addr = alloc_parms.mem_va;
71 * Free's a previous allocated DMA buffer.
74 * Pointer to DMA buffer structure
77 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
79 tfp_free(buf->va_addr);
82 /* HWRM Direct messages */
85 tf_msg_session_open(struct tf *tfp,
87 uint8_t *fw_session_id,
88 uint8_t *fw_session_client_id)
91 struct hwrm_tf_session_open_input req = { 0 };
92 struct hwrm_tf_session_open_output resp = { 0 };
93 struct tfp_send_msg_parms parms = { 0 };
95 /* Populate the request */
96 tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
98 parms.tf_type = HWRM_TF_SESSION_OPEN;
99 parms.req_data = (uint32_t *)&req;
100 parms.req_size = sizeof(req);
101 parms.resp_data = (uint32_t *)&resp;
102 parms.resp_size = sizeof(resp);
103 parms.mailbox = TF_KONG_MB;
105 rc = tfp_send_msg_direct(tfp,
110 *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
111 *fw_session_client_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
117 tf_msg_session_attach(struct tf *tfp __rte_unused,
118 char *ctrl_chan_name __rte_unused,
119 uint8_t tf_fw_session_id __rte_unused)
125 tf_msg_session_client_register(struct tf *tfp,
126 char *ctrl_channel_name,
127 uint8_t *fw_session_client_id)
130 struct hwrm_tf_session_register_input req = { 0 };
131 struct hwrm_tf_session_register_output resp = { 0 };
132 struct tfp_send_msg_parms parms = { 0 };
133 uint8_t fw_session_id;
135 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
138 "Unable to lookup FW id, rc:%s\n",
143 /* Populate the request */
144 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
145 tfp_memcpy(&req.session_client_name,
147 TF_SESSION_NAME_MAX);
149 parms.tf_type = HWRM_TF_SESSION_REGISTER;
150 parms.req_data = (uint32_t *)&req;
151 parms.req_size = sizeof(req);
152 parms.resp_data = (uint32_t *)&resp;
153 parms.resp_size = sizeof(resp);
154 parms.mailbox = TF_KONG_MB;
156 rc = tfp_send_msg_direct(tfp,
161 *fw_session_client_id =
162 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
168 tf_msg_session_client_unregister(struct tf *tfp,
169 uint8_t fw_session_client_id)
172 struct hwrm_tf_session_unregister_input req = { 0 };
173 struct hwrm_tf_session_unregister_output resp = { 0 };
174 struct tfp_send_msg_parms parms = { 0 };
175 uint8_t fw_session_id;
177 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
180 "Unable to lookup FW id, rc:%s\n",
185 /* Populate the request */
186 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
187 req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
189 parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
190 parms.req_data = (uint32_t *)&req;
191 parms.req_size = sizeof(req);
192 parms.resp_data = (uint32_t *)&resp;
193 parms.resp_size = sizeof(resp);
194 parms.mailbox = TF_KONG_MB;
196 rc = tfp_send_msg_direct(tfp,
203 tf_msg_session_close(struct tf *tfp)
206 struct hwrm_tf_session_close_input req = { 0 };
207 struct hwrm_tf_session_close_output resp = { 0 };
208 struct tfp_send_msg_parms parms = { 0 };
209 uint8_t fw_session_id;
211 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
214 "Unable to lookup FW id, rc:%s\n",
219 /* Populate the request */
220 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
222 parms.tf_type = HWRM_TF_SESSION_CLOSE;
223 parms.req_data = (uint32_t *)&req;
224 parms.req_size = sizeof(req);
225 parms.resp_data = (uint32_t *)&resp;
226 parms.resp_size = sizeof(resp);
227 parms.mailbox = TF_KONG_MB;
229 rc = tfp_send_msg_direct(tfp,
235 tf_msg_session_qcfg(struct tf *tfp)
238 struct hwrm_tf_session_qcfg_input req = { 0 };
239 struct hwrm_tf_session_qcfg_output resp = { 0 };
240 struct tfp_send_msg_parms parms = { 0 };
241 uint8_t fw_session_id;
243 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
246 "Unable to lookup FW id, rc:%s\n",
251 /* Populate the request */
252 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
254 parms.tf_type = HWRM_TF_SESSION_QCFG,
255 parms.req_data = (uint32_t *)&req;
256 parms.req_size = sizeof(req);
257 parms.resp_data = (uint32_t *)&resp;
258 parms.resp_size = sizeof(resp);
259 parms.mailbox = TF_KONG_MB;
261 rc = tfp_send_msg_direct(tfp,
267 tf_msg_session_resc_qcaps(struct tf *tfp,
270 struct tf_rm_resc_req_entry *query,
271 enum tf_rm_resc_resv_strategy *resv_strategy)
275 struct tfp_send_msg_parms parms = { 0 };
276 struct hwrm_tf_session_resc_qcaps_input req = { 0 };
277 struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
278 uint8_t fw_session_id;
279 struct tf_msg_dma_buf qcaps_buf = { 0 };
280 struct tf_rm_resc_req_entry *data;
283 TF_CHECK_PARMS3(tfp, query, resv_strategy);
285 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
288 "%s: Unable to lookup FW id, rc:%s\n",
294 /* Prepare DMA buffer */
295 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
296 rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
300 /* Populate the request */
301 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
302 req.flags = tfp_cpu_to_le_16(dir);
303 req.qcaps_size = size;
304 req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
306 parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
307 parms.req_data = (uint32_t *)&req;
308 parms.req_size = sizeof(req);
309 parms.resp_data = (uint32_t *)&resp;
310 parms.resp_size = sizeof(resp);
311 parms.mailbox = TF_KONG_MB;
313 rc = tfp_send_msg_direct(tfp, &parms);
317 /* Process the response
318 * Should always get expected number of entries
320 if (tfp_le_to_cpu_32(resp.size) != size) {
322 "%s: QCAPS message size error, rc:%s\n",
329 #if (TF_RM_MSG_DEBUG == 1)
330 printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
331 #endif /* (TF_RM_MSG_DEBUG == 1) */
333 /* Post process the response */
334 data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
336 #if (TF_RM_MSG_DEBUG == 1)
338 #endif /* (TF_RM_MSG_DEBUG == 1) */
339 for (i = 0; i < size; i++) {
340 query[i].type = tfp_le_to_cpu_32(data[i].type);
341 query[i].min = tfp_le_to_cpu_16(data[i].min);
342 query[i].max = tfp_le_to_cpu_16(data[i].max);
344 #if (TF_RM_MSG_DEBUG == 1)
345 printf("type: %d(0x%x) %d %d\n",
350 #endif /* (TF_RM_MSG_DEBUG == 1) */
354 *resv_strategy = resp.flags &
355 HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
358 tf_msg_free_dma_buf(&qcaps_buf);
364 tf_msg_session_resc_alloc(struct tf *tfp,
367 struct tf_rm_resc_req_entry *request,
368 struct tf_rm_resc_entry *resv)
372 struct tfp_send_msg_parms parms = { 0 };
373 struct hwrm_tf_session_resc_alloc_input req = { 0 };
374 struct hwrm_tf_session_resc_alloc_output resp = { 0 };
375 uint8_t fw_session_id;
376 struct tf_msg_dma_buf req_buf = { 0 };
377 struct tf_msg_dma_buf resv_buf = { 0 };
378 struct tf_rm_resc_req_entry *req_data;
379 struct tf_rm_resc_entry *resv_data;
382 TF_CHECK_PARMS3(tfp, request, resv);
384 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
387 "%s: Unable to lookup FW id, rc:%s\n",
393 /* Prepare DMA buffers */
394 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
395 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
399 dma_size = size * sizeof(struct tf_rm_resc_entry);
400 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
402 tf_msg_free_dma_buf(&req_buf);
406 /* Populate the request */
407 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
408 req.flags = tfp_cpu_to_le_16(dir);
411 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
412 for (i = 0; i < size; i++) {
413 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
414 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
415 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
418 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
419 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
421 parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
422 parms.req_data = (uint32_t *)&req;
423 parms.req_size = sizeof(req);
424 parms.resp_data = (uint32_t *)&resp;
425 parms.resp_size = sizeof(resp);
426 parms.mailbox = TF_KONG_MB;
428 rc = tfp_send_msg_direct(tfp, &parms);
432 /* Process the response
433 * Should always get expected number of entries
435 if (tfp_le_to_cpu_32(resp.size) != size) {
437 "%s: Alloc message size error, rc:%s\n",
444 #if (TF_RM_MSG_DEBUG == 1)
446 printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
447 #endif /* (TF_RM_MSG_DEBUG == 1) */
449 /* Post process the response */
450 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
451 for (i = 0; i < size; i++) {
452 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
453 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
454 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
456 #if (TF_RM_MSG_DEBUG == 1)
457 printf("%d type: %d(0x%x) %d %d\n",
463 #endif /* (TF_RM_MSG_DEBUG == 1) */
467 tf_msg_free_dma_buf(&req_buf);
468 tf_msg_free_dma_buf(&resv_buf);
474 tf_msg_session_resc_flush(struct tf *tfp,
477 struct tf_rm_resc_entry *resv)
481 struct tfp_send_msg_parms parms = { 0 };
482 struct hwrm_tf_session_resc_flush_input req = { 0 };
483 struct hwrm_tf_session_resc_flush_output resp = { 0 };
484 uint8_t fw_session_id;
485 struct tf_msg_dma_buf resv_buf = { 0 };
486 struct tf_rm_resc_entry *resv_data;
489 TF_CHECK_PARMS2(tfp, resv);
491 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
494 "%s: Unable to lookup FW id, rc:%s\n",
500 /* Prepare DMA buffers */
501 dma_size = size * sizeof(struct tf_rm_resc_entry);
502 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
506 /* Populate the request */
507 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
508 req.flags = tfp_cpu_to_le_16(dir);
509 req.flush_size = size;
511 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
512 for (i = 0; i < size; i++) {
513 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
514 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
515 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
518 req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
520 parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
521 parms.req_data = (uint32_t *)&req;
522 parms.req_size = sizeof(req);
523 parms.resp_data = (uint32_t *)&resp;
524 parms.resp_size = sizeof(resp);
525 parms.mailbox = TF_KONG_MB;
527 rc = tfp_send_msg_direct(tfp, &parms);
529 tf_msg_free_dma_buf(&resv_buf);
535 tf_msg_insert_em_internal_entry(struct tf *tfp,
536 struct tf_insert_em_entry_parms *em_parms,
537 uint16_t *rptr_index,
539 uint8_t *num_of_entries)
542 struct tfp_send_msg_parms parms = { 0 };
543 struct hwrm_tf_em_insert_input req = { 0 };
544 struct hwrm_tf_em_insert_output resp = { 0 };
545 struct tf_em_64b_entry *em_result =
546 (struct tf_em_64b_entry *)em_parms->em_record;
548 uint8_t fw_session_id;
550 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
553 "%s: Unable to lookup FW id, rc:%s\n",
554 tf_dir_2_str(em_parms->dir),
559 /* Populate the request */
560 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
561 tfp_memcpy(req.em_key,
563 ((em_parms->key_sz_in_bits + 7) / 8));
565 flags = (em_parms->dir == TF_DIR_TX ?
566 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
567 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
568 req.flags = tfp_cpu_to_le_16(flags);
569 req.strength = (em_result->hdr.word1 &
570 CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
571 CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
572 req.em_key_bitlen = em_parms->key_sz_in_bits;
573 req.action_ptr = em_result->hdr.pointer;
574 req.em_record_idx = *rptr_index;
576 parms.tf_type = HWRM_TF_EM_INSERT;
577 parms.req_data = (uint32_t *)&req;
578 parms.req_size = sizeof(req);
579 parms.resp_data = (uint32_t *)&resp;
580 parms.resp_size = sizeof(resp);
581 parms.mailbox = TF_KONG_MB;
583 rc = tfp_send_msg_direct(tfp,
588 *rptr_entry = resp.rptr_entry;
589 *rptr_index = resp.rptr_index;
590 *num_of_entries = resp.num_of_entries;
596 tf_msg_delete_em_entry(struct tf *tfp,
597 struct tf_delete_em_entry_parms *em_parms)
600 struct tfp_send_msg_parms parms = { 0 };
601 struct hwrm_tf_em_delete_input req = { 0 };
602 struct hwrm_tf_em_delete_output resp = { 0 };
604 uint8_t fw_session_id;
606 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
609 "%s: Unable to lookup FW id, rc:%s\n",
610 tf_dir_2_str(em_parms->dir),
615 /* Populate the request */
616 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
618 flags = (em_parms->dir == TF_DIR_TX ?
619 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
620 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
621 req.flags = tfp_cpu_to_le_16(flags);
622 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
624 parms.tf_type = HWRM_TF_EM_DELETE;
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 em_parms->index = tfp_le_to_cpu_16(resp.em_index);
642 tf_msg_em_mem_rgtr(struct tf *tfp,
649 struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
650 struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
651 struct tfp_send_msg_parms parms = { 0 };
653 req.page_level = page_lvl;
654 req.page_size = page_size;
655 req.page_dir = tfp_cpu_to_le_64(dma_addr);
657 parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
658 parms.req_data = (uint32_t *)&req;
659 parms.req_size = sizeof(req);
660 parms.resp_data = (uint32_t *)&resp;
661 parms.resp_size = sizeof(resp);
662 parms.mailbox = TF_KONG_MB;
664 rc = tfp_send_msg_direct(tfp,
669 *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
675 tf_msg_em_mem_unrgtr(struct tf *tfp,
679 struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
680 struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
681 struct tfp_send_msg_parms parms = { 0 };
683 req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
685 parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
686 parms.req_data = (uint32_t *)&req;
687 parms.req_size = sizeof(req);
688 parms.resp_data = (uint32_t *)&resp;
689 parms.resp_size = sizeof(resp);
690 parms.mailbox = TF_KONG_MB;
692 rc = tfp_send_msg_direct(tfp,
698 tf_msg_em_qcaps(struct tf *tfp,
700 struct tf_em_caps *em_caps)
703 struct hwrm_tf_ext_em_qcaps_input req = {0};
704 struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
706 struct tfp_send_msg_parms parms = { 0 };
708 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
709 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
710 req.flags = tfp_cpu_to_le_32(flags);
712 parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
713 parms.req_data = (uint32_t *)&req;
714 parms.req_size = sizeof(req);
715 parms.resp_data = (uint32_t *)&resp;
716 parms.resp_size = sizeof(resp);
717 parms.mailbox = TF_KONG_MB;
719 rc = tfp_send_msg_direct(tfp,
724 em_caps->supported = tfp_le_to_cpu_32(resp.supported);
725 em_caps->max_entries_supported =
726 tfp_le_to_cpu_32(resp.max_entries_supported);
727 em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
728 em_caps->record_entry_size =
729 tfp_le_to_cpu_16(resp.record_entry_size);
730 em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
736 tf_msg_em_cfg(struct tf *tfp,
737 uint32_t num_entries,
738 uint16_t key0_ctx_id,
739 uint16_t key1_ctx_id,
740 uint16_t record_ctx_id,
742 uint8_t flush_interval,
746 struct hwrm_tf_ext_em_cfg_input req = {0};
747 struct hwrm_tf_ext_em_cfg_output resp = {0};
749 struct tfp_send_msg_parms parms = { 0 };
751 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
752 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
753 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
755 req.flags = tfp_cpu_to_le_32(flags);
756 req.num_entries = tfp_cpu_to_le_32(num_entries);
758 req.flush_interval = flush_interval;
760 req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
761 req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
762 req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
763 req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
765 parms.tf_type = HWRM_TF_EXT_EM_CFG;
766 parms.req_data = (uint32_t *)&req;
767 parms.req_size = sizeof(req);
768 parms.resp_data = (uint32_t *)&resp;
769 parms.resp_size = sizeof(resp);
770 parms.mailbox = TF_KONG_MB;
772 rc = tfp_send_msg_direct(tfp,
778 tf_msg_em_op(struct tf *tfp,
783 struct hwrm_tf_ext_em_op_input req = {0};
784 struct hwrm_tf_ext_em_op_output resp = {0};
786 struct tfp_send_msg_parms parms = { 0 };
788 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
789 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
790 req.flags = tfp_cpu_to_le_32(flags);
791 req.op = tfp_cpu_to_le_16(op);
793 parms.tf_type = HWRM_TF_EXT_EM_OP;
794 parms.req_data = (uint32_t *)&req;
795 parms.req_size = sizeof(req);
796 parms.resp_data = (uint32_t *)&resp;
797 parms.resp_size = sizeof(resp);
798 parms.mailbox = TF_KONG_MB;
800 rc = tfp_send_msg_direct(tfp,
806 tf_msg_tcam_entry_set(struct tf *tfp,
807 struct tf_tcam_set_parms *parms)
810 struct tfp_send_msg_parms mparms = { 0 };
811 struct hwrm_tf_tcam_set_input req = { 0 };
812 struct hwrm_tf_tcam_set_output resp = { 0 };
813 struct tf_msg_dma_buf buf = { 0 };
814 uint8_t *data = NULL;
817 req.type = parms->hcapi_type;
818 req.idx = tfp_cpu_to_le_16(parms->idx);
819 if (parms->dir == TF_DIR_TX)
820 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
822 req.key_size = parms->key_size;
823 req.mask_offset = parms->key_size;
824 /* Result follows after key and mask, thus multiply by 2 */
825 req.result_offset = 2 * parms->key_size;
826 req.result_size = parms->result_size;
827 data_size = 2 * req.key_size + req.result_size;
829 if (data_size <= TF_PCI_BUF_SIZE_MAX) {
831 data = &req.dev_data[0];
834 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
835 rc = tf_msg_alloc_dma_buf(&buf, data_size);
839 tfp_memcpy(&req.dev_data[0],
841 sizeof(buf.pa_addr));
844 tfp_memcpy(&data[0], parms->key, parms->key_size);
845 tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
846 tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
848 mparms.tf_type = HWRM_TF_TCAM_SET;
849 mparms.req_data = (uint32_t *)&req;
850 mparms.req_size = sizeof(req);
851 mparms.resp_data = (uint32_t *)&resp;
852 mparms.resp_size = sizeof(resp);
853 mparms.mailbox = TF_KONG_MB;
855 rc = tfp_send_msg_direct(tfp,
859 tf_msg_free_dma_buf(&buf);
865 tf_msg_tcam_entry_free(struct tf *tfp,
866 struct tf_tcam_free_parms *in_parms)
869 struct hwrm_tf_tcam_free_input req = { 0 };
870 struct hwrm_tf_tcam_free_output resp = { 0 };
871 struct tfp_send_msg_parms parms = { 0 };
873 req.type = in_parms->hcapi_type;
875 req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
876 if (in_parms->dir == TF_DIR_TX)
877 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
879 parms.tf_type = HWRM_TF_TCAM_FREE;
880 parms.req_data = (uint32_t *)&req;
881 parms.req_size = sizeof(req);
882 parms.resp_data = (uint32_t *)&resp;
883 parms.resp_size = sizeof(resp);
884 parms.mailbox = TF_KONG_MB;
886 rc = tfp_send_msg_direct(tfp,
892 tf_msg_set_tbl_entry(struct tf *tfp,
900 struct hwrm_tf_tbl_type_set_input req = { 0 };
901 struct hwrm_tf_tbl_type_set_output resp = { 0 };
902 struct tfp_send_msg_parms parms = { 0 };
903 uint8_t fw_session_id;
905 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
908 "%s: Unable to lookup FW id, rc:%s\n",
914 /* Populate the request */
915 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
916 req.flags = tfp_cpu_to_le_16(dir);
917 req.type = tfp_cpu_to_le_32(hcapi_type);
918 req.size = tfp_cpu_to_le_16(size);
919 req.index = tfp_cpu_to_le_32(index);
921 tfp_memcpy(&req.data,
925 parms.tf_type = HWRM_TF_TBL_TYPE_SET;
926 parms.req_data = (uint32_t *)&req;
927 parms.req_size = sizeof(req);
928 parms.resp_data = (uint32_t *)&resp;
929 parms.resp_size = sizeof(resp);
930 parms.mailbox = TF_KONG_MB;
932 rc = tfp_send_msg_direct(tfp,
937 return tfp_le_to_cpu_32(parms.tf_resp_code);
941 tf_msg_get_tbl_entry(struct tf *tfp,
949 struct hwrm_tf_tbl_type_get_input req = { 0 };
950 struct hwrm_tf_tbl_type_get_output resp = { 0 };
951 struct tfp_send_msg_parms parms = { 0 };
952 uint8_t fw_session_id;
954 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
957 "%s: Unable to lookup FW id, rc:%s\n",
963 /* Populate the request */
964 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
965 req.flags = tfp_cpu_to_le_16(dir);
966 req.type = tfp_cpu_to_le_32(hcapi_type);
967 req.index = tfp_cpu_to_le_32(index);
969 parms.tf_type = HWRM_TF_TBL_TYPE_GET;
970 parms.req_data = (uint32_t *)&req;
971 parms.req_size = sizeof(req);
972 parms.resp_data = (uint32_t *)&resp;
973 parms.resp_size = sizeof(resp);
974 parms.mailbox = TF_KONG_MB;
976 rc = tfp_send_msg_direct(tfp,
981 /* Verify that we got enough buffer to return the requested data */
982 if (tfp_le_to_cpu_32(resp.size) != size)
989 return tfp_le_to_cpu_32(parms.tf_resp_code);
992 /* HWRM Tunneled messages */
995 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
998 uint32_t starting_idx,
999 uint16_t num_entries,
1000 uint16_t entry_sz_in_bytes,
1001 uint64_t physical_mem_addr)
1004 struct tfp_send_msg_parms parms = { 0 };
1005 struct tf_tbl_type_bulk_get_input req = { 0 };
1006 struct tf_tbl_type_bulk_get_output resp = { 0 };
1008 uint8_t fw_session_id;
1010 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1013 "%s: Unable to lookup FW id, rc:%s\n",
1019 /* Populate the request */
1020 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1021 req.flags = tfp_cpu_to_le_16(dir);
1022 req.type = tfp_cpu_to_le_32(hcapi_type);
1023 req.start_index = tfp_cpu_to_le_32(starting_idx);
1024 req.num_entries = tfp_cpu_to_le_32(num_entries);
1026 data_size = num_entries * entry_sz_in_bytes;
1028 req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1033 HWRM_TFT_TBL_TYPE_BULK_GET,
1037 rc = tfp_send_msg_tunneled(tfp, &parms);
1041 /* Verify that we got enough buffer to return the requested data */
1042 if (tfp_le_to_cpu_32(resp.size) != data_size)
1045 return tfp_le_to_cpu_32(parms.tf_resp_code);
1049 tf_msg_get_if_tbl_entry(struct tf *tfp,
1050 struct tf_if_tbl_get_parms *params)
1053 struct tfp_send_msg_parms parms = { 0 };
1054 tf_if_tbl_get_input_t req = { 0 };
1055 tf_if_tbl_get_output_t resp;
1057 struct tf_session *tfs;
1059 /* Retrieve the session information */
1060 rc = tf_session_get_session(tfp, &tfs);
1063 "%s: Failed to lookup session, rc:%s\n",
1064 tf_dir_2_str(params->dir),
1069 flags = (params->dir == TF_DIR_TX ? TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1070 TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1072 /* Populate the request */
1074 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1076 req.tf_if_tbl_type = params->hcapi_type;
1077 req.idx = tfp_cpu_to_le_16(params->idx);
1078 req.data_sz_in_bytes = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1083 HWRM_TFT_IF_TBL_GET,
1087 rc = tfp_send_msg_tunneled(tfp, &parms);
1092 if (parms.tf_resp_code != 0)
1093 return tfp_le_to_cpu_32(parms.tf_resp_code);
1095 tfp_memcpy(¶ms->data[0], resp.data, req.data_sz_in_bytes);
1097 return tfp_le_to_cpu_32(parms.tf_resp_code);
1101 tf_msg_set_if_tbl_entry(struct tf *tfp,
1102 struct tf_if_tbl_set_parms *params)
1105 struct tfp_send_msg_parms parms = { 0 };
1106 tf_if_tbl_set_input_t req = { 0 };
1108 struct tf_session *tfs;
1110 /* Retrieve the session information */
1111 rc = tf_session_get_session(tfp, &tfs);
1114 "%s: Failed to lookup session, rc:%s\n",
1115 tf_dir_2_str(params->dir),
1121 flags = (params->dir == TF_DIR_TX ? TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1122 TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1124 /* Populate the request */
1126 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1128 req.tf_if_tbl_type = params->hcapi_type;
1129 req.idx = tfp_cpu_to_le_32(params->idx);
1130 req.data_sz_in_bytes = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1131 tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1133 MSG_PREP_NO_RESP(parms,
1136 HWRM_TFT_IF_TBL_SET,
1139 rc = tfp_send_msg_tunneled(tfp, &parms);
1144 return tfp_le_to_cpu_32(parms.tf_resp_code);