net/bnxt: add functions to get shared table increments
[dpdk.git] / drivers / net / bnxt / tf_core / tf_msg.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5
6 #include <assert.h>
7 #include <inttypes.h>
8 #include <stdbool.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "tf_em_common.h"
13 #include "tf_msg_common.h"
14 #include "tf_device.h"
15 #include "tf_msg.h"
16 #include "tf_util.h"
17 #include "tf_common.h"
18 #include "tf_session.h"
19 #include "tfp.h"
20 #include "tf_em.h"
21
22 /* Specific msg size defines as we cannot use defines in tf.yaml. This
23  * means we have to manually sync hwrm with these defines if the
24  * tf.yaml changes.
25  */
26 #define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE  16
27 #define TF_MSG_EM_INSERT_KEY_SIZE        64
28 #define TF_MSG_EM_INSERT_RECORD_SIZE     80
29 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE    88
30
31 /* Compile check - Catch any msg changes that we depend on, like the
32  * defines listed above for array size checking.
33  *
34  * Checking array size is dangerous in that the type could change and
35  * we wouldn't be able to catch it. Thus we check if the complete msg
36  * changed instead. Best we can do.
37  *
38  * If failure is observed then both msg size (defines below) and the
39  * array size (define above) should be checked and compared.
40  */
41 #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56
42 static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
43               TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET,
44               "HWRM message size changed: hwrm_tf_global_cfg_set_input");
45
46 #define TF_MSG_SIZE_HWRM_TF_EM_INSERT      104
47 static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
48               TF_MSG_SIZE_HWRM_TF_EM_INSERT,
49               "HWRM message size changed: hwrm_tf_em_insert_input");
50
51 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET   128
52 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
53               TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
54               "HWRM message size changed: hwrm_tf_tbl_type_set_input");
55
56 /**
57  * This is the MAX data we can transport across regular HWRM
58  */
59 #define TF_PCI_BUF_SIZE_MAX 88
60
61 /**
62  * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
63  */
64 struct tf_msg_dma_buf {
65         void *va_addr;
66         uint64_t pa_addr;
67 };
68
69 /**
70  * Allocates a DMA buffer that can be used for message transfer.
71  *
72  * [in] buf
73  *   Pointer to DMA buffer structure
74  *
75  * [in] size
76  *   Requested size of the buffer in bytes
77  *
78  * Returns:
79  *    0      - Success
80  *   -ENOMEM - Unable to allocate buffer, no memory
81  */
82 static int
83 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
84 {
85         struct tfp_calloc_parms alloc_parms;
86         int rc;
87
88         /* Allocate session */
89         alloc_parms.nitems = 1;
90         alloc_parms.size = size;
91         alloc_parms.alignment = 4096;
92         rc = tfp_calloc(&alloc_parms);
93         if (rc)
94                 return -ENOMEM;
95
96         buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
97         buf->va_addr = alloc_parms.mem_va;
98
99         return 0;
100 }
101
102 /**
103  * Free's a previous allocated DMA buffer.
104  *
105  * [in] buf
106  *   Pointer to DMA buffer structure
107  */
108 static void
109 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
110 {
111         tfp_free(buf->va_addr);
112 }
113
114 /* HWRM Direct messages */
115
116 int
117 tf_msg_session_open(struct bnxt *bp,
118                     char *ctrl_chan_name,
119                     uint8_t *fw_session_id,
120                     uint8_t *fw_session_client_id,
121                     struct tf_dev_info *dev,
122                     bool *shared_session_creator)
123 {
124         int rc;
125         struct hwrm_tf_session_open_input req = { 0 };
126         struct hwrm_tf_session_open_output resp = { 0 };
127         struct tfp_send_msg_parms parms = { 0 };
128         int name_len;
129         char *name;
130
131         /* Populate the request */
132         name_len = strnlen(ctrl_chan_name, TF_SESSION_NAME_MAX);
133         name = &ctrl_chan_name[name_len - strlen("tf_shared")];
134         if (!strncmp(name, "tf_shared", strlen("tf_shared")))
135                 tfp_memcpy(&req.session_name, name, strlen("tf_share"));
136         else
137                 tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
138
139         parms.tf_type = HWRM_TF_SESSION_OPEN;
140         parms.req_data = (uint32_t *)&req;
141         parms.req_size = sizeof(req);
142         parms.resp_data = (uint32_t *)&resp;
143         parms.resp_size = sizeof(resp);
144         parms.mailbox = dev->ops->tf_dev_get_mailbox();
145
146         rc = tfp_send_msg_direct(bp,
147                                  &parms);
148         if (rc)
149                 return rc;
150
151         *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
152         *fw_session_client_id =
153                 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
154         *shared_session_creator = (bool)tfp_le_to_cpu_32(resp.flags
155                 & HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR);
156
157         return rc;
158 }
159
160 int
161 tf_msg_session_attach(struct tf *tfp __rte_unused,
162                       char *ctrl_chan_name __rte_unused,
163                       uint8_t tf_fw_session_id __rte_unused)
164 {
165         return -1;
166 }
167
168 int
169 tf_msg_session_client_register(struct tf *tfp,
170                                struct tf_session *tfs,
171                                char *ctrl_channel_name,
172                                uint8_t *fw_session_client_id)
173 {
174         int rc;
175         struct hwrm_tf_session_register_input req = { 0 };
176         struct hwrm_tf_session_register_output resp = { 0 };
177         struct tfp_send_msg_parms parms = { 0 };
178         uint8_t fw_session_id;
179         struct tf_dev_info *dev;
180
181         /* Retrieve the device information */
182         rc = tf_session_get_device(tfs, &dev);
183         if (rc) {
184                 TFP_DRV_LOG(ERR,
185                             "Failed to lookup device, rc:%s\n",
186                             strerror(-rc));
187                 return rc;
188         }
189
190         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
191         if (rc) {
192                 TFP_DRV_LOG(ERR,
193                             "Unable to lookup FW id, rc:%s\n",
194                             strerror(-rc));
195                 return rc;
196         }
197
198         /* Populate the request */
199         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
200         tfp_memcpy(&req.session_client_name,
201                    ctrl_channel_name,
202                    TF_SESSION_NAME_MAX);
203
204         parms.tf_type = HWRM_TF_SESSION_REGISTER;
205         parms.req_data = (uint32_t *)&req;
206         parms.req_size = sizeof(req);
207         parms.resp_data = (uint32_t *)&resp;
208         parms.resp_size = sizeof(resp);
209         parms.mailbox = dev->ops->tf_dev_get_mailbox();
210
211         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
212                                  &parms);
213         if (rc)
214                 return rc;
215
216         *fw_session_client_id =
217                 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
218
219         return rc;
220 }
221
222 int
223 tf_msg_session_client_unregister(struct tf *tfp,
224                                  struct tf_session *tfs,
225                                  uint8_t fw_session_client_id)
226 {
227         int rc;
228         struct hwrm_tf_session_unregister_input req = { 0 };
229         struct hwrm_tf_session_unregister_output resp = { 0 };
230         struct tfp_send_msg_parms parms = { 0 };
231         uint8_t fw_session_id;
232         struct tf_dev_info *dev;
233
234         /* Retrieve the device information */
235         rc = tf_session_get_device(tfs, &dev);
236         if (rc) {
237                 TFP_DRV_LOG(ERR,
238                             "Failed to lookup device, rc:%s\n",
239                             strerror(-rc));
240                 return rc;
241         }
242
243         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
244         if (rc) {
245                 TFP_DRV_LOG(ERR,
246                             "Unable to lookup FW id, rc:%s\n",
247                             strerror(-rc));
248                 return rc;
249         }
250
251         /* Populate the request */
252         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
253         req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
254
255         parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
256         parms.req_data = (uint32_t *)&req;
257         parms.req_size = sizeof(req);
258         parms.resp_data = (uint32_t *)&resp;
259         parms.resp_size = sizeof(resp);
260         parms.mailbox = dev->ops->tf_dev_get_mailbox();
261
262         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
263                                  &parms);
264
265         return rc;
266 }
267
268 int
269 tf_msg_session_close(struct tf *tfp,
270                      struct tf_session *tfs)
271 {
272         int rc;
273         struct hwrm_tf_session_close_input req = { 0 };
274         struct hwrm_tf_session_close_output resp = { 0 };
275         struct tfp_send_msg_parms parms = { 0 };
276         uint8_t fw_session_id;
277         struct tf_dev_info *dev;
278
279         /* Retrieve the device information */
280         rc = tf_session_get_device(tfs, &dev);
281         if (rc) {
282                 TFP_DRV_LOG(ERR,
283                             "Failed to lookup device, rc:%s\n",
284                             strerror(-rc));
285                 return rc;
286         }
287
288         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
289         if (rc) {
290                 TFP_DRV_LOG(ERR,
291                             "Unable to lookup FW id, rc:%s\n",
292                             strerror(-rc));
293                 return rc;
294         }
295
296         /* Populate the request */
297         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
298
299         parms.tf_type = HWRM_TF_SESSION_CLOSE;
300         parms.req_data = (uint32_t *)&req;
301         parms.req_size = sizeof(req);
302         parms.resp_data = (uint32_t *)&resp;
303         parms.resp_size = sizeof(resp);
304         parms.mailbox = dev->ops->tf_dev_get_mailbox();
305
306         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
307                                  &parms);
308         return rc;
309 }
310
311 int
312 tf_msg_session_qcfg(struct tf *tfp)
313 {
314         int rc;
315         struct hwrm_tf_session_qcfg_input req = { 0 };
316         struct hwrm_tf_session_qcfg_output resp = { 0 };
317         struct tfp_send_msg_parms parms = { 0 };
318         uint8_t fw_session_id;
319         struct tf_dev_info *dev;
320         struct tf_session *tfs;
321
322         /* Retrieve the session information */
323         rc = tf_session_get_session_internal(tfp, &tfs);
324         if (rc) {
325                 TFP_DRV_LOG(ERR,
326                             "Failed to lookup session, rc:%s\n",
327                             strerror(-rc));
328                 return rc;
329         }
330
331         /* Retrieve the device information */
332         rc = tf_session_get_device(tfs, &dev);
333         if (rc) {
334                 TFP_DRV_LOG(ERR,
335                             "Failed to lookup device, rc:%s\n",
336                             strerror(-rc));
337                 return rc;
338         }
339
340         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
341         if (rc) {
342                 TFP_DRV_LOG(ERR,
343                             "Unable to lookup FW id, rc:%s\n",
344                             strerror(-rc));
345                 return rc;
346         }
347
348         /* Populate the request */
349         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
350
351         parms.tf_type = HWRM_TF_SESSION_QCFG,
352         parms.req_data = (uint32_t *)&req;
353         parms.req_size = sizeof(req);
354         parms.resp_data = (uint32_t *)&resp;
355         parms.resp_size = sizeof(resp);
356         parms.mailbox = dev->ops->tf_dev_get_mailbox();
357
358         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
359                                  &parms);
360         return rc;
361 }
362
363 int
364 tf_msg_session_resc_qcaps(struct tf *tfp,
365                           struct tf_dev_info *dev,
366                           enum tf_dir dir,
367                           uint16_t size,
368                           struct tf_rm_resc_req_entry *query,
369                           enum tf_rm_resc_resv_strategy *resv_strategy)
370 {
371         int rc;
372         int i;
373         struct tfp_send_msg_parms parms = { 0 };
374         struct hwrm_tf_session_resc_qcaps_input req = { 0 };
375         struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
376         uint8_t fw_session_id;
377         struct tf_msg_dma_buf qcaps_buf = { 0 };
378         struct tf_rm_resc_req_entry *data;
379         int dma_size;
380         struct tf_session *tfs;
381
382         /* Retrieve the session information */
383         rc = tf_session_get_session_internal(tfp, &tfs);
384         if (rc) {
385                 TFP_DRV_LOG(ERR,
386                             "Failed to lookup session, rc:%s\n",
387                             strerror(-rc));
388                 return rc;
389         }
390
391         TF_CHECK_PARMS3(tfp, query, resv_strategy);
392
393         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
394         if (rc) {
395                 TFP_DRV_LOG(ERR,
396                             "%s: Unable to lookup FW id, rc:%s\n",
397                             tf_dir_2_str(dir),
398                             strerror(-rc));
399                 return rc;
400         }
401
402         /* Prepare DMA buffer */
403         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
404         rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
405         if (rc)
406                 return rc;
407
408         /* Populate the request */
409         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
410         req.flags = tfp_cpu_to_le_16(dir);
411         req.qcaps_size = size;
412         req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
413
414         parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
415         parms.req_data = (uint32_t *)&req;
416         parms.req_size = sizeof(req);
417         parms.resp_data = (uint32_t *)&resp;
418         parms.resp_size = sizeof(resp);
419         parms.mailbox = dev->ops->tf_dev_get_mailbox();
420
421         rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
422         if (rc)
423                 goto cleanup;
424
425         /* Process the response
426          * Should always get expected number of entries
427          */
428         if (tfp_le_to_cpu_32(resp.size) != size) {
429                 TFP_DRV_LOG(ERR,
430                             "%s: QCAPS message size error, rc:%s\n",
431                             tf_dir_2_str(dir),
432                             strerror(EINVAL));
433                 rc = -EINVAL;
434                 goto cleanup;
435         }
436
437         /* Post process the response */
438         data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
439
440         for (i = 0; i < size; i++) {
441                 query[i].type = tfp_le_to_cpu_32(data[i].type);
442                 query[i].min = tfp_le_to_cpu_16(data[i].min);
443                 query[i].max = tfp_le_to_cpu_16(data[i].max);
444         }
445
446         *resv_strategy = resp.flags &
447               HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
448
449 cleanup:
450         tf_msg_free_dma_buf(&qcaps_buf);
451
452         return rc;
453 }
454
455 int
456 tf_msg_session_resc_alloc(struct tf *tfp,
457                           struct tf_dev_info *dev,
458                           enum tf_dir dir,
459                           uint16_t size,
460                           struct tf_rm_resc_req_entry *request,
461                           struct tf_rm_resc_entry *resv)
462 {
463         int rc;
464         int i;
465         struct tfp_send_msg_parms parms = { 0 };
466         struct hwrm_tf_session_resc_alloc_input req = { 0 };
467         struct hwrm_tf_session_resc_alloc_output resp = { 0 };
468         uint8_t fw_session_id;
469         struct tf_msg_dma_buf req_buf = { 0 };
470         struct tf_msg_dma_buf resv_buf = { 0 };
471         struct tf_rm_resc_req_entry *req_data;
472         struct tf_rm_resc_entry *resv_data;
473         int dma_size;
474         struct tf_session *tfs;
475
476         /* Retrieve the session information */
477         rc = tf_session_get_session_internal(tfp, &tfs);
478         if (rc) {
479                 TFP_DRV_LOG(ERR,
480                             "Failed to lookup session, rc:%s\n",
481                             strerror(-rc));
482                 return rc;
483         }
484
485         TF_CHECK_PARMS3(tfp, request, resv);
486
487         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
488         if (rc) {
489                 TFP_DRV_LOG(ERR,
490                             "%s: Unable to lookup FW id, rc:%s\n",
491                             tf_dir_2_str(dir),
492                             strerror(-rc));
493                 return rc;
494         }
495
496         /* Prepare DMA buffers */
497         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
498         rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
499         if (rc)
500                 return rc;
501
502         dma_size = size * sizeof(struct tf_rm_resc_entry);
503         rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
504         if (rc) {
505                 tf_msg_free_dma_buf(&req_buf);
506                 return rc;
507         }
508
509         /* Populate the request */
510         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
511         req.flags = tfp_cpu_to_le_16(dir);
512         req.req_size = size;
513
514         req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
515         for (i = 0; i < size; i++) {
516                 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
517                 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
518                 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
519         }
520
521         req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
522         req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
523
524         parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
525         parms.req_data = (uint32_t *)&req;
526         parms.req_size = sizeof(req);
527         parms.resp_data = (uint32_t *)&resp;
528         parms.resp_size = sizeof(resp);
529         parms.mailbox = dev->ops->tf_dev_get_mailbox();
530
531         rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
532         if (rc)
533                 goto cleanup;
534
535         /* Process the response
536          * Should always get expected number of entries
537          */
538         if (tfp_le_to_cpu_32(resp.size) != size) {
539                 TFP_DRV_LOG(ERR,
540                             "%s: Alloc message size error, rc:%s\n",
541                             tf_dir_2_str(dir),
542                             strerror(EINVAL));
543                 rc = -EINVAL;
544                 goto cleanup;
545         }
546
547         /* Post process the response */
548         resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
549         for (i = 0; i < size; i++) {
550                 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
551                 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
552                 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
553         }
554
555 cleanup:
556         tf_msg_free_dma_buf(&req_buf);
557         tf_msg_free_dma_buf(&resv_buf);
558
559         return rc;
560 }
561
562 int
563 tf_msg_session_resc_info(struct tf *tfp,
564                          struct tf_dev_info *dev,
565                          enum tf_dir dir,
566                          uint16_t size,
567                          struct tf_rm_resc_req_entry *request,
568                          struct tf_rm_resc_entry *resv)
569 {
570         int rc;
571         int i;
572         struct tfp_send_msg_parms parms = { 0 };
573         struct hwrm_tf_session_resc_info_input req = { 0 };
574         struct hwrm_tf_session_resc_info_output resp = { 0 };
575         uint8_t fw_session_id;
576         struct tf_msg_dma_buf req_buf = { 0 };
577         struct tf_msg_dma_buf resv_buf = { 0 };
578         struct tf_rm_resc_req_entry *req_data;
579         struct tf_rm_resc_entry *resv_data;
580         int dma_size;
581         struct tf_session *tfs;
582
583         /* Retrieve the session information */
584         rc = tf_session_get_session_internal(tfp, &tfs);
585         if (rc) {
586                 TFP_DRV_LOG(ERR,
587                             "Failed to lookup session, rc:%s\n",
588                             strerror(-rc));
589                 return rc;
590         }
591
592         TF_CHECK_PARMS3(tfp, request, resv);
593
594         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
595         if (rc) {
596                 TFP_DRV_LOG(ERR,
597                             "%s: Unable to lookup FW id, rc:%s\n",
598                             tf_dir_2_str(dir),
599                             strerror(-rc));
600                 return rc;
601         }
602
603         /* Prepare DMA buffers */
604         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
605         rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
606         if (rc)
607                 return rc;
608
609         dma_size = size * sizeof(struct tf_rm_resc_entry);
610         rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
611         if (rc) {
612                 tf_msg_free_dma_buf(&req_buf);
613                 return rc;
614         }
615
616         /* Populate the request */
617         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
618         req.flags = tfp_cpu_to_le_16(dir);
619         req.req_size = size;
620
621         req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
622         for (i = 0; i < size; i++) {
623                 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
624                 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
625                 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
626         }
627
628         req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
629         req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
630
631         parms.tf_type = HWRM_TF_SESSION_RESC_INFO;
632         parms.req_data = (uint32_t *)&req;
633         parms.req_size = sizeof(req);
634         parms.resp_data = (uint32_t *)&resp;
635         parms.resp_size = sizeof(resp);
636         parms.mailbox = dev->ops->tf_dev_get_mailbox();
637
638         rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
639         if (rc)
640                 goto cleanup;
641
642         /* Process the response
643          * Should always get expected number of entries
644          */
645         if (tfp_le_to_cpu_32(resp.size) != size) {
646                 TFP_DRV_LOG(ERR,
647                             "%s: Alloc message size error, rc:%s\n",
648                             tf_dir_2_str(dir),
649                             strerror(EINVAL));
650                 rc = -EINVAL;
651                 goto cleanup;
652         }
653
654         /* Post process the response */
655         resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
656         for (i = 0; i < size; i++) {
657                 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
658                 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
659                 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
660         }
661
662 cleanup:
663         tf_msg_free_dma_buf(&req_buf);
664         tf_msg_free_dma_buf(&resv_buf);
665
666         return rc;
667 }
668
669 int
670 tf_msg_session_resc_flush(struct tf *tfp,
671                           enum tf_dir dir,
672                           uint16_t size,
673                           struct tf_rm_resc_entry *resv)
674 {
675         int rc;
676         int i;
677         struct tfp_send_msg_parms parms = { 0 };
678         struct hwrm_tf_session_resc_flush_input req = { 0 };
679         struct hwrm_tf_session_resc_flush_output resp = { 0 };
680         uint8_t fw_session_id;
681         struct tf_msg_dma_buf resv_buf = { 0 };
682         struct tf_rm_resc_entry *resv_data;
683         int dma_size;
684         struct tf_dev_info *dev;
685         struct tf_session *tfs;
686
687         TF_CHECK_PARMS2(tfp, resv);
688
689         /* Retrieve the session information */
690         rc = tf_session_get_session_internal(tfp, &tfs);
691         if (rc) {
692                 TFP_DRV_LOG(ERR,
693                             "%s: Failed to lookup session, rc:%s\n",
694                             tf_dir_2_str(dir),
695                             strerror(-rc));
696                 return rc;
697         }
698
699         /* Retrieve the device information */
700         rc = tf_session_get_device(tfs, &dev);
701         if (rc) {
702                 TFP_DRV_LOG(ERR,
703                             "%s: Failed to lookup device, rc:%s\n",
704                             tf_dir_2_str(dir),
705                             strerror(-rc));
706                 return rc;
707         }
708
709         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
710         if (rc) {
711                 TFP_DRV_LOG(ERR,
712                             "%s: Unable to lookup FW id, rc:%s\n",
713                             tf_dir_2_str(dir),
714                             strerror(-rc));
715                 return rc;
716         }
717
718         /* Prepare DMA buffers */
719         dma_size = size * sizeof(struct tf_rm_resc_entry);
720         rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
721         if (rc)
722                 return rc;
723
724         /* Populate the request */
725         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
726         req.flags = tfp_cpu_to_le_16(dir);
727         req.flush_size = size;
728
729         resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
730         for (i = 0; i < size; i++) {
731                 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
732                 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
733                 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
734         }
735
736         req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
737
738         parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
739         parms.req_data = (uint32_t *)&req;
740         parms.req_size = sizeof(req);
741         parms.resp_data = (uint32_t *)&resp;
742         parms.resp_size = sizeof(resp);
743         parms.mailbox = dev->ops->tf_dev_get_mailbox();
744
745         rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
746
747         tf_msg_free_dma_buf(&resv_buf);
748
749         return rc;
750 }
751
752 int
753 tf_msg_insert_em_internal_entry(struct tf *tfp,
754                                 struct tf_insert_em_entry_parms *em_parms,
755                                 uint16_t *rptr_index,
756                                 uint8_t *rptr_entry,
757                                 uint8_t *num_of_entries)
758 {
759         int rc;
760         struct tfp_send_msg_parms parms = { 0 };
761         struct hwrm_tf_em_insert_input req = { 0 };
762         struct hwrm_tf_em_insert_output resp = { 0 };
763         struct tf_em_64b_entry *em_result =
764                 (struct tf_em_64b_entry *)em_parms->em_record;
765         uint16_t flags;
766         uint8_t fw_session_id;
767         uint8_t msg_key_size;
768         struct tf_dev_info *dev;
769         struct tf_session *tfs;
770
771         RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_em_insert_input) !=
772                          TF_MSG_SIZE_HWRM_TF_EM_INSERT);
773
774         /* Retrieve the session information */
775         rc = tf_session_get_session_internal(tfp, &tfs);
776         if (rc) {
777                 TFP_DRV_LOG(ERR,
778                             "%s: Failed to lookup session, rc:%s\n",
779                             tf_dir_2_str(em_parms->dir),
780                             strerror(-rc));
781                 return rc;
782         }
783
784         /* Retrieve the device information */
785         rc = tf_session_get_device(tfs, &dev);
786         if (rc) {
787                 TFP_DRV_LOG(ERR,
788                             "%s: Failed to lookup device, rc:%s\n",
789                             tf_dir_2_str(em_parms->dir),
790                             strerror(-rc));
791                 return rc;
792         }
793
794         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
795         if (rc) {
796                 TFP_DRV_LOG(ERR,
797                             "%s: Unable to lookup FW id, rc:%s\n",
798                             tf_dir_2_str(em_parms->dir),
799                             strerror(-rc));
800                 return rc;
801         }
802
803         /* Populate the request */
804         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
805
806         /* Check for key size conformity */
807         msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
808         if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
809                 rc = -EINVAL;
810                 TFP_DRV_LOG(ERR,
811                             "%s: Invalid parameters for msg type, rc:%s\n",
812                             tf_dir_2_str(em_parms->dir),
813                             strerror(-rc));
814                 return rc;
815         }
816
817         tfp_memcpy(req.em_key,
818                    em_parms->key,
819                    msg_key_size);
820
821         flags = (em_parms->dir == TF_DIR_TX ?
822                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
823                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
824         req.flags = tfp_cpu_to_le_16(flags);
825         req.strength = (em_result->hdr.word1 &
826                         CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
827                         CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
828         req.em_key_bitlen = em_parms->key_sz_in_bits;
829         req.action_ptr = em_result->hdr.pointer;
830         req.em_record_idx = *rptr_index;
831
832         parms.tf_type = HWRM_TF_EM_INSERT;
833         parms.req_data = (uint32_t *)&req;
834         parms.req_size = sizeof(req);
835         parms.resp_data = (uint32_t *)&resp;
836         parms.resp_size = sizeof(resp);
837         parms.mailbox = dev->ops->tf_dev_get_mailbox();
838
839         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
840                                  &parms);
841         if (rc)
842                 return rc;
843
844         *rptr_entry = resp.rptr_entry;
845         *rptr_index = resp.rptr_index;
846         *num_of_entries = resp.num_of_entries;
847
848         return 0;
849 }
850
851 int
852 tf_msg_hash_insert_em_internal_entry(struct tf *tfp,
853                                      struct tf_insert_em_entry_parms *em_parms,
854                                      uint32_t key0_hash,
855                                      uint32_t key1_hash,
856                                      uint16_t *rptr_index,
857                                      uint8_t *rptr_entry,
858                                      uint8_t *num_of_entries)
859 {
860         int rc;
861         struct tfp_send_msg_parms parms = { 0 };
862         struct hwrm_tf_em_hash_insert_input req = { 0 };
863         struct hwrm_tf_em_hash_insert_output resp = { 0 };
864         uint16_t flags;
865         uint8_t fw_session_id;
866         uint8_t msg_record_size;
867         struct tf_dev_info *dev;
868         struct tf_session *tfs;
869
870         /* Retrieve the session information */
871         rc = tf_session_get_session_internal(tfp, &tfs);
872         if (rc) {
873                 TFP_DRV_LOG(ERR,
874                             "%s: Failed to lookup session, rc:%s\n",
875                             tf_dir_2_str(em_parms->dir),
876                             strerror(-rc));
877                 return rc;
878         }
879
880         /* Retrieve the device information */
881         rc = tf_session_get_device(tfs, &dev);
882         if (rc) {
883                 TFP_DRV_LOG(ERR,
884                             "%s: Failed to lookup device, rc:%s\n",
885                             tf_dir_2_str(em_parms->dir),
886                             strerror(-rc));
887                 return rc;
888         }
889
890         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
891         if (rc) {
892                 TFP_DRV_LOG(ERR,
893                             "%s: Unable to lookup FW id, rc:%s\n",
894                             tf_dir_2_str(em_parms->dir),
895                             strerror(-rc));
896                 return rc;
897         }
898
899         /* Populate the request */
900         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
901
902         /* Check for key size conformity */
903         msg_record_size = (em_parms->em_record_sz_in_bits + 7) / 8;
904
905         if (msg_record_size > TF_MSG_EM_INSERT_RECORD_SIZE) {
906                 rc = -EINVAL;
907                 TFP_DRV_LOG(ERR,
908                             "%s: Record size to large, rc:%s\n",
909                             tf_dir_2_str(em_parms->dir),
910                             strerror(-rc));
911                 return rc;
912         }
913
914         tfp_memcpy((char *)req.em_record,
915                    em_parms->em_record,
916                    msg_record_size);
917
918         flags = (em_parms->dir == TF_DIR_TX ?
919                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
920                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
921         req.flags = tfp_cpu_to_le_16(flags);
922         req.em_record_size_bits = em_parms->em_record_sz_in_bits;
923         req.em_record_idx = *rptr_index;
924         req.key0_hash = key0_hash;
925         req.key1_hash = key1_hash;
926
927         parms.tf_type = HWRM_TF_EM_HASH_INSERT;
928         parms.req_data = (uint32_t *)&req;
929         parms.req_size = sizeof(req);
930         parms.resp_data = (uint32_t *)&resp;
931         parms.resp_size = sizeof(resp);
932         parms.mailbox = dev->ops->tf_dev_get_mailbox();
933
934         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
935                                  &parms);
936         if (rc)
937                 return rc;
938
939         *rptr_entry = resp.rptr_entry;
940         *rptr_index = resp.rptr_index;
941         *num_of_entries = resp.num_of_entries;
942
943         return 0;
944 }
945
946 int
947 tf_msg_delete_em_entry(struct tf *tfp,
948                        struct tf_delete_em_entry_parms *em_parms)
949 {
950         int rc;
951         struct tfp_send_msg_parms parms = { 0 };
952         struct hwrm_tf_em_delete_input req = { 0 };
953         struct hwrm_tf_em_delete_output resp = { 0 };
954         uint16_t flags;
955         uint8_t fw_session_id;
956         struct tf_dev_info *dev;
957         struct tf_session *tfs;
958
959         /* Retrieve the session information */
960         rc = tf_session_get_session_internal(tfp, &tfs);
961         if (rc) {
962                 TFP_DRV_LOG(ERR,
963                             "%s: Failed to lookup session, rc:%s\n",
964                             tf_dir_2_str(em_parms->dir),
965                             strerror(-rc));
966                 return rc;
967         }
968
969         /* Retrieve the device information */
970         rc = tf_session_get_device(tfs, &dev);
971         if (rc) {
972                 TFP_DRV_LOG(ERR,
973                             "%s: Failed to lookup device, rc:%s\n",
974                             tf_dir_2_str(em_parms->dir),
975                             strerror(-rc));
976                 return rc;
977         }
978
979         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
980         if (rc) {
981                 TFP_DRV_LOG(ERR,
982                             "%s: Unable to lookup FW id, rc:%s\n",
983                             tf_dir_2_str(em_parms->dir),
984                             strerror(-rc));
985                 return rc;
986         }
987
988         /* Populate the request */
989         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
990
991         flags = (em_parms->dir == TF_DIR_TX ?
992                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
993                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
994         req.flags = tfp_cpu_to_le_16(flags);
995         req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
996
997         parms.tf_type = HWRM_TF_EM_DELETE;
998         parms.req_data = (uint32_t *)&req;
999         parms.req_size = sizeof(req);
1000         parms.resp_data = (uint32_t *)&resp;
1001         parms.resp_size = sizeof(resp);
1002         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1003
1004         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1005                                  &parms);
1006         if (rc)
1007                 return rc;
1008
1009         em_parms->index = tfp_le_to_cpu_16(resp.em_index);
1010
1011         return 0;
1012 }
1013
1014 int
1015 tf_msg_move_em_entry(struct tf *tfp,
1016                      struct tf_move_em_entry_parms *em_parms)
1017 {
1018         int rc;
1019         struct tfp_send_msg_parms parms = { 0 };
1020         struct hwrm_tf_em_move_input req = { 0 };
1021         struct hwrm_tf_em_move_output resp = { 0 };
1022         uint16_t flags;
1023         uint8_t fw_session_id;
1024         struct tf_dev_info *dev;
1025         struct tf_session *tfs;
1026
1027         /* Retrieve the session information */
1028         rc = tf_session_get_session_internal(tfp, &tfs);
1029         if (rc) {
1030                 TFP_DRV_LOG(ERR,
1031                             "%s: Failed to lookup session, rc:%s\n",
1032                             tf_dir_2_str(em_parms->dir),
1033                             strerror(-rc));
1034                 return rc;
1035         }
1036
1037         /* Retrieve the device information */
1038         rc = tf_session_get_device(tfs, &dev);
1039         if (rc) {
1040                 TFP_DRV_LOG(ERR,
1041                             "%s: Failed to lookup device, rc:%s\n",
1042                             tf_dir_2_str(em_parms->dir),
1043                             strerror(-rc));
1044                 return rc;
1045         }
1046
1047         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1048         if (rc) {
1049                 TFP_DRV_LOG(ERR,
1050                             "%s: Unable to lookup FW id, rc:%s\n",
1051                             tf_dir_2_str(em_parms->dir),
1052                             strerror(-rc));
1053                 return rc;
1054         }
1055
1056         /* Populate the request */
1057         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1058
1059         flags = (em_parms->dir == TF_DIR_TX ?
1060                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
1061                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
1062         req.flags = tfp_cpu_to_le_16(flags);
1063         req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
1064         req.new_index = tfp_cpu_to_le_32(em_parms->new_index);
1065
1066         parms.tf_type = HWRM_TF_EM_MOVE;
1067         parms.req_data = (uint32_t *)&req;
1068         parms.req_size = sizeof(req);
1069         parms.resp_data = (uint32_t *)&resp;
1070         parms.resp_size = sizeof(resp);
1071         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1072
1073         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1074                                  &parms);
1075         if (rc)
1076                 return rc;
1077
1078         em_parms->index = tfp_le_to_cpu_16(resp.em_index);
1079
1080         return 0;
1081 }
1082
1083 int tf_msg_ext_em_ctxt_mem_alloc(struct tf *tfp,
1084                                 struct hcapi_cfa_em_table *tbl,
1085                                 uint64_t *dma_addr,
1086                                 uint32_t *page_lvl,
1087                                 uint32_t *page_size)
1088 {
1089         struct tfp_send_msg_parms parms = { 0 };
1090         struct hwrm_tf_ctxt_mem_alloc_input req = {0};
1091         struct hwrm_tf_ctxt_mem_alloc_output resp = {0};
1092         uint32_t mem_size_k;
1093         int rc = 0;
1094         struct tf_dev_info *dev;
1095         struct tf_session *tfs;
1096         uint32_t fw_se_id;
1097
1098         /* Retrieve the session information */
1099         rc = tf_session_get_session_internal(tfp, &tfs);
1100         if (rc) {
1101                 TFP_DRV_LOG(ERR,
1102                             "Failed to lookup session, rc:%s\n",
1103                             strerror(-rc));
1104                 return rc;
1105         }
1106
1107         /* Retrieve the device information */
1108         rc = tf_session_get_device(tfs, &dev);
1109         if (rc) {
1110                 TFP_DRV_LOG(ERR,
1111                             "Failed to lookup device, rc:%s\n",
1112                             strerror(-rc));
1113                 return rc;
1114         }
1115         /* Retrieve the session information */
1116         fw_se_id = tfs->session_id.internal.fw_session_id;
1117
1118         if (tbl->num_entries && tbl->entry_size) {
1119                 /* unit: kbytes */
1120                 mem_size_k = (tbl->num_entries / TF_KILOBYTE) * tbl->entry_size;
1121                 req.mem_size = tfp_cpu_to_le_32(mem_size_k);
1122                 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1123                 parms.tf_type = HWRM_TF_CTXT_MEM_ALLOC;
1124                 parms.req_data = (uint32_t *)&req;
1125                 parms.req_size = sizeof(req);
1126                 parms.resp_data = (uint32_t *)&resp;
1127                 parms.resp_size = sizeof(resp);
1128                 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1129                 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1130                 if (rc) {
1131                         TFP_DRV_LOG(ERR, "Failed ext_em_alloc error rc:%s\n",
1132                                 strerror(-rc));
1133                         return rc;
1134                 }
1135
1136                 *dma_addr = tfp_le_to_cpu_64(resp.page_dir);
1137                 *page_lvl = resp.page_level;
1138                 *page_size = resp.page_size;
1139         }
1140
1141         return rc;
1142 }
1143
1144 int tf_msg_ext_em_ctxt_mem_free(struct tf *tfp,
1145                                 uint32_t mem_size_k,
1146                                 uint64_t dma_addr,
1147                                 uint8_t page_level,
1148                                 uint8_t page_size)
1149 {
1150         struct tfp_send_msg_parms parms = { 0 };
1151         struct hwrm_tf_ctxt_mem_free_input req = {0};
1152         struct hwrm_tf_ctxt_mem_free_output resp = {0};
1153         int rc = 0;
1154         struct tf_dev_info *dev;
1155         struct tf_session *tfs;
1156         uint32_t fw_se_id;
1157
1158         /* Retrieve the session information */
1159         rc = tf_session_get_session_internal(tfp, &tfs);
1160         if (rc) {
1161                 TFP_DRV_LOG(ERR,
1162                             "Failed to lookup session, rc:%s\n",
1163                             strerror(-rc));
1164                 return rc;
1165         }
1166
1167         /* Retrieve the device information */
1168         rc = tf_session_get_device(tfs, &dev);
1169         if (rc) {
1170                 TFP_DRV_LOG(ERR,
1171                             "Failed to lookup device, rc:%s\n",
1172                             strerror(-rc));
1173                 return rc;
1174         }
1175         /* Retrieve the session information */
1176         fw_se_id = tfs->session_id.internal.fw_session_id;
1177
1178         req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1179         req.mem_size = tfp_cpu_to_le_32(mem_size_k);
1180         req.page_dir = tfp_cpu_to_le_64(dma_addr);
1181         req.page_level = page_level;
1182         req.page_size = page_size;
1183         parms.tf_type = HWRM_TF_CTXT_MEM_FREE;
1184         parms.req_data = (uint32_t *)&req;
1185         parms.req_size = sizeof(req);
1186         parms.resp_data = (uint32_t *)&resp;
1187         parms.resp_size = sizeof(resp);
1188         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1189         rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1190
1191         return rc;
1192 }
1193
1194 int
1195 tf_msg_em_mem_rgtr(struct tf *tfp,
1196                    int page_lvl,
1197                    int page_size,
1198                    uint64_t dma_addr,
1199                    uint16_t *ctx_id)
1200 {
1201         int rc;
1202         struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
1203         struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
1204         struct tfp_send_msg_parms parms = { 0 };
1205         struct tf_dev_info *dev;
1206         struct tf_session *tfs;
1207         uint32_t fw_se_id;
1208
1209         /* Retrieve the session information */
1210         rc = tf_session_get_session_internal(tfp, &tfs);
1211         if (rc) {
1212                 TFP_DRV_LOG(ERR,
1213                             "Failed to lookup session, rc:%s\n",
1214                             strerror(-rc));
1215                 return rc;
1216         }
1217
1218         /* Retrieve the device information */
1219         rc = tf_session_get_device(tfs, &dev);
1220         if (rc) {
1221                 TFP_DRV_LOG(ERR,
1222                             "Failed to lookup device, rc:%s\n",
1223                             strerror(-rc));
1224                 return rc;
1225         }
1226         fw_se_id = tfs->session_id.internal.fw_session_id;
1227
1228         req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1229         req.page_level = page_lvl;
1230         req.page_size = page_size;
1231         req.page_dir = tfp_cpu_to_le_64(dma_addr);
1232
1233         parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
1234         parms.req_data = (uint32_t *)&req;
1235         parms.req_size = sizeof(req);
1236         parms.resp_data = (uint32_t *)&resp;
1237         parms.resp_size = sizeof(resp);
1238         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1239
1240         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1241                                  &parms);
1242         if (rc)
1243                 return rc;
1244
1245         *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
1246
1247         return rc;
1248 }
1249
1250 int
1251 tf_msg_em_mem_unrgtr(struct tf *tfp,
1252                      uint16_t *ctx_id)
1253 {
1254         int rc;
1255         struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
1256         struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
1257         struct tfp_send_msg_parms parms = { 0 };
1258         struct tf_dev_info *dev;
1259         struct tf_session *tfs;
1260         uint32_t fw_se_id;
1261
1262         /* Retrieve the session information */
1263         rc = tf_session_get_session_internal(tfp, &tfs);
1264         if (rc) {
1265                 TFP_DRV_LOG(ERR,
1266                             "Failed to lookup session, rc:%s\n",
1267                             strerror(-rc));
1268                 return rc;
1269         }
1270
1271         /* Retrieve the device information */
1272         rc = tf_session_get_device(tfs, &dev);
1273         if (rc) {
1274                 TFP_DRV_LOG(ERR,
1275                             "Failed to lookup device, rc:%s\n",
1276                             strerror(-rc));
1277                 return rc;
1278         }
1279
1280         fw_se_id = tfs->session_id.internal.fw_session_id;
1281         req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1282
1283         req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
1284
1285         parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
1286         parms.req_data = (uint32_t *)&req;
1287         parms.req_size = sizeof(req);
1288         parms.resp_data = (uint32_t *)&resp;
1289         parms.resp_size = sizeof(resp);
1290         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1291
1292         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1293                                  &parms);
1294         return rc;
1295 }
1296
1297 int
1298 tf_msg_em_qcaps(struct tf *tfp,
1299                 int dir,
1300                 struct tf_em_caps *em_caps)
1301 {
1302         int rc;
1303         struct hwrm_tf_ext_em_qcaps_input  req = {0};
1304         struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
1305         uint32_t             flags;
1306         struct tfp_send_msg_parms parms = { 0 };
1307         struct tf_dev_info *dev;
1308         struct tf_session *tfs;
1309         uint32_t fw_se_id;
1310
1311         /* Retrieve the session information */
1312         rc = tf_session_get_session_internal(tfp, &tfs);
1313         if (rc) {
1314                 TFP_DRV_LOG(ERR,
1315                             "%s: Failed to lookup session, rc:%s\n",
1316                             tf_dir_2_str(dir),
1317                             strerror(-rc));
1318                 return rc;
1319         }
1320         fw_se_id = tfs->session_id.internal.fw_session_id;
1321
1322         /* Retrieve the device information */
1323         rc = tf_session_get_device(tfs, &dev);
1324         if (rc) {
1325                 TFP_DRV_LOG(ERR,
1326                             "%s: Failed to lookup device, rc:%s\n",
1327                             tf_dir_2_str(dir),
1328                             strerror(-rc));
1329                 return rc;
1330         }
1331
1332         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
1333                  HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
1334         req.flags = tfp_cpu_to_le_32(flags);
1335
1336         parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
1337         req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1338         parms.req_data = (uint32_t *)&req;
1339         parms.req_size = sizeof(req);
1340         parms.resp_data = (uint32_t *)&resp;
1341         parms.resp_size = sizeof(resp);
1342         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1343
1344         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1345                                  &parms);
1346         if (rc)
1347                 return rc;
1348
1349         em_caps->supported = tfp_le_to_cpu_32(resp.supported);
1350         em_caps->max_entries_supported =
1351                 tfp_le_to_cpu_32(resp.max_entries_supported);
1352         em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
1353         em_caps->record_entry_size =
1354                 tfp_le_to_cpu_16(resp.record_entry_size);
1355         em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
1356
1357         return rc;
1358 }
1359
1360 int
1361 tf_msg_em_cfg(struct tf *tfp,
1362               uint32_t num_entries,
1363               uint16_t key0_ctx_id,
1364               uint16_t key1_ctx_id,
1365               uint16_t record_ctx_id,
1366               uint16_t efc_ctx_id,
1367               uint8_t flush_interval,
1368               int dir)
1369 {
1370         int rc;
1371         struct hwrm_tf_ext_em_cfg_input  req = {0};
1372         struct hwrm_tf_ext_em_cfg_output resp = {0};
1373         uint32_t flags;
1374         struct tfp_send_msg_parms parms = { 0 };
1375         struct tf_dev_info *dev;
1376         struct tf_session *tfs;
1377
1378         /* Retrieve the session information */
1379         rc = tf_session_get_session_internal(tfp, &tfs);
1380         if (rc) {
1381                 TFP_DRV_LOG(ERR,
1382                             "%s: Failed to lookup session, rc:%s\n",
1383                             tf_dir_2_str(dir),
1384                             strerror(-rc));
1385                 return rc;
1386         }
1387
1388         /* Retrieve the device information */
1389         rc = tf_session_get_device(tfs, &dev);
1390         if (rc) {
1391                 TFP_DRV_LOG(ERR,
1392                             "%s: Failed to lookup device, rc:%s\n",
1393                             tf_dir_2_str(dir),
1394                             strerror(-rc));
1395                 return rc;
1396         }
1397
1398         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1399                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1400         flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
1401
1402         req.flags = tfp_cpu_to_le_32(flags);
1403         req.num_entries = tfp_cpu_to_le_32(num_entries);
1404
1405         req.flush_interval = flush_interval;
1406
1407         req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
1408         req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
1409         req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
1410         req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
1411
1412         parms.tf_type = HWRM_TF_EXT_EM_CFG;
1413         parms.req_data = (uint32_t *)&req;
1414         parms.req_size = sizeof(req);
1415         parms.resp_data = (uint32_t *)&resp;
1416         parms.resp_size = sizeof(resp);
1417         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1418
1419         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1420                                  &parms);
1421         return rc;
1422 }
1423
1424 int
1425 tf_msg_ext_em_cfg(struct tf *tfp,
1426                   struct tf_tbl_scope_cb *tbl_scope_cb,
1427                   uint32_t st_buckets,
1428                   uint8_t flush_interval,
1429                   enum tf_dir dir)
1430 {
1431         struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir];
1432         struct hcapi_cfa_em_table *lkup_tbl, *act_tbl;
1433         struct hwrm_tf_ext_em_cfg_input  req = {0};
1434         struct hwrm_tf_ext_em_cfg_output resp = {0};
1435         struct tfp_send_msg_parms parms = { 0 };
1436         uint32_t flags;
1437         struct tf_dev_info *dev;
1438         struct tf_session *tfs;
1439         uint32_t fw_se_id;
1440         int rc;
1441
1442         /* Retrieve the session information */
1443         rc = tf_session_get_session_internal(tfp, &tfs);
1444         if (rc) {
1445                 TFP_DRV_LOG(ERR,
1446                             "%s: Failed to lookup session, rc:%s\n",
1447                             tf_dir_2_str(dir),
1448                             strerror(-rc));
1449                 return rc;
1450         }
1451
1452         /* Retrieve the device information */
1453         rc = tf_session_get_device(tfs, &dev);
1454         if (rc) {
1455                 TFP_DRV_LOG(ERR,
1456                             "%s: Failed to lookup device, rc:%s\n",
1457                             tf_dir_2_str(dir),
1458                             strerror(-rc));
1459                 return rc;
1460         }
1461         fw_se_id = tfs->session_id.internal.fw_session_id;
1462
1463         lkup_tbl = &ctxp->em_tables[TF_EM_LKUP_TABLE];
1464         act_tbl = &ctxp->em_tables[TF_ACTION_TABLE];
1465         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1466                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1467         flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
1468
1469         req.flags = tfp_cpu_to_le_32(flags);
1470         req.num_entries = tfp_cpu_to_le_32(act_tbl->num_entries);
1471         req.lkup_static_buckets = tfp_cpu_to_le_32(st_buckets);
1472         req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1473         req.flush_interval = flush_interval;
1474         req.action_ctx_id = tfp_cpu_to_le_16(act_tbl->ctx_id);
1475         req.action_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id);
1476         req.lkup_ctx_id = tfp_cpu_to_le_16(lkup_tbl->ctx_id);
1477         req.lkup_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id);
1478
1479         req.enables = (HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_CTX_ID |
1480                        HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_TBL_SCOPE |
1481                        HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_CTX_ID |
1482                        HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_TBL_SCOPE |
1483                        HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_STATIC_BUCKETS |
1484                        HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_NUM_ENTRIES);
1485
1486         parms.tf_type = HWRM_TF_EXT_EM_CFG;
1487         parms.req_data = (uint32_t *)&req;
1488         parms.req_size = sizeof(req);
1489         parms.resp_data = (uint32_t *)&resp;
1490         parms.resp_size = sizeof(resp);
1491         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1492
1493         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1494                                  &parms);
1495         return rc;
1496 }
1497
1498 int
1499 tf_msg_em_op(struct tf *tfp,
1500              int dir,
1501              uint16_t op)
1502 {
1503         int rc;
1504         struct hwrm_tf_ext_em_op_input req = {0};
1505         struct hwrm_tf_ext_em_op_output resp = {0};
1506         uint32_t flags;
1507         struct tfp_send_msg_parms parms = { 0 };
1508         struct tf_dev_info *dev;
1509         struct tf_session *tfs;
1510
1511         /* Retrieve the session information */
1512         rc = tf_session_get_session_internal(tfp, &tfs);
1513         if (rc) {
1514                 TFP_DRV_LOG(ERR,
1515                             "%s: Failed to lookup session, rc:%s\n",
1516                             tf_dir_2_str(dir),
1517                             strerror(-rc));
1518                 return rc;
1519         }
1520
1521         /* Retrieve the device information */
1522         rc = tf_session_get_device(tfs, &dev);
1523         if (rc) {
1524                 TFP_DRV_LOG(ERR,
1525                             "%s: Failed to lookup device, rc:%s\n",
1526                             tf_dir_2_str(dir),
1527                             strerror(-rc));
1528                 return rc;
1529         }
1530
1531         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1532                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1533         req.flags = tfp_cpu_to_le_32(flags);
1534         req.op = tfp_cpu_to_le_16(op);
1535
1536         parms.tf_type = HWRM_TF_EXT_EM_OP;
1537         parms.req_data = (uint32_t *)&req;
1538         parms.req_size = sizeof(req);
1539         parms.resp_data = (uint32_t *)&resp;
1540         parms.resp_size = sizeof(resp);
1541         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1542
1543         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1544                                  &parms);
1545         return rc;
1546 }
1547
1548 int
1549 tf_msg_tcam_entry_set(struct tf *tfp,
1550                       struct tf_dev_info *dev,
1551                       struct tf_tcam_set_parms *parms)
1552 {
1553         int rc;
1554         struct tfp_send_msg_parms mparms = { 0 };
1555         struct hwrm_tf_tcam_set_input req = { 0 };
1556         struct hwrm_tf_tcam_set_output resp = { 0 };
1557         struct tf_msg_dma_buf buf = { 0 };
1558         uint8_t *data = NULL;
1559         int data_size = 0;
1560         uint8_t fw_session_id;
1561         struct tf_session *tfs;
1562
1563         /* Retrieve the session information */
1564         rc = tf_session_get_session_internal(tfp, &tfs);
1565         if (rc) {
1566                 TFP_DRV_LOG(ERR,
1567                             "Failed to lookup session, rc:%s\n",
1568                             strerror(-rc));
1569                 return rc;
1570         }
1571
1572         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1573         if (rc) {
1574                 TFP_DRV_LOG(ERR,
1575                             "%s: Unable to lookup FW id, rc:%s\n",
1576                             tf_dir_2_str(parms->dir),
1577                             strerror(-rc));
1578                 return rc;
1579         }
1580
1581         /* Populate the request */
1582         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1583         req.type = parms->hcapi_type;
1584         req.idx = tfp_cpu_to_le_16(parms->idx);
1585         if (parms->dir == TF_DIR_TX)
1586                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
1587
1588         req.key_size = parms->key_size;
1589         req.mask_offset = parms->key_size;
1590         /* Result follows after key and mask, thus multiply by 2 */
1591         req.result_offset = 2 * parms->key_size;
1592         req.result_size = parms->result_size;
1593         data_size = 2 * req.key_size + req.result_size;
1594
1595         if (data_size <= TF_PCI_BUF_SIZE_MAX) {
1596                 /* use pci buffer */
1597                 data = &req.dev_data[0];
1598         } else {
1599                 /* use dma buffer */
1600                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
1601                 rc = tf_msg_alloc_dma_buf(&buf, data_size);
1602                 if (rc)
1603                         goto cleanup;
1604                 data = buf.va_addr;
1605                 tfp_memcpy(&req.dev_data[0],
1606                            &buf.pa_addr,
1607                            sizeof(buf.pa_addr));
1608         }
1609
1610         tfp_memcpy(&data[0], parms->key, parms->key_size);
1611         tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
1612         tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
1613
1614         mparms.tf_type = HWRM_TF_TCAM_SET;
1615         mparms.req_data = (uint32_t *)&req;
1616         mparms.req_size = sizeof(req);
1617         mparms.resp_data = (uint32_t *)&resp;
1618         mparms.resp_size = sizeof(resp);
1619         mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1620
1621         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1622                                  &mparms);
1623
1624 cleanup:
1625         tf_msg_free_dma_buf(&buf);
1626
1627         return rc;
1628 }
1629
1630 int
1631 tf_msg_tcam_entry_get(struct tf *tfp,
1632                       struct tf_dev_info *dev,
1633                       struct tf_tcam_get_parms *parms)
1634 {
1635         int rc;
1636         struct tfp_send_msg_parms mparms = { 0 };
1637         struct hwrm_tf_tcam_get_input req = { 0 };
1638         struct hwrm_tf_tcam_get_output resp = { 0 };
1639         uint8_t fw_session_id;
1640         struct tf_session *tfs;
1641
1642         /* Retrieve the session information */
1643         rc = tf_session_get_session_internal(tfp, &tfs);
1644         if (rc) {
1645                 TFP_DRV_LOG(ERR,
1646                             "Failed to lookup session, rc:%s\n",
1647                             strerror(-rc));
1648                 return rc;
1649         }
1650
1651         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1652         if (rc) {
1653                 TFP_DRV_LOG(ERR,
1654                             "%s: Unable to lookup FW id, rc:%s\n",
1655                             tf_dir_2_str(parms->dir),
1656                             strerror(-rc));
1657                 return rc;
1658         }
1659
1660         /* Populate the request */
1661         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1662         req.type = parms->hcapi_type;
1663         req.idx = tfp_cpu_to_le_16(parms->idx);
1664         if (parms->dir == TF_DIR_TX)
1665                 req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX;
1666
1667         mparms.tf_type = HWRM_TF_TCAM_GET;
1668         mparms.req_data = (uint32_t *)&req;
1669         mparms.req_size = sizeof(req);
1670         mparms.resp_data = (uint32_t *)&resp;
1671         mparms.resp_size = sizeof(resp);
1672         mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1673
1674         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1675                                  &mparms);
1676
1677         if (rc != 0)
1678                 return rc;
1679
1680         if (parms->key_size < resp.key_size ||
1681             parms->result_size < resp.result_size) {
1682                 rc = -EINVAL;
1683                 TFP_DRV_LOG(ERR,
1684                             "%s: Key buffer(%d) is smaller than the key(%d), rc:%s\n",
1685                             tf_dir_2_str(parms->dir),
1686                             parms->key_size,
1687                             resp.key_size,
1688                             strerror(-rc));
1689                 return rc;
1690         }
1691         parms->key_size = resp.key_size;
1692         parms->result_size = resp.result_size;
1693         tfp_memcpy(parms->key, resp.dev_data, resp.key_size);
1694         tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size);
1695         tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size);
1696
1697         return 0;
1698 }
1699
1700 int
1701 tf_msg_tcam_entry_free(struct tf *tfp,
1702                        struct tf_dev_info *dev,
1703                        struct tf_tcam_free_parms *in_parms)
1704 {
1705         int rc;
1706         struct hwrm_tf_tcam_free_input req =  { 0 };
1707         struct hwrm_tf_tcam_free_output resp = { 0 };
1708         struct tfp_send_msg_parms parms = { 0 };
1709         uint8_t fw_session_id;
1710         struct tf_session *tfs;
1711
1712         /* Retrieve the session information */
1713         rc = tf_session_get_session_internal(tfp, &tfs);
1714         if (rc) {
1715                 TFP_DRV_LOG(ERR,
1716                             "Failed to lookup session, rc:%s\n",
1717                             strerror(-rc));
1718                 return rc;
1719         }
1720
1721         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1722         if (rc) {
1723                 TFP_DRV_LOG(ERR,
1724                             "%s: Unable to lookup FW id, rc:%s\n",
1725                             tf_dir_2_str(in_parms->dir),
1726                             strerror(-rc));
1727                 return rc;
1728         }
1729
1730         /* Populate the request */
1731         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1732         req.type = in_parms->hcapi_type;
1733         req.count = 1;
1734         req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
1735         if (in_parms->dir == TF_DIR_TX)
1736                 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
1737
1738         parms.tf_type = HWRM_TF_TCAM_FREE;
1739         parms.req_data = (uint32_t *)&req;
1740         parms.req_size = sizeof(req);
1741         parms.resp_data = (uint32_t *)&resp;
1742         parms.resp_size = sizeof(resp);
1743         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1744
1745         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1746                                  &parms);
1747         return rc;
1748 }
1749
1750 int
1751 tf_msg_set_tbl_entry(struct tf *tfp,
1752                      enum tf_dir dir,
1753                      uint16_t hcapi_type,
1754                      uint16_t size,
1755                      uint8_t *data,
1756                      uint32_t index)
1757 {
1758         int rc;
1759         struct hwrm_tf_tbl_type_set_input req = { 0 };
1760         struct hwrm_tf_tbl_type_set_output resp = { 0 };
1761         struct tfp_send_msg_parms parms = { 0 };
1762         uint8_t fw_session_id;
1763         struct tf_dev_info *dev;
1764         struct tf_session *tfs;
1765
1766         RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_tbl_type_set_input) !=
1767                          TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET);
1768
1769         /* Retrieve the session information */
1770         rc = tf_session_get_session_internal(tfp, &tfs);
1771         if (rc) {
1772                 TFP_DRV_LOG(ERR,
1773                             "%s: Failed to lookup session, rc:%s\n",
1774                             tf_dir_2_str(dir),
1775                             strerror(-rc));
1776                 return rc;
1777         }
1778
1779         /* Retrieve the device information */
1780         rc = tf_session_get_device(tfs, &dev);
1781         if (rc) {
1782                 TFP_DRV_LOG(ERR,
1783                             "%s: Failed to lookup device, rc:%s\n",
1784                             tf_dir_2_str(dir),
1785                             strerror(-rc));
1786                 return rc;
1787         }
1788
1789         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1790         if (rc) {
1791                 TFP_DRV_LOG(ERR,
1792                             "%s: Unable to lookup FW id, rc:%s\n",
1793                             tf_dir_2_str(dir),
1794                             strerror(-rc));
1795                 return rc;
1796         }
1797
1798         /* Populate the request */
1799         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1800         req.flags = tfp_cpu_to_le_16(dir);
1801         req.type = tfp_cpu_to_le_32(hcapi_type);
1802         req.size = tfp_cpu_to_le_16(size);
1803         req.index = tfp_cpu_to_le_32(index);
1804
1805         /* Check for data size conformity */
1806         if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
1807                 rc = -EINVAL;
1808                 TFP_DRV_LOG(ERR,
1809                             "%s: Invalid parameters for msg type, rc:%s\n",
1810                             tf_dir_2_str(dir),
1811                             strerror(-rc));
1812                 return rc;
1813         }
1814
1815         tfp_memcpy(&req.data,
1816                    data,
1817                    size);
1818
1819         parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1820         parms.req_data = (uint32_t *)&req;
1821         parms.req_size = sizeof(req);
1822         parms.resp_data = (uint32_t *)&resp;
1823         parms.resp_size = sizeof(resp);
1824         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1825
1826         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1827                                  &parms);
1828         if (rc)
1829                 return rc;
1830
1831         return 0;
1832 }
1833
1834 int
1835 tf_msg_get_tbl_entry(struct tf *tfp,
1836                      enum tf_dir dir,
1837                      uint16_t hcapi_type,
1838                      uint16_t size,
1839                      uint8_t *data,
1840                      uint32_t index)
1841 {
1842         int rc;
1843         struct hwrm_tf_tbl_type_get_input req = { 0 };
1844         struct hwrm_tf_tbl_type_get_output resp = { 0 };
1845         struct tfp_send_msg_parms parms = { 0 };
1846         uint8_t fw_session_id;
1847         struct tf_dev_info *dev;
1848         struct tf_session *tfs;
1849
1850         /* Retrieve the session information */
1851         rc = tf_session_get_session_internal(tfp, &tfs);
1852         if (rc) {
1853                 TFP_DRV_LOG(ERR,
1854                             "%s: Failed to lookup session, rc:%s\n",
1855                             tf_dir_2_str(dir),
1856                             strerror(-rc));
1857                 return rc;
1858         }
1859
1860         /* Retrieve the device information */
1861         rc = tf_session_get_device(tfs, &dev);
1862         if (rc) {
1863                 TFP_DRV_LOG(ERR,
1864                             "%s: Failed to lookup device, rc:%s\n",
1865                             tf_dir_2_str(dir),
1866                             strerror(-rc));
1867                 return rc;
1868         }
1869
1870         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1871         if (rc) {
1872                 TFP_DRV_LOG(ERR,
1873                             "%s: Unable to lookup FW id, rc:%s\n",
1874                             tf_dir_2_str(dir),
1875                             strerror(-rc));
1876                 return rc;
1877         }
1878
1879         /* Populate the request */
1880         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1881         req.flags = tfp_cpu_to_le_16(dir);
1882         req.type = tfp_cpu_to_le_32(hcapi_type);
1883         req.index = tfp_cpu_to_le_32(index);
1884
1885         parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1886         parms.req_data = (uint32_t *)&req;
1887         parms.req_size = sizeof(req);
1888         parms.resp_data = (uint32_t *)&resp;
1889         parms.resp_size = sizeof(resp);
1890         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1891
1892         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1893                                  &parms);
1894         if (rc)
1895                 return rc;
1896
1897         /*
1898          * The response will be 64 bytes long, the response size will
1899          * be in words (16). All we can test for is that the response
1900          * size is < to the requested size.
1901          */
1902         if ((tfp_le_to_cpu_32(resp.size) * 4) < size)
1903                 return -EINVAL;
1904
1905         /*
1906          * Copy the requested number of bytes
1907          */
1908         tfp_memcpy(data,
1909                    &resp.data,
1910                    size);
1911
1912         return 0;
1913 }
1914
1915 /* HWRM Tunneled messages */
1916
1917 int
1918 tf_msg_get_global_cfg(struct tf *tfp,
1919                       struct tf_global_cfg_parms *params)
1920 {
1921         int rc = 0;
1922         struct tfp_send_msg_parms parms = { 0 };
1923         struct hwrm_tf_global_cfg_get_input req = { 0 };
1924         struct hwrm_tf_global_cfg_get_output resp = { 0 };
1925         uint32_t flags = 0;
1926         uint8_t fw_session_id;
1927         uint16_t resp_size = 0;
1928         struct tf_dev_info *dev;
1929         struct tf_session *tfs;
1930
1931         /* Retrieve the session information */
1932         rc = tf_session_get_session_internal(tfp, &tfs);
1933         if (rc) {
1934                 TFP_DRV_LOG(ERR,
1935                             "%s: Failed to lookup session, rc:%s\n",
1936                             tf_dir_2_str(params->dir),
1937                             strerror(-rc));
1938                 return rc;
1939         }
1940
1941         /* Retrieve the device information */
1942         rc = tf_session_get_device(tfs, &dev);
1943         if (rc) {
1944                 TFP_DRV_LOG(ERR,
1945                             "%s: Failed to lookup device, rc:%s\n",
1946                             tf_dir_2_str(params->dir),
1947                             strerror(-rc));
1948                 return rc;
1949         }
1950
1951         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1952         if (rc) {
1953                 TFP_DRV_LOG(ERR,
1954                             "%s: Unable to lookup FW id, rc:%s\n",
1955                             tf_dir_2_str(params->dir),
1956                             strerror(-rc));
1957                 return rc;
1958         }
1959
1960         flags = (params->dir == TF_DIR_TX ?
1961                  HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1962                  HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1963
1964         /* Populate the request */
1965         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1966         req.flags = tfp_cpu_to_le_32(flags);
1967         req.type = tfp_cpu_to_le_32(params->type);
1968         req.offset = tfp_cpu_to_le_32(params->offset);
1969         req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1970
1971         parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1972         parms.req_data = (uint32_t *)&req;
1973         parms.req_size = sizeof(req);
1974         parms.resp_data = (uint32_t *)&resp;
1975         parms.resp_size = sizeof(resp);
1976         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1977
1978         rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1979         if (rc != 0)
1980                 return rc;
1981
1982         /* Verify that we got enough buffer to return the requested data */
1983         resp_size = tfp_le_to_cpu_16(resp.size);
1984         if (resp_size < params->config_sz_in_bytes)
1985                 return -EINVAL;
1986
1987         if (params->config)
1988                 tfp_memcpy(params->config,
1989                            resp.data,
1990                            resp_size);
1991         else
1992                 return -EFAULT;
1993
1994         return 0;
1995 }
1996
1997 int
1998 tf_msg_set_global_cfg(struct tf *tfp,
1999                       struct tf_global_cfg_parms *params)
2000 {
2001         int rc = 0;
2002         struct tfp_send_msg_parms parms = { 0 };
2003         struct hwrm_tf_global_cfg_set_input req = { 0 };
2004         struct hwrm_tf_global_cfg_set_output resp = { 0 };
2005         uint32_t flags = 0;
2006         uint8_t fw_session_id;
2007         struct tf_dev_info *dev;
2008         struct tf_session *tfs;
2009
2010         /* Retrieve the session information */
2011         rc = tf_session_get_session_internal(tfp, &tfs);
2012         if (rc) {
2013                 TFP_DRV_LOG(ERR,
2014                             "%s: Failed to lookup session, rc:%s\n",
2015                             tf_dir_2_str(params->dir),
2016                             strerror(-rc));
2017                 return rc;
2018         }
2019
2020         /* Retrieve the device information */
2021         rc = tf_session_get_device(tfs, &dev);
2022         if (rc) {
2023                 TFP_DRV_LOG(ERR,
2024                             "%s: Failed to lookup device, rc:%s\n",
2025                             tf_dir_2_str(params->dir),
2026                             strerror(-rc));
2027                 return rc;
2028         }
2029
2030         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2031         if (rc) {
2032                 TFP_DRV_LOG(ERR,
2033                             "%s: Unable to lookup FW id, rc:%s\n",
2034                             tf_dir_2_str(params->dir),
2035                             strerror(-rc));
2036                 return rc;
2037         }
2038
2039         flags = (params->dir == TF_DIR_TX ?
2040                  HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
2041                  HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
2042
2043         /* Populate the request */
2044         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2045         req.flags = tfp_cpu_to_le_32(flags);
2046         req.type = tfp_cpu_to_le_32(params->type);
2047         req.offset = tfp_cpu_to_le_32(params->offset);
2048
2049         /* Check for data size conformity */
2050         if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
2051                 rc = -EINVAL;
2052                 TFP_DRV_LOG(ERR,
2053                             "%s: Invalid parameters for msg type, rc:%s\n",
2054                             tf_dir_2_str(params->dir),
2055                             strerror(-rc));
2056                 return rc;
2057         }
2058
2059         tfp_memcpy(req.data, params->config,
2060                    params->config_sz_in_bytes);
2061
2062         /* Only set mask if pointer is provided
2063          */
2064         if (params->config_mask) {
2065                 tfp_memcpy(req.mask,
2066                            params->config_mask,
2067                            params->config_sz_in_bytes);
2068         }
2069
2070         req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
2071
2072         parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
2073         parms.req_data = (uint32_t *)&req;
2074         parms.req_size = sizeof(req);
2075         parms.resp_data = (uint32_t *)&resp;
2076         parms.resp_size = sizeof(resp);
2077         parms.mailbox = dev->ops->tf_dev_get_mailbox();
2078
2079         rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2080
2081         if (rc != 0)
2082                 return rc;
2083
2084         return 0;
2085 }
2086
2087 int
2088 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
2089                           enum tf_dir dir,
2090                           uint16_t hcapi_type,
2091                           uint32_t starting_idx,
2092                           uint16_t num_entries,
2093                           uint16_t entry_sz_in_bytes,
2094                           uint64_t physical_mem_addr)
2095 {
2096         int rc;
2097         struct tfp_send_msg_parms parms = { 0 };
2098         struct hwrm_tf_tbl_type_bulk_get_input req = { 0 };
2099         struct hwrm_tf_tbl_type_bulk_get_output resp = { 0 };
2100         int data_size = 0;
2101         uint8_t fw_session_id;
2102         struct tf_dev_info *dev;
2103         struct tf_session *tfs;
2104
2105         /* Retrieve the session information */
2106         rc = tf_session_get_session(tfp, &tfs);
2107         if (rc) {
2108                 TFP_DRV_LOG(ERR,
2109                             "%s: Failed to lookup session, rc:%s\n",
2110                             tf_dir_2_str(dir),
2111                             strerror(-rc));
2112                 return rc;
2113         }
2114
2115         /* Retrieve the device information */
2116         rc = tf_session_get_device(tfs, &dev);
2117         if (rc) {
2118                 TFP_DRV_LOG(ERR,
2119                             "%s: Failed to lookup device, rc:%s\n",
2120                             tf_dir_2_str(dir),
2121                             strerror(-rc));
2122                 return rc;
2123         }
2124
2125         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2126         if (rc) {
2127                 TFP_DRV_LOG(ERR,
2128                             "%s: Unable to lookup FW id, rc:%s\n",
2129                             tf_dir_2_str(dir),
2130                             strerror(-rc));
2131                 return rc;
2132         }
2133
2134         /* Populate the request */
2135         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2136         req.flags = tfp_cpu_to_le_16(dir);
2137         req.type = tfp_cpu_to_le_32(hcapi_type);
2138         req.start_index = tfp_cpu_to_le_32(starting_idx);
2139         req.num_entries = tfp_cpu_to_le_32(num_entries);
2140
2141         data_size = num_entries * entry_sz_in_bytes;
2142
2143         req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
2144
2145         parms.tf_type = HWRM_TF_TBL_TYPE_BULK_GET;
2146         parms.req_data = (uint32_t *)&req;
2147         parms.req_size = sizeof(req);
2148         parms.resp_data = (uint32_t *)&resp;
2149         parms.resp_size = sizeof(resp);
2150         parms.mailbox = dev->ops->tf_dev_get_mailbox();
2151
2152         rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
2153                                  &parms);
2154         if (rc)
2155                 return rc;
2156
2157         /* Verify that we got enough buffer to return the requested data */
2158         if (tfp_le_to_cpu_32(resp.size) != data_size)
2159                 return -EINVAL;
2160
2161         return 0;
2162 }
2163
2164 int
2165 tf_msg_get_if_tbl_entry(struct tf *tfp,
2166                         struct tf_if_tbl_get_parms *params)
2167 {
2168         int rc = 0;
2169         struct tfp_send_msg_parms parms = { 0 };
2170         struct hwrm_tf_if_tbl_get_input req = { 0 };
2171         struct hwrm_tf_if_tbl_get_output resp = { 0 };
2172         uint32_t flags = 0;
2173         struct tf_dev_info *dev;
2174         struct tf_session *tfs;
2175
2176         /* Retrieve the session information */
2177         rc = tf_session_get_session(tfp, &tfs);
2178         if (rc) {
2179                 TFP_DRV_LOG(ERR,
2180                             "%s: Failed to lookup session, rc:%s\n",
2181                             tf_dir_2_str(params->dir),
2182                             strerror(-rc));
2183                 return rc;
2184         }
2185
2186         /* Retrieve the device information */
2187         rc = tf_session_get_device(tfs, &dev);
2188         if (rc) {
2189                 TFP_DRV_LOG(ERR,
2190                             "%s: Failed to lookup device, rc:%s\n",
2191                             tf_dir_2_str(params->dir),
2192                             strerror(-rc));
2193                 return rc;
2194         }
2195
2196         flags = (params->dir == TF_DIR_TX ?
2197                 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
2198                 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
2199
2200         /* Populate the request */
2201         req.fw_session_id =
2202                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
2203         req.flags = flags;
2204         req.type = params->hcapi_type;
2205         req.index = tfp_cpu_to_le_16(params->idx);
2206         req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
2207
2208         parms.tf_type = HWRM_TF_IF_TBL_GET;
2209         parms.req_data = (uint32_t *)&req;
2210         parms.req_size = sizeof(req);
2211         parms.resp_data = (uint32_t *)&resp;
2212         parms.resp_size = sizeof(resp);
2213         parms.mailbox = dev->ops->tf_dev_get_mailbox();
2214
2215         rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2216
2217         if (rc != 0)
2218                 return rc;
2219
2220         tfp_memcpy(params->data, resp.data, req.size);
2221
2222         return 0;
2223 }
2224
2225 int
2226 tf_msg_set_if_tbl_entry(struct tf *tfp,
2227                         struct tf_if_tbl_set_parms *params)
2228 {
2229         int rc = 0;
2230         struct tfp_send_msg_parms parms = { 0 };
2231         struct hwrm_tf_if_tbl_set_input req = { 0 };
2232         struct hwrm_tf_if_tbl_get_output resp = { 0 };
2233         uint32_t flags = 0;
2234         struct tf_dev_info *dev;
2235         struct tf_session *tfs;
2236
2237         /* Retrieve the session information */
2238         rc = tf_session_get_session(tfp, &tfs);
2239         if (rc) {
2240                 TFP_DRV_LOG(ERR,
2241                             "%s: Failed to lookup session, rc:%s\n",
2242                             tf_dir_2_str(params->dir),
2243                             strerror(-rc));
2244                 return rc;
2245         }
2246
2247         /* Retrieve the device information */
2248         rc = tf_session_get_device(tfs, &dev);
2249         if (rc)
2250                 return rc;
2251
2252         flags = (params->dir == TF_DIR_TX ?
2253                 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
2254                 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
2255
2256         /* Populate the request */
2257         req.fw_session_id =
2258                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
2259         req.flags = flags;
2260         req.type = params->hcapi_type;
2261         req.index = tfp_cpu_to_le_32(params->idx);
2262         req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
2263         tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
2264
2265         parms.tf_type = HWRM_TF_IF_TBL_SET;
2266         parms.req_data = (uint32_t *)&req;
2267         parms.req_size = sizeof(req);
2268         parms.resp_data = (uint32_t *)&resp;
2269         parms.resp_size = sizeof(resp);
2270         parms.mailbox = dev->ops->tf_dev_get_mailbox();
2271
2272         rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2273
2274         if (rc != 0)
2275                 return rc;
2276
2277         return 0;
2278 }