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