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