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