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