1007211363919e578fb6b2df9a96eba9e4ca120a
[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
419         for (i = 0; i < size; i++) {
420                 query[i].type = tfp_le_to_cpu_32(data[i].type);
421                 query[i].min = tfp_le_to_cpu_16(data[i].min);
422                 query[i].max = tfp_le_to_cpu_16(data[i].max);
423         }
424
425         *resv_strategy = resp.flags &
426               HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
427
428 cleanup:
429         tf_msg_free_dma_buf(&qcaps_buf);
430
431         return rc;
432 }
433
434 int
435 tf_msg_session_resc_alloc(struct tf *tfp,
436                           struct tf_dev_info *dev,
437                           enum tf_dir dir,
438                           uint16_t size,
439                           struct tf_rm_resc_req_entry *request,
440                           struct tf_rm_resc_entry *resv)
441 {
442         int rc;
443         int i;
444         struct tfp_send_msg_parms parms = { 0 };
445         struct hwrm_tf_session_resc_alloc_input req = { 0 };
446         struct hwrm_tf_session_resc_alloc_output resp = { 0 };
447         uint8_t fw_session_id;
448         struct tf_msg_dma_buf req_buf = { 0 };
449         struct tf_msg_dma_buf resv_buf = { 0 };
450         struct tf_rm_resc_req_entry *req_data;
451         struct tf_rm_resc_entry *resv_data;
452         int dma_size;
453
454         TF_CHECK_PARMS3(tfp, request, resv);
455
456         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
457         if (rc) {
458                 TFP_DRV_LOG(ERR,
459                             "%s: Unable to lookup FW id, rc:%s\n",
460                             tf_dir_2_str(dir),
461                             strerror(-rc));
462                 return rc;
463         }
464
465         /* Prepare DMA buffers */
466         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
467         rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
468         if (rc)
469                 return rc;
470
471         dma_size = size * sizeof(struct tf_rm_resc_entry);
472         rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
473         if (rc) {
474                 tf_msg_free_dma_buf(&req_buf);
475                 return rc;
476         }
477
478         /* Populate the request */
479         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
480         req.flags = tfp_cpu_to_le_16(dir);
481         req.req_size = size;
482
483         req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
484         for (i = 0; i < size; i++) {
485                 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
486                 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
487                 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
488         }
489
490         req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
491         req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
492
493         parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
494         parms.req_data = (uint32_t *)&req;
495         parms.req_size = sizeof(req);
496         parms.resp_data = (uint32_t *)&resp;
497         parms.resp_size = sizeof(resp);
498         parms.mailbox = dev->ops->tf_dev_get_mailbox();
499
500         rc = tfp_send_msg_direct(tfp, &parms);
501         if (rc)
502                 goto cleanup;
503
504         /* Process the response
505          * Should always get expected number of entries
506          */
507         if (tfp_le_to_cpu_32(resp.size) != size) {
508                 TFP_DRV_LOG(ERR,
509                             "%s: Alloc message size error, rc:%s\n",
510                             tf_dir_2_str(dir),
511                             strerror(EINVAL));
512                 rc = -EINVAL;
513                 goto cleanup;
514         }
515
516         /* Post process the response */
517         resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
518         for (i = 0; i < size; i++) {
519                 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
520                 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
521                 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
522         }
523
524 cleanup:
525         tf_msg_free_dma_buf(&req_buf);
526         tf_msg_free_dma_buf(&resv_buf);
527
528         return rc;
529 }
530
531 int
532 tf_msg_session_resc_flush(struct tf *tfp,
533                           enum tf_dir dir,
534                           uint16_t size,
535                           struct tf_rm_resc_entry *resv)
536 {
537         int rc;
538         int i;
539         struct tfp_send_msg_parms parms = { 0 };
540         struct hwrm_tf_session_resc_flush_input req = { 0 };
541         struct hwrm_tf_session_resc_flush_output resp = { 0 };
542         uint8_t fw_session_id;
543         struct tf_msg_dma_buf resv_buf = { 0 };
544         struct tf_rm_resc_entry *resv_data;
545         int dma_size;
546         struct tf_dev_info *dev;
547         struct tf_session *tfs;
548
549         TF_CHECK_PARMS2(tfp, resv);
550
551         /* Retrieve the session information */
552         rc = tf_session_get_session_internal(tfp, &tfs);
553         if (rc) {
554                 TFP_DRV_LOG(ERR,
555                             "%s: Failed to lookup session, rc:%s\n",
556                             tf_dir_2_str(dir),
557                             strerror(-rc));
558                 return rc;
559         }
560
561         /* Retrieve the device information */
562         rc = tf_session_get_device(tfs, &dev);
563         if (rc) {
564                 TFP_DRV_LOG(ERR,
565                             "%s: Failed to lookup device, rc:%s\n",
566                             tf_dir_2_str(dir),
567                             strerror(-rc));
568                 return rc;
569         }
570
571         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
572         if (rc) {
573                 TFP_DRV_LOG(ERR,
574                             "%s: Unable to lookup FW id, rc:%s\n",
575                             tf_dir_2_str(dir),
576                             strerror(-rc));
577                 return rc;
578         }
579
580         /* Prepare DMA buffers */
581         dma_size = size * sizeof(struct tf_rm_resc_entry);
582         rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
583         if (rc)
584                 return rc;
585
586         /* Populate the request */
587         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
588         req.flags = tfp_cpu_to_le_16(dir);
589         req.flush_size = size;
590
591         resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
592         for (i = 0; i < size; i++) {
593                 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
594                 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
595                 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
596         }
597
598         req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
599
600         parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
601         parms.req_data = (uint32_t *)&req;
602         parms.req_size = sizeof(req);
603         parms.resp_data = (uint32_t *)&resp;
604         parms.resp_size = sizeof(resp);
605         parms.mailbox = dev->ops->tf_dev_get_mailbox();
606
607         rc = tfp_send_msg_direct(tfp, &parms);
608
609         tf_msg_free_dma_buf(&resv_buf);
610
611         return rc;
612 }
613
614 int
615 tf_msg_insert_em_internal_entry(struct tf *tfp,
616                                 struct tf_insert_em_entry_parms *em_parms,
617                                 uint16_t *rptr_index,
618                                 uint8_t *rptr_entry,
619                                 uint8_t *num_of_entries)
620 {
621         int rc;
622         struct tfp_send_msg_parms parms = { 0 };
623         struct hwrm_tf_em_insert_input req = { 0 };
624         struct hwrm_tf_em_insert_output resp = { 0 };
625         struct tf_em_64b_entry *em_result =
626                 (struct tf_em_64b_entry *)em_parms->em_record;
627         uint16_t flags;
628         uint8_t fw_session_id;
629         uint8_t msg_key_size;
630         struct tf_dev_info *dev;
631         struct tf_session *tfs;
632
633         /* Retrieve the session information */
634         rc = tf_session_get_session_internal(tfp, &tfs);
635         if (rc) {
636                 TFP_DRV_LOG(ERR,
637                             "%s: Failed to lookup session, rc:%s\n",
638                             tf_dir_2_str(em_parms->dir),
639                             strerror(-rc));
640                 return rc;
641         }
642
643         /* Retrieve the device information */
644         rc = tf_session_get_device(tfs, &dev);
645         if (rc) {
646                 TFP_DRV_LOG(ERR,
647                             "%s: Failed to lookup device, rc:%s\n",
648                             tf_dir_2_str(em_parms->dir),
649                             strerror(-rc));
650                 return rc;
651         }
652
653         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
654         if (rc) {
655                 TFP_DRV_LOG(ERR,
656                             "%s: Unable to lookup FW id, rc:%s\n",
657                             tf_dir_2_str(em_parms->dir),
658                             strerror(-rc));
659                 return rc;
660         }
661
662         /* Populate the request */
663         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
664
665         /* Check for key size conformity */
666         msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
667         if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
668                 rc = -EINVAL;
669                 TFP_DRV_LOG(ERR,
670                             "%s: Invalid parameters for msg type, rc:%s\n",
671                             tf_dir_2_str(em_parms->dir),
672                             strerror(-rc));
673                 return rc;
674         }
675
676         tfp_memcpy(req.em_key,
677                    em_parms->key,
678                    msg_key_size);
679
680         flags = (em_parms->dir == TF_DIR_TX ?
681                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
682                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
683         req.flags = tfp_cpu_to_le_16(flags);
684         req.strength = (em_result->hdr.word1 &
685                         CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
686                         CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
687         req.em_key_bitlen = em_parms->key_sz_in_bits;
688         req.action_ptr = em_result->hdr.pointer;
689         req.em_record_idx = *rptr_index;
690
691         parms.tf_type = HWRM_TF_EM_INSERT;
692         parms.req_data = (uint32_t *)&req;
693         parms.req_size = sizeof(req);
694         parms.resp_data = (uint32_t *)&resp;
695         parms.resp_size = sizeof(resp);
696         parms.mailbox = dev->ops->tf_dev_get_mailbox();
697
698         rc = tfp_send_msg_direct(tfp,
699                                  &parms);
700         if (rc)
701                 return rc;
702
703         *rptr_entry = resp.rptr_entry;
704         *rptr_index = resp.rptr_index;
705         *num_of_entries = resp.num_of_entries;
706
707         return 0;
708 }
709
710 int
711 tf_msg_delete_em_entry(struct tf *tfp,
712                        struct tf_delete_em_entry_parms *em_parms)
713 {
714         int rc;
715         struct tfp_send_msg_parms parms = { 0 };
716         struct hwrm_tf_em_delete_input req = { 0 };
717         struct hwrm_tf_em_delete_output resp = { 0 };
718         uint16_t flags;
719         uint8_t fw_session_id;
720         struct tf_dev_info *dev;
721         struct tf_session *tfs;
722
723         /* Retrieve the session information */
724         rc = tf_session_get_session_internal(tfp, &tfs);
725         if (rc) {
726                 TFP_DRV_LOG(ERR,
727                             "%s: Failed to lookup session, rc:%s\n",
728                             tf_dir_2_str(em_parms->dir),
729                             strerror(-rc));
730                 return rc;
731         }
732
733         /* Retrieve the device information */
734         rc = tf_session_get_device(tfs, &dev);
735         if (rc) {
736                 TFP_DRV_LOG(ERR,
737                             "%s: Failed to lookup device, rc:%s\n",
738                             tf_dir_2_str(em_parms->dir),
739                             strerror(-rc));
740                 return rc;
741         }
742
743         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
744         if (rc) {
745                 TFP_DRV_LOG(ERR,
746                             "%s: Unable to lookup FW id, rc:%s\n",
747                             tf_dir_2_str(em_parms->dir),
748                             strerror(-rc));
749                 return rc;
750         }
751
752         /* Populate the request */
753         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
754
755         flags = (em_parms->dir == TF_DIR_TX ?
756                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
757                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
758         req.flags = tfp_cpu_to_le_16(flags);
759         req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
760
761         parms.tf_type = HWRM_TF_EM_DELETE;
762         parms.req_data = (uint32_t *)&req;
763         parms.req_size = sizeof(req);
764         parms.resp_data = (uint32_t *)&resp;
765         parms.resp_size = sizeof(resp);
766         parms.mailbox = dev->ops->tf_dev_get_mailbox();
767
768         rc = tfp_send_msg_direct(tfp,
769                                  &parms);
770         if (rc)
771                 return rc;
772
773         em_parms->index = tfp_le_to_cpu_16(resp.em_index);
774
775         return 0;
776 }
777
778 int
779 tf_msg_em_mem_rgtr(struct tf *tfp,
780                    int page_lvl,
781                    int page_size,
782                    uint64_t dma_addr,
783                    uint16_t *ctx_id)
784 {
785         int rc;
786         struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
787         struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
788         struct tfp_send_msg_parms parms = { 0 };
789         struct tf_dev_info *dev;
790         struct tf_session *tfs;
791
792         /* Retrieve the session information */
793         rc = tf_session_get_session_internal(tfp, &tfs);
794         if (rc) {
795                 TFP_DRV_LOG(ERR,
796                             "Failed to lookup session, rc:%s\n",
797                             strerror(-rc));
798                 return rc;
799         }
800
801         /* Retrieve the device information */
802         rc = tf_session_get_device(tfs, &dev);
803         if (rc) {
804                 TFP_DRV_LOG(ERR,
805                             "Failed to lookup device, rc:%s\n",
806                             strerror(-rc));
807                 return rc;
808         }
809
810         req.page_level = page_lvl;
811         req.page_size = page_size;
812         req.page_dir = tfp_cpu_to_le_64(dma_addr);
813
814         parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
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(tfp,
822                                  &parms);
823         if (rc)
824                 return rc;
825
826         *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
827
828         return rc;
829 }
830
831 int
832 tf_msg_em_mem_unrgtr(struct tf *tfp,
833                      uint16_t *ctx_id)
834 {
835         int rc;
836         struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
837         struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
838         struct tfp_send_msg_parms parms = { 0 };
839         struct tf_dev_info *dev;
840         struct tf_session *tfs;
841
842         /* Retrieve the session information */
843         rc = tf_session_get_session_internal(tfp, &tfs);
844         if (rc) {
845                 TFP_DRV_LOG(ERR,
846                             "Failed to lookup session, rc:%s\n",
847                             strerror(-rc));
848                 return rc;
849         }
850
851         /* Retrieve the device information */
852         rc = tf_session_get_device(tfs, &dev);
853         if (rc) {
854                 TFP_DRV_LOG(ERR,
855                             "Failed to lookup device, rc:%s\n",
856                             strerror(-rc));
857                 return rc;
858         }
859
860         req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
861
862         parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
863         parms.req_data = (uint32_t *)&req;
864         parms.req_size = sizeof(req);
865         parms.resp_data = (uint32_t *)&resp;
866         parms.resp_size = sizeof(resp);
867         parms.mailbox = dev->ops->tf_dev_get_mailbox();
868
869         rc = tfp_send_msg_direct(tfp,
870                                  &parms);
871         return rc;
872 }
873
874 int
875 tf_msg_em_qcaps(struct tf *tfp,
876                 int dir,
877                 struct tf_em_caps *em_caps)
878 {
879         int rc;
880         struct hwrm_tf_ext_em_qcaps_input  req = {0};
881         struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
882         uint32_t             flags;
883         struct tfp_send_msg_parms parms = { 0 };
884         struct tf_dev_info *dev;
885         struct tf_session *tfs;
886
887         /* Retrieve the session information */
888         rc = tf_session_get_session_internal(tfp, &tfs);
889         if (rc) {
890                 TFP_DRV_LOG(ERR,
891                             "%s: Failed to lookup session, rc:%s\n",
892                             tf_dir_2_str(dir),
893                             strerror(-rc));
894                 return rc;
895         }
896
897         /* Retrieve the device information */
898         rc = tf_session_get_device(tfs, &dev);
899         if (rc) {
900                 TFP_DRV_LOG(ERR,
901                             "%s: Failed to lookup device, rc:%s\n",
902                             tf_dir_2_str(dir),
903                             strerror(-rc));
904                 return rc;
905         }
906
907         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
908                  HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
909         req.flags = tfp_cpu_to_le_32(flags);
910
911         parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
912         parms.req_data = (uint32_t *)&req;
913         parms.req_size = sizeof(req);
914         parms.resp_data = (uint32_t *)&resp;
915         parms.resp_size = sizeof(resp);
916         parms.mailbox = dev->ops->tf_dev_get_mailbox();
917
918         rc = tfp_send_msg_direct(tfp,
919                                  &parms);
920         if (rc)
921                 return rc;
922
923         em_caps->supported = tfp_le_to_cpu_32(resp.supported);
924         em_caps->max_entries_supported =
925                 tfp_le_to_cpu_32(resp.max_entries_supported);
926         em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
927         em_caps->record_entry_size =
928                 tfp_le_to_cpu_16(resp.record_entry_size);
929         em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
930
931         return rc;
932 }
933
934 int
935 tf_msg_em_cfg(struct tf *tfp,
936               uint32_t num_entries,
937               uint16_t key0_ctx_id,
938               uint16_t key1_ctx_id,
939               uint16_t record_ctx_id,
940               uint16_t efc_ctx_id,
941               uint8_t flush_interval,
942               int dir)
943 {
944         int rc;
945         struct hwrm_tf_ext_em_cfg_input  req = {0};
946         struct hwrm_tf_ext_em_cfg_output resp = {0};
947         uint32_t flags;
948         struct tfp_send_msg_parms parms = { 0 };
949         struct tf_dev_info *dev;
950         struct tf_session *tfs;
951
952         /* Retrieve the session information */
953         rc = tf_session_get_session_internal(tfp, &tfs);
954         if (rc) {
955                 TFP_DRV_LOG(ERR,
956                             "%s: Failed to lookup session, rc:%s\n",
957                             tf_dir_2_str(dir),
958                             strerror(-rc));
959                 return rc;
960         }
961
962         /* Retrieve the device information */
963         rc = tf_session_get_device(tfs, &dev);
964         if (rc) {
965                 TFP_DRV_LOG(ERR,
966                             "%s: Failed to lookup device, rc:%s\n",
967                             tf_dir_2_str(dir),
968                             strerror(-rc));
969                 return rc;
970         }
971
972         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
973                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
974         flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
975
976         req.flags = tfp_cpu_to_le_32(flags);
977         req.num_entries = tfp_cpu_to_le_32(num_entries);
978
979         req.flush_interval = flush_interval;
980
981         req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
982         req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
983         req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
984         req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
985
986         parms.tf_type = HWRM_TF_EXT_EM_CFG;
987         parms.req_data = (uint32_t *)&req;
988         parms.req_size = sizeof(req);
989         parms.resp_data = (uint32_t *)&resp;
990         parms.resp_size = sizeof(resp);
991         parms.mailbox = dev->ops->tf_dev_get_mailbox();
992
993         rc = tfp_send_msg_direct(tfp,
994                                  &parms);
995         return rc;
996 }
997
998 int
999 tf_msg_em_op(struct tf *tfp,
1000              int dir,
1001              uint16_t op)
1002 {
1003         int rc;
1004         struct hwrm_tf_ext_em_op_input req = {0};
1005         struct hwrm_tf_ext_em_op_output resp = {0};
1006         uint32_t flags;
1007         struct tfp_send_msg_parms parms = { 0 };
1008         struct tf_dev_info *dev;
1009         struct tf_session *tfs;
1010
1011         /* Retrieve the session information */
1012         rc = tf_session_get_session_internal(tfp, &tfs);
1013         if (rc) {
1014                 TFP_DRV_LOG(ERR,
1015                             "%s: Failed to lookup session, rc:%s\n",
1016                             tf_dir_2_str(dir),
1017                             strerror(-rc));
1018                 return rc;
1019         }
1020
1021         /* Retrieve the device information */
1022         rc = tf_session_get_device(tfs, &dev);
1023         if (rc) {
1024                 TFP_DRV_LOG(ERR,
1025                             "%s: Failed to lookup device, rc:%s\n",
1026                             tf_dir_2_str(dir),
1027                             strerror(-rc));
1028                 return rc;
1029         }
1030
1031         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1032                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1033         req.flags = tfp_cpu_to_le_32(flags);
1034         req.op = tfp_cpu_to_le_16(op);
1035
1036         parms.tf_type = HWRM_TF_EXT_EM_OP;
1037         parms.req_data = (uint32_t *)&req;
1038         parms.req_size = sizeof(req);
1039         parms.resp_data = (uint32_t *)&resp;
1040         parms.resp_size = sizeof(resp);
1041         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1042
1043         rc = tfp_send_msg_direct(tfp,
1044                                  &parms);
1045         return rc;
1046 }
1047
1048 int
1049 tf_msg_tcam_entry_set(struct tf *tfp,
1050                       struct tf_dev_info *dev,
1051                       struct tf_tcam_set_parms *parms)
1052 {
1053         int rc;
1054         struct tfp_send_msg_parms mparms = { 0 };
1055         struct hwrm_tf_tcam_set_input req = { 0 };
1056         struct hwrm_tf_tcam_set_output resp = { 0 };
1057         struct tf_msg_dma_buf buf = { 0 };
1058         uint8_t *data = NULL;
1059         int data_size = 0;
1060         uint8_t fw_session_id;
1061
1062         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1063         if (rc) {
1064                 TFP_DRV_LOG(ERR,
1065                             "%s: Unable to lookup FW id, rc:%s\n",
1066                             tf_dir_2_str(parms->dir),
1067                             strerror(-rc));
1068                 return rc;
1069         }
1070
1071         /* Populate the request */
1072         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1073         req.type = parms->hcapi_type;
1074         req.idx = tfp_cpu_to_le_16(parms->idx);
1075         if (parms->dir == TF_DIR_TX)
1076                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
1077
1078         req.key_size = parms->key_size;
1079         req.mask_offset = parms->key_size;
1080         /* Result follows after key and mask, thus multiply by 2 */
1081         req.result_offset = 2 * parms->key_size;
1082         req.result_size = parms->result_size;
1083         data_size = 2 * req.key_size + req.result_size;
1084
1085         if (data_size <= TF_PCI_BUF_SIZE_MAX) {
1086                 /* use pci buffer */
1087                 data = &req.dev_data[0];
1088         } else {
1089                 /* use dma buffer */
1090                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
1091                 rc = tf_msg_alloc_dma_buf(&buf, data_size);
1092                 if (rc)
1093                         goto cleanup;
1094                 data = buf.va_addr;
1095                 tfp_memcpy(&req.dev_data[0],
1096                            &buf.pa_addr,
1097                            sizeof(buf.pa_addr));
1098         }
1099
1100         tfp_memcpy(&data[0], parms->key, parms->key_size);
1101         tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
1102         tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
1103
1104         mparms.tf_type = HWRM_TF_TCAM_SET;
1105         mparms.req_data = (uint32_t *)&req;
1106         mparms.req_size = sizeof(req);
1107         mparms.resp_data = (uint32_t *)&resp;
1108         mparms.resp_size = sizeof(resp);
1109         mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1110
1111         rc = tfp_send_msg_direct(tfp,
1112                                  &mparms);
1113
1114 cleanup:
1115         tf_msg_free_dma_buf(&buf);
1116
1117         return rc;
1118 }
1119
1120 int
1121 tf_msg_tcam_entry_free(struct tf *tfp,
1122                        struct tf_dev_info *dev,
1123                        struct tf_tcam_free_parms *in_parms)
1124 {
1125         int rc;
1126         struct hwrm_tf_tcam_free_input req =  { 0 };
1127         struct hwrm_tf_tcam_free_output resp = { 0 };
1128         struct tfp_send_msg_parms parms = { 0 };
1129         uint8_t fw_session_id;
1130
1131         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1132         if (rc) {
1133                 TFP_DRV_LOG(ERR,
1134                             "%s: Unable to lookup FW id, rc:%s\n",
1135                             tf_dir_2_str(in_parms->dir),
1136                             strerror(-rc));
1137                 return rc;
1138         }
1139
1140         /* Populate the request */
1141         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1142         req.type = in_parms->hcapi_type;
1143         req.count = 1;
1144         req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
1145         if (in_parms->dir == TF_DIR_TX)
1146                 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
1147
1148         parms.tf_type = HWRM_TF_TCAM_FREE;
1149         parms.req_data = (uint32_t *)&req;
1150         parms.req_size = sizeof(req);
1151         parms.resp_data = (uint32_t *)&resp;
1152         parms.resp_size = sizeof(resp);
1153         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1154
1155         rc = tfp_send_msg_direct(tfp,
1156                                  &parms);
1157         return rc;
1158 }
1159
1160 int
1161 tf_msg_set_tbl_entry(struct tf *tfp,
1162                      enum tf_dir dir,
1163                      uint16_t hcapi_type,
1164                      uint16_t size,
1165                      uint8_t *data,
1166                      uint32_t index)
1167 {
1168         int rc;
1169         struct hwrm_tf_tbl_type_set_input req = { 0 };
1170         struct hwrm_tf_tbl_type_set_output resp = { 0 };
1171         struct tfp_send_msg_parms parms = { 0 };
1172         uint8_t fw_session_id;
1173         struct tf_dev_info *dev;
1174         struct tf_session *tfs;
1175
1176         /* Retrieve the session information */
1177         rc = tf_session_get_session_internal(tfp, &tfs);
1178         if (rc) {
1179                 TFP_DRV_LOG(ERR,
1180                             "%s: Failed to lookup session, rc:%s\n",
1181                             tf_dir_2_str(dir),
1182                             strerror(-rc));
1183                 return rc;
1184         }
1185
1186         /* Retrieve the device information */
1187         rc = tf_session_get_device(tfs, &dev);
1188         if (rc) {
1189                 TFP_DRV_LOG(ERR,
1190                             "%s: Failed to lookup device, rc:%s\n",
1191                             tf_dir_2_str(dir),
1192                             strerror(-rc));
1193                 return rc;
1194         }
1195
1196         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1197         if (rc) {
1198                 TFP_DRV_LOG(ERR,
1199                             "%s: Unable to lookup FW id, rc:%s\n",
1200                             tf_dir_2_str(dir),
1201                             strerror(-rc));
1202                 return rc;
1203         }
1204
1205         /* Populate the request */
1206         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1207         req.flags = tfp_cpu_to_le_16(dir);
1208         req.type = tfp_cpu_to_le_32(hcapi_type);
1209         req.size = tfp_cpu_to_le_16(size);
1210         req.index = tfp_cpu_to_le_32(index);
1211
1212         /* Check for data size conformity */
1213         if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
1214                 rc = -EINVAL;
1215                 TFP_DRV_LOG(ERR,
1216                             "%s: Invalid parameters for msg type, rc:%s\n",
1217                             tf_dir_2_str(dir),
1218                             strerror(-rc));
1219                 return rc;
1220         }
1221
1222         tfp_memcpy(&req.data,
1223                    data,
1224                    size);
1225
1226         parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1227         parms.req_data = (uint32_t *)&req;
1228         parms.req_size = sizeof(req);
1229         parms.resp_data = (uint32_t *)&resp;
1230         parms.resp_size = sizeof(resp);
1231         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1232
1233         rc = tfp_send_msg_direct(tfp,
1234                                  &parms);
1235         if (rc)
1236                 return rc;
1237
1238         return tfp_le_to_cpu_32(parms.tf_resp_code);
1239 }
1240
1241 int
1242 tf_msg_get_tbl_entry(struct tf *tfp,
1243                      enum tf_dir dir,
1244                      uint16_t hcapi_type,
1245                      uint16_t size,
1246                      uint8_t *data,
1247                      uint32_t index)
1248 {
1249         int rc;
1250         struct hwrm_tf_tbl_type_get_input req = { 0 };
1251         struct hwrm_tf_tbl_type_get_output resp = { 0 };
1252         struct tfp_send_msg_parms parms = { 0 };
1253         uint8_t fw_session_id;
1254         struct tf_dev_info *dev;
1255         struct tf_session *tfs;
1256
1257         /* Retrieve the session information */
1258         rc = tf_session_get_session_internal(tfp, &tfs);
1259         if (rc) {
1260                 TFP_DRV_LOG(ERR,
1261                             "%s: Failed to lookup session, rc:%s\n",
1262                             tf_dir_2_str(dir),
1263                             strerror(-rc));
1264                 return rc;
1265         }
1266
1267         /* Retrieve the device information */
1268         rc = tf_session_get_device(tfs, &dev);
1269         if (rc) {
1270                 TFP_DRV_LOG(ERR,
1271                             "%s: Failed to lookup device, rc:%s\n",
1272                             tf_dir_2_str(dir),
1273                             strerror(-rc));
1274                 return rc;
1275         }
1276
1277         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1278         if (rc) {
1279                 TFP_DRV_LOG(ERR,
1280                             "%s: Unable to lookup FW id, rc:%s\n",
1281                             tf_dir_2_str(dir),
1282                             strerror(-rc));
1283                 return rc;
1284         }
1285
1286         /* Populate the request */
1287         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1288         req.flags = tfp_cpu_to_le_16(dir);
1289         req.type = tfp_cpu_to_le_32(hcapi_type);
1290         req.index = tfp_cpu_to_le_32(index);
1291
1292         parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1293         parms.req_data = (uint32_t *)&req;
1294         parms.req_size = sizeof(req);
1295         parms.resp_data = (uint32_t *)&resp;
1296         parms.resp_size = sizeof(resp);
1297         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1298
1299         rc = tfp_send_msg_direct(tfp,
1300                                  &parms);
1301         if (rc)
1302                 return rc;
1303
1304         /* Verify that we got enough buffer to return the requested data */
1305         if (tfp_le_to_cpu_32(resp.size) != size)
1306                 return -EINVAL;
1307
1308         tfp_memcpy(data,
1309                    &resp.data,
1310                    size);
1311
1312         return tfp_le_to_cpu_32(parms.tf_resp_code);
1313 }
1314
1315 /* HWRM Tunneled messages */
1316
1317 int
1318 tf_msg_get_global_cfg(struct tf *tfp,
1319                       struct tf_global_cfg_parms *params)
1320 {
1321         int rc = 0;
1322         struct tfp_send_msg_parms parms = { 0 };
1323         struct hwrm_tf_global_cfg_get_input req = { 0 };
1324         struct hwrm_tf_global_cfg_get_output resp = { 0 };
1325         uint32_t flags = 0;
1326         uint8_t fw_session_id;
1327         uint16_t resp_size = 0;
1328         struct tf_dev_info *dev;
1329         struct tf_session *tfs;
1330
1331         /* Retrieve the session information */
1332         rc = tf_session_get_session_internal(tfp, &tfs);
1333         if (rc) {
1334                 TFP_DRV_LOG(ERR,
1335                             "%s: Failed to lookup session, rc:%s\n",
1336                             tf_dir_2_str(params->dir),
1337                             strerror(-rc));
1338                 return rc;
1339         }
1340
1341         /* Retrieve the device information */
1342         rc = tf_session_get_device(tfs, &dev);
1343         if (rc) {
1344                 TFP_DRV_LOG(ERR,
1345                             "%s: Failed to lookup device, rc:%s\n",
1346                             tf_dir_2_str(params->dir),
1347                             strerror(-rc));
1348                 return rc;
1349         }
1350
1351         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1352         if (rc) {
1353                 TFP_DRV_LOG(ERR,
1354                             "%s: Unable to lookup FW id, rc:%s\n",
1355                             tf_dir_2_str(params->dir),
1356                             strerror(-rc));
1357                 return rc;
1358         }
1359
1360         flags = (params->dir == TF_DIR_TX ?
1361                  HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1362                  HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1363
1364         /* Populate the request */
1365         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1366         req.flags = tfp_cpu_to_le_32(flags);
1367         req.type = tfp_cpu_to_le_32(params->type);
1368         req.offset = tfp_cpu_to_le_32(params->offset);
1369         req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1370
1371         parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1372         parms.req_data = (uint32_t *)&req;
1373         parms.req_size = sizeof(req);
1374         parms.resp_data = (uint32_t *)&resp;
1375         parms.resp_size = sizeof(resp);
1376         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1377
1378         rc = tfp_send_msg_direct(tfp, &parms);
1379         if (rc != 0)
1380                 return rc;
1381
1382         /* Verify that we got enough buffer to return the requested data */
1383         resp_size = tfp_le_to_cpu_16(resp.size);
1384         if (resp_size < params->config_sz_in_bytes)
1385                 return -EINVAL;
1386
1387         if (params->config)
1388                 tfp_memcpy(params->config,
1389                            resp.data,
1390                            resp_size);
1391         else
1392                 return -EFAULT;
1393
1394         return tfp_le_to_cpu_32(parms.tf_resp_code);
1395 }
1396
1397 int
1398 tf_msg_set_global_cfg(struct tf *tfp,
1399                       struct tf_global_cfg_parms *params)
1400 {
1401         int rc = 0;
1402         struct tfp_send_msg_parms parms = { 0 };
1403         struct hwrm_tf_global_cfg_set_input req = { 0 };
1404         struct hwrm_tf_global_cfg_set_output resp = { 0 };
1405         uint32_t flags = 0;
1406         uint8_t fw_session_id;
1407         struct tf_dev_info *dev;
1408         struct tf_session *tfs;
1409
1410         /* Retrieve the session information */
1411         rc = tf_session_get_session_internal(tfp, &tfs);
1412         if (rc) {
1413                 TFP_DRV_LOG(ERR,
1414                             "%s: Failed to lookup session, rc:%s\n",
1415                             tf_dir_2_str(params->dir),
1416                             strerror(-rc));
1417                 return rc;
1418         }
1419
1420         /* Retrieve the device information */
1421         rc = tf_session_get_device(tfs, &dev);
1422         if (rc) {
1423                 TFP_DRV_LOG(ERR,
1424                             "%s: Failed to lookup device, rc:%s\n",
1425                             tf_dir_2_str(params->dir),
1426                             strerror(-rc));
1427                 return rc;
1428         }
1429
1430         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1431         if (rc) {
1432                 TFP_DRV_LOG(ERR,
1433                             "%s: Unable to lookup FW id, rc:%s\n",
1434                             tf_dir_2_str(params->dir),
1435                             strerror(-rc));
1436                 return rc;
1437         }
1438
1439         flags = (params->dir == TF_DIR_TX ?
1440                  HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
1441                  HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
1442
1443         /* Populate the request */
1444         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1445         req.flags = tfp_cpu_to_le_32(flags);
1446         req.type = tfp_cpu_to_le_32(params->type);
1447         req.offset = tfp_cpu_to_le_32(params->offset);
1448
1449         /* Check for data size conformity */
1450         if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
1451                 rc = -EINVAL;
1452                 TFP_DRV_LOG(ERR,
1453                             "%s: Invalid parameters for msg type, rc:%s\n",
1454                             tf_dir_2_str(params->dir),
1455                             strerror(-rc));
1456                 return rc;
1457         }
1458
1459         tfp_memcpy(req.data, params->config,
1460                    params->config_sz_in_bytes);
1461
1462         /* Only set mask if pointer is provided
1463          */
1464         if (params->config_mask) {
1465                 tfp_memcpy(req.data + params->config_sz_in_bytes,
1466                            params->config_mask,
1467                            params->config_sz_in_bytes);
1468         }
1469
1470         req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1471
1472         parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
1473         parms.req_data = (uint32_t *)&req;
1474         parms.req_size = sizeof(req);
1475         parms.resp_data = (uint32_t *)&resp;
1476         parms.resp_size = sizeof(resp);
1477         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1478
1479         rc = tfp_send_msg_direct(tfp, &parms);
1480
1481         if (rc != 0)
1482                 return rc;
1483
1484         return tfp_le_to_cpu_32(parms.tf_resp_code);
1485 }
1486
1487 int
1488 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
1489                           enum tf_dir dir,
1490                           uint16_t hcapi_type,
1491                           uint32_t starting_idx,
1492                           uint16_t num_entries,
1493                           uint16_t entry_sz_in_bytes,
1494                           uint64_t physical_mem_addr)
1495 {
1496         int rc;
1497         struct tfp_send_msg_parms parms = { 0 };
1498         struct tf_tbl_type_bulk_get_input req = { 0 };
1499         struct tf_tbl_type_bulk_get_output resp = { 0 };
1500         int data_size = 0;
1501         uint8_t fw_session_id;
1502         struct tf_dev_info *dev;
1503         struct tf_session *tfs;
1504
1505         /* Retrieve the session information */
1506         rc = tf_session_get_session(tfp, &tfs);
1507         if (rc) {
1508                 TFP_DRV_LOG(ERR,
1509                             "%s: Failed to lookup session, rc:%s\n",
1510                             tf_dir_2_str(dir),
1511                             strerror(-rc));
1512                 return rc;
1513         }
1514
1515         /* Retrieve the device information */
1516         rc = tf_session_get_device(tfs, &dev);
1517         if (rc) {
1518                 TFP_DRV_LOG(ERR,
1519                             "%s: Failed to lookup device, rc:%s\n",
1520                             tf_dir_2_str(dir),
1521                             strerror(-rc));
1522                 return rc;
1523         }
1524
1525         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1526         if (rc) {
1527                 TFP_DRV_LOG(ERR,
1528                             "%s: Unable to lookup FW id, rc:%s\n",
1529                             tf_dir_2_str(dir),
1530                             strerror(-rc));
1531                 return rc;
1532         }
1533
1534         /* Populate the request */
1535         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1536         req.flags = tfp_cpu_to_le_16(dir);
1537         req.type = tfp_cpu_to_le_32(hcapi_type);
1538         req.start_index = tfp_cpu_to_le_32(starting_idx);
1539         req.num_entries = tfp_cpu_to_le_32(num_entries);
1540
1541         data_size = num_entries * entry_sz_in_bytes;
1542
1543         req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1544
1545         MSG_PREP(parms,
1546                  dev->ops->tf_dev_get_mailbox(),
1547                  HWRM_TF,
1548                  HWRM_TFT_TBL_TYPE_BULK_GET,
1549                  req,
1550                  resp);
1551
1552         rc = tfp_send_msg_tunneled(tfp, &parms);
1553         if (rc)
1554                 return rc;
1555
1556         /* Verify that we got enough buffer to return the requested data */
1557         if (tfp_le_to_cpu_32(resp.size) != data_size)
1558                 return -EINVAL;
1559
1560         return tfp_le_to_cpu_32(parms.tf_resp_code);
1561 }
1562
1563 int
1564 tf_msg_get_if_tbl_entry(struct tf *tfp,
1565                         struct tf_if_tbl_get_parms *params)
1566 {
1567         int rc = 0;
1568         struct tfp_send_msg_parms parms = { 0 };
1569         struct hwrm_tf_if_tbl_get_input req = { 0 };
1570         struct hwrm_tf_if_tbl_get_output resp = { 0 };
1571         uint32_t flags = 0;
1572         struct tf_dev_info *dev;
1573         struct tf_session *tfs;
1574
1575         /* Retrieve the session information */
1576         rc = tf_session_get_session(tfp, &tfs);
1577         if (rc) {
1578                 TFP_DRV_LOG(ERR,
1579                             "%s: Failed to lookup session, rc:%s\n",
1580                             tf_dir_2_str(params->dir),
1581                             strerror(-rc));
1582                 return rc;
1583         }
1584
1585         /* Retrieve the device information */
1586         rc = tf_session_get_device(tfs, &dev);
1587         if (rc) {
1588                 TFP_DRV_LOG(ERR,
1589                             "%s: Failed to lookup device, rc:%s\n",
1590                             tf_dir_2_str(params->dir),
1591                             strerror(-rc));
1592                 return rc;
1593         }
1594
1595         flags = (params->dir == TF_DIR_TX ?
1596                 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
1597                 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
1598
1599         /* Populate the request */
1600         req.fw_session_id =
1601                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1602         req.flags = flags;
1603         req.type = params->hcapi_type;
1604         req.index = tfp_cpu_to_le_16(params->idx);
1605         req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1606
1607         parms.tf_type = HWRM_TF_IF_TBL_GET;
1608         parms.req_data = (uint32_t *)&req;
1609         parms.req_size = sizeof(req);
1610         parms.resp_data = (uint32_t *)&resp;
1611         parms.resp_size = sizeof(resp);
1612         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1613
1614         rc = tfp_send_msg_direct(tfp, &parms);
1615
1616         if (rc != 0)
1617                 return rc;
1618
1619         if (parms.tf_resp_code != 0)
1620                 return tfp_le_to_cpu_32(parms.tf_resp_code);
1621
1622         tfp_memcpy(params->data, resp.data, req.size);
1623
1624         return tfp_le_to_cpu_32(parms.tf_resp_code);
1625 }
1626
1627 int
1628 tf_msg_set_if_tbl_entry(struct tf *tfp,
1629                         struct tf_if_tbl_set_parms *params)
1630 {
1631         int rc = 0;
1632         struct tfp_send_msg_parms parms = { 0 };
1633         struct hwrm_tf_if_tbl_set_input req = { 0 };
1634         struct hwrm_tf_if_tbl_get_output resp = { 0 };
1635         uint32_t flags = 0;
1636         struct tf_dev_info *dev;
1637         struct tf_session *tfs;
1638
1639         /* Retrieve the session information */
1640         rc = tf_session_get_session(tfp, &tfs);
1641         if (rc) {
1642                 TFP_DRV_LOG(ERR,
1643                             "%s: Failed to lookup session, rc:%s\n",
1644                             tf_dir_2_str(params->dir),
1645                             strerror(-rc));
1646                 return rc;
1647         }
1648
1649         /* Retrieve the device information */
1650         rc = tf_session_get_device(tfs, &dev);
1651         if (rc)
1652                 return rc;
1653
1654         flags = (params->dir == TF_DIR_TX ?
1655                 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1656                 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1657
1658         /* Populate the request */
1659         req.fw_session_id =
1660                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1661         req.flags = flags;
1662         req.type = params->hcapi_type;
1663         req.index = tfp_cpu_to_le_32(params->idx);
1664         req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1665         tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1666
1667         parms.tf_type = HWRM_TF_IF_TBL_SET;
1668         parms.req_data = (uint32_t *)&req;
1669         parms.req_size = sizeof(req);
1670         parms.resp_data = (uint32_t *)&resp;
1671         parms.resp_size = sizeof(resp);
1672         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1673
1674         rc = tfp_send_msg_direct(tfp, &parms);
1675
1676         if (rc != 0)
1677                 return rc;
1678
1679         return tfp_le_to_cpu_32(parms.tf_resp_code);
1680 }