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 8
31 #define TF_MSG_TCAM_SET_DEV_DATA_SIZE 88
32 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE 88
34 /* Compile check - Catch any msg changes that we depend on, like the
35 * defines listed above for array size checking.
37 * Checking array size is dangerous in that the type could change and
38 * we wouldn't be able to catch it. Thus we check if the complete msg
39 * changed instead. Best we can do.
41 * If failure is observed then both msg size (defines below) and the
42 * array size (define above) should be checked and compared.
44 #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56
45 static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
46 TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET,
47 "HWRM message size changed: hwrm_tf_global_cfg_set_input");
49 #define TF_MSG_SIZE_HWRM_TF_EM_INSERT 104
50 static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
51 TF_MSG_SIZE_HWRM_TF_EM_INSERT,
52 "HWRM message size changed: hwrm_tf_em_insert_input");
54 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET 128
55 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
56 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
57 "HWRM message size changed: hwrm_tf_tbl_type_set_input");
60 * This is the MAX data we can transport across regular HWRM
62 #define TF_PCI_BUF_SIZE_MAX 88
65 * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
67 struct tf_msg_dma_buf {
73 * Allocates a DMA buffer that can be used for message transfer.
76 * Pointer to DMA buffer structure
79 * Requested size of the buffer in bytes
83 * -ENOMEM - Unable to allocate buffer, no memory
86 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
88 struct tfp_calloc_parms alloc_parms;
91 /* Allocate session */
92 alloc_parms.nitems = 1;
93 alloc_parms.size = size;
94 alloc_parms.alignment = 4096;
95 rc = tfp_calloc(&alloc_parms);
99 buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
100 buf->va_addr = alloc_parms.mem_va;
106 * Free's a previous allocated DMA buffer.
109 * Pointer to DMA buffer structure
112 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
114 tfp_free(buf->va_addr);
117 /* HWRM Direct messages */
120 tf_msg_session_open(struct tf *tfp,
121 char *ctrl_chan_name,
122 uint8_t *fw_session_id,
123 uint8_t *fw_session_client_id)
126 struct hwrm_tf_session_open_input req = { 0 };
127 struct hwrm_tf_session_open_output resp = { 0 };
128 struct tfp_send_msg_parms parms = { 0 };
130 /* Populate the request */
131 tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
133 parms.tf_type = HWRM_TF_SESSION_OPEN;
134 parms.req_data = (uint32_t *)&req;
135 parms.req_size = sizeof(req);
136 parms.resp_data = (uint32_t *)&resp;
137 parms.resp_size = sizeof(resp);
138 parms.mailbox = TF_KONG_MB;
140 rc = tfp_send_msg_direct(tfp,
145 *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
146 *fw_session_client_id =
147 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
153 tf_msg_session_attach(struct tf *tfp __rte_unused,
154 char *ctrl_chan_name __rte_unused,
155 uint8_t tf_fw_session_id __rte_unused)
161 tf_msg_session_client_register(struct tf *tfp,
162 char *ctrl_channel_name,
163 uint8_t *fw_session_client_id)
166 struct hwrm_tf_session_register_input req = { 0 };
167 struct hwrm_tf_session_register_output resp = { 0 };
168 struct tfp_send_msg_parms parms = { 0 };
169 uint8_t fw_session_id;
171 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
174 "Unable to lookup FW id, rc:%s\n",
179 /* Populate the request */
180 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
181 tfp_memcpy(&req.session_client_name,
183 TF_SESSION_NAME_MAX);
185 parms.tf_type = HWRM_TF_SESSION_REGISTER;
186 parms.req_data = (uint32_t *)&req;
187 parms.req_size = sizeof(req);
188 parms.resp_data = (uint32_t *)&resp;
189 parms.resp_size = sizeof(resp);
190 parms.mailbox = TF_KONG_MB;
192 rc = tfp_send_msg_direct(tfp,
197 *fw_session_client_id =
198 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
204 tf_msg_session_client_unregister(struct tf *tfp,
205 uint8_t fw_session_client_id)
208 struct hwrm_tf_session_unregister_input req = { 0 };
209 struct hwrm_tf_session_unregister_output resp = { 0 };
210 struct tfp_send_msg_parms parms = { 0 };
211 uint8_t fw_session_id;
213 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
216 "Unable to lookup FW id, rc:%s\n",
221 /* Populate the request */
222 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
223 req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
225 parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
226 parms.req_data = (uint32_t *)&req;
227 parms.req_size = sizeof(req);
228 parms.resp_data = (uint32_t *)&resp;
229 parms.resp_size = sizeof(resp);
230 parms.mailbox = TF_KONG_MB;
232 rc = tfp_send_msg_direct(tfp,
239 tf_msg_session_close(struct tf *tfp)
242 struct hwrm_tf_session_close_input req = { 0 };
243 struct hwrm_tf_session_close_output resp = { 0 };
244 struct tfp_send_msg_parms parms = { 0 };
245 uint8_t fw_session_id;
247 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
250 "Unable to lookup FW id, rc:%s\n",
255 /* Populate the request */
256 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
258 parms.tf_type = HWRM_TF_SESSION_CLOSE;
259 parms.req_data = (uint32_t *)&req;
260 parms.req_size = sizeof(req);
261 parms.resp_data = (uint32_t *)&resp;
262 parms.resp_size = sizeof(resp);
263 parms.mailbox = TF_KONG_MB;
265 rc = tfp_send_msg_direct(tfp,
271 tf_msg_session_qcfg(struct tf *tfp)
274 struct hwrm_tf_session_qcfg_input req = { 0 };
275 struct hwrm_tf_session_qcfg_output resp = { 0 };
276 struct tfp_send_msg_parms parms = { 0 };
277 uint8_t fw_session_id;
279 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
282 "Unable to lookup FW id, rc:%s\n",
287 /* Populate the request */
288 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
290 parms.tf_type = HWRM_TF_SESSION_QCFG,
291 parms.req_data = (uint32_t *)&req;
292 parms.req_size = sizeof(req);
293 parms.resp_data = (uint32_t *)&resp;
294 parms.resp_size = sizeof(resp);
295 parms.mailbox = TF_KONG_MB;
297 rc = tfp_send_msg_direct(tfp,
303 tf_msg_session_resc_qcaps(struct tf *tfp,
306 struct tf_rm_resc_req_entry *query,
307 enum tf_rm_resc_resv_strategy *resv_strategy)
311 struct tfp_send_msg_parms parms = { 0 };
312 struct hwrm_tf_session_resc_qcaps_input req = { 0 };
313 struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
314 uint8_t fw_session_id;
315 struct tf_msg_dma_buf qcaps_buf = { 0 };
316 struct tf_rm_resc_req_entry *data;
319 TF_CHECK_PARMS3(tfp, query, resv_strategy);
321 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
324 "%s: Unable to lookup FW id, rc:%s\n",
330 /* Prepare DMA buffer */
331 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
332 rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
336 /* Populate the request */
337 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
338 req.flags = tfp_cpu_to_le_16(dir);
339 req.qcaps_size = size;
340 req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
342 parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
343 parms.req_data = (uint32_t *)&req;
344 parms.req_size = sizeof(req);
345 parms.resp_data = (uint32_t *)&resp;
346 parms.resp_size = sizeof(resp);
347 parms.mailbox = TF_KONG_MB;
349 rc = tfp_send_msg_direct(tfp, &parms);
353 /* Process the response
354 * Should always get expected number of entries
356 if (tfp_le_to_cpu_32(resp.size) != size) {
358 "%s: QCAPS message size error, rc:%s\n",
365 #if (TF_RM_MSG_DEBUG == 1)
366 printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
367 #endif /* (TF_RM_MSG_DEBUG == 1) */
369 /* Post process the response */
370 data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
372 #if (TF_RM_MSG_DEBUG == 1)
374 #endif /* (TF_RM_MSG_DEBUG == 1) */
375 for (i = 0; i < size; i++) {
376 query[i].type = tfp_le_to_cpu_32(data[i].type);
377 query[i].min = tfp_le_to_cpu_16(data[i].min);
378 query[i].max = tfp_le_to_cpu_16(data[i].max);
380 #if (TF_RM_MSG_DEBUG == 1)
381 printf("type: %d(0x%x) %d %d\n",
386 #endif /* (TF_RM_MSG_DEBUG == 1) */
390 *resv_strategy = resp.flags &
391 HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
394 tf_msg_free_dma_buf(&qcaps_buf);
400 tf_msg_session_resc_alloc(struct tf *tfp,
403 struct tf_rm_resc_req_entry *request,
404 struct tf_rm_resc_entry *resv)
408 struct tfp_send_msg_parms parms = { 0 };
409 struct hwrm_tf_session_resc_alloc_input req = { 0 };
410 struct hwrm_tf_session_resc_alloc_output resp = { 0 };
411 uint8_t fw_session_id;
412 struct tf_msg_dma_buf req_buf = { 0 };
413 struct tf_msg_dma_buf resv_buf = { 0 };
414 struct tf_rm_resc_req_entry *req_data;
415 struct tf_rm_resc_entry *resv_data;
418 TF_CHECK_PARMS3(tfp, request, resv);
420 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
423 "%s: Unable to lookup FW id, rc:%s\n",
429 /* Prepare DMA buffers */
430 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
431 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
435 dma_size = size * sizeof(struct tf_rm_resc_entry);
436 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
438 tf_msg_free_dma_buf(&req_buf);
442 /* Populate the request */
443 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
444 req.flags = tfp_cpu_to_le_16(dir);
447 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
448 for (i = 0; i < size; i++) {
449 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
450 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
451 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
454 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
455 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
457 parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
458 parms.req_data = (uint32_t *)&req;
459 parms.req_size = sizeof(req);
460 parms.resp_data = (uint32_t *)&resp;
461 parms.resp_size = sizeof(resp);
462 parms.mailbox = TF_KONG_MB;
464 rc = tfp_send_msg_direct(tfp, &parms);
468 /* Process the response
469 * Should always get expected number of entries
471 if (tfp_le_to_cpu_32(resp.size) != size) {
473 "%s: Alloc message size error, rc:%s\n",
480 #if (TF_RM_MSG_DEBUG == 1)
482 printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
483 #endif /* (TF_RM_MSG_DEBUG == 1) */
485 /* Post process the response */
486 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
487 for (i = 0; i < size; i++) {
488 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
489 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
490 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
492 #if (TF_RM_MSG_DEBUG == 1)
493 printf("%d type: %d(0x%x) %d %d\n",
499 #endif /* (TF_RM_MSG_DEBUG == 1) */
503 tf_msg_free_dma_buf(&req_buf);
504 tf_msg_free_dma_buf(&resv_buf);
510 tf_msg_session_resc_flush(struct tf *tfp,
513 struct tf_rm_resc_entry *resv)
517 struct tfp_send_msg_parms parms = { 0 };
518 struct hwrm_tf_session_resc_flush_input req = { 0 };
519 struct hwrm_tf_session_resc_flush_output resp = { 0 };
520 uint8_t fw_session_id;
521 struct tf_msg_dma_buf resv_buf = { 0 };
522 struct tf_rm_resc_entry *resv_data;
525 TF_CHECK_PARMS2(tfp, resv);
527 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
530 "%s: Unable to lookup FW id, rc:%s\n",
536 /* Prepare DMA buffers */
537 dma_size = size * sizeof(struct tf_rm_resc_entry);
538 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
542 /* Populate the request */
543 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
544 req.flags = tfp_cpu_to_le_16(dir);
545 req.flush_size = size;
547 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
548 for (i = 0; i < size; i++) {
549 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
550 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
551 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
554 req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
556 parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
557 parms.req_data = (uint32_t *)&req;
558 parms.req_size = sizeof(req);
559 parms.resp_data = (uint32_t *)&resp;
560 parms.resp_size = sizeof(resp);
561 parms.mailbox = TF_KONG_MB;
563 rc = tfp_send_msg_direct(tfp, &parms);
565 tf_msg_free_dma_buf(&resv_buf);
571 tf_msg_insert_em_internal_entry(struct tf *tfp,
572 struct tf_insert_em_entry_parms *em_parms,
573 uint16_t *rptr_index,
575 uint8_t *num_of_entries)
578 struct tfp_send_msg_parms parms = { 0 };
579 struct hwrm_tf_em_insert_input req = { 0 };
580 struct hwrm_tf_em_insert_output resp = { 0 };
581 struct tf_em_64b_entry *em_result =
582 (struct tf_em_64b_entry *)em_parms->em_record;
584 uint8_t fw_session_id;
585 uint8_t msg_key_size;
587 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
590 "%s: Unable to lookup FW id, rc:%s\n",
591 tf_dir_2_str(em_parms->dir),
596 /* Populate the request */
597 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
599 /* Check for key size conformity */
600 msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
601 if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
604 "%s: Invalid parameters for msg type, rc:%s\n",
605 tf_dir_2_str(em_parms->dir),
610 tfp_memcpy(req.em_key,
614 flags = (em_parms->dir == TF_DIR_TX ?
615 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
616 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
617 req.flags = tfp_cpu_to_le_16(flags);
618 req.strength = (em_result->hdr.word1 &
619 CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
620 CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
621 req.em_key_bitlen = em_parms->key_sz_in_bits;
622 req.action_ptr = em_result->hdr.pointer;
623 req.em_record_idx = *rptr_index;
625 parms.tf_type = HWRM_TF_EM_INSERT;
626 parms.req_data = (uint32_t *)&req;
627 parms.req_size = sizeof(req);
628 parms.resp_data = (uint32_t *)&resp;
629 parms.resp_size = sizeof(resp);
630 parms.mailbox = TF_KONG_MB;
632 rc = tfp_send_msg_direct(tfp,
637 *rptr_entry = resp.rptr_entry;
638 *rptr_index = resp.rptr_index;
639 *num_of_entries = resp.num_of_entries;
645 tf_msg_delete_em_entry(struct tf *tfp,
646 struct tf_delete_em_entry_parms *em_parms)
649 struct tfp_send_msg_parms parms = { 0 };
650 struct hwrm_tf_em_delete_input req = { 0 };
651 struct hwrm_tf_em_delete_output resp = { 0 };
653 uint8_t fw_session_id;
655 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
658 "%s: Unable to lookup FW id, rc:%s\n",
659 tf_dir_2_str(em_parms->dir),
664 /* Populate the request */
665 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
667 flags = (em_parms->dir == TF_DIR_TX ?
668 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
669 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
670 req.flags = tfp_cpu_to_le_16(flags);
671 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
673 parms.tf_type = HWRM_TF_EM_DELETE;
674 parms.req_data = (uint32_t *)&req;
675 parms.req_size = sizeof(req);
676 parms.resp_data = (uint32_t *)&resp;
677 parms.resp_size = sizeof(resp);
678 parms.mailbox = TF_KONG_MB;
680 rc = tfp_send_msg_direct(tfp,
685 em_parms->index = tfp_le_to_cpu_16(resp.em_index);
691 tf_msg_em_mem_rgtr(struct tf *tfp,
698 struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
699 struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
700 struct tfp_send_msg_parms parms = { 0 };
702 req.page_level = page_lvl;
703 req.page_size = page_size;
704 req.page_dir = tfp_cpu_to_le_64(dma_addr);
706 parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
707 parms.req_data = (uint32_t *)&req;
708 parms.req_size = sizeof(req);
709 parms.resp_data = (uint32_t *)&resp;
710 parms.resp_size = sizeof(resp);
711 parms.mailbox = TF_KONG_MB;
713 rc = tfp_send_msg_direct(tfp,
718 *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
724 tf_msg_em_mem_unrgtr(struct tf *tfp,
728 struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
729 struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
730 struct tfp_send_msg_parms parms = { 0 };
732 req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
734 parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
735 parms.req_data = (uint32_t *)&req;
736 parms.req_size = sizeof(req);
737 parms.resp_data = (uint32_t *)&resp;
738 parms.resp_size = sizeof(resp);
739 parms.mailbox = TF_KONG_MB;
741 rc = tfp_send_msg_direct(tfp,
747 tf_msg_em_qcaps(struct tf *tfp,
749 struct tf_em_caps *em_caps)
752 struct hwrm_tf_ext_em_qcaps_input req = {0};
753 struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
755 struct tfp_send_msg_parms parms = { 0 };
757 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
758 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
759 req.flags = tfp_cpu_to_le_32(flags);
761 parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
762 parms.req_data = (uint32_t *)&req;
763 parms.req_size = sizeof(req);
764 parms.resp_data = (uint32_t *)&resp;
765 parms.resp_size = sizeof(resp);
766 parms.mailbox = TF_KONG_MB;
768 rc = tfp_send_msg_direct(tfp,
773 em_caps->supported = tfp_le_to_cpu_32(resp.supported);
774 em_caps->max_entries_supported =
775 tfp_le_to_cpu_32(resp.max_entries_supported);
776 em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
777 em_caps->record_entry_size =
778 tfp_le_to_cpu_16(resp.record_entry_size);
779 em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
785 tf_msg_em_cfg(struct tf *tfp,
786 uint32_t num_entries,
787 uint16_t key0_ctx_id,
788 uint16_t key1_ctx_id,
789 uint16_t record_ctx_id,
791 uint8_t flush_interval,
795 struct hwrm_tf_ext_em_cfg_input req = {0};
796 struct hwrm_tf_ext_em_cfg_output resp = {0};
798 struct tfp_send_msg_parms parms = { 0 };
800 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
801 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
802 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
804 req.flags = tfp_cpu_to_le_32(flags);
805 req.num_entries = tfp_cpu_to_le_32(num_entries);
807 req.flush_interval = flush_interval;
809 req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
810 req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
811 req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
812 req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
814 parms.tf_type = HWRM_TF_EXT_EM_CFG;
815 parms.req_data = (uint32_t *)&req;
816 parms.req_size = sizeof(req);
817 parms.resp_data = (uint32_t *)&resp;
818 parms.resp_size = sizeof(resp);
819 parms.mailbox = TF_KONG_MB;
821 rc = tfp_send_msg_direct(tfp,
827 tf_msg_em_op(struct tf *tfp,
832 struct hwrm_tf_ext_em_op_input req = {0};
833 struct hwrm_tf_ext_em_op_output resp = {0};
835 struct tfp_send_msg_parms parms = { 0 };
837 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
838 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
839 req.flags = tfp_cpu_to_le_32(flags);
840 req.op = tfp_cpu_to_le_16(op);
842 parms.tf_type = HWRM_TF_EXT_EM_OP;
843 parms.req_data = (uint32_t *)&req;
844 parms.req_size = sizeof(req);
845 parms.resp_data = (uint32_t *)&resp;
846 parms.resp_size = sizeof(resp);
847 parms.mailbox = TF_KONG_MB;
849 rc = tfp_send_msg_direct(tfp,
855 tf_msg_tcam_entry_set(struct tf *tfp,
856 struct tf_tcam_set_parms *parms)
859 struct tfp_send_msg_parms mparms = { 0 };
860 struct hwrm_tf_tcam_set_input req = { 0 };
861 struct hwrm_tf_tcam_set_output resp = { 0 };
862 struct tf_msg_dma_buf buf = { 0 };
863 uint8_t *data = NULL;
865 uint8_t fw_session_id;
867 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
870 "%s: Unable to lookup FW id, rc:%s\n",
871 tf_dir_2_str(parms->dir),
876 /* Populate the request */
877 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
878 req.type = parms->hcapi_type;
879 req.idx = tfp_cpu_to_le_16(parms->idx);
880 if (parms->dir == TF_DIR_TX)
881 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
883 req.key_size = parms->key_size;
884 req.mask_offset = parms->key_size;
885 /* Result follows after key and mask, thus multiply by 2 */
886 req.result_offset = 2 * parms->key_size;
887 req.result_size = parms->result_size;
888 data_size = 2 * req.key_size + req.result_size;
890 if (data_size <= TF_PCI_BUF_SIZE_MAX) {
892 data = &req.dev_data[0];
895 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
896 rc = tf_msg_alloc_dma_buf(&buf, data_size);
900 tfp_memcpy(&req.dev_data[0],
902 sizeof(buf.pa_addr));
905 tfp_memcpy(&data[0], parms->key, parms->key_size);
906 tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
907 tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
909 mparms.tf_type = HWRM_TF_TCAM_SET;
910 mparms.req_data = (uint32_t *)&req;
911 mparms.req_size = sizeof(req);
912 mparms.resp_data = (uint32_t *)&resp;
913 mparms.resp_size = sizeof(resp);
914 mparms.mailbox = TF_KONG_MB;
916 rc = tfp_send_msg_direct(tfp,
920 tf_msg_free_dma_buf(&buf);
926 tf_msg_tcam_entry_free(struct tf *tfp,
927 struct tf_tcam_free_parms *in_parms)
930 struct hwrm_tf_tcam_free_input req = { 0 };
931 struct hwrm_tf_tcam_free_output resp = { 0 };
932 struct tfp_send_msg_parms parms = { 0 };
933 uint8_t fw_session_id;
935 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
938 "%s: Unable to lookup FW id, rc:%s\n",
939 tf_dir_2_str(in_parms->dir),
944 /* Populate the request */
945 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
946 req.type = in_parms->hcapi_type;
948 req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
949 if (in_parms->dir == TF_DIR_TX)
950 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
952 parms.tf_type = HWRM_TF_TCAM_FREE;
953 parms.req_data = (uint32_t *)&req;
954 parms.req_size = sizeof(req);
955 parms.resp_data = (uint32_t *)&resp;
956 parms.resp_size = sizeof(resp);
957 parms.mailbox = TF_KONG_MB;
959 rc = tfp_send_msg_direct(tfp,
965 tf_msg_set_tbl_entry(struct tf *tfp,
973 struct hwrm_tf_tbl_type_set_input req = { 0 };
974 struct hwrm_tf_tbl_type_set_output resp = { 0 };
975 struct tfp_send_msg_parms parms = { 0 };
976 uint8_t fw_session_id;
978 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
981 "%s: Unable to lookup FW id, rc:%s\n",
987 /* Populate the request */
988 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
989 req.flags = tfp_cpu_to_le_16(dir);
990 req.type = tfp_cpu_to_le_32(hcapi_type);
991 req.size = tfp_cpu_to_le_16(size);
992 req.index = tfp_cpu_to_le_32(index);
994 /* Check for data size conformity */
995 if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
998 "%s: Invalid parameters for msg type, rc:%s\n",
1004 tfp_memcpy(&req.data,
1008 parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1009 parms.req_data = (uint32_t *)&req;
1010 parms.req_size = sizeof(req);
1011 parms.resp_data = (uint32_t *)&resp;
1012 parms.resp_size = sizeof(resp);
1013 parms.mailbox = TF_KONG_MB;
1015 rc = tfp_send_msg_direct(tfp,
1020 return tfp_le_to_cpu_32(parms.tf_resp_code);
1024 tf_msg_get_tbl_entry(struct tf *tfp,
1026 uint16_t hcapi_type,
1032 struct hwrm_tf_tbl_type_get_input req = { 0 };
1033 struct hwrm_tf_tbl_type_get_output resp = { 0 };
1034 struct tfp_send_msg_parms parms = { 0 };
1035 uint8_t fw_session_id;
1037 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1040 "%s: Unable to lookup FW id, rc:%s\n",
1046 /* Populate the request */
1047 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1048 req.flags = tfp_cpu_to_le_16(dir);
1049 req.type = tfp_cpu_to_le_32(hcapi_type);
1050 req.index = tfp_cpu_to_le_32(index);
1052 parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1053 parms.req_data = (uint32_t *)&req;
1054 parms.req_size = sizeof(req);
1055 parms.resp_data = (uint32_t *)&resp;
1056 parms.resp_size = sizeof(resp);
1057 parms.mailbox = TF_KONG_MB;
1059 rc = tfp_send_msg_direct(tfp,
1064 /* Verify that we got enough buffer to return the requested data */
1065 if (tfp_le_to_cpu_32(resp.size) != size)
1072 return tfp_le_to_cpu_32(parms.tf_resp_code);
1075 /* HWRM Tunneled messages */
1078 tf_msg_get_global_cfg(struct tf *tfp,
1079 struct tf_dev_global_cfg_parms *params)
1082 struct tfp_send_msg_parms parms = { 0 };
1083 struct hwrm_tf_global_cfg_get_input req = { 0 };
1084 struct hwrm_tf_global_cfg_get_output resp = { 0 };
1086 uint8_t fw_session_id;
1087 uint16_t resp_size = 0;
1089 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1092 "%s: Unable to lookup FW id, rc:%s\n",
1093 tf_dir_2_str(params->dir),
1098 flags = (params->dir == TF_DIR_TX ?
1099 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1100 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1102 /* Populate the request */
1103 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1104 req.flags = tfp_cpu_to_le_32(flags);
1105 req.type = tfp_cpu_to_le_32(params->type);
1106 req.offset = tfp_cpu_to_le_32(params->offset);
1107 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1109 parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1110 parms.req_data = (uint32_t *)&req;
1111 parms.req_size = sizeof(req);
1112 parms.resp_data = (uint32_t *)&resp;
1113 parms.resp_size = sizeof(resp);
1114 parms.mailbox = TF_KONG_MB;
1116 rc = tfp_send_msg_direct(tfp, &parms);
1120 /* Verify that we got enough buffer to return the requested data */
1121 resp_size = tfp_le_to_cpu_16(resp.size);
1122 if (resp_size < params->config_sz_in_bytes)
1126 tfp_memcpy(params->config,
1132 return tfp_le_to_cpu_32(parms.tf_resp_code);
1136 tf_msg_set_global_cfg(struct tf *tfp,
1137 struct tf_dev_global_cfg_parms *params)
1140 struct tfp_send_msg_parms parms = { 0 };
1141 struct hwrm_tf_global_cfg_set_input req = { 0 };
1142 struct hwrm_tf_global_cfg_set_output resp = { 0 };
1144 uint8_t fw_session_id;
1146 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1149 "%s: Unable to lookup FW id, rc:%s\n",
1150 tf_dir_2_str(params->dir),
1155 flags = (params->dir == TF_DIR_TX ?
1156 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
1157 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
1159 /* Populate the request */
1160 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1161 req.flags = tfp_cpu_to_le_32(flags);
1162 req.type = tfp_cpu_to_le_32(params->type);
1163 req.offset = tfp_cpu_to_le_32(params->offset);
1165 /* Check for data size conformity */
1166 if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
1169 "%s: Invalid parameters for msg type, rc:%s\n",
1170 tf_dir_2_str(params->dir),
1175 tfp_memcpy(req.data, params->config,
1176 params->config_sz_in_bytes);
1177 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1179 parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
1180 parms.req_data = (uint32_t *)&req;
1181 parms.req_size = sizeof(req);
1182 parms.resp_data = (uint32_t *)&resp;
1183 parms.resp_size = sizeof(resp);
1184 parms.mailbox = TF_KONG_MB;
1186 rc = tfp_send_msg_direct(tfp, &parms);
1191 return tfp_le_to_cpu_32(parms.tf_resp_code);
1195 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
1197 uint16_t hcapi_type,
1198 uint32_t starting_idx,
1199 uint16_t num_entries,
1200 uint16_t entry_sz_in_bytes,
1201 uint64_t physical_mem_addr)
1204 struct tfp_send_msg_parms parms = { 0 };
1205 struct tf_tbl_type_bulk_get_input req = { 0 };
1206 struct tf_tbl_type_bulk_get_output resp = { 0 };
1208 uint8_t fw_session_id;
1210 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1213 "%s: Unable to lookup FW id, rc:%s\n",
1219 /* Populate the request */
1220 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1221 req.flags = tfp_cpu_to_le_16(dir);
1222 req.type = tfp_cpu_to_le_32(hcapi_type);
1223 req.start_index = tfp_cpu_to_le_32(starting_idx);
1224 req.num_entries = tfp_cpu_to_le_32(num_entries);
1226 data_size = num_entries * entry_sz_in_bytes;
1228 req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1233 HWRM_TFT_TBL_TYPE_BULK_GET,
1237 rc = tfp_send_msg_tunneled(tfp, &parms);
1241 /* Verify that we got enough buffer to return the requested data */
1242 if (tfp_le_to_cpu_32(resp.size) != data_size)
1245 return tfp_le_to_cpu_32(parms.tf_resp_code);
1249 tf_msg_get_if_tbl_entry(struct tf *tfp,
1250 struct tf_if_tbl_get_parms *params)
1253 struct tfp_send_msg_parms parms = { 0 };
1254 tf_if_tbl_get_input_t req = { 0 };
1255 tf_if_tbl_get_output_t resp;
1257 struct tf_session *tfs;
1259 /* Retrieve the session information */
1260 rc = tf_session_get_session(tfp, &tfs);
1263 "%s: Failed to lookup session, rc:%s\n",
1264 tf_dir_2_str(params->dir),
1269 flags = (params->dir == TF_DIR_TX ? TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
1270 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.tf_if_tbl_type = params->hcapi_type;
1277 req.idx = tfp_cpu_to_le_16(params->idx);
1278 req.data_sz_in_bytes = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1283 HWRM_TFT_IF_TBL_GET,
1287 rc = tfp_send_msg_tunneled(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.data_sz_in_bytes);
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 tf_if_tbl_set_input_t req = { 0 };
1308 struct tf_session *tfs;
1310 /* Retrieve the session information */
1311 rc = tf_session_get_session(tfp, &tfs);
1314 "%s: Failed to lookup session, rc:%s\n",
1315 tf_dir_2_str(params->dir),
1321 flags = (params->dir == TF_DIR_TX ? TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1322 TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1324 /* Populate the request */
1326 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1328 req.tf_if_tbl_type = params->hcapi_type;
1329 req.idx = tfp_cpu_to_le_32(params->idx);
1330 req.data_sz_in_bytes = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1331 tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1333 MSG_PREP_NO_RESP(parms,
1336 HWRM_TFT_IF_TBL_SET,
1339 rc = tfp_send_msg_tunneled(tfp, &parms);
1344 return tfp_le_to_cpu_32(parms.tf_resp_code);