e08a96f23cecac5248a3ee2ed4a9e8bd200ecc63
[dpdk.git] / drivers / net / bnxt / tf_core / tf_msg.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 Broadcom
3  * All rights reserved.
4  */
5
6 #include <inttypes.h>
7 #include <stdbool.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "tf_msg_common.h"
12 #include "tf_msg.h"
13 #include "tf_util.h"
14 #include "tf_session.h"
15 #include "tfp.h"
16 #include "hwrm_tf.h"
17 #include "tf_em.h"
18
19 /**
20  * Endian converts min and max values from the HW response to the query
21  */
22 #define TF_HW_RESP_TO_QUERY(query, index, response, element) do {            \
23         (query)->hw_query[index].min =                                       \
24                 tfp_le_to_cpu_16(response. element ## _min);                 \
25         (query)->hw_query[index].max =                                       \
26                 tfp_le_to_cpu_16(response. element ## _max);                 \
27 } while (0)
28
29 /**
30  * Endian converts the number of entries from the alloc to the request
31  */
32 #define TF_HW_ALLOC_TO_REQ(alloc, index, request, element)                   \
33         (request. num_ ## element = tfp_cpu_to_le_16((alloc)->hw_num[index]))
34
35 /**
36  * Endian converts the start and stride value from the free to the request
37  */
38 #define TF_HW_FREE_TO_REQ(hw_entry, index, request, element) do {            \
39         request.element ## _start =                                          \
40                 tfp_cpu_to_le_16(hw_entry[index].start);                     \
41         request.element ## _stride =                                         \
42                 tfp_cpu_to_le_16(hw_entry[index].stride);                    \
43 } while (0)
44
45 /**
46  * Endian converts the start and stride from the HW response to the
47  * alloc
48  */
49 #define TF_HW_RESP_TO_ALLOC(hw_entry, index, response, element) do {         \
50         hw_entry[index].start =                                              \
51                 tfp_le_to_cpu_16(response.element ## _start);                \
52         hw_entry[index].stride =                                             \
53                 tfp_le_to_cpu_16(response.element ## _stride);               \
54 } while (0)
55
56 /**
57  * Endian converts min and max values from the SRAM response to the
58  * query
59  */
60 #define TF_SRAM_RESP_TO_QUERY(query, index, response, element) do {          \
61         (query)->sram_query[index].min =                                     \
62                 tfp_le_to_cpu_16(response.element ## _min);                  \
63         (query)->sram_query[index].max =                                     \
64                 tfp_le_to_cpu_16(response.element ## _max);                  \
65 } while (0)
66
67 /**
68  * Endian converts the number of entries from the action (alloc) to
69  * the request
70  */
71 #define TF_SRAM_ALLOC_TO_REQ(action, index, request, element)                \
72         (request. num_ ## element = tfp_cpu_to_le_16((action)->sram_num[index]))
73
74 /**
75  * Endian converts the start and stride value from the free to the request
76  */
77 #define TF_SRAM_FREE_TO_REQ(sram_entry, index, request, element) do {        \
78         request.element ## _start =                                          \
79                 tfp_cpu_to_le_16(sram_entry[index].start);                   \
80         request.element ## _stride =                                         \
81                 tfp_cpu_to_le_16(sram_entry[index].stride);                  \
82 } while (0)
83
84 /**
85  * Endian converts the start and stride from the HW response to the
86  * alloc
87  */
88 #define TF_SRAM_RESP_TO_ALLOC(sram_entry, index, response, element) do {     \
89         sram_entry[index].start =                                            \
90                 tfp_le_to_cpu_16(response.element ## _start);                \
91         sram_entry[index].stride =                                           \
92                 tfp_le_to_cpu_16(response.element ## _stride);               \
93 } while (0)
94
95 /**
96  * This is the MAX data we can transport across regular HWRM
97  */
98 #define TF_PCI_BUF_SIZE_MAX 88
99
100 /**
101  * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
102  */
103 struct tf_msg_dma_buf {
104         void *va_addr;
105         uint64_t pa_addr;
106 };
107
108 static int
109 tf_tcam_tbl_2_hwrm(enum tf_tcam_tbl_type tcam_type,
110                    uint32_t *hwrm_type)
111 {
112         int rc = 0;
113
114         switch (tcam_type) {
115         case TF_TCAM_TBL_TYPE_L2_CTXT_TCAM:
116                 *hwrm_type = TF_DEV_DATA_TYPE_TF_L2_CTX_ENTRY;
117                 break;
118         case TF_TCAM_TBL_TYPE_PROF_TCAM:
119                 *hwrm_type = TF_DEV_DATA_TYPE_TF_PROF_TCAM_ENTRY;
120                 break;
121         case TF_TCAM_TBL_TYPE_WC_TCAM:
122                 *hwrm_type = TF_DEV_DATA_TYPE_TF_WC_ENTRY;
123                 break;
124         case TF_TCAM_TBL_TYPE_VEB_TCAM:
125                 rc = -EOPNOTSUPP;
126                 break;
127         case TF_TCAM_TBL_TYPE_SP_TCAM:
128                 rc = -EOPNOTSUPP;
129                 break;
130         case TF_TCAM_TBL_TYPE_CT_RULE_TCAM:
131                 rc = -EOPNOTSUPP;
132                 break;
133         default:
134                 rc = -EOPNOTSUPP;
135                 break;
136         }
137
138         return rc;
139 }
140
141 /**
142  * Allocates a DMA buffer that can be used for message transfer.
143  *
144  * [in] buf
145  *   Pointer to DMA buffer structure
146  *
147  * [in] size
148  *   Requested size of the buffer in bytes
149  *
150  * Returns:
151  *    0      - Success
152  *   -ENOMEM - Unable to allocate buffer, no memory
153  */
154 static int
155 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
156 {
157         struct tfp_calloc_parms alloc_parms;
158         int rc;
159
160         /* Allocate session */
161         alloc_parms.nitems = 1;
162         alloc_parms.size = size;
163         alloc_parms.alignment = 4096;
164         rc = tfp_calloc(&alloc_parms);
165         if (rc)
166                 return -ENOMEM;
167
168         buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
169         buf->va_addr = alloc_parms.mem_va;
170
171         return 0;
172 }
173
174 /**
175  * Free's a previous allocated DMA buffer.
176  *
177  * [in] buf
178  *   Pointer to DMA buffer structure
179  */
180 static void
181 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
182 {
183         tfp_free(buf->va_addr);
184 }
185
186 /**
187  * Sends session open request to TF Firmware
188  */
189 int
190 tf_msg_session_open(struct tf *tfp,
191                     char *ctrl_chan_name,
192                     uint8_t *fw_session_id)
193 {
194         int rc;
195         struct hwrm_tf_session_open_input req = { 0 };
196         struct hwrm_tf_session_open_output resp = { 0 };
197         struct tfp_send_msg_parms parms = { 0 };
198
199         /* Populate the request */
200         tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
201
202         parms.tf_type = HWRM_TF_SESSION_OPEN;
203         parms.req_data = (uint32_t *)&req;
204         parms.req_size = sizeof(req);
205         parms.resp_data = (uint32_t *)&resp;
206         parms.resp_size = sizeof(resp);
207         parms.mailbox = TF_KONG_MB;
208
209         rc = tfp_send_msg_direct(tfp,
210                                  &parms);
211         if (rc)
212                 return rc;
213
214         *fw_session_id = resp.fw_session_id;
215
216         return rc;
217 }
218
219 /**
220  * Sends session attach request to TF Firmware
221  */
222 int
223 tf_msg_session_attach(struct tf *tfp __rte_unused,
224                       char *ctrl_chan_name __rte_unused,
225                       uint8_t tf_fw_session_id __rte_unused)
226 {
227         return -1;
228 }
229
230 /**
231  * Sends session close request to TF Firmware
232  */
233 int
234 tf_msg_session_close(struct tf *tfp)
235 {
236         int rc;
237         struct hwrm_tf_session_close_input req = { 0 };
238         struct hwrm_tf_session_close_output resp = { 0 };
239         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
240         struct tfp_send_msg_parms parms = { 0 };
241
242         /* Populate the request */
243         req.fw_session_id =
244                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
245
246         parms.tf_type = HWRM_TF_SESSION_CLOSE;
247         parms.req_data = (uint32_t *)&req;
248         parms.req_size = sizeof(req);
249         parms.resp_data = (uint32_t *)&resp;
250         parms.resp_size = sizeof(resp);
251         parms.mailbox = TF_KONG_MB;
252
253         rc = tfp_send_msg_direct(tfp,
254                                  &parms);
255         return rc;
256 }
257
258 /**
259  * Sends session query config request to TF Firmware
260  */
261 int
262 tf_msg_session_qcfg(struct tf *tfp)
263 {
264         int rc;
265         struct hwrm_tf_session_qcfg_input  req = { 0 };
266         struct hwrm_tf_session_qcfg_output resp = { 0 };
267         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
268         struct tfp_send_msg_parms parms = { 0 };
269
270         /* Populate the request */
271         req.fw_session_id =
272                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
273
274         parms.tf_type = HWRM_TF_SESSION_QCFG,
275         parms.req_data = (uint32_t *)&req;
276         parms.req_size = sizeof(req);
277         parms.resp_data = (uint32_t *)&resp;
278         parms.resp_size = sizeof(resp);
279         parms.mailbox = TF_KONG_MB;
280
281         rc = tfp_send_msg_direct(tfp,
282                                  &parms);
283         return rc;
284 }
285
286 /**
287  * Sends session HW resource query capability request to TF Firmware
288  */
289 int
290 tf_msg_session_hw_resc_qcaps(struct tf *tfp,
291                              enum tf_dir dir,
292                              struct tf_rm_hw_query *query)
293 {
294         int rc;
295         struct tfp_send_msg_parms parms = { 0 };
296         struct tf_session_hw_resc_qcaps_input req = { 0 };
297         struct tf_session_hw_resc_qcaps_output resp = { 0 };
298         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
299
300         memset(query, 0, sizeof(*query));
301
302         /* Populate the request */
303         req.fw_session_id =
304                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
305         req.flags = tfp_cpu_to_le_16(dir);
306
307         MSG_PREP(parms,
308                  TF_KONG_MB,
309                  HWRM_TF,
310                  HWRM_TFT_SESSION_HW_RESC_QCAPS,
311                  req,
312                  resp);
313
314         rc = tfp_send_msg_tunneled(tfp, &parms);
315         if (rc)
316                 return rc;
317
318         /* Process the response */
319         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_L2_CTXT_TCAM, resp,
320                             l2_ctx_tcam_entries);
321         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_PROF_FUNC, resp,
322                             prof_func);
323         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_PROF_TCAM, resp,
324                             prof_tcam_entries);
325         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EM_PROF_ID, resp,
326                             em_prof_id);
327         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EM_REC, resp,
328                             em_record_entries);
329         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, resp,
330                             wc_tcam_prof_id);
331         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_WC_TCAM, resp,
332                             wc_tcam_entries);
333         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_METER_PROF, resp,
334                             meter_profiles);
335         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_METER_INST,
336                             resp, meter_inst);
337         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_MIRROR, resp,
338                             mirrors);
339         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_UPAR, resp,
340                             upar);
341         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_SP_TCAM, resp,
342                             sp_tcam_entries);
343         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_L2_FUNC, resp,
344                             l2_func);
345         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_FKB, resp,
346                             flex_key_templ);
347         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_TBL_SCOPE, resp,
348                             tbl_scope);
349         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EPOCH0, resp,
350                             epoch0_entries);
351         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EPOCH1, resp,
352                             epoch1_entries);
353         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_METADATA, resp,
354                             metadata);
355         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_CT_STATE, resp,
356                             ct_state);
357         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_RANGE_PROF, resp,
358                             range_prof);
359         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_RANGE_ENTRY, resp,
360                             range_entries);
361         TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_LAG_ENTRY, resp,
362                             lag_tbl_entries);
363
364         return tfp_le_to_cpu_32(parms.tf_resp_code);
365 }
366
367 /**
368  * Sends session HW resource allocation request to TF Firmware
369  */
370 int
371 tf_msg_session_hw_resc_alloc(struct tf *tfp __rte_unused,
372                              enum tf_dir dir,
373                              struct tf_rm_hw_alloc *hw_alloc __rte_unused,
374                              struct tf_rm_entry *hw_entry __rte_unused)
375 {
376         int rc;
377         struct tfp_send_msg_parms parms = { 0 };
378         struct tf_session_hw_resc_alloc_input req = { 0 };
379         struct tf_session_hw_resc_alloc_output resp = { 0 };
380         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
381
382         memset(hw_entry, 0, sizeof(*hw_entry));
383
384         /* Populate the request */
385         req.fw_session_id =
386                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
387         req.flags = tfp_cpu_to_le_16(dir);
388
389         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_L2_CTXT_TCAM, req,
390                            l2_ctx_tcam_entries);
391         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_PROF_FUNC, req,
392                            prof_func_entries);
393         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_PROF_TCAM, req,
394                            prof_tcam_entries);
395         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EM_PROF_ID, req,
396                            em_prof_id);
397         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EM_REC, req,
398                            em_record_entries);
399         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, req,
400                            wc_tcam_prof_id);
401         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_WC_TCAM, req,
402                            wc_tcam_entries);
403         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_METER_PROF, req,
404                            meter_profiles);
405         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_METER_INST, req,
406                            meter_inst);
407         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_MIRROR, req,
408                            mirrors);
409         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_UPAR, req,
410                            upar);
411         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_SP_TCAM, req,
412                            sp_tcam_entries);
413         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_L2_FUNC, req,
414                            l2_func);
415         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_FKB, req,
416                            flex_key_templ);
417         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_TBL_SCOPE, req,
418                            tbl_scope);
419         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EPOCH0, req,
420                            epoch0_entries);
421         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EPOCH1, req,
422                            epoch1_entries);
423         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_METADATA, req,
424                            metadata);
425         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_CT_STATE, req,
426                            ct_state);
427         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_RANGE_PROF, req,
428                            range_prof);
429         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_RANGE_ENTRY, req,
430                            range_entries);
431         TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_LAG_ENTRY, req,
432                            lag_tbl_entries);
433
434         MSG_PREP(parms,
435                  TF_KONG_MB,
436                  HWRM_TF,
437                  HWRM_TFT_SESSION_HW_RESC_ALLOC,
438                  req,
439                  resp);
440
441         rc = tfp_send_msg_tunneled(tfp, &parms);
442         if (rc)
443                 return rc;
444
445         /* Process the response */
446         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_L2_CTXT_TCAM, resp,
447                             l2_ctx_tcam_entries);
448         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_PROF_FUNC, resp,
449                             prof_func);
450         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_PROF_TCAM, resp,
451                             prof_tcam_entries);
452         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EM_PROF_ID, resp,
453                             em_prof_id);
454         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EM_REC, resp,
455                             em_record_entries);
456         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, resp,
457                             wc_tcam_prof_id);
458         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_WC_TCAM, resp,
459                             wc_tcam_entries);
460         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_METER_PROF, resp,
461                             meter_profiles);
462         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_METER_INST, resp,
463                             meter_inst);
464         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_MIRROR, resp,
465                             mirrors);
466         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_UPAR, resp,
467                             upar);
468         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_SP_TCAM, resp,
469                             sp_tcam_entries);
470         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_L2_FUNC, resp,
471                             l2_func);
472         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_FKB, resp,
473                             flex_key_templ);
474         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_TBL_SCOPE, resp,
475                             tbl_scope);
476         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EPOCH0, resp,
477                             epoch0_entries);
478         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EPOCH1, resp,
479                             epoch1_entries);
480         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_METADATA, resp,
481                             metadata);
482         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_CT_STATE, resp,
483                             ct_state);
484         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_RANGE_PROF, resp,
485                             range_prof);
486         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_RANGE_ENTRY, resp,
487                             range_entries);
488         TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_LAG_ENTRY, resp,
489                             lag_tbl_entries);
490
491         return tfp_le_to_cpu_32(parms.tf_resp_code);
492 }
493
494 /**
495  * Sends session HW resource free request to TF Firmware
496  */
497 int
498 tf_msg_session_hw_resc_free(struct tf *tfp,
499                             enum tf_dir dir,
500                             struct tf_rm_entry *hw_entry)
501 {
502         int rc;
503         struct tfp_send_msg_parms parms = { 0 };
504         struct tf_session_hw_resc_free_input req = { 0 };
505         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
506
507         memset(hw_entry, 0, sizeof(*hw_entry));
508
509         /* Populate the request */
510         req.fw_session_id =
511                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
512         req.flags = tfp_cpu_to_le_16(dir);
513
514         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_CTXT_TCAM, req,
515                           l2_ctx_tcam_entries);
516         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_FUNC, req,
517                           prof_func);
518         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_TCAM, req,
519                           prof_tcam_entries);
520         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_PROF_ID, req,
521                           em_prof_id);
522         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_REC, req,
523                           em_record_entries);
524         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, req,
525                           wc_tcam_prof_id);
526         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM, req,
527                           wc_tcam_entries);
528         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_PROF, req,
529                           meter_profiles);
530         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_INST, req,
531                           meter_inst);
532         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_MIRROR, req,
533                           mirrors);
534         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_UPAR, req,
535                           upar);
536         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_SP_TCAM, req,
537                           sp_tcam_entries);
538         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_FUNC, req,
539                           l2_func);
540         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_FKB, req,
541                           flex_key_templ);
542         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_TBL_SCOPE, req,
543                           tbl_scope);
544         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH0, req,
545                           epoch0_entries);
546         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH1, req,
547                           epoch1_entries);
548         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METADATA, req,
549                           metadata);
550         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_CT_STATE, req,
551                           ct_state);
552         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_PROF, req,
553                           range_prof);
554         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_ENTRY, req,
555                           range_entries);
556         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_LAG_ENTRY, req,
557                           lag_tbl_entries);
558
559         MSG_PREP_NO_RESP(parms,
560                          TF_KONG_MB,
561                          HWRM_TF,
562                          HWRM_TFT_SESSION_HW_RESC_FREE,
563                          req);
564
565         rc = tfp_send_msg_tunneled(tfp, &parms);
566         if (rc)
567                 return rc;
568
569         return tfp_le_to_cpu_32(parms.tf_resp_code);
570 }
571
572 /**
573  * Sends session HW resource flush request to TF Firmware
574  */
575 int
576 tf_msg_session_hw_resc_flush(struct tf *tfp,
577                              enum tf_dir dir,
578                              struct tf_rm_entry *hw_entry)
579 {
580         int rc;
581         struct tfp_send_msg_parms parms = { 0 };
582         struct tf_session_hw_resc_free_input req = { 0 };
583         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
584
585         /* Populate the request */
586         req.fw_session_id =
587                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
588         req.flags = tfp_cpu_to_le_16(dir);
589
590         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_CTXT_TCAM, req,
591                           l2_ctx_tcam_entries);
592         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_FUNC, req,
593                           prof_func);
594         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_TCAM, req,
595                           prof_tcam_entries);
596         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_PROF_ID, req,
597                           em_prof_id);
598         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_REC, req,
599                           em_record_entries);
600         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, req,
601                           wc_tcam_prof_id);
602         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM, req,
603                           wc_tcam_entries);
604         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_PROF, req,
605                           meter_profiles);
606         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_INST, req,
607                           meter_inst);
608         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_MIRROR, req,
609                           mirrors);
610         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_UPAR, req,
611                           upar);
612         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_SP_TCAM, req,
613                           sp_tcam_entries);
614         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_FUNC, req,
615                           l2_func);
616         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_FKB, req,
617                           flex_key_templ);
618         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_TBL_SCOPE, req,
619                           tbl_scope);
620         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH0, req,
621                           epoch0_entries);
622         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH1, req,
623                           epoch1_entries);
624         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METADATA, req,
625                           metadata);
626         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_CT_STATE, req,
627                           ct_state);
628         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_PROF, req,
629                           range_prof);
630         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_ENTRY, req,
631                           range_entries);
632         TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_LAG_ENTRY, req,
633                           lag_tbl_entries);
634
635         MSG_PREP_NO_RESP(parms,
636                          TF_KONG_MB,
637                          TF_TYPE_TRUFLOW,
638                          HWRM_TFT_SESSION_HW_RESC_FLUSH,
639                          req);
640
641         rc = tfp_send_msg_tunneled(tfp, &parms);
642         if (rc)
643                 return rc;
644
645         return tfp_le_to_cpu_32(parms.tf_resp_code);
646 }
647
648 /**
649  * Sends session SRAM resource query capability request to TF Firmware
650  */
651 int
652 tf_msg_session_sram_resc_qcaps(struct tf *tfp __rte_unused,
653                                enum tf_dir dir,
654                                struct tf_rm_sram_query *query __rte_unused)
655 {
656         int rc;
657         struct tfp_send_msg_parms parms = { 0 };
658         struct tf_session_sram_resc_qcaps_input req = { 0 };
659         struct tf_session_sram_resc_qcaps_output resp = { 0 };
660         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
661
662         /* Populate the request */
663         req.fw_session_id =
664                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
665         req.flags = tfp_cpu_to_le_16(dir);
666
667         MSG_PREP(parms,
668                  TF_KONG_MB,
669                  HWRM_TF,
670                  HWRM_TFT_SESSION_SRAM_RESC_QCAPS,
671                  req,
672                  resp);
673
674         rc = tfp_send_msg_tunneled(tfp, &parms);
675         if (rc)
676                 return rc;
677
678         /* Process the response */
679         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_FULL_ACTION, resp,
680                               full_action);
681         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_MCG, resp,
682                               mcg);
683         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_ENCAP_8B, resp,
684                               encap_8b);
685         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_ENCAP_16B, resp,
686                               encap_16b);
687         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_ENCAP_64B, resp,
688                               encap_64b);
689         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_SP_SMAC, resp,
690                               sp_smac);
691         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4, resp,
692                               sp_smac_ipv4);
693         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6, resp,
694                               sp_smac_ipv6);
695         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_COUNTER_64B, resp,
696                               counter_64b);
697         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_SPORT, resp,
698                               nat_sport);
699         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_DPORT, resp,
700                               nat_dport);
701         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_S_IPV4, resp,
702                               nat_s_ipv4);
703         TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_D_IPV4, resp,
704                               nat_d_ipv4);
705
706         return tfp_le_to_cpu_32(parms.tf_resp_code);
707 }
708
709 /**
710  * Sends session SRAM resource allocation request to TF Firmware
711  */
712 int
713 tf_msg_session_sram_resc_alloc(struct tf *tfp __rte_unused,
714                                enum tf_dir dir,
715                                struct tf_rm_sram_alloc *sram_alloc __rte_unused,
716                                struct tf_rm_entry *sram_entry __rte_unused)
717 {
718         int rc;
719         struct tfp_send_msg_parms parms = { 0 };
720         struct tf_session_sram_resc_alloc_input req = { 0 };
721         struct tf_session_sram_resc_alloc_output resp;
722         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
723
724         memset(&resp, 0, sizeof(resp));
725
726         /* Populate the request */
727         req.fw_session_id =
728                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
729         req.flags = tfp_cpu_to_le_16(dir);
730
731         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_FULL_ACTION, req,
732                              full_action);
733         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_MCG, req,
734                              mcg);
735         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_ENCAP_8B, req,
736                              encap_8b);
737         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_ENCAP_16B, req,
738                              encap_16b);
739         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_ENCAP_64B, req,
740                              encap_64b);
741         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_SP_SMAC, req,
742                              sp_smac);
743         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4,
744                              req, sp_smac_ipv4);
745         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6,
746                              req, sp_smac_ipv6);
747         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_COUNTER_64B,
748                              req, counter_64b);
749         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_SPORT, req,
750                              nat_sport);
751         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_DPORT, req,
752                              nat_dport);
753         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_S_IPV4, req,
754                              nat_s_ipv4);
755         TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_D_IPV4, req,
756                              nat_d_ipv4);
757
758         MSG_PREP(parms,
759                  TF_KONG_MB,
760                  HWRM_TF,
761                  HWRM_TFT_SESSION_SRAM_RESC_ALLOC,
762                  req,
763                  resp);
764
765         rc = tfp_send_msg_tunneled(tfp, &parms);
766         if (rc)
767                 return rc;
768
769         /* Process the response */
770         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_FULL_ACTION,
771                               resp, full_action);
772         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_MCG, resp,
773                               mcg);
774         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_8B, resp,
775                               encap_8b);
776         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_16B, resp,
777                               encap_16b);
778         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_64B, resp,
779                               encap_64b);
780         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC, resp,
781                               sp_smac);
782         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4,
783                               resp, sp_smac_ipv4);
784         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6,
785                               resp, sp_smac_ipv6);
786         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_COUNTER_64B, resp,
787                               counter_64b);
788         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_SPORT, resp,
789                               nat_sport);
790         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_DPORT, resp,
791                               nat_dport);
792         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_S_IPV4, resp,
793                               nat_s_ipv4);
794         TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_D_IPV4, resp,
795                               nat_d_ipv4);
796
797         return tfp_le_to_cpu_32(parms.tf_resp_code);
798 }
799
800 /**
801  * Sends session SRAM resource free request to TF Firmware
802  */
803 int
804 tf_msg_session_sram_resc_free(struct tf *tfp __rte_unused,
805                               enum tf_dir dir,
806                               struct tf_rm_entry *sram_entry __rte_unused)
807 {
808         int rc;
809         struct tfp_send_msg_parms parms = { 0 };
810         struct tf_session_sram_resc_free_input req = { 0 };
811         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
812
813         /* Populate the request */
814         req.fw_session_id =
815                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
816         req.flags = tfp_cpu_to_le_16(dir);
817
818         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_FULL_ACTION, req,
819                             full_action);
820         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_MCG, req,
821                             mcg);
822         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_8B, req,
823                             encap_8b);
824         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_16B, req,
825                             encap_16b);
826         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_64B, req,
827                             encap_64b);
828         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC, req,
829                             sp_smac);
830         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4, req,
831                             sp_smac_ipv4);
832         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6, req,
833                             sp_smac_ipv6);
834         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_COUNTER_64B, req,
835                             counter_64b);
836         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_SPORT, req,
837                             nat_sport);
838         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_DPORT, req,
839                             nat_dport);
840         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_S_IPV4, req,
841                             nat_s_ipv4);
842         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_D_IPV4, req,
843                             nat_d_ipv4);
844
845         MSG_PREP_NO_RESP(parms,
846                          TF_KONG_MB,
847                          HWRM_TF,
848                          HWRM_TFT_SESSION_SRAM_RESC_FREE,
849                          req);
850
851         rc = tfp_send_msg_tunneled(tfp, &parms);
852         if (rc)
853                 return rc;
854
855         return tfp_le_to_cpu_32(parms.tf_resp_code);
856 }
857
858 /**
859  * Sends session SRAM resource flush request to TF Firmware
860  */
861 int
862 tf_msg_session_sram_resc_flush(struct tf *tfp,
863                                enum tf_dir dir,
864                                struct tf_rm_entry *sram_entry)
865 {
866         int rc;
867         struct tfp_send_msg_parms parms = { 0 };
868         struct tf_session_sram_resc_free_input req = { 0 };
869         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
870
871         /* Populate the request */
872         req.fw_session_id =
873                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
874         req.flags = tfp_cpu_to_le_16(dir);
875
876         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_FULL_ACTION, req,
877                             full_action);
878         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_MCG, req,
879                             mcg);
880         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_8B, req,
881                             encap_8b);
882         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_16B, req,
883                             encap_16b);
884         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_64B, req,
885                             encap_64b);
886         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC, req,
887                             sp_smac);
888         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4, req,
889                             sp_smac_ipv4);
890         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6, req,
891                             sp_smac_ipv6);
892         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_COUNTER_64B, req,
893                             counter_64b);
894         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_SPORT, req,
895                             nat_sport);
896         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_DPORT, req,
897                             nat_dport);
898         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_S_IPV4, req,
899                             nat_s_ipv4);
900         TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_D_IPV4, req,
901                             nat_d_ipv4);
902
903         MSG_PREP_NO_RESP(parms,
904                          TF_KONG_MB,
905                          TF_TYPE_TRUFLOW,
906                          HWRM_TFT_SESSION_SRAM_RESC_FLUSH,
907                          req);
908
909         rc = tfp_send_msg_tunneled(tfp, &parms);
910         if (rc)
911                 return rc;
912
913         return tfp_le_to_cpu_32(parms.tf_resp_code);
914 }
915
916 int
917 tf_msg_session_resc_qcaps(struct tf *tfp,
918                           enum tf_dir dir,
919                           uint16_t size,
920                           struct tf_rm_resc_req_entry *query,
921                           enum tf_rm_resc_resv_strategy *resv_strategy)
922 {
923         int rc;
924         int i;
925         struct tfp_send_msg_parms parms = { 0 };
926         struct hwrm_tf_session_resc_qcaps_input req = { 0 };
927         struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
928         uint8_t fw_session_id;
929         struct tf_msg_dma_buf qcaps_buf = { 0 };
930         struct tf_rm_resc_req_entry *data;
931         int dma_size;
932
933         if (size == 0 || query == NULL || resv_strategy == NULL) {
934                 TFP_DRV_LOG(ERR,
935                             "%s: Resource QCAPS parameter error, rc:%s\n",
936                             tf_dir_2_str(dir),
937                             strerror(-EINVAL));
938                 return -EINVAL;
939         }
940
941         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
942         if (rc) {
943                 TFP_DRV_LOG(ERR,
944                             "%s: Unable to lookup FW id, rc:%s\n",
945                             tf_dir_2_str(dir),
946                             strerror(-rc));
947                 return rc;
948         }
949
950         /* Prepare DMA buffer */
951         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
952         rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
953         if (rc)
954                 return rc;
955
956         /* Populate the request */
957         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
958         req.flags = tfp_cpu_to_le_16(dir);
959         req.qcaps_size = size;
960         req.qcaps_addr = qcaps_buf.pa_addr;
961
962         parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
963         parms.req_data = (uint32_t *)&req;
964         parms.req_size = sizeof(req);
965         parms.resp_data = (uint32_t *)&resp;
966         parms.resp_size = sizeof(resp);
967         parms.mailbox = TF_KONG_MB;
968
969         rc = tfp_send_msg_direct(tfp, &parms);
970         if (rc)
971                 return rc;
972
973         /* Process the response
974          * Should always get expected number of entries
975          */
976         if (resp.size != size) {
977                 TFP_DRV_LOG(ERR,
978                             "%s: QCAPS message error, rc:%s\n",
979                             tf_dir_2_str(dir),
980                             strerror(-EINVAL));
981                 return -EINVAL;
982         }
983
984         /* Post process the response */
985         data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
986         for (i = 0; i < size; i++) {
987                 query[i].type = tfp_cpu_to_le_32(data[i].type);
988                 query[i].min = tfp_le_to_cpu_16(data[i].min);
989                 query[i].max = tfp_le_to_cpu_16(data[i].max);
990         }
991
992         *resv_strategy = resp.flags &
993               HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
994
995         tf_msg_free_dma_buf(&qcaps_buf);
996
997         return rc;
998 }
999
1000 int
1001 tf_msg_session_resc_alloc(struct tf *tfp,
1002                           enum tf_dir dir,
1003                           uint16_t size,
1004                           struct tf_rm_resc_req_entry *request,
1005                           struct tf_rm_resc_entry *resv)
1006 {
1007         int rc;
1008         int i;
1009         struct tfp_send_msg_parms parms = { 0 };
1010         struct hwrm_tf_session_resc_alloc_input req = { 0 };
1011         struct hwrm_tf_session_resc_alloc_output resp = { 0 };
1012         uint8_t fw_session_id;
1013         struct tf_msg_dma_buf req_buf = { 0 };
1014         struct tf_msg_dma_buf resv_buf = { 0 };
1015         struct tf_rm_resc_req_entry *req_data;
1016         struct tf_rm_resc_entry *resv_data;
1017         int dma_size;
1018
1019         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1020         if (rc) {
1021                 TFP_DRV_LOG(ERR,
1022                             "%s: Unable to lookup FW id, rc:%s\n",
1023                             tf_dir_2_str(dir),
1024                             strerror(-rc));
1025                 return rc;
1026         }
1027
1028         /* Prepare DMA buffers */
1029         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
1030         rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
1031         if (rc)
1032                 return rc;
1033
1034         dma_size = size * sizeof(struct tf_rm_resc_entry);
1035         rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
1036         if (rc)
1037                 return rc;
1038
1039         /* Populate the request */
1040         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1041         req.flags = tfp_cpu_to_le_16(dir);
1042         req.req_size = size;
1043
1044         req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
1045         for (i = 0; i < size; i++) {
1046                 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
1047                 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
1048                 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
1049         }
1050
1051         req.req_addr = req_buf.pa_addr;
1052         req.resp_addr = resv_buf.pa_addr;
1053
1054         parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
1055         parms.req_data = (uint32_t *)&req;
1056         parms.req_size = sizeof(req);
1057         parms.resp_data = (uint32_t *)&resp;
1058         parms.resp_size = sizeof(resp);
1059         parms.mailbox = TF_KONG_MB;
1060
1061         rc = tfp_send_msg_direct(tfp, &parms);
1062         if (rc)
1063                 return rc;
1064
1065         /* Process the response
1066          * Should always get expected number of entries
1067          */
1068         if (resp.size != size) {
1069                 TFP_DRV_LOG(ERR,
1070                             "%s: Alloc message error, rc:%s\n",
1071                             tf_dir_2_str(dir),
1072                             strerror(-EINVAL));
1073                 return -EINVAL;
1074         }
1075
1076         /* Post process the response */
1077         resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
1078         for (i = 0; i < size; i++) {
1079                 resv[i].type = tfp_cpu_to_le_32(resv_data[i].type);
1080                 resv[i].start = tfp_cpu_to_le_16(resv_data[i].start);
1081                 resv[i].stride = tfp_cpu_to_le_16(resv_data[i].stride);
1082         }
1083
1084         tf_msg_free_dma_buf(&req_buf);
1085         tf_msg_free_dma_buf(&resv_buf);
1086
1087         return rc;
1088 }
1089
1090 /**
1091  * Sends EM mem register request to Firmware
1092  */
1093 int tf_msg_em_mem_rgtr(struct tf *tfp,
1094                        int           page_lvl,
1095                        int           page_size,
1096                        uint64_t      dma_addr,
1097                        uint16_t     *ctx_id)
1098 {
1099         int rc;
1100         struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
1101         struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
1102         struct tfp_send_msg_parms parms = { 0 };
1103
1104         req.page_level = page_lvl;
1105         req.page_size = page_size;
1106         req.page_dir = tfp_cpu_to_le_64(dma_addr);
1107
1108         parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
1109         parms.req_data = (uint32_t *)&req;
1110         parms.req_size = sizeof(req);
1111         parms.resp_data = (uint32_t *)&resp;
1112         parms.resp_size = sizeof(resp);
1113         parms.mailbox = TF_KONG_MB;
1114
1115         rc = tfp_send_msg_direct(tfp,
1116                                  &parms);
1117         if (rc)
1118                 return rc;
1119
1120         *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
1121
1122         return rc;
1123 }
1124
1125 /**
1126  * Sends EM mem unregister request to Firmware
1127  */
1128 int tf_msg_em_mem_unrgtr(struct tf *tfp,
1129                          uint16_t  *ctx_id)
1130 {
1131         int rc;
1132         struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
1133         struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
1134         struct tfp_send_msg_parms parms = { 0 };
1135
1136         req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
1137
1138         parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
1139         parms.req_data = (uint32_t *)&req;
1140         parms.req_size = sizeof(req);
1141         parms.resp_data = (uint32_t *)&resp;
1142         parms.resp_size = sizeof(resp);
1143         parms.mailbox = TF_KONG_MB;
1144
1145         rc = tfp_send_msg_direct(tfp,
1146                                  &parms);
1147         return rc;
1148 }
1149
1150 /**
1151  * Sends EM qcaps request to Firmware
1152  */
1153 int tf_msg_em_qcaps(struct tf *tfp,
1154                     int dir,
1155                     struct tf_em_caps *em_caps)
1156 {
1157         int rc;
1158         struct hwrm_tf_ext_em_qcaps_input  req = {0};
1159         struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
1160         uint32_t             flags;
1161         struct tfp_send_msg_parms parms = { 0 };
1162
1163         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
1164                  HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
1165         req.flags = tfp_cpu_to_le_32(flags);
1166
1167         parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
1168         parms.req_data = (uint32_t *)&req;
1169         parms.req_size = sizeof(req);
1170         parms.resp_data = (uint32_t *)&resp;
1171         parms.resp_size = sizeof(resp);
1172         parms.mailbox = TF_KONG_MB;
1173
1174         rc = tfp_send_msg_direct(tfp,
1175                                  &parms);
1176         if (rc)
1177                 return rc;
1178
1179         em_caps->supported = tfp_le_to_cpu_32(resp.supported);
1180         em_caps->max_entries_supported =
1181                 tfp_le_to_cpu_32(resp.max_entries_supported);
1182         em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
1183         em_caps->record_entry_size =
1184                 tfp_le_to_cpu_16(resp.record_entry_size);
1185         em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
1186
1187         return rc;
1188 }
1189
1190 /**
1191  * Sends EM config request to Firmware
1192  */
1193 int tf_msg_em_cfg(struct tf *tfp,
1194                   uint32_t   num_entries,
1195                   uint16_t   key0_ctx_id,
1196                   uint16_t   key1_ctx_id,
1197                   uint16_t   record_ctx_id,
1198                   uint16_t   efc_ctx_id,
1199                   uint8_t    flush_interval,
1200                   int        dir)
1201 {
1202         int rc;
1203         struct hwrm_tf_ext_em_cfg_input  req = {0};
1204         struct hwrm_tf_ext_em_cfg_output resp = {0};
1205         uint32_t flags;
1206         struct tfp_send_msg_parms parms = { 0 };
1207
1208         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1209                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1210         flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
1211
1212         req.flags = tfp_cpu_to_le_32(flags);
1213         req.num_entries = tfp_cpu_to_le_32(num_entries);
1214
1215         req.flush_interval = flush_interval;
1216
1217         req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
1218         req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
1219         req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
1220         req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
1221
1222         parms.tf_type = HWRM_TF_EXT_EM_CFG;
1223         parms.req_data = (uint32_t *)&req;
1224         parms.req_size = sizeof(req);
1225         parms.resp_data = (uint32_t *)&resp;
1226         parms.resp_size = sizeof(resp);
1227         parms.mailbox = TF_KONG_MB;
1228
1229         rc = tfp_send_msg_direct(tfp,
1230                                  &parms);
1231         return rc;
1232 }
1233
1234 /**
1235  * Sends EM internal insert request to Firmware
1236  */
1237 int tf_msg_insert_em_internal_entry(struct tf *tfp,
1238                                 struct tf_insert_em_entry_parms *em_parms,
1239                                 uint16_t *rptr_index,
1240                                 uint8_t *rptr_entry,
1241                                 uint8_t *num_of_entries)
1242 {
1243         int                         rc;
1244         struct tfp_send_msg_parms        parms = { 0 };
1245         struct hwrm_tf_em_insert_input   req = { 0 };
1246         struct hwrm_tf_em_insert_output  resp = { 0 };
1247         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
1248         struct tf_em_64b_entry *em_result =
1249                 (struct tf_em_64b_entry *)em_parms->em_record;
1250         uint32_t flags;
1251
1252         req.fw_session_id =
1253                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1254         tfp_memcpy(req.em_key,
1255                    em_parms->key,
1256                    ((em_parms->key_sz_in_bits + 7) / 8));
1257
1258         flags = (em_parms->dir == TF_DIR_TX ?
1259                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
1260                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
1261         req.flags = tfp_cpu_to_le_16(flags);
1262         req.strength = (em_result->hdr.word1 & TF_LKUP_RECORD_STRENGTH_MASK) >>
1263                 TF_LKUP_RECORD_STRENGTH_SHIFT;
1264         req.em_key_bitlen = em_parms->key_sz_in_bits;
1265         req.action_ptr = em_result->hdr.pointer;
1266         req.em_record_idx = *rptr_index;
1267
1268         parms.tf_type = HWRM_TF_EM_INSERT;
1269         parms.req_data = (uint32_t *)&req;
1270         parms.req_size = sizeof(req);
1271         parms.resp_data = (uint32_t *)&resp;
1272         parms.resp_size = sizeof(resp);
1273         parms.mailbox = TF_KONG_MB;
1274
1275         rc = tfp_send_msg_direct(tfp,
1276                                  &parms);
1277         if (rc)
1278                 return rc;
1279
1280         *rptr_entry = resp.rptr_entry;
1281         *rptr_index = resp.rptr_index;
1282         *num_of_entries = resp.num_of_entries;
1283
1284         return 0;
1285 }
1286
1287 /**
1288  * Sends EM delete insert request to Firmware
1289  */
1290 int tf_msg_delete_em_entry(struct tf *tfp,
1291                            struct tf_delete_em_entry_parms *em_parms)
1292 {
1293         int                             rc;
1294         struct tfp_send_msg_parms       parms = { 0 };
1295         struct hwrm_tf_em_delete_input  req = { 0 };
1296         struct hwrm_tf_em_delete_output resp = { 0 };
1297         uint32_t flags;
1298         struct tf_session *tfs =
1299                 (struct tf_session *)(tfp->session->core_data);
1300
1301         req.fw_session_id =
1302                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1303
1304         flags = (em_parms->dir == TF_DIR_TX ?
1305                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
1306                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
1307         req.flags = tfp_cpu_to_le_16(flags);
1308         req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
1309
1310         parms.tf_type = HWRM_TF_EM_DELETE;
1311         parms.req_data = (uint32_t *)&req;
1312         parms.req_size = sizeof(req);
1313         parms.resp_data = (uint32_t *)&resp;
1314         parms.resp_size = sizeof(resp);
1315         parms.mailbox = TF_KONG_MB;
1316
1317         rc = tfp_send_msg_direct(tfp,
1318                                  &parms);
1319         if (rc)
1320                 return rc;
1321
1322         em_parms->index = tfp_le_to_cpu_16(resp.em_index);
1323
1324         return 0;
1325 }
1326
1327 /**
1328  * Sends EM operation request to Firmware
1329  */
1330 int tf_msg_em_op(struct tf *tfp,
1331                  int dir,
1332                  uint16_t op)
1333 {
1334         int rc;
1335         struct hwrm_tf_ext_em_op_input req = {0};
1336         struct hwrm_tf_ext_em_op_output resp = {0};
1337         uint32_t flags;
1338         struct tfp_send_msg_parms parms = { 0 };
1339
1340         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1341                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1342         req.flags = tfp_cpu_to_le_32(flags);
1343         req.op = tfp_cpu_to_le_16(op);
1344
1345         parms.tf_type = HWRM_TF_EXT_EM_OP;
1346         parms.req_data = (uint32_t *)&req;
1347         parms.req_size = sizeof(req);
1348         parms.resp_data = (uint32_t *)&resp;
1349         parms.resp_size = sizeof(resp);
1350         parms.mailbox = TF_KONG_MB;
1351
1352         rc = tfp_send_msg_direct(tfp,
1353                                  &parms);
1354         return rc;
1355 }
1356
1357 int
1358 tf_msg_set_tbl_entry(struct tf *tfp,
1359                      enum tf_dir dir,
1360                      enum tf_tbl_type type,
1361                      uint16_t size,
1362                      uint8_t *data,
1363                      uint32_t index)
1364 {
1365         int rc;
1366         struct tfp_send_msg_parms parms = { 0 };
1367         struct tf_tbl_type_set_input req = { 0 };
1368         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
1369
1370         /* Populate the request */
1371         req.fw_session_id =
1372                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1373         req.flags = tfp_cpu_to_le_16(dir);
1374         req.type = tfp_cpu_to_le_32(type);
1375         req.size = tfp_cpu_to_le_16(size);
1376         req.index = tfp_cpu_to_le_32(index);
1377
1378         tfp_memcpy(&req.data,
1379                    data,
1380                    size);
1381
1382         MSG_PREP_NO_RESP(parms,
1383                          TF_KONG_MB,
1384                          HWRM_TF,
1385                          HWRM_TFT_TBL_TYPE_SET,
1386                          req);
1387
1388         rc = tfp_send_msg_tunneled(tfp, &parms);
1389         if (rc)
1390                 return rc;
1391
1392         return tfp_le_to_cpu_32(parms.tf_resp_code);
1393 }
1394
1395 int
1396 tf_msg_get_tbl_entry(struct tf *tfp,
1397                      enum tf_dir dir,
1398                      enum tf_tbl_type type,
1399                      uint16_t size,
1400                      uint8_t *data,
1401                      uint32_t index)
1402 {
1403         int rc;
1404         struct tfp_send_msg_parms parms = { 0 };
1405         struct tf_tbl_type_get_input req = { 0 };
1406         struct tf_tbl_type_get_output resp = { 0 };
1407         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
1408
1409         /* Populate the request */
1410         req.fw_session_id =
1411                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1412         req.flags = tfp_cpu_to_le_16(dir);
1413         req.type = tfp_cpu_to_le_32(type);
1414         req.index = tfp_cpu_to_le_32(index);
1415
1416         MSG_PREP(parms,
1417                  TF_KONG_MB,
1418                  HWRM_TF,
1419                  HWRM_TFT_TBL_TYPE_GET,
1420                  req,
1421                  resp);
1422
1423         rc = tfp_send_msg_tunneled(tfp, &parms);
1424         if (rc)
1425                 return rc;
1426
1427         /* Verify that we got enough buffer to return the requested data */
1428         if (resp.size < size)
1429                 return -EINVAL;
1430
1431         tfp_memcpy(data,
1432                    &resp.data,
1433                    resp.size);
1434
1435         return tfp_le_to_cpu_32(parms.tf_resp_code);
1436 }
1437
1438 int
1439 tf_msg_get_bulk_tbl_entry(struct tf *tfp,
1440                           struct tf_get_bulk_tbl_entry_parms *params)
1441 {
1442         int rc;
1443         struct tfp_send_msg_parms parms = { 0 };
1444         struct tf_tbl_type_get_bulk_input req = { 0 };
1445         struct tf_tbl_type_get_bulk_output resp = { 0 };
1446         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
1447         int data_size = 0;
1448
1449         /* Populate the request */
1450         req.fw_session_id =
1451                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1452         req.flags = tfp_cpu_to_le_16((params->dir) |
1453                 ((params->clear_on_read) ?
1454                  TF_TBL_TYPE_GET_BULK_INPUT_FLAGS_CLEAR_ON_READ : 0x0));
1455         req.type = tfp_cpu_to_le_32(params->type);
1456         req.start_index = tfp_cpu_to_le_32(params->starting_idx);
1457         req.num_entries = tfp_cpu_to_le_32(params->num_entries);
1458
1459         data_size = (params->num_entries * params->entry_sz_in_bytes);
1460         req.host_addr = tfp_cpu_to_le_64(params->physical_mem_addr);
1461
1462         MSG_PREP(parms,
1463                  TF_KONG_MB,
1464                  HWRM_TF,
1465                  HWRM_TFT_TBL_TYPE_GET_BULK,
1466                  req,
1467                  resp);
1468
1469         rc = tfp_send_msg_tunneled(tfp, &parms);
1470         if (rc)
1471                 return rc;
1472
1473         /* Verify that we got enough buffer to return the requested data */
1474         if (resp.size < data_size)
1475                 return -EINVAL;
1476
1477         return tfp_le_to_cpu_32(parms.tf_resp_code);
1478 }
1479
1480 #define TF_BYTES_PER_SLICE(tfp) 12
1481 #define NUM_SLICES(tfp, bytes) \
1482         (((bytes) + TF_BYTES_PER_SLICE(tfp) - 1) / TF_BYTES_PER_SLICE(tfp))
1483
1484 int
1485 tf_msg_tcam_entry_set(struct tf *tfp,
1486                       struct tf_set_tcam_entry_parms *parms)
1487 {
1488         int rc;
1489         struct tfp_send_msg_parms mparms = { 0 };
1490         struct hwrm_tf_tcam_set_input req = { 0 };
1491         struct hwrm_tf_tcam_set_output resp = { 0 };
1492         uint16_t key_bytes =
1493                 TF_BITS2BYTES_WORD_ALIGN(parms->key_sz_in_bits);
1494         uint16_t result_bytes =
1495                 TF_BITS2BYTES_WORD_ALIGN(parms->result_sz_in_bits);
1496         struct tf_msg_dma_buf buf = { 0 };
1497         uint8_t *data = NULL;
1498         int data_size = 0;
1499
1500         rc = tf_tcam_tbl_2_hwrm(parms->tcam_tbl_type, &req.type);
1501         if (rc != 0)
1502                 return rc;
1503
1504         req.idx = tfp_cpu_to_le_16(parms->idx);
1505         if (parms->dir == TF_DIR_TX)
1506                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
1507
1508         req.key_size = key_bytes;
1509         req.mask_offset = key_bytes;
1510         /* Result follows after key and mask, thus multiply by 2 */
1511         req.result_offset = 2 * key_bytes;
1512         req.result_size = result_bytes;
1513         data_size = 2 * req.key_size + req.result_size;
1514
1515         if (data_size <= TF_PCI_BUF_SIZE_MAX) {
1516                 /* use pci buffer */
1517                 data = &req.dev_data[0];
1518         } else {
1519                 /* use dma buffer */
1520                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
1521                 rc = tf_msg_alloc_dma_buf(&buf, data_size);
1522                 if (rc)
1523                         goto cleanup;
1524                 data = buf.va_addr;
1525                 tfp_memcpy(&req.dev_data[0],
1526                            &buf.pa_addr,
1527                            sizeof(buf.pa_addr));
1528         }
1529
1530         tfp_memcpy(&data[0], parms->key, key_bytes);
1531         tfp_memcpy(&data[key_bytes], parms->mask, key_bytes);
1532         tfp_memcpy(&data[req.result_offset], parms->result, result_bytes);
1533
1534         mparms.tf_type = HWRM_TF_TCAM_SET;
1535         mparms.req_data = (uint32_t *)&req;
1536         mparms.req_size = sizeof(req);
1537         mparms.resp_data = (uint32_t *)&resp;
1538         mparms.resp_size = sizeof(resp);
1539         mparms.mailbox = TF_KONG_MB;
1540
1541         rc = tfp_send_msg_direct(tfp,
1542                                  &mparms);
1543         if (rc)
1544                 goto cleanup;
1545
1546 cleanup:
1547         tf_msg_free_dma_buf(&buf);
1548
1549         return rc;
1550 }
1551
1552 int
1553 tf_msg_tcam_entry_free(struct tf *tfp,
1554                        struct tf_free_tcam_entry_parms *in_parms)
1555 {
1556         int rc;
1557         struct hwrm_tf_tcam_free_input req =  { 0 };
1558         struct hwrm_tf_tcam_free_output resp = { 0 };
1559         struct tfp_send_msg_parms parms = { 0 };
1560
1561         /* Populate the request */
1562         rc = tf_tcam_tbl_2_hwrm(in_parms->tcam_tbl_type, &req.type);
1563         if (rc != 0)
1564                 return rc;
1565
1566         req.count = 1;
1567         req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
1568         if (in_parms->dir == TF_DIR_TX)
1569                 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
1570
1571         parms.tf_type = HWRM_TF_TCAM_FREE;
1572         parms.req_data = (uint32_t *)&req;
1573         parms.req_size = sizeof(req);
1574         parms.resp_data = (uint32_t *)&resp;
1575         parms.resp_size = sizeof(resp);
1576         parms.mailbox = TF_KONG_MB;
1577
1578         rc = tfp_send_msg_direct(tfp,
1579                                  &parms);
1580         return rc;
1581 }