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