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,
120 struct tf_dev_info *dev)
123 struct hwrm_tf_session_open_input req = { 0 };
124 struct hwrm_tf_session_open_output resp = { 0 };
125 struct tfp_send_msg_parms parms = { 0 };
127 /* Populate the request */
128 tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
130 parms.tf_type = HWRM_TF_SESSION_OPEN;
131 parms.req_data = (uint32_t *)&req;
132 parms.req_size = sizeof(req);
133 parms.resp_data = (uint32_t *)&resp;
134 parms.resp_size = sizeof(resp);
135 parms.mailbox = dev->ops->tf_dev_get_mailbox();
137 rc = tfp_send_msg_direct(tfp,
142 *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
143 *fw_session_client_id =
144 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
150 tf_msg_session_attach(struct tf *tfp __rte_unused,
151 char *ctrl_chan_name __rte_unused,
152 uint8_t tf_fw_session_id __rte_unused)
158 tf_msg_session_client_register(struct tf *tfp,
159 struct tf_session *tfs,
160 char *ctrl_channel_name,
161 uint8_t *fw_session_client_id)
164 struct hwrm_tf_session_register_input req = { 0 };
165 struct hwrm_tf_session_register_output resp = { 0 };
166 struct tfp_send_msg_parms parms = { 0 };
167 uint8_t fw_session_id;
168 struct tf_dev_info *dev;
170 /* Retrieve the device information */
171 rc = tf_session_get_device(tfs, &dev);
174 "Failed to lookup device, rc:%s\n",
179 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
182 "Unable to lookup FW id, rc:%s\n",
187 /* Populate the request */
188 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
189 tfp_memcpy(&req.session_client_name,
191 TF_SESSION_NAME_MAX);
193 parms.tf_type = HWRM_TF_SESSION_REGISTER;
194 parms.req_data = (uint32_t *)&req;
195 parms.req_size = sizeof(req);
196 parms.resp_data = (uint32_t *)&resp;
197 parms.resp_size = sizeof(resp);
198 parms.mailbox = dev->ops->tf_dev_get_mailbox();
200 rc = tfp_send_msg_direct(tfp,
205 *fw_session_client_id =
206 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
212 tf_msg_session_client_unregister(struct tf *tfp,
213 struct tf_session *tfs,
214 uint8_t fw_session_client_id)
217 struct hwrm_tf_session_unregister_input req = { 0 };
218 struct hwrm_tf_session_unregister_output resp = { 0 };
219 struct tfp_send_msg_parms parms = { 0 };
220 uint8_t fw_session_id;
221 struct tf_dev_info *dev;
223 /* Retrieve the device information */
224 rc = tf_session_get_device(tfs, &dev);
227 "Failed to lookup device, rc:%s\n",
232 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
235 "Unable to lookup FW id, rc:%s\n",
240 /* Populate the request */
241 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
242 req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
244 parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
245 parms.req_data = (uint32_t *)&req;
246 parms.req_size = sizeof(req);
247 parms.resp_data = (uint32_t *)&resp;
248 parms.resp_size = sizeof(resp);
249 parms.mailbox = dev->ops->tf_dev_get_mailbox();
251 rc = tfp_send_msg_direct(tfp,
258 tf_msg_session_close(struct tf *tfp,
259 struct tf_session *tfs)
262 struct hwrm_tf_session_close_input req = { 0 };
263 struct hwrm_tf_session_close_output resp = { 0 };
264 struct tfp_send_msg_parms parms = { 0 };
265 uint8_t fw_session_id;
266 struct tf_dev_info *dev;
268 /* Retrieve the device information */
269 rc = tf_session_get_device(tfs, &dev);
272 "Failed to lookup device, rc:%s\n",
277 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
280 "Unable to lookup FW id, rc:%s\n",
285 /* Populate the request */
286 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
288 parms.tf_type = HWRM_TF_SESSION_CLOSE;
289 parms.req_data = (uint32_t *)&req;
290 parms.req_size = sizeof(req);
291 parms.resp_data = (uint32_t *)&resp;
292 parms.resp_size = sizeof(resp);
293 parms.mailbox = dev->ops->tf_dev_get_mailbox();
295 rc = tfp_send_msg_direct(tfp,
301 tf_msg_session_qcfg(struct tf *tfp)
304 struct hwrm_tf_session_qcfg_input req = { 0 };
305 struct hwrm_tf_session_qcfg_output resp = { 0 };
306 struct tfp_send_msg_parms parms = { 0 };
307 uint8_t fw_session_id;
308 struct tf_dev_info *dev;
309 struct tf_session *tfs;
311 /* Retrieve the session information */
312 rc = tf_session_get_session_internal(tfp, &tfs);
315 "Failed to lookup session, rc:%s\n",
320 /* Retrieve the device information */
321 rc = tf_session_get_device(tfs, &dev);
324 "Failed to lookup device, rc:%s\n",
329 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
332 "Unable to lookup FW id, rc:%s\n",
337 /* Populate the request */
338 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
340 parms.tf_type = HWRM_TF_SESSION_QCFG,
341 parms.req_data = (uint32_t *)&req;
342 parms.req_size = sizeof(req);
343 parms.resp_data = (uint32_t *)&resp;
344 parms.resp_size = sizeof(resp);
345 parms.mailbox = dev->ops->tf_dev_get_mailbox();
347 rc = tfp_send_msg_direct(tfp,
353 tf_msg_session_resc_qcaps(struct tf *tfp,
354 struct tf_dev_info *dev,
357 struct tf_rm_resc_req_entry *query,
358 enum tf_rm_resc_resv_strategy *resv_strategy)
362 struct tfp_send_msg_parms parms = { 0 };
363 struct hwrm_tf_session_resc_qcaps_input req = { 0 };
364 struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
365 uint8_t fw_session_id;
366 struct tf_msg_dma_buf qcaps_buf = { 0 };
367 struct tf_rm_resc_req_entry *data;
370 TF_CHECK_PARMS3(tfp, query, resv_strategy);
372 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
375 "%s: Unable to lookup FW id, rc:%s\n",
381 /* Prepare DMA buffer */
382 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
383 rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
387 /* Populate the request */
388 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
389 req.flags = tfp_cpu_to_le_16(dir);
390 req.qcaps_size = size;
391 req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
393 parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
394 parms.req_data = (uint32_t *)&req;
395 parms.req_size = sizeof(req);
396 parms.resp_data = (uint32_t *)&resp;
397 parms.resp_size = sizeof(resp);
398 parms.mailbox = dev->ops->tf_dev_get_mailbox();
400 rc = tfp_send_msg_direct(tfp, &parms);
404 /* Process the response
405 * Should always get expected number of entries
407 if (tfp_le_to_cpu_32(resp.size) != size) {
409 "%s: QCAPS message size error, rc:%s\n",
416 /* Post process the response */
417 data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
419 for (i = 0; i < size; i++) {
420 query[i].type = tfp_le_to_cpu_32(data[i].type);
421 query[i].min = tfp_le_to_cpu_16(data[i].min);
422 query[i].max = tfp_le_to_cpu_16(data[i].max);
425 *resv_strategy = resp.flags &
426 HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
429 tf_msg_free_dma_buf(&qcaps_buf);
435 tf_msg_session_resc_alloc(struct tf *tfp,
436 struct tf_dev_info *dev,
439 struct tf_rm_resc_req_entry *request,
440 struct tf_rm_resc_entry *resv)
444 struct tfp_send_msg_parms parms = { 0 };
445 struct hwrm_tf_session_resc_alloc_input req = { 0 };
446 struct hwrm_tf_session_resc_alloc_output resp = { 0 };
447 uint8_t fw_session_id;
448 struct tf_msg_dma_buf req_buf = { 0 };
449 struct tf_msg_dma_buf resv_buf = { 0 };
450 struct tf_rm_resc_req_entry *req_data;
451 struct tf_rm_resc_entry *resv_data;
454 TF_CHECK_PARMS3(tfp, request, resv);
456 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
459 "%s: Unable to lookup FW id, rc:%s\n",
465 /* Prepare DMA buffers */
466 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
467 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
471 dma_size = size * sizeof(struct tf_rm_resc_entry);
472 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
474 tf_msg_free_dma_buf(&req_buf);
478 /* Populate the request */
479 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
480 req.flags = tfp_cpu_to_le_16(dir);
483 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
484 for (i = 0; i < size; i++) {
485 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
486 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
487 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
490 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
491 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
493 parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
494 parms.req_data = (uint32_t *)&req;
495 parms.req_size = sizeof(req);
496 parms.resp_data = (uint32_t *)&resp;
497 parms.resp_size = sizeof(resp);
498 parms.mailbox = dev->ops->tf_dev_get_mailbox();
500 rc = tfp_send_msg_direct(tfp, &parms);
504 /* Process the response
505 * Should always get expected number of entries
507 if (tfp_le_to_cpu_32(resp.size) != size) {
509 "%s: Alloc message size error, rc:%s\n",
516 /* Post process the response */
517 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
518 for (i = 0; i < size; i++) {
519 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
520 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
521 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
525 tf_msg_free_dma_buf(&req_buf);
526 tf_msg_free_dma_buf(&resv_buf);
532 tf_msg_session_resc_flush(struct tf *tfp,
535 struct tf_rm_resc_entry *resv)
539 struct tfp_send_msg_parms parms = { 0 };
540 struct hwrm_tf_session_resc_flush_input req = { 0 };
541 struct hwrm_tf_session_resc_flush_output resp = { 0 };
542 uint8_t fw_session_id;
543 struct tf_msg_dma_buf resv_buf = { 0 };
544 struct tf_rm_resc_entry *resv_data;
546 struct tf_dev_info *dev;
547 struct tf_session *tfs;
549 TF_CHECK_PARMS2(tfp, resv);
551 /* Retrieve the session information */
552 rc = tf_session_get_session_internal(tfp, &tfs);
555 "%s: Failed to lookup session, rc:%s\n",
561 /* Retrieve the device information */
562 rc = tf_session_get_device(tfs, &dev);
565 "%s: Failed to lookup device, rc:%s\n",
571 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
574 "%s: Unable to lookup FW id, rc:%s\n",
580 /* Prepare DMA buffers */
581 dma_size = size * sizeof(struct tf_rm_resc_entry);
582 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
586 /* Populate the request */
587 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
588 req.flags = tfp_cpu_to_le_16(dir);
589 req.flush_size = size;
591 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
592 for (i = 0; i < size; i++) {
593 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
594 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
595 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
598 req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
600 parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
601 parms.req_data = (uint32_t *)&req;
602 parms.req_size = sizeof(req);
603 parms.resp_data = (uint32_t *)&resp;
604 parms.resp_size = sizeof(resp);
605 parms.mailbox = dev->ops->tf_dev_get_mailbox();
607 rc = tfp_send_msg_direct(tfp, &parms);
609 tf_msg_free_dma_buf(&resv_buf);
615 tf_msg_insert_em_internal_entry(struct tf *tfp,
616 struct tf_insert_em_entry_parms *em_parms,
617 uint16_t *rptr_index,
619 uint8_t *num_of_entries)
622 struct tfp_send_msg_parms parms = { 0 };
623 struct hwrm_tf_em_insert_input req = { 0 };
624 struct hwrm_tf_em_insert_output resp = { 0 };
625 struct tf_em_64b_entry *em_result =
626 (struct tf_em_64b_entry *)em_parms->em_record;
628 uint8_t fw_session_id;
629 uint8_t msg_key_size;
630 struct tf_dev_info *dev;
631 struct tf_session *tfs;
633 /* Retrieve the session information */
634 rc = tf_session_get_session_internal(tfp, &tfs);
637 "%s: Failed to lookup session, rc:%s\n",
638 tf_dir_2_str(em_parms->dir),
643 /* Retrieve the device information */
644 rc = tf_session_get_device(tfs, &dev);
647 "%s: Failed to lookup device, rc:%s\n",
648 tf_dir_2_str(em_parms->dir),
653 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
656 "%s: Unable to lookup FW id, rc:%s\n",
657 tf_dir_2_str(em_parms->dir),
662 /* Populate the request */
663 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
665 /* Check for key size conformity */
666 msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
667 if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
670 "%s: Invalid parameters for msg type, rc:%s\n",
671 tf_dir_2_str(em_parms->dir),
676 tfp_memcpy(req.em_key,
680 flags = (em_parms->dir == TF_DIR_TX ?
681 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
682 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
683 req.flags = tfp_cpu_to_le_16(flags);
684 req.strength = (em_result->hdr.word1 &
685 CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
686 CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
687 req.em_key_bitlen = em_parms->key_sz_in_bits;
688 req.action_ptr = em_result->hdr.pointer;
689 req.em_record_idx = *rptr_index;
691 parms.tf_type = HWRM_TF_EM_INSERT;
692 parms.req_data = (uint32_t *)&req;
693 parms.req_size = sizeof(req);
694 parms.resp_data = (uint32_t *)&resp;
695 parms.resp_size = sizeof(resp);
696 parms.mailbox = dev->ops->tf_dev_get_mailbox();
698 rc = tfp_send_msg_direct(tfp,
703 *rptr_entry = resp.rptr_entry;
704 *rptr_index = resp.rptr_index;
705 *num_of_entries = resp.num_of_entries;
711 tf_msg_delete_em_entry(struct tf *tfp,
712 struct tf_delete_em_entry_parms *em_parms)
715 struct tfp_send_msg_parms parms = { 0 };
716 struct hwrm_tf_em_delete_input req = { 0 };
717 struct hwrm_tf_em_delete_output resp = { 0 };
719 uint8_t fw_session_id;
720 struct tf_dev_info *dev;
721 struct tf_session *tfs;
723 /* Retrieve the session information */
724 rc = tf_session_get_session_internal(tfp, &tfs);
727 "%s: Failed to lookup session, rc:%s\n",
728 tf_dir_2_str(em_parms->dir),
733 /* Retrieve the device information */
734 rc = tf_session_get_device(tfs, &dev);
737 "%s: Failed to lookup device, rc:%s\n",
738 tf_dir_2_str(em_parms->dir),
743 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
746 "%s: Unable to lookup FW id, rc:%s\n",
747 tf_dir_2_str(em_parms->dir),
752 /* Populate the request */
753 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
755 flags = (em_parms->dir == TF_DIR_TX ?
756 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
757 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
758 req.flags = tfp_cpu_to_le_16(flags);
759 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
761 parms.tf_type = HWRM_TF_EM_DELETE;
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 = dev->ops->tf_dev_get_mailbox();
768 rc = tfp_send_msg_direct(tfp,
773 em_parms->index = tfp_le_to_cpu_16(resp.em_index);
779 tf_msg_em_mem_rgtr(struct tf *tfp,
786 struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
787 struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
788 struct tfp_send_msg_parms parms = { 0 };
789 struct tf_dev_info *dev;
790 struct tf_session *tfs;
792 /* Retrieve the session information */
793 rc = tf_session_get_session_internal(tfp, &tfs);
796 "Failed to lookup session, rc:%s\n",
801 /* Retrieve the device information */
802 rc = tf_session_get_device(tfs, &dev);
805 "Failed to lookup device, rc:%s\n",
810 req.page_level = page_lvl;
811 req.page_size = page_size;
812 req.page_dir = tfp_cpu_to_le_64(dma_addr);
814 parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
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 = dev->ops->tf_dev_get_mailbox();
821 rc = tfp_send_msg_direct(tfp,
826 *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
832 tf_msg_em_mem_unrgtr(struct tf *tfp,
836 struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
837 struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
838 struct tfp_send_msg_parms parms = { 0 };
839 struct tf_dev_info *dev;
840 struct tf_session *tfs;
842 /* Retrieve the session information */
843 rc = tf_session_get_session_internal(tfp, &tfs);
846 "Failed to lookup session, rc:%s\n",
851 /* Retrieve the device information */
852 rc = tf_session_get_device(tfs, &dev);
855 "Failed to lookup device, rc:%s\n",
860 req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
862 parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
863 parms.req_data = (uint32_t *)&req;
864 parms.req_size = sizeof(req);
865 parms.resp_data = (uint32_t *)&resp;
866 parms.resp_size = sizeof(resp);
867 parms.mailbox = dev->ops->tf_dev_get_mailbox();
869 rc = tfp_send_msg_direct(tfp,
875 tf_msg_em_qcaps(struct tf *tfp,
877 struct tf_em_caps *em_caps)
880 struct hwrm_tf_ext_em_qcaps_input req = {0};
881 struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
883 struct tfp_send_msg_parms parms = { 0 };
884 struct tf_dev_info *dev;
885 struct tf_session *tfs;
887 /* Retrieve the session information */
888 rc = tf_session_get_session_internal(tfp, &tfs);
891 "%s: Failed to lookup session, rc:%s\n",
897 /* Retrieve the device information */
898 rc = tf_session_get_device(tfs, &dev);
901 "%s: Failed to lookup device, rc:%s\n",
907 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
908 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
909 req.flags = tfp_cpu_to_le_32(flags);
911 parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
912 parms.req_data = (uint32_t *)&req;
913 parms.req_size = sizeof(req);
914 parms.resp_data = (uint32_t *)&resp;
915 parms.resp_size = sizeof(resp);
916 parms.mailbox = dev->ops->tf_dev_get_mailbox();
918 rc = tfp_send_msg_direct(tfp,
923 em_caps->supported = tfp_le_to_cpu_32(resp.supported);
924 em_caps->max_entries_supported =
925 tfp_le_to_cpu_32(resp.max_entries_supported);
926 em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
927 em_caps->record_entry_size =
928 tfp_le_to_cpu_16(resp.record_entry_size);
929 em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
935 tf_msg_em_cfg(struct tf *tfp,
936 uint32_t num_entries,
937 uint16_t key0_ctx_id,
938 uint16_t key1_ctx_id,
939 uint16_t record_ctx_id,
941 uint8_t flush_interval,
945 struct hwrm_tf_ext_em_cfg_input req = {0};
946 struct hwrm_tf_ext_em_cfg_output resp = {0};
948 struct tfp_send_msg_parms parms = { 0 };
949 struct tf_dev_info *dev;
950 struct tf_session *tfs;
952 /* Retrieve the session information */
953 rc = tf_session_get_session_internal(tfp, &tfs);
956 "%s: Failed to lookup session, rc:%s\n",
962 /* Retrieve the device information */
963 rc = tf_session_get_device(tfs, &dev);
966 "%s: Failed to lookup device, rc:%s\n",
972 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
973 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
974 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
976 req.flags = tfp_cpu_to_le_32(flags);
977 req.num_entries = tfp_cpu_to_le_32(num_entries);
979 req.flush_interval = flush_interval;
981 req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
982 req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
983 req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
984 req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
986 parms.tf_type = HWRM_TF_EXT_EM_CFG;
987 parms.req_data = (uint32_t *)&req;
988 parms.req_size = sizeof(req);
989 parms.resp_data = (uint32_t *)&resp;
990 parms.resp_size = sizeof(resp);
991 parms.mailbox = dev->ops->tf_dev_get_mailbox();
993 rc = tfp_send_msg_direct(tfp,
999 tf_msg_em_op(struct tf *tfp,
1004 struct hwrm_tf_ext_em_op_input req = {0};
1005 struct hwrm_tf_ext_em_op_output resp = {0};
1007 struct tfp_send_msg_parms parms = { 0 };
1008 struct tf_dev_info *dev;
1009 struct tf_session *tfs;
1011 /* Retrieve the session information */
1012 rc = tf_session_get_session_internal(tfp, &tfs);
1015 "%s: Failed to lookup session, rc:%s\n",
1021 /* Retrieve the device information */
1022 rc = tf_session_get_device(tfs, &dev);
1025 "%s: Failed to lookup device, rc:%s\n",
1031 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1032 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1033 req.flags = tfp_cpu_to_le_32(flags);
1034 req.op = tfp_cpu_to_le_16(op);
1036 parms.tf_type = HWRM_TF_EXT_EM_OP;
1037 parms.req_data = (uint32_t *)&req;
1038 parms.req_size = sizeof(req);
1039 parms.resp_data = (uint32_t *)&resp;
1040 parms.resp_size = sizeof(resp);
1041 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1043 rc = tfp_send_msg_direct(tfp,
1049 tf_msg_tcam_entry_set(struct tf *tfp,
1050 struct tf_dev_info *dev,
1051 struct tf_tcam_set_parms *parms)
1054 struct tfp_send_msg_parms mparms = { 0 };
1055 struct hwrm_tf_tcam_set_input req = { 0 };
1056 struct hwrm_tf_tcam_set_output resp = { 0 };
1057 struct tf_msg_dma_buf buf = { 0 };
1058 uint8_t *data = NULL;
1060 uint8_t fw_session_id;
1062 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1065 "%s: Unable to lookup FW id, rc:%s\n",
1066 tf_dir_2_str(parms->dir),
1071 /* Populate the request */
1072 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1073 req.type = parms->hcapi_type;
1074 req.idx = tfp_cpu_to_le_16(parms->idx);
1075 if (parms->dir == TF_DIR_TX)
1076 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
1078 req.key_size = parms->key_size;
1079 req.mask_offset = parms->key_size;
1080 /* Result follows after key and mask, thus multiply by 2 */
1081 req.result_offset = 2 * parms->key_size;
1082 req.result_size = parms->result_size;
1083 data_size = 2 * req.key_size + req.result_size;
1085 if (data_size <= TF_PCI_BUF_SIZE_MAX) {
1086 /* use pci buffer */
1087 data = &req.dev_data[0];
1089 /* use dma buffer */
1090 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
1091 rc = tf_msg_alloc_dma_buf(&buf, data_size);
1095 tfp_memcpy(&req.dev_data[0],
1097 sizeof(buf.pa_addr));
1100 tfp_memcpy(&data[0], parms->key, parms->key_size);
1101 tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
1102 tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
1104 mparms.tf_type = HWRM_TF_TCAM_SET;
1105 mparms.req_data = (uint32_t *)&req;
1106 mparms.req_size = sizeof(req);
1107 mparms.resp_data = (uint32_t *)&resp;
1108 mparms.resp_size = sizeof(resp);
1109 mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1111 rc = tfp_send_msg_direct(tfp,
1115 tf_msg_free_dma_buf(&buf);
1121 tf_msg_tcam_entry_free(struct tf *tfp,
1122 struct tf_dev_info *dev,
1123 struct tf_tcam_free_parms *in_parms)
1126 struct hwrm_tf_tcam_free_input req = { 0 };
1127 struct hwrm_tf_tcam_free_output resp = { 0 };
1128 struct tfp_send_msg_parms parms = { 0 };
1129 uint8_t fw_session_id;
1131 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1134 "%s: Unable to lookup FW id, rc:%s\n",
1135 tf_dir_2_str(in_parms->dir),
1140 /* Populate the request */
1141 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1142 req.type = in_parms->hcapi_type;
1144 req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
1145 if (in_parms->dir == TF_DIR_TX)
1146 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
1148 parms.tf_type = HWRM_TF_TCAM_FREE;
1149 parms.req_data = (uint32_t *)&req;
1150 parms.req_size = sizeof(req);
1151 parms.resp_data = (uint32_t *)&resp;
1152 parms.resp_size = sizeof(resp);
1153 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1155 rc = tfp_send_msg_direct(tfp,
1161 tf_msg_set_tbl_entry(struct tf *tfp,
1163 uint16_t hcapi_type,
1169 struct hwrm_tf_tbl_type_set_input req = { 0 };
1170 struct hwrm_tf_tbl_type_set_output resp = { 0 };
1171 struct tfp_send_msg_parms parms = { 0 };
1172 uint8_t fw_session_id;
1173 struct tf_dev_info *dev;
1174 struct tf_session *tfs;
1176 /* Retrieve the session information */
1177 rc = tf_session_get_session_internal(tfp, &tfs);
1180 "%s: Failed to lookup session, rc:%s\n",
1186 /* Retrieve the device information */
1187 rc = tf_session_get_device(tfs, &dev);
1190 "%s: Failed to lookup device, rc:%s\n",
1196 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1199 "%s: Unable to lookup FW id, rc:%s\n",
1205 /* Populate the request */
1206 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1207 req.flags = tfp_cpu_to_le_16(dir);
1208 req.type = tfp_cpu_to_le_32(hcapi_type);
1209 req.size = tfp_cpu_to_le_16(size);
1210 req.index = tfp_cpu_to_le_32(index);
1212 /* Check for data size conformity */
1213 if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
1216 "%s: Invalid parameters for msg type, rc:%s\n",
1222 tfp_memcpy(&req.data,
1226 parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1227 parms.req_data = (uint32_t *)&req;
1228 parms.req_size = sizeof(req);
1229 parms.resp_data = (uint32_t *)&resp;
1230 parms.resp_size = sizeof(resp);
1231 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1233 rc = tfp_send_msg_direct(tfp,
1238 return tfp_le_to_cpu_32(parms.tf_resp_code);
1242 tf_msg_get_tbl_entry(struct tf *tfp,
1244 uint16_t hcapi_type,
1250 struct hwrm_tf_tbl_type_get_input req = { 0 };
1251 struct hwrm_tf_tbl_type_get_output resp = { 0 };
1252 struct tfp_send_msg_parms parms = { 0 };
1253 uint8_t fw_session_id;
1254 struct tf_dev_info *dev;
1255 struct tf_session *tfs;
1257 /* Retrieve the session information */
1258 rc = tf_session_get_session_internal(tfp, &tfs);
1261 "%s: Failed to lookup session, rc:%s\n",
1267 /* Retrieve the device information */
1268 rc = tf_session_get_device(tfs, &dev);
1271 "%s: Failed to lookup device, rc:%s\n",
1277 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1280 "%s: Unable to lookup FW id, rc:%s\n",
1286 /* Populate the request */
1287 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1288 req.flags = tfp_cpu_to_le_16(dir);
1289 req.type = tfp_cpu_to_le_32(hcapi_type);
1290 req.index = tfp_cpu_to_le_32(index);
1292 parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1293 parms.req_data = (uint32_t *)&req;
1294 parms.req_size = sizeof(req);
1295 parms.resp_data = (uint32_t *)&resp;
1296 parms.resp_size = sizeof(resp);
1297 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1299 rc = tfp_send_msg_direct(tfp,
1304 /* Verify that we got enough buffer to return the requested data */
1305 if (tfp_le_to_cpu_32(resp.size) != size)
1312 return tfp_le_to_cpu_32(parms.tf_resp_code);
1315 /* HWRM Tunneled messages */
1318 tf_msg_get_global_cfg(struct tf *tfp,
1319 struct tf_global_cfg_parms *params)
1322 struct tfp_send_msg_parms parms = { 0 };
1323 struct hwrm_tf_global_cfg_get_input req = { 0 };
1324 struct hwrm_tf_global_cfg_get_output resp = { 0 };
1326 uint8_t fw_session_id;
1327 uint16_t resp_size = 0;
1328 struct tf_dev_info *dev;
1329 struct tf_session *tfs;
1331 /* Retrieve the session information */
1332 rc = tf_session_get_session_internal(tfp, &tfs);
1335 "%s: Failed to lookup session, rc:%s\n",
1336 tf_dir_2_str(params->dir),
1341 /* Retrieve the device information */
1342 rc = tf_session_get_device(tfs, &dev);
1345 "%s: Failed to lookup device, rc:%s\n",
1346 tf_dir_2_str(params->dir),
1351 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1354 "%s: Unable to lookup FW id, rc:%s\n",
1355 tf_dir_2_str(params->dir),
1360 flags = (params->dir == TF_DIR_TX ?
1361 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1362 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1364 /* Populate the request */
1365 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1366 req.flags = tfp_cpu_to_le_32(flags);
1367 req.type = tfp_cpu_to_le_32(params->type);
1368 req.offset = tfp_cpu_to_le_32(params->offset);
1369 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1371 parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1372 parms.req_data = (uint32_t *)&req;
1373 parms.req_size = sizeof(req);
1374 parms.resp_data = (uint32_t *)&resp;
1375 parms.resp_size = sizeof(resp);
1376 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1378 rc = tfp_send_msg_direct(tfp, &parms);
1382 /* Verify that we got enough buffer to return the requested data */
1383 resp_size = tfp_le_to_cpu_16(resp.size);
1384 if (resp_size < params->config_sz_in_bytes)
1388 tfp_memcpy(params->config,
1394 return tfp_le_to_cpu_32(parms.tf_resp_code);
1398 tf_msg_set_global_cfg(struct tf *tfp,
1399 struct tf_global_cfg_parms *params)
1402 struct tfp_send_msg_parms parms = { 0 };
1403 struct hwrm_tf_global_cfg_set_input req = { 0 };
1404 struct hwrm_tf_global_cfg_set_output resp = { 0 };
1406 uint8_t fw_session_id;
1407 struct tf_dev_info *dev;
1408 struct tf_session *tfs;
1410 /* Retrieve the session information */
1411 rc = tf_session_get_session_internal(tfp, &tfs);
1414 "%s: Failed to lookup session, rc:%s\n",
1415 tf_dir_2_str(params->dir),
1420 /* Retrieve the device information */
1421 rc = tf_session_get_device(tfs, &dev);
1424 "%s: Failed to lookup device, rc:%s\n",
1425 tf_dir_2_str(params->dir),
1430 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1433 "%s: Unable to lookup FW id, rc:%s\n",
1434 tf_dir_2_str(params->dir),
1439 flags = (params->dir == TF_DIR_TX ?
1440 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
1441 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
1443 /* Populate the request */
1444 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1445 req.flags = tfp_cpu_to_le_32(flags);
1446 req.type = tfp_cpu_to_le_32(params->type);
1447 req.offset = tfp_cpu_to_le_32(params->offset);
1449 /* Check for data size conformity */
1450 if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
1453 "%s: Invalid parameters for msg type, rc:%s\n",
1454 tf_dir_2_str(params->dir),
1459 tfp_memcpy(req.data, params->config,
1460 params->config_sz_in_bytes);
1462 /* Only set mask if pointer is provided
1464 if (params->config_mask) {
1465 tfp_memcpy(req.data + params->config_sz_in_bytes,
1466 params->config_mask,
1467 params->config_sz_in_bytes);
1470 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1472 parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
1473 parms.req_data = (uint32_t *)&req;
1474 parms.req_size = sizeof(req);
1475 parms.resp_data = (uint32_t *)&resp;
1476 parms.resp_size = sizeof(resp);
1477 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1479 rc = tfp_send_msg_direct(tfp, &parms);
1484 return tfp_le_to_cpu_32(parms.tf_resp_code);
1488 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
1490 uint16_t hcapi_type,
1491 uint32_t starting_idx,
1492 uint16_t num_entries,
1493 uint16_t entry_sz_in_bytes,
1494 uint64_t physical_mem_addr)
1497 struct tfp_send_msg_parms parms = { 0 };
1498 struct tf_tbl_type_bulk_get_input req = { 0 };
1499 struct tf_tbl_type_bulk_get_output resp = { 0 };
1501 uint8_t fw_session_id;
1502 struct tf_dev_info *dev;
1503 struct tf_session *tfs;
1505 /* Retrieve the session information */
1506 rc = tf_session_get_session(tfp, &tfs);
1509 "%s: Failed to lookup session, rc:%s\n",
1515 /* Retrieve the device information */
1516 rc = tf_session_get_device(tfs, &dev);
1519 "%s: Failed to lookup device, rc:%s\n",
1525 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1528 "%s: Unable to lookup FW id, rc:%s\n",
1534 /* Populate the request */
1535 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1536 req.flags = tfp_cpu_to_le_16(dir);
1537 req.type = tfp_cpu_to_le_32(hcapi_type);
1538 req.start_index = tfp_cpu_to_le_32(starting_idx);
1539 req.num_entries = tfp_cpu_to_le_32(num_entries);
1541 data_size = num_entries * entry_sz_in_bytes;
1543 req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1546 dev->ops->tf_dev_get_mailbox(),
1548 HWRM_TFT_TBL_TYPE_BULK_GET,
1552 rc = tfp_send_msg_tunneled(tfp, &parms);
1556 /* Verify that we got enough buffer to return the requested data */
1557 if (tfp_le_to_cpu_32(resp.size) != data_size)
1560 return tfp_le_to_cpu_32(parms.tf_resp_code);
1564 tf_msg_get_if_tbl_entry(struct tf *tfp,
1565 struct tf_if_tbl_get_parms *params)
1568 struct tfp_send_msg_parms parms = { 0 };
1569 struct hwrm_tf_if_tbl_get_input req = { 0 };
1570 struct hwrm_tf_if_tbl_get_output resp = { 0 };
1572 struct tf_dev_info *dev;
1573 struct tf_session *tfs;
1575 /* Retrieve the session information */
1576 rc = tf_session_get_session(tfp, &tfs);
1579 "%s: Failed to lookup session, rc:%s\n",
1580 tf_dir_2_str(params->dir),
1585 /* Retrieve the device information */
1586 rc = tf_session_get_device(tfs, &dev);
1589 "%s: Failed to lookup device, rc:%s\n",
1590 tf_dir_2_str(params->dir),
1595 flags = (params->dir == TF_DIR_TX ?
1596 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
1597 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
1599 /* Populate the request */
1601 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1603 req.type = params->hcapi_type;
1604 req.index = tfp_cpu_to_le_16(params->idx);
1605 req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1607 parms.tf_type = HWRM_TF_IF_TBL_GET;
1608 parms.req_data = (uint32_t *)&req;
1609 parms.req_size = sizeof(req);
1610 parms.resp_data = (uint32_t *)&resp;
1611 parms.resp_size = sizeof(resp);
1612 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1614 rc = tfp_send_msg_direct(tfp, &parms);
1619 if (parms.tf_resp_code != 0)
1620 return tfp_le_to_cpu_32(parms.tf_resp_code);
1622 tfp_memcpy(params->data, resp.data, req.size);
1624 return tfp_le_to_cpu_32(parms.tf_resp_code);
1628 tf_msg_set_if_tbl_entry(struct tf *tfp,
1629 struct tf_if_tbl_set_parms *params)
1632 struct tfp_send_msg_parms parms = { 0 };
1633 struct hwrm_tf_if_tbl_set_input req = { 0 };
1634 struct hwrm_tf_if_tbl_get_output resp = { 0 };
1636 struct tf_dev_info *dev;
1637 struct tf_session *tfs;
1639 /* Retrieve the session information */
1640 rc = tf_session_get_session(tfp, &tfs);
1643 "%s: Failed to lookup session, rc:%s\n",
1644 tf_dir_2_str(params->dir),
1649 /* Retrieve the device information */
1650 rc = tf_session_get_device(tfs, &dev);
1654 flags = (params->dir == TF_DIR_TX ?
1655 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1656 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1658 /* Populate the request */
1660 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1662 req.type = params->hcapi_type;
1663 req.index = tfp_cpu_to_le_32(params->idx);
1664 req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1665 tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1667 parms.tf_type = HWRM_TF_IF_TBL_SET;
1668 parms.req_data = (uint32_t *)&req;
1669 parms.req_size = sizeof(req);
1670 parms.resp_data = (uint32_t *)&resp;
1671 parms.resp_size = sizeof(resp);
1672 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1674 rc = tfp_send_msg_direct(tfp, &parms);
1679 return tfp_le_to_cpu_32(parms.tf_resp_code);