1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2021 Broadcom
12 #include "tf_msg_common.h"
13 #include "tf_device.h"
16 #include "tf_common.h"
17 #include "tf_session.h"
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
26 #define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE 16
27 #define TF_MSG_EM_INSERT_KEY_SIZE 64
28 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE 88
30 /* Compile check - Catch any msg changes that we depend on, like the
31 * defines listed above for array size checking.
33 * Checking array size is dangerous in that the type could change and
34 * we wouldn't be able to catch it. Thus we check if the complete msg
35 * changed instead. Best we can do.
37 * If failure is observed then both msg size (defines below) and the
38 * array size (define above) should be checked and compared.
40 #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56
41 static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
42 TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET,
43 "HWRM message size changed: hwrm_tf_global_cfg_set_input");
45 #define TF_MSG_SIZE_HWRM_TF_EM_INSERT 104
46 static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
47 TF_MSG_SIZE_HWRM_TF_EM_INSERT,
48 "HWRM message size changed: hwrm_tf_em_insert_input");
50 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET 128
51 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
52 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
53 "HWRM message size changed: hwrm_tf_tbl_type_set_input");
56 * This is the MAX data we can transport across regular HWRM
58 #define TF_PCI_BUF_SIZE_MAX 88
61 * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
63 struct tf_msg_dma_buf {
69 * Allocates a DMA buffer that can be used for message transfer.
72 * Pointer to DMA buffer structure
75 * Requested size of the buffer in bytes
79 * -ENOMEM - Unable to allocate buffer, no memory
82 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
84 struct tfp_calloc_parms alloc_parms;
87 /* Allocate session */
88 alloc_parms.nitems = 1;
89 alloc_parms.size = size;
90 alloc_parms.alignment = 4096;
91 rc = tfp_calloc(&alloc_parms);
95 buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
96 buf->va_addr = alloc_parms.mem_va;
102 * Free's a previous allocated DMA buffer.
105 * Pointer to DMA buffer structure
108 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
110 tfp_free(buf->va_addr);
113 /* HWRM Direct messages */
116 tf_msg_session_open(struct tf *tfp,
117 char *ctrl_chan_name,
118 uint8_t *fw_session_id,
119 uint8_t *fw_session_client_id)
122 struct hwrm_tf_session_open_input req = { 0 };
123 struct hwrm_tf_session_open_output resp = { 0 };
124 struct tfp_send_msg_parms parms = { 0 };
126 /* Populate the request */
127 tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
129 parms.tf_type = HWRM_TF_SESSION_OPEN;
130 parms.req_data = (uint32_t *)&req;
131 parms.req_size = sizeof(req);
132 parms.resp_data = (uint32_t *)&resp;
133 parms.resp_size = sizeof(resp);
134 parms.mailbox = TF_KONG_MB;
136 rc = tfp_send_msg_direct(tfp,
141 *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
142 *fw_session_client_id =
143 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
149 tf_msg_session_attach(struct tf *tfp __rte_unused,
150 char *ctrl_chan_name __rte_unused,
151 uint8_t tf_fw_session_id __rte_unused)
157 tf_msg_session_client_register(struct tf *tfp,
158 char *ctrl_channel_name,
159 uint8_t *fw_session_client_id)
162 struct hwrm_tf_session_register_input req = { 0 };
163 struct hwrm_tf_session_register_output resp = { 0 };
164 struct tfp_send_msg_parms parms = { 0 };
165 uint8_t fw_session_id;
167 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
170 "Unable to lookup FW id, rc:%s\n",
175 /* Populate the request */
176 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
177 tfp_memcpy(&req.session_client_name,
179 TF_SESSION_NAME_MAX);
181 parms.tf_type = HWRM_TF_SESSION_REGISTER;
182 parms.req_data = (uint32_t *)&req;
183 parms.req_size = sizeof(req);
184 parms.resp_data = (uint32_t *)&resp;
185 parms.resp_size = sizeof(resp);
186 parms.mailbox = TF_KONG_MB;
188 rc = tfp_send_msg_direct(tfp,
193 *fw_session_client_id =
194 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
200 tf_msg_session_client_unregister(struct tf *tfp,
201 uint8_t fw_session_client_id)
204 struct hwrm_tf_session_unregister_input req = { 0 };
205 struct hwrm_tf_session_unregister_output resp = { 0 };
206 struct tfp_send_msg_parms parms = { 0 };
207 uint8_t fw_session_id;
209 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
212 "Unable to lookup FW id, rc:%s\n",
217 /* Populate the request */
218 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
219 req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
221 parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
222 parms.req_data = (uint32_t *)&req;
223 parms.req_size = sizeof(req);
224 parms.resp_data = (uint32_t *)&resp;
225 parms.resp_size = sizeof(resp);
226 parms.mailbox = TF_KONG_MB;
228 rc = tfp_send_msg_direct(tfp,
235 tf_msg_session_close(struct tf *tfp)
238 struct hwrm_tf_session_close_input req = { 0 };
239 struct hwrm_tf_session_close_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_CLOSE;
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_qcfg(struct tf *tfp)
270 struct hwrm_tf_session_qcfg_input req = { 0 };
271 struct hwrm_tf_session_qcfg_output resp = { 0 };
272 struct tfp_send_msg_parms parms = { 0 };
273 uint8_t fw_session_id;
275 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
278 "Unable to lookup FW id, rc:%s\n",
283 /* Populate the request */
284 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
286 parms.tf_type = HWRM_TF_SESSION_QCFG,
287 parms.req_data = (uint32_t *)&req;
288 parms.req_size = sizeof(req);
289 parms.resp_data = (uint32_t *)&resp;
290 parms.resp_size = sizeof(resp);
291 parms.mailbox = TF_KONG_MB;
293 rc = tfp_send_msg_direct(tfp,
299 tf_msg_session_resc_qcaps(struct tf *tfp,
302 struct tf_rm_resc_req_entry *query,
303 enum tf_rm_resc_resv_strategy *resv_strategy)
307 struct tfp_send_msg_parms parms = { 0 };
308 struct hwrm_tf_session_resc_qcaps_input req = { 0 };
309 struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
310 uint8_t fw_session_id;
311 struct tf_msg_dma_buf qcaps_buf = { 0 };
312 struct tf_rm_resc_req_entry *data;
315 TF_CHECK_PARMS3(tfp, query, resv_strategy);
317 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
320 "%s: Unable to lookup FW id, rc:%s\n",
326 /* Prepare DMA buffer */
327 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
328 rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
332 /* Populate the request */
333 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
334 req.flags = tfp_cpu_to_le_16(dir);
335 req.qcaps_size = size;
336 req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
338 parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
339 parms.req_data = (uint32_t *)&req;
340 parms.req_size = sizeof(req);
341 parms.resp_data = (uint32_t *)&resp;
342 parms.resp_size = sizeof(resp);
343 parms.mailbox = TF_KONG_MB;
345 rc = tfp_send_msg_direct(tfp, &parms);
349 /* Process the response
350 * Should always get expected number of entries
352 if (tfp_le_to_cpu_32(resp.size) != size) {
354 "%s: QCAPS message size error, rc:%s\n",
361 /* Post process the response */
362 data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
364 for (i = 0; i < size; i++) {
365 query[i].type = tfp_le_to_cpu_32(data[i].type);
366 query[i].min = tfp_le_to_cpu_16(data[i].min);
367 query[i].max = tfp_le_to_cpu_16(data[i].max);
370 *resv_strategy = resp.flags &
371 HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
374 tf_msg_free_dma_buf(&qcaps_buf);
380 tf_msg_session_resc_alloc(struct tf *tfp,
383 struct tf_rm_resc_req_entry *request,
384 struct tf_rm_resc_entry *resv)
388 struct tfp_send_msg_parms parms = { 0 };
389 struct hwrm_tf_session_resc_alloc_input req = { 0 };
390 struct hwrm_tf_session_resc_alloc_output resp = { 0 };
391 uint8_t fw_session_id;
392 struct tf_msg_dma_buf req_buf = { 0 };
393 struct tf_msg_dma_buf resv_buf = { 0 };
394 struct tf_rm_resc_req_entry *req_data;
395 struct tf_rm_resc_entry *resv_data;
398 TF_CHECK_PARMS3(tfp, request, resv);
400 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
403 "%s: Unable to lookup FW id, rc:%s\n",
409 /* Prepare DMA buffers */
410 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
411 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
415 dma_size = size * sizeof(struct tf_rm_resc_entry);
416 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
418 tf_msg_free_dma_buf(&req_buf);
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);
427 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
428 for (i = 0; i < size; i++) {
429 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
430 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
431 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
434 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
435 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
437 parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
438 parms.req_data = (uint32_t *)&req;
439 parms.req_size = sizeof(req);
440 parms.resp_data = (uint32_t *)&resp;
441 parms.resp_size = sizeof(resp);
442 parms.mailbox = TF_KONG_MB;
444 rc = tfp_send_msg_direct(tfp, &parms);
448 /* Process the response
449 * Should always get expected number of entries
451 if (tfp_le_to_cpu_32(resp.size) != size) {
453 "%s: Alloc message size error, rc:%s\n",
460 /* Post process the response */
461 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
462 for (i = 0; i < size; i++) {
463 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
464 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
465 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
469 tf_msg_free_dma_buf(&req_buf);
470 tf_msg_free_dma_buf(&resv_buf);
476 tf_msg_session_resc_flush(struct tf *tfp,
479 struct tf_rm_resc_entry *resv)
483 struct tfp_send_msg_parms parms = { 0 };
484 struct hwrm_tf_session_resc_flush_input req = { 0 };
485 struct hwrm_tf_session_resc_flush_output resp = { 0 };
486 uint8_t fw_session_id;
487 struct tf_msg_dma_buf resv_buf = { 0 };
488 struct tf_rm_resc_entry *resv_data;
491 TF_CHECK_PARMS2(tfp, resv);
493 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
496 "%s: Unable to lookup FW id, rc:%s\n",
502 /* Prepare DMA buffers */
503 dma_size = size * sizeof(struct tf_rm_resc_entry);
504 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
508 /* Populate the request */
509 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
510 req.flags = tfp_cpu_to_le_16(dir);
511 req.flush_size = size;
513 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
514 for (i = 0; i < size; i++) {
515 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
516 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
517 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
520 req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
522 parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
523 parms.req_data = (uint32_t *)&req;
524 parms.req_size = sizeof(req);
525 parms.resp_data = (uint32_t *)&resp;
526 parms.resp_size = sizeof(resp);
527 parms.mailbox = TF_KONG_MB;
529 rc = tfp_send_msg_direct(tfp, &parms);
531 tf_msg_free_dma_buf(&resv_buf);
537 tf_msg_insert_em_internal_entry(struct tf *tfp,
538 struct tf_insert_em_entry_parms *em_parms,
539 uint16_t *rptr_index,
541 uint8_t *num_of_entries)
544 struct tfp_send_msg_parms parms = { 0 };
545 struct hwrm_tf_em_insert_input req = { 0 };
546 struct hwrm_tf_em_insert_output resp = { 0 };
547 struct tf_em_64b_entry *em_result =
548 (struct tf_em_64b_entry *)em_parms->em_record;
550 uint8_t fw_session_id;
551 uint8_t msg_key_size;
553 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
556 "%s: Unable to lookup FW id, rc:%s\n",
557 tf_dir_2_str(em_parms->dir),
562 /* Populate the request */
563 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
565 /* Check for key size conformity */
566 msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
567 if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
570 "%s: Invalid parameters for msg type, rc:%s\n",
571 tf_dir_2_str(em_parms->dir),
576 tfp_memcpy(req.em_key,
580 flags = (em_parms->dir == TF_DIR_TX ?
581 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
582 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
583 req.flags = tfp_cpu_to_le_16(flags);
584 req.strength = (em_result->hdr.word1 &
585 CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
586 CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
587 req.em_key_bitlen = em_parms->key_sz_in_bits;
588 req.action_ptr = em_result->hdr.pointer;
589 req.em_record_idx = *rptr_index;
591 parms.tf_type = HWRM_TF_EM_INSERT;
592 parms.req_data = (uint32_t *)&req;
593 parms.req_size = sizeof(req);
594 parms.resp_data = (uint32_t *)&resp;
595 parms.resp_size = sizeof(resp);
596 parms.mailbox = TF_KONG_MB;
598 rc = tfp_send_msg_direct(tfp,
603 *rptr_entry = resp.rptr_entry;
604 *rptr_index = resp.rptr_index;
605 *num_of_entries = resp.num_of_entries;
611 tf_msg_delete_em_entry(struct tf *tfp,
612 struct tf_delete_em_entry_parms *em_parms)
615 struct tfp_send_msg_parms parms = { 0 };
616 struct hwrm_tf_em_delete_input req = { 0 };
617 struct hwrm_tf_em_delete_output resp = { 0 };
619 uint8_t fw_session_id;
621 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
624 "%s: Unable to lookup FW id, rc:%s\n",
625 tf_dir_2_str(em_parms->dir),
630 /* Populate the request */
631 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
633 flags = (em_parms->dir == TF_DIR_TX ?
634 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
635 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
636 req.flags = tfp_cpu_to_le_16(flags);
637 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
639 parms.tf_type = HWRM_TF_EM_DELETE;
640 parms.req_data = (uint32_t *)&req;
641 parms.req_size = sizeof(req);
642 parms.resp_data = (uint32_t *)&resp;
643 parms.resp_size = sizeof(resp);
644 parms.mailbox = TF_KONG_MB;
646 rc = tfp_send_msg_direct(tfp,
651 em_parms->index = tfp_le_to_cpu_16(resp.em_index);
657 tf_msg_em_mem_rgtr(struct tf *tfp,
664 struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
665 struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
666 struct tfp_send_msg_parms parms = { 0 };
668 req.page_level = page_lvl;
669 req.page_size = page_size;
670 req.page_dir = tfp_cpu_to_le_64(dma_addr);
672 parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
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 *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
690 tf_msg_em_mem_unrgtr(struct tf *tfp,
694 struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
695 struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
696 struct tfp_send_msg_parms parms = { 0 };
698 req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
700 parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
701 parms.req_data = (uint32_t *)&req;
702 parms.req_size = sizeof(req);
703 parms.resp_data = (uint32_t *)&resp;
704 parms.resp_size = sizeof(resp);
705 parms.mailbox = TF_KONG_MB;
707 rc = tfp_send_msg_direct(tfp,
713 tf_msg_em_qcaps(struct tf *tfp,
715 struct tf_em_caps *em_caps)
718 struct hwrm_tf_ext_em_qcaps_input req = {0};
719 struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
721 struct tfp_send_msg_parms parms = { 0 };
723 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
724 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
725 req.flags = tfp_cpu_to_le_32(flags);
727 parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
728 parms.req_data = (uint32_t *)&req;
729 parms.req_size = sizeof(req);
730 parms.resp_data = (uint32_t *)&resp;
731 parms.resp_size = sizeof(resp);
732 parms.mailbox = TF_KONG_MB;
734 rc = tfp_send_msg_direct(tfp,
739 em_caps->supported = tfp_le_to_cpu_32(resp.supported);
740 em_caps->max_entries_supported =
741 tfp_le_to_cpu_32(resp.max_entries_supported);
742 em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
743 em_caps->record_entry_size =
744 tfp_le_to_cpu_16(resp.record_entry_size);
745 em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
751 tf_msg_em_cfg(struct tf *tfp,
752 uint32_t num_entries,
753 uint16_t key0_ctx_id,
754 uint16_t key1_ctx_id,
755 uint16_t record_ctx_id,
757 uint8_t flush_interval,
761 struct hwrm_tf_ext_em_cfg_input req = {0};
762 struct hwrm_tf_ext_em_cfg_output resp = {0};
764 struct tfp_send_msg_parms parms = { 0 };
766 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
767 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
768 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
770 req.flags = tfp_cpu_to_le_32(flags);
771 req.num_entries = tfp_cpu_to_le_32(num_entries);
773 req.flush_interval = flush_interval;
775 req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
776 req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
777 req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
778 req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
780 parms.tf_type = HWRM_TF_EXT_EM_CFG;
781 parms.req_data = (uint32_t *)&req;
782 parms.req_size = sizeof(req);
783 parms.resp_data = (uint32_t *)&resp;
784 parms.resp_size = sizeof(resp);
785 parms.mailbox = TF_KONG_MB;
787 rc = tfp_send_msg_direct(tfp,
793 tf_msg_em_op(struct tf *tfp,
798 struct hwrm_tf_ext_em_op_input req = {0};
799 struct hwrm_tf_ext_em_op_output resp = {0};
801 struct tfp_send_msg_parms parms = { 0 };
803 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
804 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
805 req.flags = tfp_cpu_to_le_32(flags);
806 req.op = tfp_cpu_to_le_16(op);
808 parms.tf_type = HWRM_TF_EXT_EM_OP;
809 parms.req_data = (uint32_t *)&req;
810 parms.req_size = sizeof(req);
811 parms.resp_data = (uint32_t *)&resp;
812 parms.resp_size = sizeof(resp);
813 parms.mailbox = TF_KONG_MB;
815 rc = tfp_send_msg_direct(tfp,
821 tf_msg_tcam_entry_set(struct tf *tfp,
822 struct tf_tcam_set_parms *parms)
825 struct tfp_send_msg_parms mparms = { 0 };
826 struct hwrm_tf_tcam_set_input req = { 0 };
827 struct hwrm_tf_tcam_set_output resp = { 0 };
828 struct tf_msg_dma_buf buf = { 0 };
829 uint8_t *data = NULL;
831 uint8_t fw_session_id;
833 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
836 "%s: Unable to lookup FW id, rc:%s\n",
837 tf_dir_2_str(parms->dir),
842 /* Populate the request */
843 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
844 req.type = parms->hcapi_type;
845 req.idx = tfp_cpu_to_le_16(parms->idx);
846 if (parms->dir == TF_DIR_TX)
847 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
849 req.key_size = parms->key_size;
850 req.mask_offset = parms->key_size;
851 /* Result follows after key and mask, thus multiply by 2 */
852 req.result_offset = 2 * parms->key_size;
853 req.result_size = parms->result_size;
854 data_size = 2 * req.key_size + req.result_size;
856 if (data_size <= TF_PCI_BUF_SIZE_MAX) {
858 data = &req.dev_data[0];
861 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
862 rc = tf_msg_alloc_dma_buf(&buf, data_size);
866 tfp_memcpy(&req.dev_data[0],
868 sizeof(buf.pa_addr));
871 tfp_memcpy(&data[0], parms->key, parms->key_size);
872 tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
873 tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
875 mparms.tf_type = HWRM_TF_TCAM_SET;
876 mparms.req_data = (uint32_t *)&req;
877 mparms.req_size = sizeof(req);
878 mparms.resp_data = (uint32_t *)&resp;
879 mparms.resp_size = sizeof(resp);
880 mparms.mailbox = TF_KONG_MB;
882 rc = tfp_send_msg_direct(tfp,
886 tf_msg_free_dma_buf(&buf);
892 tf_msg_tcam_entry_free(struct tf *tfp,
893 struct tf_tcam_free_parms *in_parms)
896 struct hwrm_tf_tcam_free_input req = { 0 };
897 struct hwrm_tf_tcam_free_output resp = { 0 };
898 struct tfp_send_msg_parms parms = { 0 };
899 uint8_t fw_session_id;
901 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
904 "%s: Unable to lookup FW id, rc:%s\n",
905 tf_dir_2_str(in_parms->dir),
910 /* Populate the request */
911 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
912 req.type = in_parms->hcapi_type;
914 req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
915 if (in_parms->dir == TF_DIR_TX)
916 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
918 parms.tf_type = HWRM_TF_TCAM_FREE;
919 parms.req_data = (uint32_t *)&req;
920 parms.req_size = sizeof(req);
921 parms.resp_data = (uint32_t *)&resp;
922 parms.resp_size = sizeof(resp);
923 parms.mailbox = TF_KONG_MB;
925 rc = tfp_send_msg_direct(tfp,
931 tf_msg_set_tbl_entry(struct tf *tfp,
939 struct hwrm_tf_tbl_type_set_input req = { 0 };
940 struct hwrm_tf_tbl_type_set_output resp = { 0 };
941 struct tfp_send_msg_parms parms = { 0 };
942 uint8_t fw_session_id;
944 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
947 "%s: Unable to lookup FW id, rc:%s\n",
953 /* Populate the request */
954 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
955 req.flags = tfp_cpu_to_le_16(dir);
956 req.type = tfp_cpu_to_le_32(hcapi_type);
957 req.size = tfp_cpu_to_le_16(size);
958 req.index = tfp_cpu_to_le_32(index);
960 /* Check for data size conformity */
961 if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
964 "%s: Invalid parameters for msg type, rc:%s\n",
970 tfp_memcpy(&req.data,
974 parms.tf_type = HWRM_TF_TBL_TYPE_SET;
975 parms.req_data = (uint32_t *)&req;
976 parms.req_size = sizeof(req);
977 parms.resp_data = (uint32_t *)&resp;
978 parms.resp_size = sizeof(resp);
979 parms.mailbox = TF_KONG_MB;
981 rc = tfp_send_msg_direct(tfp,
986 return tfp_le_to_cpu_32(parms.tf_resp_code);
990 tf_msg_get_tbl_entry(struct tf *tfp,
998 struct hwrm_tf_tbl_type_get_input req = { 0 };
999 struct hwrm_tf_tbl_type_get_output resp = { 0 };
1000 struct tfp_send_msg_parms parms = { 0 };
1001 uint8_t fw_session_id;
1003 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1006 "%s: Unable to lookup FW id, rc:%s\n",
1012 /* Populate the request */
1013 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1014 req.flags = tfp_cpu_to_le_16(dir);
1015 req.type = tfp_cpu_to_le_32(hcapi_type);
1016 req.index = tfp_cpu_to_le_32(index);
1018 parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1019 parms.req_data = (uint32_t *)&req;
1020 parms.req_size = sizeof(req);
1021 parms.resp_data = (uint32_t *)&resp;
1022 parms.resp_size = sizeof(resp);
1023 parms.mailbox = TF_KONG_MB;
1025 rc = tfp_send_msg_direct(tfp,
1030 /* Verify that we got enough buffer to return the requested data */
1031 if (tfp_le_to_cpu_32(resp.size) != size)
1038 return tfp_le_to_cpu_32(parms.tf_resp_code);
1041 /* HWRM Tunneled messages */
1044 tf_msg_get_global_cfg(struct tf *tfp,
1045 struct tf_global_cfg_parms *params)
1048 struct tfp_send_msg_parms parms = { 0 };
1049 struct hwrm_tf_global_cfg_get_input req = { 0 };
1050 struct hwrm_tf_global_cfg_get_output resp = { 0 };
1052 uint8_t fw_session_id;
1053 uint16_t resp_size = 0;
1055 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1058 "%s: Unable to lookup FW id, rc:%s\n",
1059 tf_dir_2_str(params->dir),
1064 flags = (params->dir == TF_DIR_TX ?
1065 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1066 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1068 /* Populate the request */
1069 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1070 req.flags = tfp_cpu_to_le_32(flags);
1071 req.type = tfp_cpu_to_le_32(params->type);
1072 req.offset = tfp_cpu_to_le_32(params->offset);
1073 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1075 parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1076 parms.req_data = (uint32_t *)&req;
1077 parms.req_size = sizeof(req);
1078 parms.resp_data = (uint32_t *)&resp;
1079 parms.resp_size = sizeof(resp);
1080 parms.mailbox = TF_KONG_MB;
1082 rc = tfp_send_msg_direct(tfp, &parms);
1086 /* Verify that we got enough buffer to return the requested data */
1087 resp_size = tfp_le_to_cpu_16(resp.size);
1088 if (resp_size < params->config_sz_in_bytes)
1092 tfp_memcpy(params->config,
1098 return tfp_le_to_cpu_32(parms.tf_resp_code);
1102 tf_msg_set_global_cfg(struct tf *tfp,
1103 struct tf_global_cfg_parms *params)
1106 struct tfp_send_msg_parms parms = { 0 };
1107 struct hwrm_tf_global_cfg_set_input req = { 0 };
1108 struct hwrm_tf_global_cfg_set_output resp = { 0 };
1110 uint8_t fw_session_id;
1112 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1115 "%s: Unable to lookup FW id, rc:%s\n",
1116 tf_dir_2_str(params->dir),
1121 flags = (params->dir == TF_DIR_TX ?
1122 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
1123 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
1125 /* Populate the request */
1126 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1127 req.flags = tfp_cpu_to_le_32(flags);
1128 req.type = tfp_cpu_to_le_32(params->type);
1129 req.offset = tfp_cpu_to_le_32(params->offset);
1131 /* Check for data size conformity */
1132 if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
1135 "%s: Invalid parameters for msg type, rc:%s\n",
1136 tf_dir_2_str(params->dir),
1141 tfp_memcpy(req.data, params->config,
1142 params->config_sz_in_bytes);
1144 /* Only set mask if pointer is provided
1146 if (params->config_mask) {
1147 tfp_memcpy(req.data + params->config_sz_in_bytes,
1148 params->config_mask,
1149 params->config_sz_in_bytes);
1152 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1154 parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
1155 parms.req_data = (uint32_t *)&req;
1156 parms.req_size = sizeof(req);
1157 parms.resp_data = (uint32_t *)&resp;
1158 parms.resp_size = sizeof(resp);
1159 parms.mailbox = TF_KONG_MB;
1161 rc = tfp_send_msg_direct(tfp, &parms);
1166 return tfp_le_to_cpu_32(parms.tf_resp_code);
1170 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
1172 uint16_t hcapi_type,
1173 uint32_t starting_idx,
1174 uint16_t num_entries,
1175 uint16_t entry_sz_in_bytes,
1176 uint64_t physical_mem_addr)
1179 struct tfp_send_msg_parms parms = { 0 };
1180 struct tf_tbl_type_bulk_get_input req = { 0 };
1181 struct tf_tbl_type_bulk_get_output resp = { 0 };
1183 uint8_t fw_session_id;
1185 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1188 "%s: Unable to lookup FW id, rc:%s\n",
1194 /* Populate the request */
1195 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1196 req.flags = tfp_cpu_to_le_16(dir);
1197 req.type = tfp_cpu_to_le_32(hcapi_type);
1198 req.start_index = tfp_cpu_to_le_32(starting_idx);
1199 req.num_entries = tfp_cpu_to_le_32(num_entries);
1201 data_size = num_entries * entry_sz_in_bytes;
1203 req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1208 HWRM_TFT_TBL_TYPE_BULK_GET,
1212 rc = tfp_send_msg_tunneled(tfp, &parms);
1216 /* Verify that we got enough buffer to return the requested data */
1217 if (tfp_le_to_cpu_32(resp.size) != data_size)
1220 return tfp_le_to_cpu_32(parms.tf_resp_code);
1224 tf_msg_get_if_tbl_entry(struct tf *tfp,
1225 struct tf_if_tbl_get_parms *params)
1228 struct tfp_send_msg_parms parms = { 0 };
1229 struct hwrm_tf_if_tbl_get_input req = { 0 };
1230 struct hwrm_tf_if_tbl_get_output resp = { 0 };
1232 struct tf_session *tfs;
1234 /* Retrieve the session information */
1235 rc = tf_session_get_session(tfp, &tfs);
1238 "%s: Failed to lookup session, rc:%s\n",
1239 tf_dir_2_str(params->dir),
1244 flags = (params->dir == TF_DIR_TX ?
1245 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
1246 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
1248 /* Populate the request */
1250 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1252 req.type = params->hcapi_type;
1253 req.index = tfp_cpu_to_le_16(params->idx);
1254 req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1256 parms.tf_type = HWRM_TF_IF_TBL_GET;
1257 parms.req_data = (uint32_t *)&req;
1258 parms.req_size = sizeof(req);
1259 parms.resp_data = (uint32_t *)&resp;
1260 parms.resp_size = sizeof(resp);
1261 parms.mailbox = TF_KONG_MB;
1263 rc = tfp_send_msg_direct(tfp, &parms);
1268 if (parms.tf_resp_code != 0)
1269 return tfp_le_to_cpu_32(parms.tf_resp_code);
1271 tfp_memcpy(¶ms->data[0], resp.data, req.size);
1273 return tfp_le_to_cpu_32(parms.tf_resp_code);
1277 tf_msg_set_if_tbl_entry(struct tf *tfp,
1278 struct tf_if_tbl_set_parms *params)
1281 struct tfp_send_msg_parms parms = { 0 };
1282 struct hwrm_tf_if_tbl_set_input req = { 0 };
1283 struct hwrm_tf_if_tbl_get_output resp = { 0 };
1285 struct tf_session *tfs;
1287 /* Retrieve the session information */
1288 rc = tf_session_get_session(tfp, &tfs);
1291 "%s: Failed to lookup session, rc:%s\n",
1292 tf_dir_2_str(params->dir),
1298 flags = (params->dir == TF_DIR_TX ?
1299 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1300 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1302 /* Populate the request */
1304 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1306 req.type = params->hcapi_type;
1307 req.index = tfp_cpu_to_le_32(params->idx);
1308 req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1309 tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1311 parms.tf_type = HWRM_TF_IF_TBL_SET;
1312 parms.req_data = (uint32_t *)&req;
1313 parms.req_size = sizeof(req);
1314 parms.resp_data = (uint32_t *)&resp;
1315 parms.resp_size = sizeof(resp);
1316 parms.mailbox = TF_KONG_MB;
1318 rc = tfp_send_msg_direct(tfp, &parms);
1323 return tfp_le_to_cpu_32(parms.tf_resp_code);