xref: /dpdk/drivers/net/bnxt/tf_core/tf_msg.c (revision 19f3ac618ab2d309e24a3034fcfdacaa6f31c718)
18430a8b8SMichael Wildt /* SPDX-License-Identifier: BSD-3-Clause
297435d79SRandy Schacher  * Copyright(c) 2019-2023 Broadcom
38430a8b8SMichael Wildt  * All rights reserved.
48430a8b8SMichael Wildt  */
58430a8b8SMichael Wildt 
698487d72SKishore Padmanabha #include <assert.h>
78430a8b8SMichael Wildt #include <inttypes.h>
88430a8b8SMichael Wildt #include <stdbool.h>
98430a8b8SMichael Wildt #include <stdlib.h>
10a46bbb57SMichael Wildt #include <string.h>
118430a8b8SMichael Wildt 
1208e1af1aSFarah Smith #include "tf_em_common.h"
138430a8b8SMichael Wildt #include "tf_msg_common.h"
148de01320SJay Ding #include "tf_device.h"
158430a8b8SMichael Wildt #include "tf_msg.h"
16a46bbb57SMichael Wildt #include "tf_util.h"
1748d3dff2SMichael Wildt #include "tf_common.h"
18a46bbb57SMichael Wildt #include "tf_session.h"
19a46bbb57SMichael Wildt #include "tfp.h"
20ae2ebb98SPeter Spreadborough #include "tf_em.h"
218430a8b8SMichael Wildt 
2298487d72SKishore Padmanabha /* Specific msg size defines as we cannot use defines in tf.yaml. This
2398487d72SKishore Padmanabha  * means we have to manually sync hwrm with these defines if the
2498487d72SKishore Padmanabha  * tf.yaml changes.
2598487d72SKishore Padmanabha  */
2698487d72SKishore Padmanabha #define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE  16
2706b997c7SFarah Smith #define TF_MSG_EM_INSERT_KEY_SIZE        64
28912abed4SFarah Smith #define TF_MSG_EM_INSERT_RECORD_SIZE     96
2998487d72SKishore Padmanabha #define TF_MSG_TBL_TYPE_SET_DATA_SIZE    88
3098487d72SKishore Padmanabha 
3198487d72SKishore Padmanabha /* Compile check - Catch any msg changes that we depend on, like the
3298487d72SKishore Padmanabha  * defines listed above for array size checking.
3398487d72SKishore Padmanabha  *
3498487d72SKishore Padmanabha  * Checking array size is dangerous in that the type could change and
3598487d72SKishore Padmanabha  * we wouldn't be able to catch it. Thus we check if the complete msg
3698487d72SKishore Padmanabha  * changed instead. Best we can do.
3798487d72SKishore Padmanabha  *
3898487d72SKishore Padmanabha  * If failure is observed then both msg size (defines below) and the
3998487d72SKishore Padmanabha  * array size (define above) should be checked and compared.
4098487d72SKishore Padmanabha  */
4198487d72SKishore Padmanabha #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56
4208e1af1aSFarah Smith static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
4308e1af1aSFarah Smith 	      TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET,
4408e1af1aSFarah Smith 	      "HWRM message size changed: hwrm_tf_global_cfg_set_input");
4508e1af1aSFarah Smith 
4698487d72SKishore Padmanabha #define TF_MSG_SIZE_HWRM_TF_EM_INSERT      104
4708e1af1aSFarah Smith static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
4808e1af1aSFarah Smith 	      TF_MSG_SIZE_HWRM_TF_EM_INSERT,
4908e1af1aSFarah Smith 	      "HWRM message size changed: hwrm_tf_em_insert_input");
5098487d72SKishore Padmanabha #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET   128
5108e1af1aSFarah Smith static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
5208e1af1aSFarah Smith 	      TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
5308e1af1aSFarah Smith 	      "HWRM message size changed: hwrm_tf_tbl_type_set_input");
5498487d72SKishore Padmanabha 
558430a8b8SMichael Wildt /**
566cf2f95dSFarah Smith  * This is the MAX data we can transport across regular HWRM
576cf2f95dSFarah Smith  */
586cf2f95dSFarah Smith #define TF_PCI_BUF_SIZE_MAX 88
596cf2f95dSFarah Smith 
606cf2f95dSFarah Smith /**
61e32312d1SJay Ding  * This is the length of shared session name "tf_share"
62e32312d1SJay Ding  */
6397435d79SRandy Schacher #define TF_SHARED_SESSION_NAME_LEN 9
64e32312d1SJay Ding 
65e32312d1SJay Ding /**
66e32312d1SJay Ding  * This is the length of tcam shared session name "tf_shared-wc_tcam"
67e32312d1SJay Ding  */
68e32312d1SJay Ding #define TF_TCAM_SHARED_SESSION_NAME_LEN 17
69e32312d1SJay Ding 
70e32312d1SJay Ding /**
7197435d79SRandy Schacher  * This is the length of tcam shared session name "tf_shared-poolx"
7297435d79SRandy Schacher  */
7397435d79SRandy Schacher #define TF_POOL_SHARED_SESSION_NAME_LEN 16
7497435d79SRandy Schacher 
7597435d79SRandy Schacher /**
766cf2f95dSFarah Smith  * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
776cf2f95dSFarah Smith  */
786cf2f95dSFarah Smith struct tf_msg_dma_buf {
796cf2f95dSFarah Smith 	void *va_addr;
806cf2f95dSFarah Smith 	uint64_t pa_addr;
816cf2f95dSFarah Smith };
826cf2f95dSFarah Smith 
836cf2f95dSFarah Smith /**
84a46bbb57SMichael Wildt  * Allocates a DMA buffer that can be used for message transfer.
85a46bbb57SMichael Wildt  *
86a46bbb57SMichael Wildt  * [in] buf
87a46bbb57SMichael Wildt  *   Pointer to DMA buffer structure
88a46bbb57SMichael Wildt  *
89a46bbb57SMichael Wildt  * [in] size
90a46bbb57SMichael Wildt  *   Requested size of the buffer in bytes
91a46bbb57SMichael Wildt  *
92a46bbb57SMichael Wildt  * Returns:
93a46bbb57SMichael Wildt  *    0      - Success
94a46bbb57SMichael Wildt  *   -ENOMEM - Unable to allocate buffer, no memory
95a46bbb57SMichael Wildt  */
96a46bbb57SMichael Wildt static int
97a46bbb57SMichael Wildt tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
98a46bbb57SMichael Wildt {
99a46bbb57SMichael Wildt 	struct tfp_calloc_parms alloc_parms;
100a46bbb57SMichael Wildt 	int rc;
101a46bbb57SMichael Wildt 
102a46bbb57SMichael Wildt 	/* Allocate session */
103a46bbb57SMichael Wildt 	alloc_parms.nitems = 1;
104a46bbb57SMichael Wildt 	alloc_parms.size = size;
105a46bbb57SMichael Wildt 	alloc_parms.alignment = 4096;
106a46bbb57SMichael Wildt 	rc = tfp_calloc(&alloc_parms);
107a46bbb57SMichael Wildt 	if (rc)
108a46bbb57SMichael Wildt 		return -ENOMEM;
109a46bbb57SMichael Wildt 
110a46bbb57SMichael Wildt 	buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
111a46bbb57SMichael Wildt 	buf->va_addr = alloc_parms.mem_va;
112a46bbb57SMichael Wildt 
113a46bbb57SMichael Wildt 	return 0;
114a46bbb57SMichael Wildt }
115a46bbb57SMichael Wildt 
116a46bbb57SMichael Wildt /**
117a46bbb57SMichael Wildt  * Free's a previous allocated DMA buffer.
118a46bbb57SMichael Wildt  *
119a46bbb57SMichael Wildt  * [in] buf
120a46bbb57SMichael Wildt  *   Pointer to DMA buffer structure
121a46bbb57SMichael Wildt  */
122a46bbb57SMichael Wildt static void
123a46bbb57SMichael Wildt tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
124a46bbb57SMichael Wildt {
125a46bbb57SMichael Wildt 	tfp_free(buf->va_addr);
126a46bbb57SMichael Wildt }
127a46bbb57SMichael Wildt 
128ca5e61bdSPeter Spreadborough /* HWRM Direct messages */
12977805a17SRandy Schacher 
1308430a8b8SMichael Wildt int
131873661aaSJay Ding tf_msg_session_open(struct bnxt *bp,
1328430a8b8SMichael Wildt 		    char *ctrl_chan_name,
133aa2be509SMichael Wildt 		    uint8_t *fw_session_id,
1343d3ab7dfSPeter Spreadborough 		    uint8_t *fw_session_client_id,
135873661aaSJay Ding 		    struct tf_dev_info *dev,
136873661aaSJay Ding 		    bool *shared_session_creator)
1378430a8b8SMichael Wildt {
1388430a8b8SMichael Wildt 	int rc;
1398430a8b8SMichael Wildt 	struct hwrm_tf_session_open_input req = { 0 };
1408430a8b8SMichael Wildt 	struct hwrm_tf_session_open_output resp = { 0 };
1418430a8b8SMichael Wildt 	struct tfp_send_msg_parms parms = { 0 };
142e32312d1SJay Ding 	char *session_name;
143e32312d1SJay Ding 	char *tcam_session_name;
14497435d79SRandy Schacher 	char *pool_session_name;
1458430a8b8SMichael Wildt 
14697435d79SRandy Schacher 	/*
14797435d79SRandy Schacher 	 * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0.
14897435d79SRandy Schacher 	 * "tf_shared-pool" is defined for version 1.0.1.
14997435d79SRandy Schacher 	 * "tf_shared" is used by both verions.
15097435d79SRandy Schacher 	 */
15197435d79SRandy Schacher 	tcam_session_name = strstr(ctrl_chan_name, "tf_shared-wc_tcam");
15297435d79SRandy Schacher 	pool_session_name = strstr(ctrl_chan_name, "tf_shared-pool");
15397435d79SRandy Schacher 	session_name = strstr(ctrl_chan_name, "tf_shared");
15497435d79SRandy Schacher 	if (tcam_session_name)
15597435d79SRandy Schacher 		tfp_memcpy(&req.session_name,
15697435d79SRandy Schacher 			   tcam_session_name,
15797435d79SRandy Schacher 			   TF_TCAM_SHARED_SESSION_NAME_LEN);
15897435d79SRandy Schacher 	else if (pool_session_name)
15997435d79SRandy Schacher 		tfp_memcpy(&req.session_name,
16097435d79SRandy Schacher 			   pool_session_name,
16197435d79SRandy Schacher 			   TF_POOL_SHARED_SESSION_NAME_LEN);
16297435d79SRandy Schacher 	else if (session_name)
16397435d79SRandy Schacher 		tfp_memcpy(&req.session_name,
16497435d79SRandy Schacher 			   session_name,
16597435d79SRandy Schacher 			   TF_SHARED_SESSION_NAME_LEN);
166b97763fcSJay Ding 	else
167a46bbb57SMichael Wildt 		tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
1688430a8b8SMichael Wildt 
1698430a8b8SMichael Wildt 	parms.tf_type = HWRM_TF_SESSION_OPEN;
1708430a8b8SMichael Wildt 	parms.req_data = (uint32_t *)&req;
1718430a8b8SMichael Wildt 	parms.req_size = sizeof(req);
1728430a8b8SMichael Wildt 	parms.resp_data = (uint32_t *)&resp;
1738430a8b8SMichael Wildt 	parms.resp_size = sizeof(resp);
1743d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1758430a8b8SMichael Wildt 
176873661aaSJay Ding 	rc = tfp_send_msg_direct(bp,
1778430a8b8SMichael Wildt 				 &parms);
1788430a8b8SMichael Wildt 	if (rc)
1798430a8b8SMichael Wildt 		return rc;
1808430a8b8SMichael Wildt 
181aa2be509SMichael Wildt 	*fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
1821ff85c97SJay Ding 	*fw_session_client_id =
1831ff85c97SJay Ding 		(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
184873661aaSJay Ding 	*shared_session_creator = (bool)tfp_le_to_cpu_32(resp.flags
185873661aaSJay Ding 		& HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR);
1868430a8b8SMichael Wildt 
1878430a8b8SMichael Wildt 	return rc;
1888430a8b8SMichael Wildt }
1898430a8b8SMichael Wildt 
190a0dcaea2SMichael Wildt int
191a0dcaea2SMichael Wildt tf_msg_session_attach(struct tf *tfp __rte_unused,
192a0dcaea2SMichael Wildt 		      char *ctrl_chan_name __rte_unused,
193a0dcaea2SMichael Wildt 		      uint8_t tf_fw_session_id __rte_unused)
194a0dcaea2SMichael Wildt {
195a0dcaea2SMichael Wildt 	return -1;
196a0dcaea2SMichael Wildt }
197a0dcaea2SMichael Wildt 
198a0dcaea2SMichael Wildt int
199aa2be509SMichael Wildt tf_msg_session_client_register(struct tf *tfp,
2003d3ab7dfSPeter Spreadborough 			       struct tf_session *tfs,
201aa2be509SMichael Wildt 			       char *ctrl_channel_name,
202aa2be509SMichael Wildt 			       uint8_t *fw_session_client_id)
203aa2be509SMichael Wildt {
204aa2be509SMichael Wildt 	int rc;
205aa2be509SMichael Wildt 	struct hwrm_tf_session_register_input req = { 0 };
206aa2be509SMichael Wildt 	struct hwrm_tf_session_register_output resp = { 0 };
207aa2be509SMichael Wildt 	struct tfp_send_msg_parms parms = { 0 };
208aa2be509SMichael Wildt 	uint8_t fw_session_id;
2093d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
210e32312d1SJay Ding 	char *session_name;
211e32312d1SJay Ding 	char *tcam_session_name;
21297435d79SRandy Schacher 	char *pool_session_name;
2133d3ab7dfSPeter Spreadborough 
2143d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
2153d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
2163d3ab7dfSPeter Spreadborough 	if (rc) {
2173d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
2183d3ab7dfSPeter Spreadborough 			    "Failed to lookup device, rc:%s\n",
2193d3ab7dfSPeter Spreadborough 			    strerror(-rc));
2203d3ab7dfSPeter Spreadborough 		return rc;
2213d3ab7dfSPeter Spreadborough 	}
222aa2be509SMichael Wildt 
223aa2be509SMichael Wildt 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
224aa2be509SMichael Wildt 	if (rc) {
225aa2be509SMichael Wildt 		TFP_DRV_LOG(ERR,
226aa2be509SMichael Wildt 			    "Unable to lookup FW id, rc:%s\n",
227aa2be509SMichael Wildt 			    strerror(-rc));
228aa2be509SMichael Wildt 		return rc;
229aa2be509SMichael Wildt 	}
230aa2be509SMichael Wildt 
231aa2be509SMichael Wildt 	/* Populate the request */
232aa2be509SMichael Wildt 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
23397435d79SRandy Schacher 
23497435d79SRandy Schacher 	/*
23597435d79SRandy Schacher 	 * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0.
23697435d79SRandy Schacher 	 * "tf_shared-pool" is defined for version 1.0.1.
23797435d79SRandy Schacher 	 * "tf_shared" is used by both verions.
23897435d79SRandy Schacher 	 */
23997435d79SRandy Schacher 	tcam_session_name = strstr(ctrl_channel_name, "tf_shared-wc_tcam");
24097435d79SRandy Schacher 	pool_session_name = strstr(ctrl_channel_name, "tf_shared-pool");
24197435d79SRandy Schacher 	session_name = strstr(ctrl_channel_name, "tf_shared");
24297435d79SRandy Schacher 	if (tcam_session_name)
243e32312d1SJay Ding 		tfp_memcpy(&req.session_client_name,
244e32312d1SJay Ding 			   tcam_session_name,
245e32312d1SJay Ding 			   TF_TCAM_SHARED_SESSION_NAME_LEN);
24697435d79SRandy Schacher 	else if (pool_session_name)
24797435d79SRandy Schacher 		tfp_memcpy(&req.session_client_name,
24897435d79SRandy Schacher 			   pool_session_name,
24997435d79SRandy Schacher 			   TF_POOL_SHARED_SESSION_NAME_LEN);
25097435d79SRandy Schacher 	else if (session_name)
251e32312d1SJay Ding 		tfp_memcpy(&req.session_client_name,
252e32312d1SJay Ding 			   session_name,
253e32312d1SJay Ding 			   TF_SHARED_SESSION_NAME_LEN);
254e32312d1SJay Ding 	else
255aa2be509SMichael Wildt 		tfp_memcpy(&req.session_client_name,
256aa2be509SMichael Wildt 			   ctrl_channel_name,
257aa2be509SMichael Wildt 			   TF_SESSION_NAME_MAX);
258aa2be509SMichael Wildt 
259aa2be509SMichael Wildt 	parms.tf_type = HWRM_TF_SESSION_REGISTER;
260aa2be509SMichael Wildt 	parms.req_data = (uint32_t *)&req;
261aa2be509SMichael Wildt 	parms.req_size = sizeof(req);
262aa2be509SMichael Wildt 	parms.resp_data = (uint32_t *)&resp;
263aa2be509SMichael Wildt 	parms.resp_size = sizeof(resp);
2643d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
265aa2be509SMichael Wildt 
266b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
267aa2be509SMichael Wildt 				 &parms);
268aa2be509SMichael Wildt 	if (rc)
269aa2be509SMichael Wildt 		return rc;
270aa2be509SMichael Wildt 
271aa2be509SMichael Wildt 	*fw_session_client_id =
272aa2be509SMichael Wildt 		(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
273aa2be509SMichael Wildt 
274aa2be509SMichael Wildt 	return rc;
275aa2be509SMichael Wildt }
276aa2be509SMichael Wildt 
277aa2be509SMichael Wildt int
278aa2be509SMichael Wildt tf_msg_session_client_unregister(struct tf *tfp,
2793d3ab7dfSPeter Spreadborough 				 struct tf_session *tfs,
280aa2be509SMichael Wildt 				 uint8_t fw_session_client_id)
281aa2be509SMichael Wildt {
282aa2be509SMichael Wildt 	int rc;
283aa2be509SMichael Wildt 	struct hwrm_tf_session_unregister_input req = { 0 };
284aa2be509SMichael Wildt 	struct hwrm_tf_session_unregister_output resp = { 0 };
285aa2be509SMichael Wildt 	struct tfp_send_msg_parms parms = { 0 };
286aa2be509SMichael Wildt 	uint8_t fw_session_id;
2873d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
2883d3ab7dfSPeter Spreadborough 
2893d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
2903d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
2913d3ab7dfSPeter Spreadborough 	if (rc) {
2923d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
2933d3ab7dfSPeter Spreadborough 			    "Failed to lookup device, rc:%s\n",
2943d3ab7dfSPeter Spreadborough 			    strerror(-rc));
2953d3ab7dfSPeter Spreadborough 		return rc;
2963d3ab7dfSPeter Spreadborough 	}
297aa2be509SMichael Wildt 
298aa2be509SMichael Wildt 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
299aa2be509SMichael Wildt 	if (rc) {
300aa2be509SMichael Wildt 		TFP_DRV_LOG(ERR,
301aa2be509SMichael Wildt 			    "Unable to lookup FW id, rc:%s\n",
302aa2be509SMichael Wildt 			    strerror(-rc));
303aa2be509SMichael Wildt 		return rc;
304aa2be509SMichael Wildt 	}
305aa2be509SMichael Wildt 
306aa2be509SMichael Wildt 	/* Populate the request */
307aa2be509SMichael Wildt 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
308aa2be509SMichael Wildt 	req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
309aa2be509SMichael Wildt 
310aa2be509SMichael Wildt 	parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
311aa2be509SMichael Wildt 	parms.req_data = (uint32_t *)&req;
312aa2be509SMichael Wildt 	parms.req_size = sizeof(req);
313aa2be509SMichael Wildt 	parms.resp_data = (uint32_t *)&resp;
314aa2be509SMichael Wildt 	parms.resp_size = sizeof(resp);
3153d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
316aa2be509SMichael Wildt 
317b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
318aa2be509SMichael Wildt 				 &parms);
319aa2be509SMichael Wildt 
320aa2be509SMichael Wildt 	return rc;
321aa2be509SMichael Wildt }
322aa2be509SMichael Wildt 
323aa2be509SMichael Wildt int
3243d3ab7dfSPeter Spreadborough tf_msg_session_close(struct tf *tfp,
325b08e34cdSJay Ding 		     uint8_t fw_session_id,
326b08e34cdSJay Ding 		     int mailbox)
327a0dcaea2SMichael Wildt {
328a0dcaea2SMichael Wildt 	int rc;
329a0dcaea2SMichael Wildt 	struct hwrm_tf_session_close_input req = { 0 };
330a0dcaea2SMichael Wildt 	struct hwrm_tf_session_close_output resp = { 0 };
331a0dcaea2SMichael Wildt 	struct tfp_send_msg_parms parms = { 0 };
332a0dcaea2SMichael Wildt 
333a0dcaea2SMichael Wildt 	/* Populate the request */
334f3502f5cSJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
335a0dcaea2SMichael Wildt 
336a0dcaea2SMichael Wildt 	parms.tf_type = HWRM_TF_SESSION_CLOSE;
337a0dcaea2SMichael Wildt 	parms.req_data = (uint32_t *)&req;
338a0dcaea2SMichael Wildt 	parms.req_size = sizeof(req);
339a0dcaea2SMichael Wildt 	parms.resp_data = (uint32_t *)&resp;
340a0dcaea2SMichael Wildt 	parms.resp_size = sizeof(resp);
341b08e34cdSJay Ding 	parms.mailbox = mailbox;
342a0dcaea2SMichael Wildt 
343b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
344a0dcaea2SMichael Wildt 				 &parms);
345a0dcaea2SMichael Wildt 	return rc;
346a0dcaea2SMichael Wildt }
347a0dcaea2SMichael Wildt 
3488430a8b8SMichael Wildt int
3498430a8b8SMichael Wildt tf_msg_session_qcfg(struct tf *tfp)
3508430a8b8SMichael Wildt {
3518430a8b8SMichael Wildt 	int rc;
3528430a8b8SMichael Wildt 	struct hwrm_tf_session_qcfg_input req = { 0 };
3538430a8b8SMichael Wildt 	struct hwrm_tf_session_qcfg_output resp = { 0 };
3548430a8b8SMichael Wildt 	struct tfp_send_msg_parms parms = { 0 };
355f3502f5cSJay Ding 	uint8_t fw_session_id;
3563d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
3573d3ab7dfSPeter Spreadborough 	struct tf_session *tfs;
3583d3ab7dfSPeter Spreadborough 
3593d3ab7dfSPeter Spreadborough 	/* Retrieve the session information */
3603d3ab7dfSPeter Spreadborough 	rc = tf_session_get_session_internal(tfp, &tfs);
3613d3ab7dfSPeter Spreadborough 	if (rc) {
3623d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
3633d3ab7dfSPeter Spreadborough 			    "Failed to lookup session, rc:%s\n",
3643d3ab7dfSPeter Spreadborough 			    strerror(-rc));
3653d3ab7dfSPeter Spreadborough 		return rc;
3663d3ab7dfSPeter Spreadborough 	}
3673d3ab7dfSPeter Spreadborough 
3683d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
3693d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
3703d3ab7dfSPeter Spreadborough 	if (rc) {
3713d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
3723d3ab7dfSPeter Spreadborough 			    "Failed to lookup device, rc:%s\n",
3733d3ab7dfSPeter Spreadborough 			    strerror(-rc));
3743d3ab7dfSPeter Spreadborough 		return rc;
3753d3ab7dfSPeter Spreadborough 	}
376f3502f5cSJay Ding 
377f3502f5cSJay Ding 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
378f3502f5cSJay Ding 	if (rc) {
379f3502f5cSJay Ding 		TFP_DRV_LOG(ERR,
380f3502f5cSJay Ding 			    "Unable to lookup FW id, rc:%s\n",
381f3502f5cSJay Ding 			    strerror(-rc));
382f3502f5cSJay Ding 		return rc;
383f3502f5cSJay Ding 	}
3848430a8b8SMichael Wildt 
3858430a8b8SMichael Wildt 	/* Populate the request */
386f3502f5cSJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
3878430a8b8SMichael Wildt 
3888430a8b8SMichael Wildt 	parms.tf_type = HWRM_TF_SESSION_QCFG,
3898430a8b8SMichael Wildt 	parms.req_data = (uint32_t *)&req;
3908430a8b8SMichael Wildt 	parms.req_size = sizeof(req);
3918430a8b8SMichael Wildt 	parms.resp_data = (uint32_t *)&resp;
3928430a8b8SMichael Wildt 	parms.resp_size = sizeof(resp);
3933d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
3948430a8b8SMichael Wildt 
395b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
3968430a8b8SMichael Wildt 				 &parms);
3978430a8b8SMichael Wildt 	return rc;
3988430a8b8SMichael Wildt }
399a0dcaea2SMichael Wildt 
400a46bbb57SMichael Wildt int
401a46bbb57SMichael Wildt tf_msg_session_resc_qcaps(struct tf *tfp,
4023d3ab7dfSPeter Spreadborough 			  struct tf_dev_info *dev,
403a46bbb57SMichael Wildt 			  enum tf_dir dir,
404a46bbb57SMichael Wildt 			  uint16_t size,
405a46bbb57SMichael Wildt 			  struct tf_rm_resc_req_entry *query,
4064d05ce4eSJay Ding 			  enum tf_rm_resc_resv_strategy *resv_strategy,
4074d05ce4eSJay Ding 			  uint8_t *sram_profile)
408a46bbb57SMichael Wildt {
409a46bbb57SMichael Wildt 	int rc;
410a46bbb57SMichael Wildt 	int i;
411a46bbb57SMichael Wildt 	struct tfp_send_msg_parms parms = { 0 };
412a46bbb57SMichael Wildt 	struct hwrm_tf_session_resc_qcaps_input req = { 0 };
413a46bbb57SMichael Wildt 	struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
414a46bbb57SMichael Wildt 	struct tf_msg_dma_buf qcaps_buf = { 0 };
415a46bbb57SMichael Wildt 	struct tf_rm_resc_req_entry *data;
416a46bbb57SMichael Wildt 	int dma_size;
417a46bbb57SMichael Wildt 
41848d3dff2SMichael Wildt 	TF_CHECK_PARMS3(tfp, query, resv_strategy);
419a46bbb57SMichael Wildt 
420a46bbb57SMichael Wildt 	/* Prepare DMA buffer */
421a46bbb57SMichael Wildt 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
422a46bbb57SMichael Wildt 	rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
423a46bbb57SMichael Wildt 	if (rc)
424a46bbb57SMichael Wildt 		return rc;
425a46bbb57SMichael Wildt 
426a46bbb57SMichael Wildt 	/* Populate the request */
4274d05ce4eSJay Ding 	req.fw_session_id = 0;
428a46bbb57SMichael Wildt 	req.flags = tfp_cpu_to_le_16(dir);
429a46bbb57SMichael Wildt 	req.qcaps_size = size;
43048d3dff2SMichael Wildt 	req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
431a46bbb57SMichael Wildt 
432a46bbb57SMichael Wildt 	parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
433a46bbb57SMichael Wildt 	parms.req_data = (uint32_t *)&req;
434a46bbb57SMichael Wildt 	parms.req_size = sizeof(req);
435a46bbb57SMichael Wildt 	parms.resp_data = (uint32_t *)&resp;
436a46bbb57SMichael Wildt 	parms.resp_size = sizeof(resp);
4373d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
438a46bbb57SMichael Wildt 
439b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
440a46bbb57SMichael Wildt 	if (rc)
441d0d22f1fSRandy Schacher 		goto cleanup;
442a46bbb57SMichael Wildt 
443a46bbb57SMichael Wildt 	/* Process the response
444a46bbb57SMichael Wildt 	 * Should always get expected number of entries
445a46bbb57SMichael Wildt 	 */
446ca5e61bdSPeter Spreadborough 	if (tfp_le_to_cpu_32(resp.size) != size) {
447c18b1b1fSJay Ding 		TFP_DRV_LOG(WARNING,
448c18b1b1fSJay Ding 			    "%s: QCAPS message size error, rc:%s, request %d vs response %d\n",
449a46bbb57SMichael Wildt 			    tf_dir_2_str(dir),
450c18b1b1fSJay Ding 			    strerror(EINVAL),
451c18b1b1fSJay Ding 			    size,
452c18b1b1fSJay Ding 			    resp.size);
453a46bbb57SMichael Wildt 	}
454a46bbb57SMichael Wildt 
455a46bbb57SMichael Wildt 	/* Post process the response */
456a46bbb57SMichael Wildt 	data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
457c18b1b1fSJay Ding 	for (i = 0; i < resp.size; i++) {
458ca5e61bdSPeter Spreadborough 		query[i].type = tfp_le_to_cpu_32(data[i].type);
459a46bbb57SMichael Wildt 		query[i].min = tfp_le_to_cpu_16(data[i].min);
460a46bbb57SMichael Wildt 		query[i].max = tfp_le_to_cpu_16(data[i].max);
461a46bbb57SMichael Wildt 	}
462a46bbb57SMichael Wildt 
463a46bbb57SMichael Wildt 	*resv_strategy = resp.flags &
464a46bbb57SMichael Wildt 	      HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
465a46bbb57SMichael Wildt 
4664d05ce4eSJay Ding 	if (sram_profile != NULL)
4674d05ce4eSJay Ding 		*sram_profile = resp.sram_profile;
4684d05ce4eSJay Ding 
469d0d22f1fSRandy Schacher cleanup:
470a46bbb57SMichael Wildt 	tf_msg_free_dma_buf(&qcaps_buf);
471a46bbb57SMichael Wildt 
472a46bbb57SMichael Wildt 	return rc;
473a46bbb57SMichael Wildt }
474a46bbb57SMichael Wildt 
475a46bbb57SMichael Wildt int
476a46bbb57SMichael Wildt tf_msg_session_resc_alloc(struct tf *tfp,
4773d3ab7dfSPeter Spreadborough 			  struct tf_dev_info *dev,
478a46bbb57SMichael Wildt 			  enum tf_dir dir,
479a46bbb57SMichael Wildt 			  uint16_t size,
480a46bbb57SMichael Wildt 			  struct tf_rm_resc_req_entry *request,
481a46bbb57SMichael Wildt 			  struct tf_rm_resc_entry *resv)
482a46bbb57SMichael Wildt {
483a46bbb57SMichael Wildt 	int rc;
484a46bbb57SMichael Wildt 	int i;
485a46bbb57SMichael Wildt 	struct tfp_send_msg_parms parms = { 0 };
486a46bbb57SMichael Wildt 	struct hwrm_tf_session_resc_alloc_input req = { 0 };
487a46bbb57SMichael Wildt 	struct hwrm_tf_session_resc_alloc_output resp = { 0 };
488a46bbb57SMichael Wildt 	uint8_t fw_session_id;
489a46bbb57SMichael Wildt 	struct tf_msg_dma_buf req_buf = { 0 };
490a46bbb57SMichael Wildt 	struct tf_msg_dma_buf resv_buf = { 0 };
491a46bbb57SMichael Wildt 	struct tf_rm_resc_req_entry *req_data;
492a46bbb57SMichael Wildt 	struct tf_rm_resc_entry *resv_data;
493a46bbb57SMichael Wildt 	int dma_size;
494873661aaSJay Ding 	struct tf_session *tfs;
495873661aaSJay Ding 
496873661aaSJay Ding 	/* Retrieve the session information */
497873661aaSJay Ding 	rc = tf_session_get_session_internal(tfp, &tfs);
498873661aaSJay Ding 	if (rc) {
499873661aaSJay Ding 		TFP_DRV_LOG(ERR,
500873661aaSJay Ding 			    "Failed to lookup session, rc:%s\n",
501873661aaSJay Ding 			    strerror(-rc));
502873661aaSJay Ding 		return rc;
503873661aaSJay Ding 	}
504a46bbb57SMichael Wildt 
50548d3dff2SMichael Wildt 	TF_CHECK_PARMS3(tfp, request, resv);
50648d3dff2SMichael Wildt 
507a46bbb57SMichael Wildt 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
508a46bbb57SMichael Wildt 	if (rc) {
509a46bbb57SMichael Wildt 		TFP_DRV_LOG(ERR,
510a46bbb57SMichael Wildt 			    "%s: Unable to lookup FW id, rc:%s\n",
511a46bbb57SMichael Wildt 			    tf_dir_2_str(dir),
512a46bbb57SMichael Wildt 			    strerror(-rc));
513a46bbb57SMichael Wildt 		return rc;
514a46bbb57SMichael Wildt 	}
515a46bbb57SMichael Wildt 
516a46bbb57SMichael Wildt 	/* Prepare DMA buffers */
517a46bbb57SMichael Wildt 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
518a46bbb57SMichael Wildt 	rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
519a46bbb57SMichael Wildt 	if (rc)
520a46bbb57SMichael Wildt 		return rc;
521a46bbb57SMichael Wildt 
522a46bbb57SMichael Wildt 	dma_size = size * sizeof(struct tf_rm_resc_entry);
523a46bbb57SMichael Wildt 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
524d0d22f1fSRandy Schacher 	if (rc) {
525d0d22f1fSRandy Schacher 		tf_msg_free_dma_buf(&req_buf);
526a46bbb57SMichael Wildt 		return rc;
527d0d22f1fSRandy Schacher 	}
528a46bbb57SMichael Wildt 
529a46bbb57SMichael Wildt 	/* Populate the request */
530a46bbb57SMichael Wildt 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
531a46bbb57SMichael Wildt 	req.flags = tfp_cpu_to_le_16(dir);
532a46bbb57SMichael Wildt 	req.req_size = size;
533a46bbb57SMichael Wildt 
534a46bbb57SMichael Wildt 	req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
535a46bbb57SMichael Wildt 	for (i = 0; i < size; i++) {
536a46bbb57SMichael Wildt 		req_data[i].type = tfp_cpu_to_le_32(request[i].type);
537a46bbb57SMichael Wildt 		req_data[i].min = tfp_cpu_to_le_16(request[i].min);
538a46bbb57SMichael Wildt 		req_data[i].max = tfp_cpu_to_le_16(request[i].max);
539a46bbb57SMichael Wildt 	}
540a46bbb57SMichael Wildt 
54148d3dff2SMichael Wildt 	req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
54248d3dff2SMichael Wildt 	req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
543a46bbb57SMichael Wildt 
544a46bbb57SMichael Wildt 	parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
545a46bbb57SMichael Wildt 	parms.req_data = (uint32_t *)&req;
546a46bbb57SMichael Wildt 	parms.req_size = sizeof(req);
547a46bbb57SMichael Wildt 	parms.resp_data = (uint32_t *)&resp;
548a46bbb57SMichael Wildt 	parms.resp_size = sizeof(resp);
5493d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
550a46bbb57SMichael Wildt 
551b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
552873661aaSJay Ding 	if (rc)
553873661aaSJay Ding 		goto cleanup;
554873661aaSJay Ding 
555873661aaSJay Ding 	/* Process the response
556873661aaSJay Ding 	 * Should always get expected number of entries
557873661aaSJay Ding 	 */
558873661aaSJay Ding 	if (tfp_le_to_cpu_32(resp.size) != size) {
559873661aaSJay Ding 		TFP_DRV_LOG(ERR,
560873661aaSJay Ding 			    "%s: Alloc message size error, rc:%s\n",
561873661aaSJay Ding 			    tf_dir_2_str(dir),
562873661aaSJay Ding 			    strerror(EINVAL));
563873661aaSJay Ding 		rc = -EINVAL;
564873661aaSJay Ding 		goto cleanup;
565873661aaSJay Ding 	}
566873661aaSJay Ding 
567873661aaSJay Ding 	/* Post process the response */
568873661aaSJay Ding 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
569873661aaSJay Ding 	for (i = 0; i < size; i++) {
570873661aaSJay Ding 		resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
571873661aaSJay Ding 		resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
572873661aaSJay Ding 		resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
573873661aaSJay Ding 	}
574873661aaSJay Ding 
575873661aaSJay Ding cleanup:
576873661aaSJay Ding 	tf_msg_free_dma_buf(&req_buf);
577873661aaSJay Ding 	tf_msg_free_dma_buf(&resv_buf);
578873661aaSJay Ding 
579873661aaSJay Ding 	return rc;
580873661aaSJay Ding }
581873661aaSJay Ding 
582873661aaSJay Ding int
583873661aaSJay Ding tf_msg_session_resc_info(struct tf *tfp,
584873661aaSJay Ding 			 struct tf_dev_info *dev,
585873661aaSJay Ding 			 enum tf_dir dir,
586873661aaSJay Ding 			 uint16_t size,
587873661aaSJay Ding 			 struct tf_rm_resc_req_entry *request,
588873661aaSJay Ding 			 struct tf_rm_resc_entry *resv)
589873661aaSJay Ding {
590873661aaSJay Ding 	int rc;
591873661aaSJay Ding 	int i;
592873661aaSJay Ding 	struct tfp_send_msg_parms parms = { 0 };
593873661aaSJay Ding 	struct hwrm_tf_session_resc_info_input req = { 0 };
594873661aaSJay Ding 	struct hwrm_tf_session_resc_info_output resp = { 0 };
595873661aaSJay Ding 	uint8_t fw_session_id;
596873661aaSJay Ding 	struct tf_msg_dma_buf req_buf = { 0 };
597873661aaSJay Ding 	struct tf_msg_dma_buf resv_buf = { 0 };
598873661aaSJay Ding 	struct tf_rm_resc_req_entry *req_data;
599873661aaSJay Ding 	struct tf_rm_resc_entry *resv_data;
600873661aaSJay Ding 	int dma_size;
601873661aaSJay Ding 	struct tf_session *tfs;
602873661aaSJay Ding 
603873661aaSJay Ding 	/* Retrieve the session information */
604873661aaSJay Ding 	rc = tf_session_get_session_internal(tfp, &tfs);
605873661aaSJay Ding 	if (rc) {
606873661aaSJay Ding 		TFP_DRV_LOG(ERR,
607873661aaSJay Ding 			    "Failed to lookup session, rc:%s\n",
608873661aaSJay Ding 			    strerror(-rc));
609873661aaSJay Ding 		return rc;
610873661aaSJay Ding 	}
611873661aaSJay Ding 
612873661aaSJay Ding 	TF_CHECK_PARMS3(tfp, request, resv);
613873661aaSJay Ding 
614873661aaSJay Ding 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
615873661aaSJay Ding 	if (rc) {
616873661aaSJay Ding 		TFP_DRV_LOG(ERR,
617873661aaSJay Ding 			    "%s: Unable to lookup FW id, rc:%s\n",
618873661aaSJay Ding 			    tf_dir_2_str(dir),
619873661aaSJay Ding 			    strerror(-rc));
620873661aaSJay Ding 		return rc;
621873661aaSJay Ding 	}
622873661aaSJay Ding 
623873661aaSJay Ding 	/* Prepare DMA buffers */
624873661aaSJay Ding 	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
625873661aaSJay Ding 	rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
626873661aaSJay Ding 	if (rc)
627873661aaSJay Ding 		return rc;
628873661aaSJay Ding 
629873661aaSJay Ding 	dma_size = size * sizeof(struct tf_rm_resc_entry);
630873661aaSJay Ding 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
631873661aaSJay Ding 	if (rc) {
632873661aaSJay Ding 		tf_msg_free_dma_buf(&req_buf);
633873661aaSJay Ding 		return rc;
634873661aaSJay Ding 	}
635873661aaSJay Ding 
636873661aaSJay Ding 	/* Populate the request */
637873661aaSJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
638873661aaSJay Ding 	req.flags = tfp_cpu_to_le_16(dir);
639873661aaSJay Ding 	req.req_size = size;
640873661aaSJay Ding 
641873661aaSJay Ding 	req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
642873661aaSJay Ding 	for (i = 0; i < size; i++) {
643873661aaSJay Ding 		req_data[i].type = tfp_cpu_to_le_32(request[i].type);
644873661aaSJay Ding 		req_data[i].min = tfp_cpu_to_le_16(request[i].min);
645873661aaSJay Ding 		req_data[i].max = tfp_cpu_to_le_16(request[i].max);
646873661aaSJay Ding 	}
647873661aaSJay Ding 
648873661aaSJay Ding 	req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
649873661aaSJay Ding 	req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
650873661aaSJay Ding 
651873661aaSJay Ding 	parms.tf_type = HWRM_TF_SESSION_RESC_INFO;
652873661aaSJay Ding 	parms.req_data = (uint32_t *)&req;
653873661aaSJay Ding 	parms.req_size = sizeof(req);
654873661aaSJay Ding 	parms.resp_data = (uint32_t *)&resp;
655873661aaSJay Ding 	parms.resp_size = sizeof(resp);
656873661aaSJay Ding 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
657873661aaSJay Ding 
658b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
659a46bbb57SMichael Wildt 	if (rc)
660d0d22f1fSRandy Schacher 		goto cleanup;
661a46bbb57SMichael Wildt 
662a46bbb57SMichael Wildt 	/* Process the response
663a46bbb57SMichael Wildt 	 * Should always get expected number of entries
664a46bbb57SMichael Wildt 	 */
665ca5e61bdSPeter Spreadborough 	if (tfp_le_to_cpu_32(resp.size) != size) {
666a46bbb57SMichael Wildt 		TFP_DRV_LOG(ERR,
66748d3dff2SMichael Wildt 			    "%s: Alloc message size error, rc:%s\n",
668a46bbb57SMichael Wildt 			    tf_dir_2_str(dir),
66998487d72SKishore Padmanabha 			    strerror(EINVAL));
670d0d22f1fSRandy Schacher 		rc = -EINVAL;
671d0d22f1fSRandy Schacher 		goto cleanup;
672a46bbb57SMichael Wildt 	}
673a46bbb57SMichael Wildt 
674a46bbb57SMichael Wildt 	/* Post process the response */
675a46bbb57SMichael Wildt 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
676a46bbb57SMichael Wildt 	for (i = 0; i < size; i++) {
677ca5e61bdSPeter Spreadborough 		resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
678ca5e61bdSPeter Spreadborough 		resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
679ca5e61bdSPeter Spreadborough 		resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
680a46bbb57SMichael Wildt 	}
681a46bbb57SMichael Wildt 
682d0d22f1fSRandy Schacher cleanup:
683a46bbb57SMichael Wildt 	tf_msg_free_dma_buf(&req_buf);
684a46bbb57SMichael Wildt 	tf_msg_free_dma_buf(&resv_buf);
685a46bbb57SMichael Wildt 
686a46bbb57SMichael Wildt 	return rc;
687a46bbb57SMichael Wildt }
688a46bbb57SMichael Wildt 
689eee264adSMichael Wildt int
690eee264adSMichael Wildt tf_msg_session_resc_flush(struct tf *tfp,
691eee264adSMichael Wildt 			  enum tf_dir dir,
692eee264adSMichael Wildt 			  uint16_t size,
693eee264adSMichael Wildt 			  struct tf_rm_resc_entry *resv)
694eee264adSMichael Wildt {
695eee264adSMichael Wildt 	int rc;
696eee264adSMichael Wildt 	int i;
697eee264adSMichael Wildt 	struct tfp_send_msg_parms parms = { 0 };
698eee264adSMichael Wildt 	struct hwrm_tf_session_resc_flush_input req = { 0 };
699eee264adSMichael Wildt 	struct hwrm_tf_session_resc_flush_output resp = { 0 };
700eee264adSMichael Wildt 	uint8_t fw_session_id;
701eee264adSMichael Wildt 	struct tf_msg_dma_buf resv_buf = { 0 };
702eee264adSMichael Wildt 	struct tf_rm_resc_entry *resv_data;
703eee264adSMichael Wildt 	int dma_size;
7043d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
7053d3ab7dfSPeter Spreadborough 	struct tf_session *tfs;
706eee264adSMichael Wildt 
707eee264adSMichael Wildt 	TF_CHECK_PARMS2(tfp, resv);
708eee264adSMichael Wildt 
7093d3ab7dfSPeter Spreadborough 	/* Retrieve the session information */
7103d3ab7dfSPeter Spreadborough 	rc = tf_session_get_session_internal(tfp, &tfs);
7113d3ab7dfSPeter Spreadborough 	if (rc) {
7123d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
7133d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup session, rc:%s\n",
7143d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(dir),
7153d3ab7dfSPeter Spreadborough 			    strerror(-rc));
7163d3ab7dfSPeter Spreadborough 		return rc;
7173d3ab7dfSPeter Spreadborough 	}
7183d3ab7dfSPeter Spreadborough 
7193d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
7203d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
7213d3ab7dfSPeter Spreadborough 	if (rc) {
7223d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
7233d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
7243d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(dir),
7253d3ab7dfSPeter Spreadborough 			    strerror(-rc));
7263d3ab7dfSPeter Spreadborough 		return rc;
7273d3ab7dfSPeter Spreadborough 	}
7283d3ab7dfSPeter Spreadborough 
729eee264adSMichael Wildt 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
730eee264adSMichael Wildt 	if (rc) {
731eee264adSMichael Wildt 		TFP_DRV_LOG(ERR,
732eee264adSMichael Wildt 			    "%s: Unable to lookup FW id, rc:%s\n",
733eee264adSMichael Wildt 			    tf_dir_2_str(dir),
734eee264adSMichael Wildt 			    strerror(-rc));
735eee264adSMichael Wildt 		return rc;
736eee264adSMichael Wildt 	}
737eee264adSMichael Wildt 
738eee264adSMichael Wildt 	/* Prepare DMA buffers */
739eee264adSMichael Wildt 	dma_size = size * sizeof(struct tf_rm_resc_entry);
740eee264adSMichael Wildt 	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
741eee264adSMichael Wildt 	if (rc)
742eee264adSMichael Wildt 		return rc;
743eee264adSMichael Wildt 
744eee264adSMichael Wildt 	/* Populate the request */
745eee264adSMichael Wildt 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
746eee264adSMichael Wildt 	req.flags = tfp_cpu_to_le_16(dir);
747eee264adSMichael Wildt 	req.flush_size = size;
748eee264adSMichael Wildt 
749eee264adSMichael Wildt 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
750eee264adSMichael Wildt 	for (i = 0; i < size; i++) {
751eee264adSMichael Wildt 		resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
752eee264adSMichael Wildt 		resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
753eee264adSMichael Wildt 		resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
754eee264adSMichael Wildt 	}
755eee264adSMichael Wildt 
756eee264adSMichael Wildt 	req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
757eee264adSMichael Wildt 
758eee264adSMichael Wildt 	parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
759eee264adSMichael Wildt 	parms.req_data = (uint32_t *)&req;
760eee264adSMichael Wildt 	parms.req_size = sizeof(req);
761eee264adSMichael Wildt 	parms.resp_data = (uint32_t *)&resp;
762eee264adSMichael Wildt 	parms.resp_size = sizeof(resp);
7633d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
764eee264adSMichael Wildt 
765b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
766eee264adSMichael Wildt 
767eee264adSMichael Wildt 	tf_msg_free_dma_buf(&resv_buf);
768eee264adSMichael Wildt 
769eee264adSMichael Wildt 	return rc;
770eee264adSMichael Wildt }
771eee264adSMichael Wildt 
772ca5e61bdSPeter Spreadborough int
773ca5e61bdSPeter Spreadborough tf_msg_insert_em_internal_entry(struct tf *tfp,
774ca5e61bdSPeter Spreadborough 				struct tf_insert_em_entry_parms *em_parms,
775ca5e61bdSPeter Spreadborough 				uint16_t *rptr_index,
776ca5e61bdSPeter Spreadborough 				uint8_t *rptr_entry,
777ca5e61bdSPeter Spreadborough 				uint8_t *num_of_entries)
778ca5e61bdSPeter Spreadborough {
779ca5e61bdSPeter Spreadborough 	int rc;
780ca5e61bdSPeter Spreadborough 	struct tfp_send_msg_parms parms = { 0 };
781ca5e61bdSPeter Spreadborough 	struct hwrm_tf_em_insert_input req = { 0 };
782ca5e61bdSPeter Spreadborough 	struct hwrm_tf_em_insert_output resp = { 0 };
783ca5e61bdSPeter Spreadborough 	struct tf_em_64b_entry *em_result =
784ca5e61bdSPeter Spreadborough 		(struct tf_em_64b_entry *)em_parms->em_record;
785d0d22f1fSRandy Schacher 	uint16_t flags;
786f3502f5cSJay Ding 	uint8_t fw_session_id;
78798487d72SKishore Padmanabha 	uint8_t msg_key_size;
7883d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
7893d3ab7dfSPeter Spreadborough 	struct tf_session *tfs;
7903d3ab7dfSPeter Spreadborough 
791902fa8b5SJay Ding 	RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_em_insert_input) !=
792902fa8b5SJay Ding 			 TF_MSG_SIZE_HWRM_TF_EM_INSERT);
793902fa8b5SJay Ding 
7943d3ab7dfSPeter Spreadborough 	/* Retrieve the session information */
7953d3ab7dfSPeter Spreadborough 	rc = tf_session_get_session_internal(tfp, &tfs);
7963d3ab7dfSPeter Spreadborough 	if (rc) {
7973d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
7983d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup session, rc:%s\n",
7993d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
8003d3ab7dfSPeter Spreadborough 			    strerror(-rc));
8013d3ab7dfSPeter Spreadborough 		return rc;
8023d3ab7dfSPeter Spreadborough 	}
8033d3ab7dfSPeter Spreadborough 
8043d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
8053d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
8063d3ab7dfSPeter Spreadborough 	if (rc) {
8073d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
8083d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
8093d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
8103d3ab7dfSPeter Spreadborough 			    strerror(-rc));
8113d3ab7dfSPeter Spreadborough 		return rc;
8123d3ab7dfSPeter Spreadborough 	}
813ca5e61bdSPeter Spreadborough 
814f3502f5cSJay Ding 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
815f3502f5cSJay Ding 	if (rc) {
816f3502f5cSJay Ding 		TFP_DRV_LOG(ERR,
817f3502f5cSJay Ding 			    "%s: Unable to lookup FW id, rc:%s\n",
818f3502f5cSJay Ding 			    tf_dir_2_str(em_parms->dir),
819f3502f5cSJay Ding 			    strerror(-rc));
820f3502f5cSJay Ding 		return rc;
821f3502f5cSJay Ding 	}
822f3502f5cSJay Ding 
823f3502f5cSJay Ding 	/* Populate the request */
824f3502f5cSJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
82598487d72SKishore Padmanabha 
82698487d72SKishore Padmanabha 	/* Check for key size conformity */
82798487d72SKishore Padmanabha 	msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
82898487d72SKishore Padmanabha 	if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
82998487d72SKishore Padmanabha 		rc = -EINVAL;
83098487d72SKishore Padmanabha 		TFP_DRV_LOG(ERR,
83198487d72SKishore Padmanabha 			    "%s: Invalid parameters for msg type, rc:%s\n",
83298487d72SKishore Padmanabha 			    tf_dir_2_str(em_parms->dir),
83398487d72SKishore Padmanabha 			    strerror(-rc));
83498487d72SKishore Padmanabha 		return rc;
83598487d72SKishore Padmanabha 	}
83698487d72SKishore Padmanabha 
837ca5e61bdSPeter Spreadborough 	tfp_memcpy(req.em_key,
838ca5e61bdSPeter Spreadborough 		   em_parms->key,
83998487d72SKishore Padmanabha 		   msg_key_size);
840ca5e61bdSPeter Spreadborough 
841ca5e61bdSPeter Spreadborough 	flags = (em_parms->dir == TF_DIR_TX ?
842ca5e61bdSPeter Spreadborough 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
843ca5e61bdSPeter Spreadborough 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
844ca5e61bdSPeter Spreadborough 	req.flags = tfp_cpu_to_le_16(flags);
845ca5e61bdSPeter Spreadborough 	req.strength = (em_result->hdr.word1 &
846ca5e61bdSPeter Spreadborough 			CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
847ca5e61bdSPeter Spreadborough 			CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
848ca5e61bdSPeter Spreadborough 	req.em_key_bitlen = em_parms->key_sz_in_bits;
849ca5e61bdSPeter Spreadborough 	req.action_ptr = em_result->hdr.pointer;
850ca5e61bdSPeter Spreadborough 	req.em_record_idx = *rptr_index;
851ca5e61bdSPeter Spreadborough 
852ca5e61bdSPeter Spreadborough 	parms.tf_type = HWRM_TF_EM_INSERT;
853ca5e61bdSPeter Spreadborough 	parms.req_data = (uint32_t *)&req;
854ca5e61bdSPeter Spreadborough 	parms.req_size = sizeof(req);
855ca5e61bdSPeter Spreadborough 	parms.resp_data = (uint32_t *)&resp;
856ca5e61bdSPeter Spreadborough 	parms.resp_size = sizeof(resp);
8573d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
858ca5e61bdSPeter Spreadborough 
859b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
860ca5e61bdSPeter Spreadborough 				 &parms);
861ca5e61bdSPeter Spreadborough 	if (rc)
862ca5e61bdSPeter Spreadborough 		return rc;
863ca5e61bdSPeter Spreadborough 
864ca5e61bdSPeter Spreadborough 	*rptr_entry = resp.rptr_entry;
865ca5e61bdSPeter Spreadborough 	*rptr_index = resp.rptr_index;
866ca5e61bdSPeter Spreadborough 	*num_of_entries = resp.num_of_entries;
867ca5e61bdSPeter Spreadborough 
868ca5e61bdSPeter Spreadborough 	return 0;
869ca5e61bdSPeter Spreadborough }
870ca5e61bdSPeter Spreadborough 
871ca5e61bdSPeter Spreadborough int
872539931eaSPeter Spreadborough tf_msg_hash_insert_em_internal_entry(struct tf *tfp,
873539931eaSPeter Spreadborough 				     struct tf_insert_em_entry_parms *em_parms,
874539931eaSPeter Spreadborough 				     uint32_t key0_hash,
875539931eaSPeter Spreadborough 				     uint32_t key1_hash,
876539931eaSPeter Spreadborough 				     uint16_t *rptr_index,
877539931eaSPeter Spreadborough 				     uint8_t *rptr_entry,
878539931eaSPeter Spreadborough 				     uint8_t *num_of_entries)
879539931eaSPeter Spreadborough {
880539931eaSPeter Spreadborough 	int rc;
881539931eaSPeter Spreadborough 	struct tfp_send_msg_parms parms = { 0 };
882539931eaSPeter Spreadborough 	struct hwrm_tf_em_hash_insert_input req = { 0 };
883539931eaSPeter Spreadborough 	struct hwrm_tf_em_hash_insert_output resp = { 0 };
884539931eaSPeter Spreadborough 	uint16_t flags;
885539931eaSPeter Spreadborough 	uint8_t fw_session_id;
886539931eaSPeter Spreadborough 	uint8_t msg_record_size;
887539931eaSPeter Spreadborough 	struct tf_dev_info *dev;
888539931eaSPeter Spreadborough 	struct tf_session *tfs;
889539931eaSPeter Spreadborough 
890539931eaSPeter Spreadborough 	/* Retrieve the session information */
891539931eaSPeter Spreadborough 	rc = tf_session_get_session_internal(tfp, &tfs);
892539931eaSPeter Spreadborough 	if (rc) {
893539931eaSPeter Spreadborough 		TFP_DRV_LOG(ERR,
894539931eaSPeter Spreadborough 			    "%s: Failed to lookup session, rc:%s\n",
895539931eaSPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
896539931eaSPeter Spreadborough 			    strerror(-rc));
897539931eaSPeter Spreadborough 		return rc;
898539931eaSPeter Spreadborough 	}
899539931eaSPeter Spreadborough 
900539931eaSPeter Spreadborough 	/* Retrieve the device information */
901539931eaSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
902539931eaSPeter Spreadborough 	if (rc) {
903539931eaSPeter Spreadborough 		TFP_DRV_LOG(ERR,
904539931eaSPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
905539931eaSPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
906539931eaSPeter Spreadborough 			    strerror(-rc));
907539931eaSPeter Spreadborough 		return rc;
908539931eaSPeter Spreadborough 	}
909539931eaSPeter Spreadborough 
910539931eaSPeter Spreadborough 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
911539931eaSPeter Spreadborough 	if (rc) {
912539931eaSPeter Spreadborough 		TFP_DRV_LOG(ERR,
913539931eaSPeter Spreadborough 			    "%s: Unable to lookup FW id, rc:%s\n",
914539931eaSPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
915539931eaSPeter Spreadborough 			    strerror(-rc));
916539931eaSPeter Spreadborough 		return rc;
917539931eaSPeter Spreadborough 	}
918539931eaSPeter Spreadborough 
919539931eaSPeter Spreadborough 	/* Populate the request */
920539931eaSPeter Spreadborough 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
921539931eaSPeter Spreadborough 
922539931eaSPeter Spreadborough 	/* Check for key size conformity */
923539931eaSPeter Spreadborough 	msg_record_size = (em_parms->em_record_sz_in_bits + 7) / 8;
924539931eaSPeter Spreadborough 
925539931eaSPeter Spreadborough 	if (msg_record_size > TF_MSG_EM_INSERT_RECORD_SIZE) {
926539931eaSPeter Spreadborough 		rc = -EINVAL;
927539931eaSPeter Spreadborough 		TFP_DRV_LOG(ERR,
9288a2e845dSKishore Padmanabha 			    "%s: Record size too large, rc:%s\n",
929539931eaSPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
930539931eaSPeter Spreadborough 			    strerror(-rc));
931539931eaSPeter Spreadborough 		return rc;
932539931eaSPeter Spreadborough 	}
933539931eaSPeter Spreadborough 
934539931eaSPeter Spreadborough 	tfp_memcpy((char *)req.em_record,
935539931eaSPeter Spreadborough 		   em_parms->em_record,
936539931eaSPeter Spreadborough 		   msg_record_size);
937539931eaSPeter Spreadborough 
938539931eaSPeter Spreadborough 	flags = (em_parms->dir == TF_DIR_TX ?
939539931eaSPeter Spreadborough 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
940539931eaSPeter Spreadborough 		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
941539931eaSPeter Spreadborough 	req.flags = tfp_cpu_to_le_16(flags);
942539931eaSPeter Spreadborough 	req.em_record_size_bits = em_parms->em_record_sz_in_bits;
943539931eaSPeter Spreadborough 	req.em_record_idx = *rptr_index;
944539931eaSPeter Spreadborough 	req.key0_hash = key0_hash;
945539931eaSPeter Spreadborough 	req.key1_hash = key1_hash;
946539931eaSPeter Spreadborough 
947539931eaSPeter Spreadborough 	parms.tf_type = HWRM_TF_EM_HASH_INSERT;
948539931eaSPeter Spreadborough 	parms.req_data = (uint32_t *)&req;
949539931eaSPeter Spreadborough 	parms.req_size = sizeof(req);
950539931eaSPeter Spreadborough 	parms.resp_data = (uint32_t *)&resp;
951539931eaSPeter Spreadborough 	parms.resp_size = sizeof(resp);
952539931eaSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
953539931eaSPeter Spreadborough 
954b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
955539931eaSPeter Spreadborough 				 &parms);
956539931eaSPeter Spreadborough 	if (rc)
957539931eaSPeter Spreadborough 		return rc;
958539931eaSPeter Spreadborough 
959539931eaSPeter Spreadborough 	*rptr_entry = resp.rptr_entry;
960539931eaSPeter Spreadborough 	*rptr_index = resp.rptr_index;
961539931eaSPeter Spreadborough 	*num_of_entries = resp.num_of_entries;
962539931eaSPeter Spreadborough 
963539931eaSPeter Spreadborough 	return 0;
964539931eaSPeter Spreadborough }
965539931eaSPeter Spreadborough 
966539931eaSPeter Spreadborough int
967ca5e61bdSPeter Spreadborough tf_msg_delete_em_entry(struct tf *tfp,
968ca5e61bdSPeter Spreadborough 		       struct tf_delete_em_entry_parms *em_parms)
969ca5e61bdSPeter Spreadborough {
970ca5e61bdSPeter Spreadborough 	int rc;
971ca5e61bdSPeter Spreadborough 	struct tfp_send_msg_parms parms = { 0 };
972ca5e61bdSPeter Spreadborough 	struct hwrm_tf_em_delete_input req = { 0 };
973ca5e61bdSPeter Spreadborough 	struct hwrm_tf_em_delete_output resp = { 0 };
974d0d22f1fSRandy Schacher 	uint16_t flags;
975f3502f5cSJay Ding 	uint8_t fw_session_id;
9763d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
9773d3ab7dfSPeter Spreadborough 	struct tf_session *tfs;
9783d3ab7dfSPeter Spreadborough 
9793d3ab7dfSPeter Spreadborough 	/* Retrieve the session information */
9803d3ab7dfSPeter Spreadborough 	rc = tf_session_get_session_internal(tfp, &tfs);
9813d3ab7dfSPeter Spreadborough 	if (rc) {
9823d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
9833d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup session, rc:%s\n",
9843d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
9853d3ab7dfSPeter Spreadborough 			    strerror(-rc));
9863d3ab7dfSPeter Spreadborough 		return rc;
9873d3ab7dfSPeter Spreadborough 	}
9883d3ab7dfSPeter Spreadborough 
9893d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
9903d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
9913d3ab7dfSPeter Spreadborough 	if (rc) {
9923d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
9933d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
9943d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
9953d3ab7dfSPeter Spreadborough 			    strerror(-rc));
9963d3ab7dfSPeter Spreadborough 		return rc;
9973d3ab7dfSPeter Spreadborough 	}
998ca5e61bdSPeter Spreadborough 
999f3502f5cSJay Ding 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1000f3502f5cSJay Ding 	if (rc) {
1001f3502f5cSJay Ding 		TFP_DRV_LOG(ERR,
1002f3502f5cSJay Ding 			    "%s: Unable to lookup FW id, rc:%s\n",
1003f3502f5cSJay Ding 			    tf_dir_2_str(em_parms->dir),
1004f3502f5cSJay Ding 			    strerror(-rc));
1005f3502f5cSJay Ding 		return rc;
1006f3502f5cSJay Ding 	}
1007f3502f5cSJay Ding 
1008f3502f5cSJay Ding 	/* Populate the request */
1009f3502f5cSJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1010ca5e61bdSPeter Spreadborough 
1011ca5e61bdSPeter Spreadborough 	flags = (em_parms->dir == TF_DIR_TX ?
1012ca5e61bdSPeter Spreadborough 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
1013ca5e61bdSPeter Spreadborough 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
1014ca5e61bdSPeter Spreadborough 	req.flags = tfp_cpu_to_le_16(flags);
1015ca5e61bdSPeter Spreadborough 	req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
1016ca5e61bdSPeter Spreadborough 
1017ca5e61bdSPeter Spreadborough 	parms.tf_type = HWRM_TF_EM_DELETE;
1018ca5e61bdSPeter Spreadborough 	parms.req_data = (uint32_t *)&req;
1019ca5e61bdSPeter Spreadborough 	parms.req_size = sizeof(req);
1020ca5e61bdSPeter Spreadborough 	parms.resp_data = (uint32_t *)&resp;
1021ca5e61bdSPeter Spreadborough 	parms.resp_size = sizeof(resp);
10223d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1023ca5e61bdSPeter Spreadborough 
1024b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1025ca5e61bdSPeter Spreadborough 				 &parms);
1026ca5e61bdSPeter Spreadborough 	if (rc)
1027ca5e61bdSPeter Spreadborough 		return rc;
1028ca5e61bdSPeter Spreadborough 
1029ca5e61bdSPeter Spreadborough 	em_parms->index = tfp_le_to_cpu_16(resp.em_index);
1030ca5e61bdSPeter Spreadborough 
1031ca5e61bdSPeter Spreadborough 	return 0;
1032ca5e61bdSPeter Spreadborough }
1033ca5e61bdSPeter Spreadborough 
103405b405d5SPeter Spreadborough int
103505b405d5SPeter Spreadborough tf_msg_move_em_entry(struct tf *tfp,
103605b405d5SPeter Spreadborough 		     struct tf_move_em_entry_parms *em_parms)
103705b405d5SPeter Spreadborough {
103805b405d5SPeter Spreadborough 	int rc;
103905b405d5SPeter Spreadborough 	struct tfp_send_msg_parms parms = { 0 };
104005b405d5SPeter Spreadborough 	struct hwrm_tf_em_move_input req = { 0 };
104105b405d5SPeter Spreadborough 	struct hwrm_tf_em_move_output resp = { 0 };
104205b405d5SPeter Spreadborough 	uint16_t flags;
104305b405d5SPeter Spreadborough 	uint8_t fw_session_id;
104405b405d5SPeter Spreadborough 	struct tf_dev_info *dev;
104505b405d5SPeter Spreadborough 	struct tf_session *tfs;
104605b405d5SPeter Spreadborough 
104705b405d5SPeter Spreadborough 	/* Retrieve the session information */
104805b405d5SPeter Spreadborough 	rc = tf_session_get_session_internal(tfp, &tfs);
104905b405d5SPeter Spreadborough 	if (rc) {
105005b405d5SPeter Spreadborough 		TFP_DRV_LOG(ERR,
105105b405d5SPeter Spreadborough 			    "%s: Failed to lookup session, rc:%s\n",
105205b405d5SPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
105305b405d5SPeter Spreadborough 			    strerror(-rc));
105405b405d5SPeter Spreadborough 		return rc;
105505b405d5SPeter Spreadborough 	}
105605b405d5SPeter Spreadborough 
105705b405d5SPeter Spreadborough 	/* Retrieve the device information */
105805b405d5SPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
105905b405d5SPeter Spreadborough 	if (rc) {
106005b405d5SPeter Spreadborough 		TFP_DRV_LOG(ERR,
106105b405d5SPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
106205b405d5SPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
106305b405d5SPeter Spreadborough 			    strerror(-rc));
106405b405d5SPeter Spreadborough 		return rc;
106505b405d5SPeter Spreadborough 	}
106605b405d5SPeter Spreadborough 
106705b405d5SPeter Spreadborough 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
106805b405d5SPeter Spreadborough 	if (rc) {
106905b405d5SPeter Spreadborough 		TFP_DRV_LOG(ERR,
107005b405d5SPeter Spreadborough 			    "%s: Unable to lookup FW id, rc:%s\n",
107105b405d5SPeter Spreadborough 			    tf_dir_2_str(em_parms->dir),
107205b405d5SPeter Spreadborough 			    strerror(-rc));
107305b405d5SPeter Spreadborough 		return rc;
107405b405d5SPeter Spreadborough 	}
107505b405d5SPeter Spreadborough 
107605b405d5SPeter Spreadborough 	/* Populate the request */
107705b405d5SPeter Spreadborough 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
107805b405d5SPeter Spreadborough 
107905b405d5SPeter Spreadborough 	flags = (em_parms->dir == TF_DIR_TX ?
108005b405d5SPeter Spreadborough 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
108105b405d5SPeter Spreadborough 		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
108205b405d5SPeter Spreadborough 	req.flags = tfp_cpu_to_le_16(flags);
108305b405d5SPeter Spreadborough 	req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
108405b405d5SPeter Spreadborough 	req.new_index = tfp_cpu_to_le_32(em_parms->new_index);
108505b405d5SPeter Spreadborough 
108605b405d5SPeter Spreadborough 	parms.tf_type = HWRM_TF_EM_MOVE;
108705b405d5SPeter Spreadborough 	parms.req_data = (uint32_t *)&req;
108805b405d5SPeter Spreadborough 	parms.req_size = sizeof(req);
108905b405d5SPeter Spreadborough 	parms.resp_data = (uint32_t *)&resp;
109005b405d5SPeter Spreadborough 	parms.resp_size = sizeof(resp);
109105b405d5SPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
109205b405d5SPeter Spreadborough 
1093b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
109405b405d5SPeter Spreadborough 				 &parms);
109505b405d5SPeter Spreadborough 	if (rc)
109605b405d5SPeter Spreadborough 		return rc;
109705b405d5SPeter Spreadborough 
109805b405d5SPeter Spreadborough 	em_parms->index = tfp_le_to_cpu_16(resp.em_index);
109905b405d5SPeter Spreadborough 
110005b405d5SPeter Spreadborough 	return 0;
110105b405d5SPeter Spreadborough }
110205b405d5SPeter Spreadborough 
1103dba3ca8bSFarah Smith int
110482fa189dSShahaji Bhosle tf_msg_tcam_entry_set(struct tf *tfp,
11053d3ab7dfSPeter Spreadborough 		      struct tf_dev_info *dev,
11068de01320SJay Ding 		      struct tf_tcam_set_parms *parms)
110782fa189dSShahaji Bhosle {
110882fa189dSShahaji Bhosle 	int rc;
110982fa189dSShahaji Bhosle 	struct tfp_send_msg_parms mparms = { 0 };
111082fa189dSShahaji Bhosle 	struct hwrm_tf_tcam_set_input req = { 0 };
111182fa189dSShahaji Bhosle 	struct hwrm_tf_tcam_set_output resp = { 0 };
111282fa189dSShahaji Bhosle 	struct tf_msg_dma_buf buf = { 0 };
111382fa189dSShahaji Bhosle 	uint8_t *data = NULL;
111482fa189dSShahaji Bhosle 	int data_size = 0;
1115b2da0248SPeter Spreadborough 	uint8_t fw_session_id;
1116873661aaSJay Ding 	struct tf_session *tfs;
1117873661aaSJay Ding 
1118873661aaSJay Ding 	/* Retrieve the session information */
1119873661aaSJay Ding 	rc = tf_session_get_session_internal(tfp, &tfs);
1120873661aaSJay Ding 	if (rc) {
1121873661aaSJay Ding 		TFP_DRV_LOG(ERR,
1122873661aaSJay Ding 			    "Failed to lookup session, rc:%s\n",
1123873661aaSJay Ding 			    strerror(-rc));
1124873661aaSJay Ding 		return rc;
1125873661aaSJay Ding 	}
112682fa189dSShahaji Bhosle 
1127b2da0248SPeter Spreadborough 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1128b2da0248SPeter Spreadborough 	if (rc) {
1129b2da0248SPeter Spreadborough 		TFP_DRV_LOG(ERR,
1130b2da0248SPeter Spreadborough 			    "%s: Unable to lookup FW id, rc:%s\n",
1131b2da0248SPeter Spreadborough 			    tf_dir_2_str(parms->dir),
1132b2da0248SPeter Spreadborough 			    strerror(-rc));
1133b2da0248SPeter Spreadborough 		return rc;
1134b2da0248SPeter Spreadborough 	}
1135b2da0248SPeter Spreadborough 
1136b2da0248SPeter Spreadborough 	/* Populate the request */
1137b2da0248SPeter Spreadborough 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1138ca5e61bdSPeter Spreadborough 	req.type = parms->hcapi_type;
113982fa189dSShahaji Bhosle 	req.idx = tfp_cpu_to_le_16(parms->idx);
114082fa189dSShahaji Bhosle 	if (parms->dir == TF_DIR_TX)
114182fa189dSShahaji Bhosle 		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
114282fa189dSShahaji Bhosle 
11438de01320SJay Ding 	req.key_size = parms->key_size;
11448de01320SJay Ding 	req.mask_offset = parms->key_size;
114582fa189dSShahaji Bhosle 	/* Result follows after key and mask, thus multiply by 2 */
11468de01320SJay Ding 	req.result_offset = 2 * parms->key_size;
11478de01320SJay Ding 	req.result_size = parms->result_size;
114882fa189dSShahaji Bhosle 	data_size = 2 * req.key_size + req.result_size;
114982fa189dSShahaji Bhosle 
115078dcdb82SShahaji Bhosle 	/*
115178dcdb82SShahaji Bhosle 	 * Always use dma buffer, as the delete multi slice
115278dcdb82SShahaji Bhosle 	 * tcam entries not support with HWRM request buffer
115378dcdb82SShahaji Bhosle 	 * only DMA'ed buffer can update the mode bits for
115478dcdb82SShahaji Bhosle 	 * the delete to work
115578dcdb82SShahaji Bhosle 	 */
115682fa189dSShahaji Bhosle 	req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
11578c37258dSShahaji Bhosle 	rc = tf_msg_alloc_dma_buf(&buf, data_size);
11588c37258dSShahaji Bhosle 	if (rc)
11598c37258dSShahaji Bhosle 		goto cleanup;
116082fa189dSShahaji Bhosle 	data = buf.va_addr;
1161a46bbb57SMichael Wildt 	tfp_memcpy(&req.dev_data[0],
1162a46bbb57SMichael Wildt 		   &buf.pa_addr,
1163a46bbb57SMichael Wildt 		   sizeof(buf.pa_addr));
116482fa189dSShahaji Bhosle 
11658de01320SJay Ding 	tfp_memcpy(&data[0], parms->key, parms->key_size);
11668de01320SJay Ding 	tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
11678de01320SJay Ding 	tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
116882fa189dSShahaji Bhosle 
116982fa189dSShahaji Bhosle 	mparms.tf_type = HWRM_TF_TCAM_SET;
117082fa189dSShahaji Bhosle 	mparms.req_data = (uint32_t *)&req;
117182fa189dSShahaji Bhosle 	mparms.req_size = sizeof(req);
117282fa189dSShahaji Bhosle 	mparms.resp_data = (uint32_t *)&resp;
117382fa189dSShahaji Bhosle 	mparms.resp_size = sizeof(resp);
11743d3ab7dfSPeter Spreadborough 	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
117582fa189dSShahaji Bhosle 
1176b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
117782fa189dSShahaji Bhosle 				 &mparms);
117882fa189dSShahaji Bhosle 
11798c37258dSShahaji Bhosle cleanup:
1180a46bbb57SMichael Wildt 	tf_msg_free_dma_buf(&buf);
118182fa189dSShahaji Bhosle 
118282fa189dSShahaji Bhosle 	return rc;
118382fa189dSShahaji Bhosle }
118482fa189dSShahaji Bhosle 
118582fa189dSShahaji Bhosle int
1186a9597be7SJay Ding tf_msg_tcam_entry_get(struct tf *tfp,
1187a9597be7SJay Ding 		      struct tf_dev_info *dev,
1188a9597be7SJay Ding 		      struct tf_tcam_get_parms *parms)
1189a9597be7SJay Ding {
1190a9597be7SJay Ding 	int rc;
1191a9597be7SJay Ding 	struct tfp_send_msg_parms mparms = { 0 };
1192a9597be7SJay Ding 	struct hwrm_tf_tcam_get_input req = { 0 };
1193a9597be7SJay Ding 	struct hwrm_tf_tcam_get_output resp = { 0 };
1194a9597be7SJay Ding 	uint8_t fw_session_id;
1195873661aaSJay Ding 	struct tf_session *tfs;
1196873661aaSJay Ding 
1197873661aaSJay Ding 	/* Retrieve the session information */
1198873661aaSJay Ding 	rc = tf_session_get_session_internal(tfp, &tfs);
1199873661aaSJay Ding 	if (rc) {
1200873661aaSJay Ding 		TFP_DRV_LOG(ERR,
1201873661aaSJay Ding 			    "Failed to lookup session, rc:%s\n",
1202873661aaSJay Ding 			    strerror(-rc));
1203873661aaSJay Ding 		return rc;
1204873661aaSJay Ding 	}
1205a9597be7SJay Ding 
1206a9597be7SJay Ding 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1207a9597be7SJay Ding 	if (rc) {
1208a9597be7SJay Ding 		TFP_DRV_LOG(ERR,
1209a9597be7SJay Ding 			    "%s: Unable to lookup FW id, rc:%s\n",
1210a9597be7SJay Ding 			    tf_dir_2_str(parms->dir),
1211a9597be7SJay Ding 			    strerror(-rc));
1212a9597be7SJay Ding 		return rc;
1213a9597be7SJay Ding 	}
1214a9597be7SJay Ding 
1215a9597be7SJay Ding 	/* Populate the request */
1216a9597be7SJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1217a9597be7SJay Ding 	req.type = parms->hcapi_type;
1218a9597be7SJay Ding 	req.idx = tfp_cpu_to_le_16(parms->idx);
1219a9597be7SJay Ding 	if (parms->dir == TF_DIR_TX)
1220a9597be7SJay Ding 		req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX;
1221a9597be7SJay Ding 
1222a9597be7SJay Ding 	mparms.tf_type = HWRM_TF_TCAM_GET;
1223a9597be7SJay Ding 	mparms.req_data = (uint32_t *)&req;
1224a9597be7SJay Ding 	mparms.req_size = sizeof(req);
1225a9597be7SJay Ding 	mparms.resp_data = (uint32_t *)&resp;
1226a9597be7SJay Ding 	mparms.resp_size = sizeof(resp);
1227a9597be7SJay Ding 	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1228a9597be7SJay Ding 
1229b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1230a9597be7SJay Ding 				 &mparms);
1231a9597be7SJay Ding 
1232a9597be7SJay Ding 	if (rc != 0)
1233a9597be7SJay Ding 		return rc;
1234a9597be7SJay Ding 
1235902fa8b5SJay Ding 	if (parms->key_size < resp.key_size ||
1236902fa8b5SJay Ding 	    parms->result_size < resp.result_size) {
1237902fa8b5SJay Ding 		rc = -EINVAL;
1238902fa8b5SJay Ding 		TFP_DRV_LOG(ERR,
1239902fa8b5SJay Ding 			    "%s: Key buffer(%d) is smaller than the key(%d), rc:%s\n",
1240902fa8b5SJay Ding 			    tf_dir_2_str(parms->dir),
1241902fa8b5SJay Ding 			    parms->key_size,
1242902fa8b5SJay Ding 			    resp.key_size,
1243902fa8b5SJay Ding 			    strerror(-rc));
1244902fa8b5SJay Ding 		return rc;
1245902fa8b5SJay Ding 	}
1246a9597be7SJay Ding 	parms->key_size = resp.key_size;
1247a9597be7SJay Ding 	parms->result_size = resp.result_size;
1248a9597be7SJay Ding 	tfp_memcpy(parms->key, resp.dev_data, resp.key_size);
1249a9597be7SJay Ding 	tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size);
1250a9597be7SJay Ding 	tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size);
1251a9597be7SJay Ding 
125208e1af1aSFarah Smith 	return 0;
1253a9597be7SJay Ding }
1254a9597be7SJay Ding 
1255a9597be7SJay Ding int
125682fa189dSShahaji Bhosle tf_msg_tcam_entry_free(struct tf *tfp,
12573d3ab7dfSPeter Spreadborough 		       struct tf_dev_info *dev,
12588de01320SJay Ding 		       struct tf_tcam_free_parms *in_parms)
125982fa189dSShahaji Bhosle {
126082fa189dSShahaji Bhosle 	int rc;
126182fa189dSShahaji Bhosle 	struct hwrm_tf_tcam_free_input req =  { 0 };
126282fa189dSShahaji Bhosle 	struct hwrm_tf_tcam_free_output resp = { 0 };
126382fa189dSShahaji Bhosle 	struct tfp_send_msg_parms parms = { 0 };
1264b2da0248SPeter Spreadborough 	uint8_t fw_session_id;
1265873661aaSJay Ding 	struct tf_session *tfs;
1266873661aaSJay Ding 
1267873661aaSJay Ding 	/* Retrieve the session information */
1268873661aaSJay Ding 	rc = tf_session_get_session_internal(tfp, &tfs);
1269873661aaSJay Ding 	if (rc) {
1270873661aaSJay Ding 		TFP_DRV_LOG(ERR,
1271873661aaSJay Ding 			    "Failed to lookup session, rc:%s\n",
1272873661aaSJay Ding 			    strerror(-rc));
1273873661aaSJay Ding 		return rc;
1274873661aaSJay Ding 	}
127582fa189dSShahaji Bhosle 
1276b2da0248SPeter Spreadborough 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1277b2da0248SPeter Spreadborough 	if (rc) {
1278b2da0248SPeter Spreadborough 		TFP_DRV_LOG(ERR,
1279b2da0248SPeter Spreadborough 			    "%s: Unable to lookup FW id, rc:%s\n",
1280b2da0248SPeter Spreadborough 			    tf_dir_2_str(in_parms->dir),
1281b2da0248SPeter Spreadborough 			    strerror(-rc));
1282b2da0248SPeter Spreadborough 		return rc;
1283b2da0248SPeter Spreadborough 	}
1284b2da0248SPeter Spreadborough 
1285b2da0248SPeter Spreadborough 	/* Populate the request */
1286b2da0248SPeter Spreadborough 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1287ca5e61bdSPeter Spreadborough 	req.type = in_parms->hcapi_type;
128882fa189dSShahaji Bhosle 	req.count = 1;
128982fa189dSShahaji Bhosle 	req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
129082fa189dSShahaji Bhosle 	if (in_parms->dir == TF_DIR_TX)
129182fa189dSShahaji Bhosle 		req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
129282fa189dSShahaji Bhosle 
129382fa189dSShahaji Bhosle 	parms.tf_type = HWRM_TF_TCAM_FREE;
129482fa189dSShahaji Bhosle 	parms.req_data = (uint32_t *)&req;
129582fa189dSShahaji Bhosle 	parms.req_size = sizeof(req);
129682fa189dSShahaji Bhosle 	parms.resp_data = (uint32_t *)&resp;
129782fa189dSShahaji Bhosle 	parms.resp_size = sizeof(resp);
12983d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
129982fa189dSShahaji Bhosle 
1300b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
130182fa189dSShahaji Bhosle 				 &parms);
130282fa189dSShahaji Bhosle 	return rc;
130382fa189dSShahaji Bhosle }
1304ca5e61bdSPeter Spreadborough 
1305ca5e61bdSPeter Spreadborough int
1306ca5e61bdSPeter Spreadborough tf_msg_set_tbl_entry(struct tf *tfp,
1307ca5e61bdSPeter Spreadborough 		     enum tf_dir dir,
1308ca5e61bdSPeter Spreadborough 		     uint16_t hcapi_type,
1309ca5e61bdSPeter Spreadborough 		     uint16_t size,
1310ca5e61bdSPeter Spreadborough 		     uint8_t *data,
1311ca5e61bdSPeter Spreadborough 		     uint32_t index)
1312ca5e61bdSPeter Spreadborough {
1313ca5e61bdSPeter Spreadborough 	int rc;
1314ca5e61bdSPeter Spreadborough 	struct hwrm_tf_tbl_type_set_input req = { 0 };
1315ca5e61bdSPeter Spreadborough 	struct hwrm_tf_tbl_type_set_output resp = { 0 };
1316ca5e61bdSPeter Spreadborough 	struct tfp_send_msg_parms parms = { 0 };
131797435d79SRandy Schacher 	struct tf_msg_dma_buf buf = { 0 };
1318f3502f5cSJay Ding 	uint8_t fw_session_id;
13193d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
13203d3ab7dfSPeter Spreadborough 	struct tf_session *tfs;
13213d3ab7dfSPeter Spreadborough 
1322902fa8b5SJay Ding 	RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_tbl_type_set_input) !=
1323902fa8b5SJay Ding 			 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET);
1324902fa8b5SJay Ding 
13253d3ab7dfSPeter Spreadborough 	/* Retrieve the session information */
13263d3ab7dfSPeter Spreadborough 	rc = tf_session_get_session_internal(tfp, &tfs);
13273d3ab7dfSPeter Spreadborough 	if (rc) {
13283d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
13293d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup session, rc:%s\n",
13303d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(dir),
13313d3ab7dfSPeter Spreadborough 			    strerror(-rc));
13323d3ab7dfSPeter Spreadborough 		return rc;
13333d3ab7dfSPeter Spreadborough 	}
13343d3ab7dfSPeter Spreadborough 
13353d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
13363d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
13373d3ab7dfSPeter Spreadborough 	if (rc) {
13383d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
13393d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
13403d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(dir),
13413d3ab7dfSPeter Spreadborough 			    strerror(-rc));
13423d3ab7dfSPeter Spreadborough 		return rc;
13433d3ab7dfSPeter Spreadborough 	}
1344ca5e61bdSPeter Spreadborough 
1345f3502f5cSJay Ding 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1346ca5e61bdSPeter Spreadborough 	if (rc) {
1347ca5e61bdSPeter Spreadborough 		TFP_DRV_LOG(ERR,
1348f3502f5cSJay Ding 			    "%s: Unable to lookup FW id, rc:%s\n",
1349ca5e61bdSPeter Spreadborough 			    tf_dir_2_str(dir),
1350ca5e61bdSPeter Spreadborough 			    strerror(-rc));
1351ca5e61bdSPeter Spreadborough 		return rc;
1352ca5e61bdSPeter Spreadborough 	}
1353ca5e61bdSPeter Spreadborough 
1354ca5e61bdSPeter Spreadborough 	/* Populate the request */
1355f3502f5cSJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1356ca5e61bdSPeter Spreadborough 	req.flags = tfp_cpu_to_le_16(dir);
1357ca5e61bdSPeter Spreadborough 	req.type = tfp_cpu_to_le_32(hcapi_type);
1358ca5e61bdSPeter Spreadborough 	req.size = tfp_cpu_to_le_16(size);
1359ca5e61bdSPeter Spreadborough 	req.index = tfp_cpu_to_le_32(index);
1360ca5e61bdSPeter Spreadborough 
136198487d72SKishore Padmanabha 	/* Check for data size conformity */
136298487d72SKishore Padmanabha 	if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
136397435d79SRandy Schacher 		/* use dma buffer */
136497435d79SRandy Schacher 		req.flags |= HWRM_TF_TBL_TYPE_SET_INPUT_FLAGS_DMA;
136597435d79SRandy Schacher 		rc = tf_msg_alloc_dma_buf(&buf, size);
136697435d79SRandy Schacher 		if (rc)
136797435d79SRandy Schacher 			goto cleanup;
136897435d79SRandy Schacher 		tfp_memcpy(buf.va_addr, data, size);
136997435d79SRandy Schacher 		tfp_memcpy(&req.data[0],
137097435d79SRandy Schacher 			   &buf.pa_addr,
137197435d79SRandy Schacher 			   sizeof(buf.pa_addr));
137297435d79SRandy Schacher 	} else {
137397435d79SRandy Schacher 		tfp_memcpy(&req.data, data, size);
137498487d72SKishore Padmanabha 	}
137598487d72SKishore Padmanabha 
1376ca5e61bdSPeter Spreadborough 	parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1377ca5e61bdSPeter Spreadborough 	parms.req_data = (uint32_t *)&req;
1378ca5e61bdSPeter Spreadborough 	parms.req_size = sizeof(req);
1379ca5e61bdSPeter Spreadborough 	parms.resp_data = (uint32_t *)&resp;
1380ca5e61bdSPeter Spreadborough 	parms.resp_size = sizeof(resp);
13813d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1382ca5e61bdSPeter Spreadborough 
1383b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1384ca5e61bdSPeter Spreadborough 				 &parms);
138597435d79SRandy Schacher cleanup:
138697435d79SRandy Schacher 	tf_msg_free_dma_buf(&buf);
1387ca5e61bdSPeter Spreadborough 
138897435d79SRandy Schacher 	return rc;
1389ca5e61bdSPeter Spreadborough }
1390ca5e61bdSPeter Spreadborough 
1391ca5e61bdSPeter Spreadborough int
1392ca5e61bdSPeter Spreadborough tf_msg_get_tbl_entry(struct tf *tfp,
1393ca5e61bdSPeter Spreadborough 		     enum tf_dir dir,
1394ca5e61bdSPeter Spreadborough 		     uint16_t hcapi_type,
1395ca5e61bdSPeter Spreadborough 		     uint16_t size,
1396ca5e61bdSPeter Spreadborough 		     uint8_t *data,
139706d1a5d0SFarah Smith 		     uint32_t index,
139806d1a5d0SFarah Smith 		     bool clear_on_read)
1399ca5e61bdSPeter Spreadborough {
1400ca5e61bdSPeter Spreadborough 	int rc;
1401ca5e61bdSPeter Spreadborough 	struct hwrm_tf_tbl_type_get_input req = { 0 };
1402ca5e61bdSPeter Spreadborough 	struct hwrm_tf_tbl_type_get_output resp = { 0 };
1403ca5e61bdSPeter Spreadborough 	struct tfp_send_msg_parms parms = { 0 };
1404f3502f5cSJay Ding 	uint8_t fw_session_id;
14053d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
14063d3ab7dfSPeter Spreadborough 	struct tf_session *tfs;
140706d1a5d0SFarah Smith 	uint32_t flags = 0;
14083d3ab7dfSPeter Spreadborough 
14093d3ab7dfSPeter Spreadborough 	/* Retrieve the session information */
14103d3ab7dfSPeter Spreadborough 	rc = tf_session_get_session_internal(tfp, &tfs);
14113d3ab7dfSPeter Spreadborough 	if (rc) {
14123d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
14133d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup session, rc:%s\n",
14143d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(dir),
14153d3ab7dfSPeter Spreadborough 			    strerror(-rc));
14163d3ab7dfSPeter Spreadborough 		return rc;
14173d3ab7dfSPeter Spreadborough 	}
14183d3ab7dfSPeter Spreadborough 
14193d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
14203d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
14213d3ab7dfSPeter Spreadborough 	if (rc) {
14223d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
14233d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
14243d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(dir),
14253d3ab7dfSPeter Spreadborough 			    strerror(-rc));
14263d3ab7dfSPeter Spreadborough 		return rc;
14273d3ab7dfSPeter Spreadborough 	}
1428ca5e61bdSPeter Spreadborough 
1429f3502f5cSJay Ding 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1430ca5e61bdSPeter Spreadborough 	if (rc) {
1431ca5e61bdSPeter Spreadborough 		TFP_DRV_LOG(ERR,
1432f3502f5cSJay Ding 			    "%s: Unable to lookup FW id, rc:%s\n",
1433ca5e61bdSPeter Spreadborough 			    tf_dir_2_str(dir),
1434ca5e61bdSPeter Spreadborough 			    strerror(-rc));
1435ca5e61bdSPeter Spreadborough 		return rc;
1436ca5e61bdSPeter Spreadborough 	}
143706d1a5d0SFarah Smith 	flags = (dir == TF_DIR_TX ?
143806d1a5d0SFarah Smith 		 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_TX :
143906d1a5d0SFarah Smith 		 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_RX);
144006d1a5d0SFarah Smith 
144106d1a5d0SFarah Smith 	if (clear_on_read)
144206d1a5d0SFarah Smith 		flags |= HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_CLEAR_ON_READ;
1443ca5e61bdSPeter Spreadborough 
1444ca5e61bdSPeter Spreadborough 	/* Populate the request */
1445f3502f5cSJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
144606d1a5d0SFarah Smith 	req.flags = tfp_cpu_to_le_16(flags);
1447ca5e61bdSPeter Spreadborough 	req.type = tfp_cpu_to_le_32(hcapi_type);
1448ca5e61bdSPeter Spreadborough 	req.index = tfp_cpu_to_le_32(index);
1449ca5e61bdSPeter Spreadborough 
1450ca5e61bdSPeter Spreadborough 	parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1451ca5e61bdSPeter Spreadborough 	parms.req_data = (uint32_t *)&req;
1452ca5e61bdSPeter Spreadborough 	parms.req_size = sizeof(req);
1453ca5e61bdSPeter Spreadborough 	parms.resp_data = (uint32_t *)&resp;
1454ca5e61bdSPeter Spreadborough 	parms.resp_size = sizeof(resp);
14553d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1456ca5e61bdSPeter Spreadborough 
1457b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1458ca5e61bdSPeter Spreadborough 				 &parms);
1459ca5e61bdSPeter Spreadborough 	if (rc)
1460ca5e61bdSPeter Spreadborough 		return rc;
1461ca5e61bdSPeter Spreadborough 
146208e1af1aSFarah Smith 	/*
146308e1af1aSFarah Smith 	 * The response will be 64 bytes long, the response size will
146408e1af1aSFarah Smith 	 * be in words (16). All we can test for is that the response
146508e1af1aSFarah Smith 	 * size is < to the requested size.
146608e1af1aSFarah Smith 	 */
146708e1af1aSFarah Smith 	if ((tfp_le_to_cpu_32(resp.size) * 4) < size)
1468ca5e61bdSPeter Spreadborough 		return -EINVAL;
1469ca5e61bdSPeter Spreadborough 
147008e1af1aSFarah Smith 	/*
147108e1af1aSFarah Smith 	 * Copy the requested number of bytes
147208e1af1aSFarah Smith 	 */
1473ca5e61bdSPeter Spreadborough 	tfp_memcpy(data,
1474ca5e61bdSPeter Spreadborough 		   &resp.data,
1475e2a002d8SPeter Spreadborough 		   size);
1476ca5e61bdSPeter Spreadborough 
147708e1af1aSFarah Smith 	return 0;
1478ca5e61bdSPeter Spreadborough }
1479ca5e61bdSPeter Spreadborough 
1480ca5e61bdSPeter Spreadborough /* HWRM Tunneled messages */
1481ca5e61bdSPeter Spreadborough 
1482ca5e61bdSPeter Spreadborough int
1483a11f87d3SJay Ding tf_msg_get_global_cfg(struct tf *tfp,
14845ca95058SJay Ding 		      struct tf_global_cfg_parms *params)
1485a11f87d3SJay Ding {
1486a11f87d3SJay Ding 	int rc = 0;
1487a11f87d3SJay Ding 	struct tfp_send_msg_parms parms = { 0 };
1488247f0903SJay Ding 	struct hwrm_tf_global_cfg_get_input req = { 0 };
1489247f0903SJay Ding 	struct hwrm_tf_global_cfg_get_output resp = { 0 };
1490a11f87d3SJay Ding 	uint32_t flags = 0;
1491a11f87d3SJay Ding 	uint8_t fw_session_id;
1492a11f87d3SJay Ding 	uint16_t resp_size = 0;
14933d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
14943d3ab7dfSPeter Spreadborough 	struct tf_session *tfs;
14953d3ab7dfSPeter Spreadborough 
14963d3ab7dfSPeter Spreadborough 	/* Retrieve the session information */
14973d3ab7dfSPeter Spreadborough 	rc = tf_session_get_session_internal(tfp, &tfs);
14983d3ab7dfSPeter Spreadborough 	if (rc) {
14993d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
15003d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup session, rc:%s\n",
15013d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(params->dir),
15023d3ab7dfSPeter Spreadborough 			    strerror(-rc));
15033d3ab7dfSPeter Spreadborough 		return rc;
15043d3ab7dfSPeter Spreadborough 	}
15053d3ab7dfSPeter Spreadborough 
15063d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
15073d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
15083d3ab7dfSPeter Spreadborough 	if (rc) {
15093d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
15103d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
15113d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(params->dir),
15123d3ab7dfSPeter Spreadborough 			    strerror(-rc));
15133d3ab7dfSPeter Spreadborough 		return rc;
15143d3ab7dfSPeter Spreadborough 	}
1515a11f87d3SJay Ding 
1516a11f87d3SJay Ding 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1517a11f87d3SJay Ding 	if (rc) {
1518a11f87d3SJay Ding 		TFP_DRV_LOG(ERR,
1519a11f87d3SJay Ding 			    "%s: Unable to lookup FW id, rc:%s\n",
1520a11f87d3SJay Ding 			    tf_dir_2_str(params->dir),
1521a11f87d3SJay Ding 			    strerror(-rc));
1522a11f87d3SJay Ding 		return rc;
1523a11f87d3SJay Ding 	}
1524a11f87d3SJay Ding 
1525a11f87d3SJay Ding 	flags = (params->dir == TF_DIR_TX ?
1526247f0903SJay Ding 		 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1527247f0903SJay Ding 		 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1528a11f87d3SJay Ding 
1529a11f87d3SJay Ding 	/* Populate the request */
1530a11f87d3SJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1531a11f87d3SJay Ding 	req.flags = tfp_cpu_to_le_32(flags);
1532a11f87d3SJay Ding 	req.type = tfp_cpu_to_le_32(params->type);
1533a11f87d3SJay Ding 	req.offset = tfp_cpu_to_le_32(params->offset);
1534a11f87d3SJay Ding 	req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1535a11f87d3SJay Ding 
1536247f0903SJay Ding 	parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1537247f0903SJay Ding 	parms.req_data = (uint32_t *)&req;
1538247f0903SJay Ding 	parms.req_size = sizeof(req);
1539247f0903SJay Ding 	parms.resp_data = (uint32_t *)&resp;
1540247f0903SJay Ding 	parms.resp_size = sizeof(resp);
15413d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1542a11f87d3SJay Ding 
1543b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1544a11f87d3SJay Ding 	if (rc != 0)
1545a11f87d3SJay Ding 		return rc;
1546a11f87d3SJay Ding 
1547a11f87d3SJay Ding 	/* Verify that we got enough buffer to return the requested data */
1548a11f87d3SJay Ding 	resp_size = tfp_le_to_cpu_16(resp.size);
1549a11f87d3SJay Ding 	if (resp_size < params->config_sz_in_bytes)
1550a11f87d3SJay Ding 		return -EINVAL;
1551a11f87d3SJay Ding 
1552a11f87d3SJay Ding 	if (params->config)
1553a11f87d3SJay Ding 		tfp_memcpy(params->config,
1554a11f87d3SJay Ding 			   resp.data,
1555a11f87d3SJay Ding 			   resp_size);
1556a11f87d3SJay Ding 	else
1557a11f87d3SJay Ding 		return -EFAULT;
1558a11f87d3SJay Ding 
155908e1af1aSFarah Smith 	return 0;
1560a11f87d3SJay Ding }
1561a11f87d3SJay Ding 
1562a11f87d3SJay Ding int
1563a11f87d3SJay Ding tf_msg_set_global_cfg(struct tf *tfp,
15645ca95058SJay Ding 		      struct tf_global_cfg_parms *params)
1565a11f87d3SJay Ding {
1566a11f87d3SJay Ding 	int rc = 0;
1567a11f87d3SJay Ding 	struct tfp_send_msg_parms parms = { 0 };
1568247f0903SJay Ding 	struct hwrm_tf_global_cfg_set_input req = { 0 };
1569247f0903SJay Ding 	struct hwrm_tf_global_cfg_set_output resp = { 0 };
1570a11f87d3SJay Ding 	uint32_t flags = 0;
1571a11f87d3SJay Ding 	uint8_t fw_session_id;
15723d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
15733d3ab7dfSPeter Spreadborough 	struct tf_session *tfs;
15743d3ab7dfSPeter Spreadborough 
15753d3ab7dfSPeter Spreadborough 	/* Retrieve the session information */
15763d3ab7dfSPeter Spreadborough 	rc = tf_session_get_session_internal(tfp, &tfs);
15773d3ab7dfSPeter Spreadborough 	if (rc) {
15783d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
15793d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup session, rc:%s\n",
15803d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(params->dir),
15813d3ab7dfSPeter Spreadborough 			    strerror(-rc));
15823d3ab7dfSPeter Spreadborough 		return rc;
15833d3ab7dfSPeter Spreadborough 	}
15843d3ab7dfSPeter Spreadborough 
15853d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
15863d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
15873d3ab7dfSPeter Spreadborough 	if (rc) {
15883d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
15893d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
15903d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(params->dir),
15913d3ab7dfSPeter Spreadborough 			    strerror(-rc));
15923d3ab7dfSPeter Spreadborough 		return rc;
15933d3ab7dfSPeter Spreadborough 	}
1594a11f87d3SJay Ding 
1595a11f87d3SJay Ding 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1596a11f87d3SJay Ding 	if (rc) {
1597a11f87d3SJay Ding 		TFP_DRV_LOG(ERR,
1598a11f87d3SJay Ding 			    "%s: Unable to lookup FW id, rc:%s\n",
1599a11f87d3SJay Ding 			    tf_dir_2_str(params->dir),
1600a11f87d3SJay Ding 			    strerror(-rc));
1601a11f87d3SJay Ding 		return rc;
1602a11f87d3SJay Ding 	}
1603a11f87d3SJay Ding 
1604a11f87d3SJay Ding 	flags = (params->dir == TF_DIR_TX ?
1605247f0903SJay Ding 		 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
1606247f0903SJay Ding 		 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
1607a11f87d3SJay Ding 
1608a11f87d3SJay Ding 	/* Populate the request */
1609a11f87d3SJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1610a11f87d3SJay Ding 	req.flags = tfp_cpu_to_le_32(flags);
1611a11f87d3SJay Ding 	req.type = tfp_cpu_to_le_32(params->type);
1612a11f87d3SJay Ding 	req.offset = tfp_cpu_to_le_32(params->offset);
161398487d72SKishore Padmanabha 
161498487d72SKishore Padmanabha 	/* Check for data size conformity */
161598487d72SKishore Padmanabha 	if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
161698487d72SKishore Padmanabha 		rc = -EINVAL;
161798487d72SKishore Padmanabha 		TFP_DRV_LOG(ERR,
161898487d72SKishore Padmanabha 			    "%s: Invalid parameters for msg type, rc:%s\n",
161998487d72SKishore Padmanabha 			    tf_dir_2_str(params->dir),
162098487d72SKishore Padmanabha 			    strerror(-rc));
162198487d72SKishore Padmanabha 		return rc;
162298487d72SKishore Padmanabha 	}
162398487d72SKishore Padmanabha 
1624a11f87d3SJay Ding 	tfp_memcpy(req.data, params->config,
1625a11f87d3SJay Ding 		   params->config_sz_in_bytes);
16265ca95058SJay Ding 
16275ca95058SJay Ding 	/* Only set mask if pointer is provided
16285ca95058SJay Ding 	 */
16295ca95058SJay Ding 	if (params->config_mask) {
1630acd38b0aSFarah Smith 		tfp_memcpy(req.mask,
16315ca95058SJay Ding 			   params->config_mask,
16325ca95058SJay Ding 			   params->config_sz_in_bytes);
16335ca95058SJay Ding 	}
16345ca95058SJay Ding 
1635a11f87d3SJay Ding 	req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1636a11f87d3SJay Ding 
1637247f0903SJay Ding 	parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
1638247f0903SJay Ding 	parms.req_data = (uint32_t *)&req;
1639247f0903SJay Ding 	parms.req_size = sizeof(req);
1640247f0903SJay Ding 	parms.resp_data = (uint32_t *)&resp;
1641247f0903SJay Ding 	parms.resp_size = sizeof(resp);
16423d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1643a11f87d3SJay Ding 
1644b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1645a11f87d3SJay Ding 
1646a11f87d3SJay Ding 	if (rc != 0)
1647a11f87d3SJay Ding 		return rc;
1648a11f87d3SJay Ding 
164908e1af1aSFarah Smith 	return 0;
1650a11f87d3SJay Ding }
1651a11f87d3SJay Ding 
1652a11f87d3SJay Ding int
1653ca5e61bdSPeter Spreadborough tf_msg_bulk_get_tbl_entry(struct tf *tfp,
1654ced3cdedSMichael Wildt 			  enum tf_dir dir,
1655ced3cdedSMichael Wildt 			  uint16_t hcapi_type,
1656ced3cdedSMichael Wildt 			  uint32_t starting_idx,
1657ced3cdedSMichael Wildt 			  uint16_t num_entries,
1658ced3cdedSMichael Wildt 			  uint16_t entry_sz_in_bytes,
165906d1a5d0SFarah Smith 			  uint64_t physical_mem_addr,
166006d1a5d0SFarah Smith 			  bool clear_on_read)
1661ca5e61bdSPeter Spreadborough {
1662ca5e61bdSPeter Spreadborough 	int rc;
1663ca5e61bdSPeter Spreadborough 	struct tfp_send_msg_parms parms = { 0 };
166408e1af1aSFarah Smith 	struct hwrm_tf_tbl_type_bulk_get_input req = { 0 };
166508e1af1aSFarah Smith 	struct hwrm_tf_tbl_type_bulk_get_output resp = { 0 };
1666ca5e61bdSPeter Spreadborough 	int data_size = 0;
1667f3502f5cSJay Ding 	uint8_t fw_session_id;
16683d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
16693d3ab7dfSPeter Spreadborough 	struct tf_session *tfs;
167006d1a5d0SFarah Smith 	uint32_t flags = 0;
16713d3ab7dfSPeter Spreadborough 
16723d3ab7dfSPeter Spreadborough 	/* Retrieve the session information */
16733d3ab7dfSPeter Spreadborough 	rc = tf_session_get_session(tfp, &tfs);
16743d3ab7dfSPeter Spreadborough 	if (rc) {
16753d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
16763d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup session, rc:%s\n",
16773d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(dir),
16783d3ab7dfSPeter Spreadborough 			    strerror(-rc));
16793d3ab7dfSPeter Spreadborough 		return rc;
16803d3ab7dfSPeter Spreadborough 	}
16813d3ab7dfSPeter Spreadborough 
16823d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
16833d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
16843d3ab7dfSPeter Spreadborough 	if (rc) {
16853d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
16863d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
16873d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(dir),
16883d3ab7dfSPeter Spreadborough 			    strerror(-rc));
16893d3ab7dfSPeter Spreadborough 		return rc;
16903d3ab7dfSPeter Spreadborough 	}
1691ca5e61bdSPeter Spreadborough 
1692f3502f5cSJay Ding 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1693ced3cdedSMichael Wildt 	if (rc) {
1694ced3cdedSMichael Wildt 		TFP_DRV_LOG(ERR,
1695f3502f5cSJay Ding 			    "%s: Unable to lookup FW id, rc:%s\n",
1696ced3cdedSMichael Wildt 			    tf_dir_2_str(dir),
1697ced3cdedSMichael Wildt 			    strerror(-rc));
1698ced3cdedSMichael Wildt 		return rc;
1699ced3cdedSMichael Wildt 	}
170006d1a5d0SFarah Smith 	flags = (dir == TF_DIR_TX ?
170106d1a5d0SFarah Smith 		 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_TX :
170206d1a5d0SFarah Smith 		 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_RX);
170306d1a5d0SFarah Smith 
170406d1a5d0SFarah Smith 	if (clear_on_read)
170506d1a5d0SFarah Smith 		flags |= HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_CLEAR_ON_READ;
1706ced3cdedSMichael Wildt 
1707ca5e61bdSPeter Spreadborough 	/* Populate the request */
1708f3502f5cSJay Ding 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
170906d1a5d0SFarah Smith 	req.flags = tfp_cpu_to_le_16(flags);
1710ced3cdedSMichael Wildt 	req.type = tfp_cpu_to_le_32(hcapi_type);
1711ced3cdedSMichael Wildt 	req.start_index = tfp_cpu_to_le_32(starting_idx);
1712ced3cdedSMichael Wildt 	req.num_entries = tfp_cpu_to_le_32(num_entries);
1713ca5e61bdSPeter Spreadborough 
1714ced3cdedSMichael Wildt 	data_size = num_entries * entry_sz_in_bytes;
1715ca5e61bdSPeter Spreadborough 
1716ced3cdedSMichael Wildt 	req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1717ca5e61bdSPeter Spreadborough 
171808e1af1aSFarah Smith 	parms.tf_type = HWRM_TF_TBL_TYPE_BULK_GET;
171908e1af1aSFarah Smith 	parms.req_data = (uint32_t *)&req;
172008e1af1aSFarah Smith 	parms.req_size = sizeof(req);
172108e1af1aSFarah Smith 	parms.resp_data = (uint32_t *)&resp;
172208e1af1aSFarah Smith 	parms.resp_size = sizeof(resp);
172308e1af1aSFarah Smith 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1724ca5e61bdSPeter Spreadborough 
1725b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
172608e1af1aSFarah Smith 				 &parms);
1727ca5e61bdSPeter Spreadborough 	if (rc)
1728ca5e61bdSPeter Spreadborough 		return rc;
1729ca5e61bdSPeter Spreadborough 
1730ca5e61bdSPeter Spreadborough 	/* Verify that we got enough buffer to return the requested data */
1731e2a002d8SPeter Spreadborough 	if (tfp_le_to_cpu_32(resp.size) != data_size)
1732ca5e61bdSPeter Spreadborough 		return -EINVAL;
1733ca5e61bdSPeter Spreadborough 
173408e1af1aSFarah Smith 	return 0;
1735ca5e61bdSPeter Spreadborough }
1736f3502f5cSJay Ding 
1737f3502f5cSJay Ding int
1738f3502f5cSJay Ding tf_msg_get_if_tbl_entry(struct tf *tfp,
1739f3502f5cSJay Ding 			struct tf_if_tbl_get_parms *params)
1740f3502f5cSJay Ding {
1741f3502f5cSJay Ding 	int rc = 0;
1742f3502f5cSJay Ding 	struct tfp_send_msg_parms parms = { 0 };
1743428e4dfcSRandy Schacher 	struct hwrm_tf_if_tbl_get_input req = { 0 };
1744428e4dfcSRandy Schacher 	struct hwrm_tf_if_tbl_get_output resp = { 0 };
1745f3502f5cSJay Ding 	uint32_t flags = 0;
17463d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
1747f3502f5cSJay Ding 	struct tf_session *tfs;
1748f3502f5cSJay Ding 
1749f3502f5cSJay Ding 	/* Retrieve the session information */
1750f3502f5cSJay Ding 	rc = tf_session_get_session(tfp, &tfs);
1751f3502f5cSJay Ding 	if (rc) {
1752f3502f5cSJay Ding 		TFP_DRV_LOG(ERR,
1753f3502f5cSJay Ding 			    "%s: Failed to lookup session, rc:%s\n",
1754f3502f5cSJay Ding 			    tf_dir_2_str(params->dir),
1755f3502f5cSJay Ding 			    strerror(-rc));
1756f3502f5cSJay Ding 		return rc;
1757f3502f5cSJay Ding 	}
1758f3502f5cSJay Ding 
17593d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
17603d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
17613d3ab7dfSPeter Spreadborough 	if (rc) {
17623d3ab7dfSPeter Spreadborough 		TFP_DRV_LOG(ERR,
17633d3ab7dfSPeter Spreadborough 			    "%s: Failed to lookup device, rc:%s\n",
17643d3ab7dfSPeter Spreadborough 			    tf_dir_2_str(params->dir),
17653d3ab7dfSPeter Spreadborough 			    strerror(-rc));
17663d3ab7dfSPeter Spreadborough 		return rc;
17673d3ab7dfSPeter Spreadborough 	}
17683d3ab7dfSPeter Spreadborough 
1769428e4dfcSRandy Schacher 	flags = (params->dir == TF_DIR_TX ?
1770428e4dfcSRandy Schacher 		HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
1771428e4dfcSRandy Schacher 		HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
1772f3502f5cSJay Ding 
1773f3502f5cSJay Ding 	/* Populate the request */
1774f3502f5cSJay Ding 	req.fw_session_id =
1775f3502f5cSJay Ding 		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1776f3502f5cSJay Ding 	req.flags = flags;
1777428e4dfcSRandy Schacher 	req.type = params->hcapi_type;
1778428e4dfcSRandy Schacher 	req.index = tfp_cpu_to_le_16(params->idx);
1779428e4dfcSRandy Schacher 	req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1780f3502f5cSJay Ding 
1781428e4dfcSRandy Schacher 	parms.tf_type = HWRM_TF_IF_TBL_GET;
1782428e4dfcSRandy Schacher 	parms.req_data = (uint32_t *)&req;
1783428e4dfcSRandy Schacher 	parms.req_size = sizeof(req);
1784428e4dfcSRandy Schacher 	parms.resp_data = (uint32_t *)&resp;
1785428e4dfcSRandy Schacher 	parms.resp_size = sizeof(resp);
17863d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1787f3502f5cSJay Ding 
1788b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1789f3502f5cSJay Ding 
1790f3502f5cSJay Ding 	if (rc != 0)
1791f3502f5cSJay Ding 		return rc;
1792f3502f5cSJay Ding 
179337ff91c1SFarah Smith 	tfp_memcpy(&params->data[0], resp.data, req.size);
1794f3502f5cSJay Ding 
179508e1af1aSFarah Smith 	return 0;
1796f3502f5cSJay Ding }
1797f3502f5cSJay Ding 
1798f3502f5cSJay Ding int
1799f3502f5cSJay Ding tf_msg_set_if_tbl_entry(struct tf *tfp,
1800f3502f5cSJay Ding 			struct tf_if_tbl_set_parms *params)
1801f3502f5cSJay Ding {
1802f3502f5cSJay Ding 	int rc = 0;
1803f3502f5cSJay Ding 	struct tfp_send_msg_parms parms = { 0 };
1804428e4dfcSRandy Schacher 	struct hwrm_tf_if_tbl_set_input req = { 0 };
1805428e4dfcSRandy Schacher 	struct hwrm_tf_if_tbl_get_output resp = { 0 };
1806f3502f5cSJay Ding 	uint32_t flags = 0;
18073d3ab7dfSPeter Spreadborough 	struct tf_dev_info *dev;
1808f3502f5cSJay Ding 	struct tf_session *tfs;
1809f3502f5cSJay Ding 
1810f3502f5cSJay Ding 	/* Retrieve the session information */
1811f3502f5cSJay Ding 	rc = tf_session_get_session(tfp, &tfs);
1812f3502f5cSJay Ding 	if (rc) {
1813f3502f5cSJay Ding 		TFP_DRV_LOG(ERR,
1814f3502f5cSJay Ding 			    "%s: Failed to lookup session, rc:%s\n",
1815f3502f5cSJay Ding 			    tf_dir_2_str(params->dir),
1816f3502f5cSJay Ding 			    strerror(-rc));
1817f3502f5cSJay Ding 		return rc;
1818f3502f5cSJay Ding 	}
1819f3502f5cSJay Ding 
18203d3ab7dfSPeter Spreadborough 	/* Retrieve the device information */
18213d3ab7dfSPeter Spreadborough 	rc = tf_session_get_device(tfs, &dev);
18223d3ab7dfSPeter Spreadborough 	if (rc)
18233d3ab7dfSPeter Spreadborough 		return rc;
1824f3502f5cSJay Ding 
1825428e4dfcSRandy Schacher 	flags = (params->dir == TF_DIR_TX ?
1826428e4dfcSRandy Schacher 		HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1827428e4dfcSRandy Schacher 		HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1828f3502f5cSJay Ding 
1829f3502f5cSJay Ding 	/* Populate the request */
1830f3502f5cSJay Ding 	req.fw_session_id =
1831f3502f5cSJay Ding 		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1832f3502f5cSJay Ding 	req.flags = flags;
1833428e4dfcSRandy Schacher 	req.type = params->hcapi_type;
1834428e4dfcSRandy Schacher 	req.index = tfp_cpu_to_le_32(params->idx);
1835428e4dfcSRandy Schacher 	req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1836f3502f5cSJay Ding 	tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1837f3502f5cSJay Ding 
1838428e4dfcSRandy Schacher 	parms.tf_type = HWRM_TF_IF_TBL_SET;
1839428e4dfcSRandy Schacher 	parms.req_data = (uint32_t *)&req;
1840428e4dfcSRandy Schacher 	parms.req_size = sizeof(req);
1841428e4dfcSRandy Schacher 	parms.resp_data = (uint32_t *)&resp;
1842428e4dfcSRandy Schacher 	parms.resp_size = sizeof(resp);
18433d3ab7dfSPeter Spreadborough 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1844f3502f5cSJay Ding 
1845b97763fcSJay Ding 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1846f3502f5cSJay Ding 
1847f3502f5cSJay Ding 	if (rc != 0)
1848f3502f5cSJay Ding 		return rc;
1849f3502f5cSJay Ding 
185008e1af1aSFarah Smith 	return 0;
1851f3502f5cSJay Ding }
1852588e333eSJay Ding 
1853588e333eSJay Ding int
1854588e333eSJay Ding tf_msg_get_version(struct bnxt *bp,
1855588e333eSJay Ding 		   struct tf_dev_info *dev,
1856588e333eSJay Ding 		   struct tf_get_version_parms *params)
1857588e333eSJay Ding 
1858588e333eSJay Ding {
1859588e333eSJay Ding 	int rc;
1860588e333eSJay Ding 	struct hwrm_tf_version_get_input req = { 0 };
1861588e333eSJay Ding 	struct hwrm_tf_version_get_output resp = { 0 };
1862588e333eSJay Ding 	struct tfp_send_msg_parms parms = { 0 };
1863588e333eSJay Ding 
1864588e333eSJay Ding 	/* Populate the request */
1865588e333eSJay Ding 	parms.tf_type = HWRM_TF_VERSION_GET,
1866588e333eSJay Ding 	parms.req_data = (uint32_t *)&req;
1867588e333eSJay Ding 	parms.req_size = sizeof(req);
1868588e333eSJay Ding 	parms.resp_data = (uint32_t *)&resp;
1869588e333eSJay Ding 	parms.resp_size = sizeof(resp);
1870588e333eSJay Ding 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
1871588e333eSJay Ding 
1872588e333eSJay Ding 	rc = tfp_send_msg_direct(bp,
1873588e333eSJay Ding 				 &parms);
1874588e333eSJay Ding 
1875588e333eSJay Ding 	params->major = resp.major;
1876588e333eSJay Ding 	params->minor = resp.minor;
1877588e333eSJay Ding 	params->update = resp.update;
1878588e333eSJay Ding 
1879588e333eSJay Ding 	dev->ops->tf_dev_map_hcapi_caps(resp.dev_caps_cfg,
1880588e333eSJay Ding 					&params->dev_ident_caps,
1881588e333eSJay Ding 					&params->dev_tcam_caps,
1882588e333eSJay Ding 					&params->dev_tbl_caps,
1883588e333eSJay Ding 					&params->dev_em_caps);
1884588e333eSJay Ding 
1885588e333eSJay Ding 	return rc;
1886588e333eSJay Ding }
188797435d79SRandy Schacher 
188897435d79SRandy Schacher int
188997435d79SRandy Schacher tf_msg_session_set_hotup_state(struct tf *tfp, uint16_t state)
189097435d79SRandy Schacher {
189197435d79SRandy Schacher 	int rc;
189297435d79SRandy Schacher 	struct hwrm_tf_session_hotup_state_set_input req = { 0 };
189397435d79SRandy Schacher 	struct hwrm_tf_session_hotup_state_set_output resp = { 0 };
189497435d79SRandy Schacher 	struct tfp_send_msg_parms parms = { 0 };
189597435d79SRandy Schacher 	uint8_t fw_session_id;
189697435d79SRandy Schacher 	struct tf_dev_info *dev;
189797435d79SRandy Schacher 	struct tf_session *tfs;
189897435d79SRandy Schacher 
189997435d79SRandy Schacher 	/* Retrieve the session information */
190097435d79SRandy Schacher 	rc = tf_session_get_session_internal(tfp, &tfs);
190197435d79SRandy Schacher 	if (rc) {
190297435d79SRandy Schacher 		TFP_DRV_LOG(ERR,
190397435d79SRandy Schacher 			    "Failed to lookup session, rc:%s\n",
190497435d79SRandy Schacher 			    strerror(-rc));
190597435d79SRandy Schacher 		return rc;
190697435d79SRandy Schacher 	}
190797435d79SRandy Schacher 
190897435d79SRandy Schacher 	/* Retrieve the device information */
190997435d79SRandy Schacher 	rc = tf_session_get_device(tfs, &dev);
191097435d79SRandy Schacher 	if (rc) {
191197435d79SRandy Schacher 		TFP_DRV_LOG(ERR,
191297435d79SRandy Schacher 			    "Failed to lookup device, rc:%s\n",
191397435d79SRandy Schacher 			    strerror(-rc));
191497435d79SRandy Schacher 		return rc;
191597435d79SRandy Schacher 	}
191697435d79SRandy Schacher 
191797435d79SRandy Schacher 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
191897435d79SRandy Schacher 	if (rc) {
191997435d79SRandy Schacher 		TFP_DRV_LOG(ERR,
192097435d79SRandy Schacher 			    "Unable to lookup FW id, rc:%s\n",
192197435d79SRandy Schacher 			    strerror(-rc));
192297435d79SRandy Schacher 		return rc;
192397435d79SRandy Schacher 	}
192497435d79SRandy Schacher 
192597435d79SRandy Schacher 	/* Populate the request */
192697435d79SRandy Schacher 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
192797435d79SRandy Schacher 	req.state = tfp_cpu_to_le_16(state);
192897435d79SRandy Schacher 
192997435d79SRandy Schacher 	parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_SET;
193097435d79SRandy Schacher 	parms.req_data = (uint32_t *)&req;
193197435d79SRandy Schacher 	parms.req_size = sizeof(req);
193297435d79SRandy Schacher 	parms.resp_data = (uint32_t *)&resp;
193397435d79SRandy Schacher 	parms.resp_size = sizeof(resp);
193497435d79SRandy Schacher 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
193597435d79SRandy Schacher 
193697435d79SRandy Schacher 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
193797435d79SRandy Schacher 				 &parms);
193897435d79SRandy Schacher 	return rc;
193997435d79SRandy Schacher }
194097435d79SRandy Schacher 
194197435d79SRandy Schacher int
194297435d79SRandy Schacher tf_msg_session_get_hotup_state(struct tf *tfp,
194397435d79SRandy Schacher 			       uint16_t *state,
194497435d79SRandy Schacher 			       uint16_t *ref_cnt)
194597435d79SRandy Schacher {
194697435d79SRandy Schacher 	int rc;
194797435d79SRandy Schacher 	struct hwrm_tf_session_hotup_state_get_input req = { 0 };
194897435d79SRandy Schacher 	struct hwrm_tf_session_hotup_state_get_output resp = { 0 };
194997435d79SRandy Schacher 	struct tfp_send_msg_parms parms = { 0 };
195097435d79SRandy Schacher 	uint8_t fw_session_id;
195197435d79SRandy Schacher 	struct tf_dev_info *dev;
195297435d79SRandy Schacher 	struct tf_session *tfs;
195397435d79SRandy Schacher 
195497435d79SRandy Schacher 	/* Retrieve the session information */
195597435d79SRandy Schacher 	rc = tf_session_get_session_internal(tfp, &tfs);
195697435d79SRandy Schacher 	if (rc) {
195797435d79SRandy Schacher 		TFP_DRV_LOG(ERR,
195897435d79SRandy Schacher 			    "Failed to lookup session, rc:%s\n",
195997435d79SRandy Schacher 			    strerror(-rc));
196097435d79SRandy Schacher 		return rc;
196197435d79SRandy Schacher 	}
196297435d79SRandy Schacher 
196397435d79SRandy Schacher 	/* Retrieve the device information */
196497435d79SRandy Schacher 	rc = tf_session_get_device(tfs, &dev);
196597435d79SRandy Schacher 	if (rc) {
196697435d79SRandy Schacher 		TFP_DRV_LOG(ERR,
196797435d79SRandy Schacher 			    "Failed to lookup device, rc:%s\n",
196897435d79SRandy Schacher 			    strerror(-rc));
196997435d79SRandy Schacher 		return rc;
197097435d79SRandy Schacher 	}
197197435d79SRandy Schacher 
197297435d79SRandy Schacher 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
197397435d79SRandy Schacher 	if (rc) {
197497435d79SRandy Schacher 		TFP_DRV_LOG(ERR,
197597435d79SRandy Schacher 			    "Unable to lookup FW id, rc:%s\n",
197697435d79SRandy Schacher 			    strerror(-rc));
197797435d79SRandy Schacher 		return rc;
197897435d79SRandy Schacher 	}
197997435d79SRandy Schacher 
198097435d79SRandy Schacher 	/* Populate the request */
198197435d79SRandy Schacher 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
198297435d79SRandy Schacher 
198397435d79SRandy Schacher 	parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_GET;
198497435d79SRandy Schacher 	parms.req_data = (uint32_t *)&req;
198597435d79SRandy Schacher 	parms.req_size = sizeof(req);
198697435d79SRandy Schacher 	parms.resp_data = (uint32_t *)&resp;
198797435d79SRandy Schacher 	parms.resp_size = sizeof(resp);
198897435d79SRandy Schacher 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
198997435d79SRandy Schacher 
199097435d79SRandy Schacher 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
199197435d79SRandy Schacher 				 &parms);
199297435d79SRandy Schacher 
199397435d79SRandy Schacher 	*state = tfp_le_to_cpu_16(resp.state);
199497435d79SRandy Schacher 	*ref_cnt = tfp_le_to_cpu_16(resp.ref_cnt);
199597435d79SRandy Schacher 
199697435d79SRandy Schacher 	return rc;
199797435d79SRandy Schacher }
1998*19f3ac61SShuanglin Wang 
1999*19f3ac61SShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY
2000*19f3ac61SShuanglin Wang /* Send set resource usage request to the firmware. */
2001*19f3ac61SShuanglin Wang int
2002*19f3ac61SShuanglin Wang tf_msg_set_resc_usage(struct tf *tfp,
2003*19f3ac61SShuanglin Wang 		      enum tf_dir dir,
2004*19f3ac61SShuanglin Wang 		      uint32_t resc_types,
2005*19f3ac61SShuanglin Wang 		      uint32_t size,
2006*19f3ac61SShuanglin Wang 		      uint8_t *data)
2007*19f3ac61SShuanglin Wang {
2008*19f3ac61SShuanglin Wang 	int rc;
2009*19f3ac61SShuanglin Wang 	struct hwrm_tf_resc_usage_set_input req = { 0 };
2010*19f3ac61SShuanglin Wang 	struct hwrm_tf_resc_usage_set_output resp = { 0 };
2011*19f3ac61SShuanglin Wang 	struct tfp_send_msg_parms parms = { 0 };
2012*19f3ac61SShuanglin Wang 	struct tf_msg_dma_buf buf = { 0 };
2013*19f3ac61SShuanglin Wang 	uint8_t fw_session_id;
2014*19f3ac61SShuanglin Wang 	struct tf_dev_info *dev;
2015*19f3ac61SShuanglin Wang 	struct tf_session *tfs;
2016*19f3ac61SShuanglin Wang 
2017*19f3ac61SShuanglin Wang 	/* Retrieve the session information */
2018*19f3ac61SShuanglin Wang 	rc = tf_session_get_session_internal(tfp, &tfs);
2019*19f3ac61SShuanglin Wang 	if (rc) {
2020*19f3ac61SShuanglin Wang 		TFP_DRV_LOG(ERR,
2021*19f3ac61SShuanglin Wang 			    "%s: Failed to lookup session, rc:%s\n",
2022*19f3ac61SShuanglin Wang 			    tf_dir_2_str(dir),
2023*19f3ac61SShuanglin Wang 			    strerror(-rc));
2024*19f3ac61SShuanglin Wang 		return rc;
2025*19f3ac61SShuanglin Wang 	}
2026*19f3ac61SShuanglin Wang 
2027*19f3ac61SShuanglin Wang 	/* Retrieve the device information */
2028*19f3ac61SShuanglin Wang 	rc = tf_session_get_device(tfs, &dev);
2029*19f3ac61SShuanglin Wang 	if (rc) {
2030*19f3ac61SShuanglin Wang 		TFP_DRV_LOG(ERR,
2031*19f3ac61SShuanglin Wang 			    "%s: Failed to lookup device, rc:%s\n",
2032*19f3ac61SShuanglin Wang 			    tf_dir_2_str(dir),
2033*19f3ac61SShuanglin Wang 			    strerror(-rc));
2034*19f3ac61SShuanglin Wang 		return rc;
2035*19f3ac61SShuanglin Wang 	}
2036*19f3ac61SShuanglin Wang 
2037*19f3ac61SShuanglin Wang 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2038*19f3ac61SShuanglin Wang 	if (rc) {
2039*19f3ac61SShuanglin Wang 		TFP_DRV_LOG(ERR,
2040*19f3ac61SShuanglin Wang 			    "%s: Unable to lookup FW id, rc:%s\n",
2041*19f3ac61SShuanglin Wang 			    tf_dir_2_str(dir),
2042*19f3ac61SShuanglin Wang 			    strerror(-rc));
2043*19f3ac61SShuanglin Wang 		return rc;
2044*19f3ac61SShuanglin Wang 	}
2045*19f3ac61SShuanglin Wang 
2046*19f3ac61SShuanglin Wang 	/* Populate the request */
2047*19f3ac61SShuanglin Wang 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2048*19f3ac61SShuanglin Wang 	req.flags = tfp_cpu_to_le_16(dir);
2049*19f3ac61SShuanglin Wang 	req.types = tfp_cpu_to_le_32(resc_types);
2050*19f3ac61SShuanglin Wang 	req.size = tfp_cpu_to_le_16(size);
2051*19f3ac61SShuanglin Wang #if (TF_RM_MSG_DEBUG == 1)
2052*19f3ac61SShuanglin Wang 	/* Dump data */
2053*19f3ac61SShuanglin Wang 	dump_tf_resc_usage(dir, data, size);
2054*19f3ac61SShuanglin Wang #endif /* (TF_RM_MSG_DEBUG == 1) */
2055*19f3ac61SShuanglin Wang 	/* Check for data size conformity */
2056*19f3ac61SShuanglin Wang 	if (size > sizeof(req.data)) {
2057*19f3ac61SShuanglin Wang 		/* use dma buffer */
2058*19f3ac61SShuanglin Wang 		req.flags |= HWRM_TF_RESC_USAGE_SET_INPUT_FLAGS_DMA;
2059*19f3ac61SShuanglin Wang 		rc = tf_msg_alloc_dma_buf(&buf, size);
2060*19f3ac61SShuanglin Wang 		if (rc)
2061*19f3ac61SShuanglin Wang 			goto exit;
2062*19f3ac61SShuanglin Wang 		tfp_memcpy(buf.va_addr, data, size);
2063*19f3ac61SShuanglin Wang 		tfp_memcpy(&req.data[0],
2064*19f3ac61SShuanglin Wang 			   &buf.pa_addr,
2065*19f3ac61SShuanglin Wang 			   sizeof(buf.pa_addr));
2066*19f3ac61SShuanglin Wang 	} else {
2067*19f3ac61SShuanglin Wang 		tfp_memcpy(&req.data, data, size);
2068*19f3ac61SShuanglin Wang 	}
2069*19f3ac61SShuanglin Wang 
2070*19f3ac61SShuanglin Wang 	parms.tf_type = HWRM_TF_RESC_USAGE_SET;
2071*19f3ac61SShuanglin Wang 	parms.req_data = (uint32_t *)&req;
2072*19f3ac61SShuanglin Wang 	parms.req_size = sizeof(req);
2073*19f3ac61SShuanglin Wang 	parms.resp_data = (uint32_t *)&resp;
2074*19f3ac61SShuanglin Wang 	parms.resp_size = sizeof(resp);
2075*19f3ac61SShuanglin Wang 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2076*19f3ac61SShuanglin Wang 
2077*19f3ac61SShuanglin Wang 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
2078*19f3ac61SShuanglin Wang 				 &parms);
2079*19f3ac61SShuanglin Wang 
2080*19f3ac61SShuanglin Wang 	/* Free dma buffer */
2081*19f3ac61SShuanglin Wang 	if (size > sizeof(req.data))
2082*19f3ac61SShuanglin Wang 		tf_msg_free_dma_buf(&buf);
2083*19f3ac61SShuanglin Wang exit:
2084*19f3ac61SShuanglin Wang 	return rc;
2085*19f3ac61SShuanglin Wang }
2086*19f3ac61SShuanglin Wang 
2087*19f3ac61SShuanglin Wang /* Send query resource usage request to the firmware. */
2088*19f3ac61SShuanglin Wang int tf_msg_query_resc_usage(struct tf *tfp,
2089*19f3ac61SShuanglin Wang 			    enum tf_dir dir,
2090*19f3ac61SShuanglin Wang 			    uint32_t resc_types,
2091*19f3ac61SShuanglin Wang 			    uint32_t *size,
2092*19f3ac61SShuanglin Wang 			    uint8_t *data)
2093*19f3ac61SShuanglin Wang {
2094*19f3ac61SShuanglin Wang 	int rc;
2095*19f3ac61SShuanglin Wang 	struct hwrm_tf_resc_usage_query_input req = { 0 };
2096*19f3ac61SShuanglin Wang 	struct hwrm_tf_resc_usage_query_output resp = { 0 };
2097*19f3ac61SShuanglin Wang 	struct tfp_send_msg_parms parms = { 0 };
2098*19f3ac61SShuanglin Wang 	uint8_t fw_session_id;
2099*19f3ac61SShuanglin Wang 	struct tf_dev_info *dev;
2100*19f3ac61SShuanglin Wang 	struct tf_session *tfs;
2101*19f3ac61SShuanglin Wang 	uint32_t flags = 0;
2102*19f3ac61SShuanglin Wang 
2103*19f3ac61SShuanglin Wang 	/* Retrieve the session information */
2104*19f3ac61SShuanglin Wang 	rc = tf_session_get_session_internal(tfp, &tfs);
2105*19f3ac61SShuanglin Wang 	if (rc) {
2106*19f3ac61SShuanglin Wang 		TFP_DRV_LOG(ERR,
2107*19f3ac61SShuanglin Wang 			    "%s: Failed to lookup session, rc:%s\n",
2108*19f3ac61SShuanglin Wang 			    tf_dir_2_str(dir),
2109*19f3ac61SShuanglin Wang 			    strerror(-rc));
2110*19f3ac61SShuanglin Wang 		return rc;
2111*19f3ac61SShuanglin Wang 	}
2112*19f3ac61SShuanglin Wang 
2113*19f3ac61SShuanglin Wang 	/* Retrieve the device information */
2114*19f3ac61SShuanglin Wang 	rc = tf_session_get_device(tfs, &dev);
2115*19f3ac61SShuanglin Wang 	if (rc) {
2116*19f3ac61SShuanglin Wang 		TFP_DRV_LOG(ERR,
2117*19f3ac61SShuanglin Wang 			    "%s: Failed to lookup device, rc:%s\n",
2118*19f3ac61SShuanglin Wang 			    tf_dir_2_str(dir),
2119*19f3ac61SShuanglin Wang 			    strerror(-rc));
2120*19f3ac61SShuanglin Wang 		return rc;
2121*19f3ac61SShuanglin Wang 	}
2122*19f3ac61SShuanglin Wang 
2123*19f3ac61SShuanglin Wang 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2124*19f3ac61SShuanglin Wang 	if (rc) {
2125*19f3ac61SShuanglin Wang 		TFP_DRV_LOG(ERR,
2126*19f3ac61SShuanglin Wang 			    "%s: Unable to lookup FW id, rc:%s\n",
2127*19f3ac61SShuanglin Wang 			    tf_dir_2_str(dir),
2128*19f3ac61SShuanglin Wang 			    strerror(-rc));
2129*19f3ac61SShuanglin Wang 		return rc;
2130*19f3ac61SShuanglin Wang 	}
2131*19f3ac61SShuanglin Wang 	flags = (dir == TF_DIR_TX ?
2132*19f3ac61SShuanglin Wang 		 HWRM_TF_RESC_USAGE_QUERY_INPUT_FLAGS_DIR_TX :
2133*19f3ac61SShuanglin Wang 		 HWRM_TF_RESC_USAGE_QUERY_INPUT_FLAGS_DIR_RX);
2134*19f3ac61SShuanglin Wang 
2135*19f3ac61SShuanglin Wang 	/* Populate the request */
2136*19f3ac61SShuanglin Wang 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2137*19f3ac61SShuanglin Wang 	req.flags = tfp_cpu_to_le_16(flags);
2138*19f3ac61SShuanglin Wang 	req.types = tfp_cpu_to_le_32(resc_types);
2139*19f3ac61SShuanglin Wang 
2140*19f3ac61SShuanglin Wang 	parms.tf_type = HWRM_TF_RESC_USAGE_QUERY;
2141*19f3ac61SShuanglin Wang 	parms.req_data = (uint32_t *)&req;
2142*19f3ac61SShuanglin Wang 	parms.req_size = sizeof(req);
2143*19f3ac61SShuanglin Wang 	parms.resp_data = (uint32_t *)&resp;
2144*19f3ac61SShuanglin Wang 	parms.resp_size = sizeof(resp);
2145*19f3ac61SShuanglin Wang 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
2146*19f3ac61SShuanglin Wang 
2147*19f3ac61SShuanglin Wang 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
2148*19f3ac61SShuanglin Wang 				 &parms);
2149*19f3ac61SShuanglin Wang 	if (rc)
2150*19f3ac61SShuanglin Wang 		return rc;
2151*19f3ac61SShuanglin Wang 
2152*19f3ac61SShuanglin Wang 	/* The response size should be less than or equal to (<=) the input buffer size. */
2153*19f3ac61SShuanglin Wang 	if (resp.size > *size)
2154*19f3ac61SShuanglin Wang 		return -EINVAL;
2155*19f3ac61SShuanglin Wang 
2156*19f3ac61SShuanglin Wang 	*size = resp.size;
2157*19f3ac61SShuanglin Wang 
2158*19f3ac61SShuanglin Wang 	/*
2159*19f3ac61SShuanglin Wang 	 * Copy the requested number of bytes
2160*19f3ac61SShuanglin Wang 	 */
2161*19f3ac61SShuanglin Wang 	tfp_memcpy(data,
2162*19f3ac61SShuanglin Wang 		   &resp.data,
2163*19f3ac61SShuanglin Wang 		   resp.size);
2164*19f3ac61SShuanglin Wang 
2165*19f3ac61SShuanglin Wang #if (TF_RM_MSG_DEBUG == 1)
2166*19f3ac61SShuanglin Wang 	/* dump data */
2167*19f3ac61SShuanglin Wang 	dump_tf_resc_usage(dir, data, resp.size);
2168*19f3ac61SShuanglin Wang #endif /* (TF_RM_MSG_DEBUG == 1) */
2169*19f3ac61SShuanglin Wang 
2170*19f3ac61SShuanglin Wang 	return 0;
2171*19f3ac61SShuanglin Wang }
2172*19f3ac61SShuanglin Wang #endif /* TF_FLOW_SCALE_QUERY */
2173