net/bnxt: support EM with FKB
[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_EM_INSERT_RECORD_SIZE     80
29 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE    88
30
31 /* Compile check - Catch any msg changes that we depend on, like the
32  * defines listed above for array size checking.
33  *
34  * Checking array size is dangerous in that the type could change and
35  * we wouldn't be able to catch it. Thus we check if the complete msg
36  * changed instead. Best we can do.
37  *
38  * If failure is observed then both msg size (defines below) and the
39  * array size (define above) should be checked and compared.
40  */
41 #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56
42 static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
43               TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET,
44               "HWRM message size changed: hwrm_tf_global_cfg_set_input");
45
46 #define TF_MSG_SIZE_HWRM_TF_EM_INSERT      104
47 static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
48               TF_MSG_SIZE_HWRM_TF_EM_INSERT,
49               "HWRM message size changed: hwrm_tf_em_insert_input");
50
51 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET   128
52 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
53               TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
54               "HWRM message size changed: hwrm_tf_tbl_type_set_input");
55
56 /**
57  * This is the MAX data we can transport across regular HWRM
58  */
59 #define TF_PCI_BUF_SIZE_MAX 88
60
61 /**
62  * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
63  */
64 struct tf_msg_dma_buf {
65         void *va_addr;
66         uint64_t pa_addr;
67 };
68
69 /**
70  * Allocates a DMA buffer that can be used for message transfer.
71  *
72  * [in] buf
73  *   Pointer to DMA buffer structure
74  *
75  * [in] size
76  *   Requested size of the buffer in bytes
77  *
78  * Returns:
79  *    0      - Success
80  *   -ENOMEM - Unable to allocate buffer, no memory
81  */
82 static int
83 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
84 {
85         struct tfp_calloc_parms alloc_parms;
86         int rc;
87
88         /* Allocate session */
89         alloc_parms.nitems = 1;
90         alloc_parms.size = size;
91         alloc_parms.alignment = 4096;
92         rc = tfp_calloc(&alloc_parms);
93         if (rc)
94                 return -ENOMEM;
95
96         buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
97         buf->va_addr = alloc_parms.mem_va;
98
99         return 0;
100 }
101
102 /**
103  * Free's a previous allocated DMA buffer.
104  *
105  * [in] buf
106  *   Pointer to DMA buffer structure
107  */
108 static void
109 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
110 {
111         tfp_free(buf->va_addr);
112 }
113
114 /* HWRM Direct messages */
115
116 int
117 tf_msg_session_open(struct tf *tfp,
118                     char *ctrl_chan_name,
119                     uint8_t *fw_session_id,
120                     uint8_t *fw_session_client_id,
121                     struct tf_dev_info *dev)
122 {
123         int rc;
124         struct hwrm_tf_session_open_input req = { 0 };
125         struct hwrm_tf_session_open_output resp = { 0 };
126         struct tfp_send_msg_parms parms = { 0 };
127
128         /* Populate the request */
129         tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
130
131         parms.tf_type = HWRM_TF_SESSION_OPEN;
132         parms.req_data = (uint32_t *)&req;
133         parms.req_size = sizeof(req);
134         parms.resp_data = (uint32_t *)&resp;
135         parms.resp_size = sizeof(resp);
136         parms.mailbox = dev->ops->tf_dev_get_mailbox();
137
138         rc = tfp_send_msg_direct(tfp,
139                                  &parms);
140         if (rc)
141                 return rc;
142
143         *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
144         *fw_session_client_id =
145                 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
146
147         return rc;
148 }
149
150 int
151 tf_msg_session_attach(struct tf *tfp __rte_unused,
152                       char *ctrl_chan_name __rte_unused,
153                       uint8_t tf_fw_session_id __rte_unused)
154 {
155         return -1;
156 }
157
158 int
159 tf_msg_session_client_register(struct tf *tfp,
160                                struct tf_session *tfs,
161                                char *ctrl_channel_name,
162                                uint8_t *fw_session_client_id)
163 {
164         int rc;
165         struct hwrm_tf_session_register_input req = { 0 };
166         struct hwrm_tf_session_register_output resp = { 0 };
167         struct tfp_send_msg_parms parms = { 0 };
168         uint8_t fw_session_id;
169         struct tf_dev_info *dev;
170
171         /* Retrieve the device information */
172         rc = tf_session_get_device(tfs, &dev);
173         if (rc) {
174                 TFP_DRV_LOG(ERR,
175                             "Failed to lookup device, rc:%s\n",
176                             strerror(-rc));
177                 return rc;
178         }
179
180         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
181         if (rc) {
182                 TFP_DRV_LOG(ERR,
183                             "Unable to lookup FW id, rc:%s\n",
184                             strerror(-rc));
185                 return rc;
186         }
187
188         /* Populate the request */
189         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
190         tfp_memcpy(&req.session_client_name,
191                    ctrl_channel_name,
192                    TF_SESSION_NAME_MAX);
193
194         parms.tf_type = HWRM_TF_SESSION_REGISTER;
195         parms.req_data = (uint32_t *)&req;
196         parms.req_size = sizeof(req);
197         parms.resp_data = (uint32_t *)&resp;
198         parms.resp_size = sizeof(resp);
199         parms.mailbox = dev->ops->tf_dev_get_mailbox();
200
201         rc = tfp_send_msg_direct(tfp,
202                                  &parms);
203         if (rc)
204                 return rc;
205
206         *fw_session_client_id =
207                 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
208
209         return rc;
210 }
211
212 int
213 tf_msg_session_client_unregister(struct tf *tfp,
214                                  struct tf_session *tfs,
215                                  uint8_t fw_session_client_id)
216 {
217         int rc;
218         struct hwrm_tf_session_unregister_input req = { 0 };
219         struct hwrm_tf_session_unregister_output resp = { 0 };
220         struct tfp_send_msg_parms parms = { 0 };
221         uint8_t fw_session_id;
222         struct tf_dev_info *dev;
223
224         /* Retrieve the device information */
225         rc = tf_session_get_device(tfs, &dev);
226         if (rc) {
227                 TFP_DRV_LOG(ERR,
228                             "Failed to lookup device, rc:%s\n",
229                             strerror(-rc));
230                 return rc;
231         }
232
233         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
234         if (rc) {
235                 TFP_DRV_LOG(ERR,
236                             "Unable to lookup FW id, rc:%s\n",
237                             strerror(-rc));
238                 return rc;
239         }
240
241         /* Populate the request */
242         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
243         req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
244
245         parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
246         parms.req_data = (uint32_t *)&req;
247         parms.req_size = sizeof(req);
248         parms.resp_data = (uint32_t *)&resp;
249         parms.resp_size = sizeof(resp);
250         parms.mailbox = dev->ops->tf_dev_get_mailbox();
251
252         rc = tfp_send_msg_direct(tfp,
253                                  &parms);
254
255         return rc;
256 }
257
258 int
259 tf_msg_session_close(struct tf *tfp,
260                      struct tf_session *tfs)
261 {
262         int rc;
263         struct hwrm_tf_session_close_input req = { 0 };
264         struct hwrm_tf_session_close_output resp = { 0 };
265         struct tfp_send_msg_parms parms = { 0 };
266         uint8_t fw_session_id;
267         struct tf_dev_info *dev;
268
269         /* Retrieve the device information */
270         rc = tf_session_get_device(tfs, &dev);
271         if (rc) {
272                 TFP_DRV_LOG(ERR,
273                             "Failed to lookup device, rc:%s\n",
274                             strerror(-rc));
275                 return rc;
276         }
277
278         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
279         if (rc) {
280                 TFP_DRV_LOG(ERR,
281                             "Unable to lookup FW id, rc:%s\n",
282                             strerror(-rc));
283                 return rc;
284         }
285
286         /* Populate the request */
287         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
288
289         parms.tf_type = HWRM_TF_SESSION_CLOSE;
290         parms.req_data = (uint32_t *)&req;
291         parms.req_size = sizeof(req);
292         parms.resp_data = (uint32_t *)&resp;
293         parms.resp_size = sizeof(resp);
294         parms.mailbox = dev->ops->tf_dev_get_mailbox();
295
296         rc = tfp_send_msg_direct(tfp,
297                                  &parms);
298         return rc;
299 }
300
301 int
302 tf_msg_session_qcfg(struct tf *tfp)
303 {
304         int rc;
305         struct hwrm_tf_session_qcfg_input req = { 0 };
306         struct hwrm_tf_session_qcfg_output resp = { 0 };
307         struct tfp_send_msg_parms parms = { 0 };
308         uint8_t fw_session_id;
309         struct tf_dev_info *dev;
310         struct tf_session *tfs;
311
312         /* Retrieve the session information */
313         rc = tf_session_get_session_internal(tfp, &tfs);
314         if (rc) {
315                 TFP_DRV_LOG(ERR,
316                             "Failed to lookup session, rc:%s\n",
317                             strerror(-rc));
318                 return rc;
319         }
320
321         /* Retrieve the device information */
322         rc = tf_session_get_device(tfs, &dev);
323         if (rc) {
324                 TFP_DRV_LOG(ERR,
325                             "Failed to lookup device, rc:%s\n",
326                             strerror(-rc));
327                 return rc;
328         }
329
330         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
331         if (rc) {
332                 TFP_DRV_LOG(ERR,
333                             "Unable to lookup FW id, rc:%s\n",
334                             strerror(-rc));
335                 return rc;
336         }
337
338         /* Populate the request */
339         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
340
341         parms.tf_type = HWRM_TF_SESSION_QCFG,
342         parms.req_data = (uint32_t *)&req;
343         parms.req_size = sizeof(req);
344         parms.resp_data = (uint32_t *)&resp;
345         parms.resp_size = sizeof(resp);
346         parms.mailbox = dev->ops->tf_dev_get_mailbox();
347
348         rc = tfp_send_msg_direct(tfp,
349                                  &parms);
350         return rc;
351 }
352
353 int
354 tf_msg_session_resc_qcaps(struct tf *tfp,
355                           struct tf_dev_info *dev,
356                           enum tf_dir dir,
357                           uint16_t size,
358                           struct tf_rm_resc_req_entry *query,
359                           enum tf_rm_resc_resv_strategy *resv_strategy)
360 {
361         int rc;
362         int i;
363         struct tfp_send_msg_parms parms = { 0 };
364         struct hwrm_tf_session_resc_qcaps_input req = { 0 };
365         struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
366         uint8_t fw_session_id;
367         struct tf_msg_dma_buf qcaps_buf = { 0 };
368         struct tf_rm_resc_req_entry *data;
369         int dma_size;
370
371         TF_CHECK_PARMS3(tfp, query, resv_strategy);
372
373         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
374         if (rc) {
375                 TFP_DRV_LOG(ERR,
376                             "%s: Unable to lookup FW id, rc:%s\n",
377                             tf_dir_2_str(dir),
378                             strerror(-rc));
379                 return rc;
380         }
381
382         /* Prepare DMA buffer */
383         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
384         rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
385         if (rc)
386                 return rc;
387
388         /* Populate the request */
389         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
390         req.flags = tfp_cpu_to_le_16(dir);
391         req.qcaps_size = size;
392         req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
393
394         parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
395         parms.req_data = (uint32_t *)&req;
396         parms.req_size = sizeof(req);
397         parms.resp_data = (uint32_t *)&resp;
398         parms.resp_size = sizeof(resp);
399         parms.mailbox = dev->ops->tf_dev_get_mailbox();
400
401         rc = tfp_send_msg_direct(tfp, &parms);
402         if (rc)
403                 goto cleanup;
404
405         /* Process the response
406          * Should always get expected number of entries
407          */
408         if (tfp_le_to_cpu_32(resp.size) != size) {
409                 TFP_DRV_LOG(ERR,
410                             "%s: QCAPS message size error, rc:%s\n",
411                             tf_dir_2_str(dir),
412                             strerror(EINVAL));
413                 rc = -EINVAL;
414                 goto cleanup;
415         }
416
417         /* Post process the response */
418         data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
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_hash_insert_em_internal_entry(struct tf *tfp,
712                                      struct tf_insert_em_entry_parms *em_parms,
713                                      uint32_t key0_hash,
714                                      uint32_t key1_hash,
715                                      uint16_t *rptr_index,
716                                      uint8_t *rptr_entry,
717                                      uint8_t *num_of_entries)
718 {
719         int rc;
720         struct tfp_send_msg_parms parms = { 0 };
721         struct hwrm_tf_em_hash_insert_input req = { 0 };
722         struct hwrm_tf_em_hash_insert_output resp = { 0 };
723         uint16_t flags;
724         uint8_t fw_session_id;
725         uint8_t msg_record_size;
726         struct tf_dev_info *dev;
727         struct tf_session *tfs;
728
729         /* Retrieve the session information */
730         rc = tf_session_get_session_internal(tfp, &tfs);
731         if (rc) {
732                 TFP_DRV_LOG(ERR,
733                             "%s: Failed to lookup session, rc:%s\n",
734                             tf_dir_2_str(em_parms->dir),
735                             strerror(-rc));
736                 return rc;
737         }
738
739         /* Retrieve the device information */
740         rc = tf_session_get_device(tfs, &dev);
741         if (rc) {
742                 TFP_DRV_LOG(ERR,
743                             "%s: Failed to lookup device, rc:%s\n",
744                             tf_dir_2_str(em_parms->dir),
745                             strerror(-rc));
746                 return rc;
747         }
748
749         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
750         if (rc) {
751                 TFP_DRV_LOG(ERR,
752                             "%s: Unable to lookup FW id, rc:%s\n",
753                             tf_dir_2_str(em_parms->dir),
754                             strerror(-rc));
755                 return rc;
756         }
757
758         /* Populate the request */
759         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
760
761         /* Check for key size conformity */
762         msg_record_size = (em_parms->em_record_sz_in_bits + 7) / 8;
763
764         if (msg_record_size > TF_MSG_EM_INSERT_RECORD_SIZE) {
765                 rc = -EINVAL;
766                 TFP_DRV_LOG(ERR,
767                             "%s: Record size to large, rc:%s\n",
768                             tf_dir_2_str(em_parms->dir),
769                             strerror(-rc));
770                 return rc;
771         }
772
773         tfp_memcpy((char *)req.em_record,
774                    em_parms->em_record,
775                    msg_record_size);
776
777         flags = (em_parms->dir == TF_DIR_TX ?
778                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
779                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
780         req.flags = tfp_cpu_to_le_16(flags);
781         req.em_record_size_bits = em_parms->em_record_sz_in_bits;
782         req.em_record_idx = *rptr_index;
783         req.key0_hash = key0_hash;
784         req.key1_hash = key1_hash;
785
786         parms.tf_type = HWRM_TF_EM_HASH_INSERT;
787         parms.req_data = (uint32_t *)&req;
788         parms.req_size = sizeof(req);
789         parms.resp_data = (uint32_t *)&resp;
790         parms.resp_size = sizeof(resp);
791         parms.mailbox = dev->ops->tf_dev_get_mailbox();
792
793         rc = tfp_send_msg_direct(tfp,
794                                  &parms);
795         if (rc)
796                 return rc;
797
798         *rptr_entry = resp.rptr_entry;
799         *rptr_index = resp.rptr_index;
800         *num_of_entries = resp.num_of_entries;
801
802         return 0;
803 }
804
805 int
806 tf_msg_delete_em_entry(struct tf *tfp,
807                        struct tf_delete_em_entry_parms *em_parms)
808 {
809         int rc;
810         struct tfp_send_msg_parms parms = { 0 };
811         struct hwrm_tf_em_delete_input req = { 0 };
812         struct hwrm_tf_em_delete_output resp = { 0 };
813         uint16_t flags;
814         uint8_t fw_session_id;
815         struct tf_dev_info *dev;
816         struct tf_session *tfs;
817
818         /* Retrieve the session information */
819         rc = tf_session_get_session_internal(tfp, &tfs);
820         if (rc) {
821                 TFP_DRV_LOG(ERR,
822                             "%s: Failed to lookup session, rc:%s\n",
823                             tf_dir_2_str(em_parms->dir),
824                             strerror(-rc));
825                 return rc;
826         }
827
828         /* Retrieve the device information */
829         rc = tf_session_get_device(tfs, &dev);
830         if (rc) {
831                 TFP_DRV_LOG(ERR,
832                             "%s: Failed to lookup device, rc:%s\n",
833                             tf_dir_2_str(em_parms->dir),
834                             strerror(-rc));
835                 return rc;
836         }
837
838         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
839         if (rc) {
840                 TFP_DRV_LOG(ERR,
841                             "%s: Unable to lookup FW id, rc:%s\n",
842                             tf_dir_2_str(em_parms->dir),
843                             strerror(-rc));
844                 return rc;
845         }
846
847         /* Populate the request */
848         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
849
850         flags = (em_parms->dir == TF_DIR_TX ?
851                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
852                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
853         req.flags = tfp_cpu_to_le_16(flags);
854         req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
855
856         parms.tf_type = HWRM_TF_EM_DELETE;
857         parms.req_data = (uint32_t *)&req;
858         parms.req_size = sizeof(req);
859         parms.resp_data = (uint32_t *)&resp;
860         parms.resp_size = sizeof(resp);
861         parms.mailbox = dev->ops->tf_dev_get_mailbox();
862
863         rc = tfp_send_msg_direct(tfp,
864                                  &parms);
865         if (rc)
866                 return rc;
867
868         em_parms->index = tfp_le_to_cpu_16(resp.em_index);
869
870         return 0;
871 }
872
873 int
874 tf_msg_em_mem_rgtr(struct tf *tfp,
875                    int page_lvl,
876                    int page_size,
877                    uint64_t dma_addr,
878                    uint16_t *ctx_id)
879 {
880         int rc;
881         struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
882         struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
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                             "Failed to lookup session, rc:%s\n",
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                             "Failed to lookup device, rc:%s\n",
901                             strerror(-rc));
902                 return rc;
903         }
904
905         req.page_level = page_lvl;
906         req.page_size = page_size;
907         req.page_dir = tfp_cpu_to_le_64(dma_addr);
908
909         parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
910         parms.req_data = (uint32_t *)&req;
911         parms.req_size = sizeof(req);
912         parms.resp_data = (uint32_t *)&resp;
913         parms.resp_size = sizeof(resp);
914         parms.mailbox = dev->ops->tf_dev_get_mailbox();
915
916         rc = tfp_send_msg_direct(tfp,
917                                  &parms);
918         if (rc)
919                 return rc;
920
921         *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
922
923         return rc;
924 }
925
926 int
927 tf_msg_em_mem_unrgtr(struct tf *tfp,
928                      uint16_t *ctx_id)
929 {
930         int rc;
931         struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
932         struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
933         struct tfp_send_msg_parms parms = { 0 };
934         struct tf_dev_info *dev;
935         struct tf_session *tfs;
936
937         /* Retrieve the session information */
938         rc = tf_session_get_session_internal(tfp, &tfs);
939         if (rc) {
940                 TFP_DRV_LOG(ERR,
941                             "Failed to lookup session, rc:%s\n",
942                             strerror(-rc));
943                 return rc;
944         }
945
946         /* Retrieve the device information */
947         rc = tf_session_get_device(tfs, &dev);
948         if (rc) {
949                 TFP_DRV_LOG(ERR,
950                             "Failed to lookup device, rc:%s\n",
951                             strerror(-rc));
952                 return rc;
953         }
954
955         req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
956
957         parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
958         parms.req_data = (uint32_t *)&req;
959         parms.req_size = sizeof(req);
960         parms.resp_data = (uint32_t *)&resp;
961         parms.resp_size = sizeof(resp);
962         parms.mailbox = dev->ops->tf_dev_get_mailbox();
963
964         rc = tfp_send_msg_direct(tfp,
965                                  &parms);
966         return rc;
967 }
968
969 int
970 tf_msg_em_qcaps(struct tf *tfp,
971                 int dir,
972                 struct tf_em_caps *em_caps)
973 {
974         int rc;
975         struct hwrm_tf_ext_em_qcaps_input  req = {0};
976         struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
977         uint32_t             flags;
978         struct tfp_send_msg_parms parms = { 0 };
979         struct tf_dev_info *dev;
980         struct tf_session *tfs;
981
982         /* Retrieve the session information */
983         rc = tf_session_get_session_internal(tfp, &tfs);
984         if (rc) {
985                 TFP_DRV_LOG(ERR,
986                             "%s: Failed to lookup session, rc:%s\n",
987                             tf_dir_2_str(dir),
988                             strerror(-rc));
989                 return rc;
990         }
991
992         /* Retrieve the device information */
993         rc = tf_session_get_device(tfs, &dev);
994         if (rc) {
995                 TFP_DRV_LOG(ERR,
996                             "%s: Failed to lookup device, rc:%s\n",
997                             tf_dir_2_str(dir),
998                             strerror(-rc));
999                 return rc;
1000         }
1001
1002         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
1003                  HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
1004         req.flags = tfp_cpu_to_le_32(flags);
1005
1006         parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
1007         parms.req_data = (uint32_t *)&req;
1008         parms.req_size = sizeof(req);
1009         parms.resp_data = (uint32_t *)&resp;
1010         parms.resp_size = sizeof(resp);
1011         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1012
1013         rc = tfp_send_msg_direct(tfp,
1014                                  &parms);
1015         if (rc)
1016                 return rc;
1017
1018         em_caps->supported = tfp_le_to_cpu_32(resp.supported);
1019         em_caps->max_entries_supported =
1020                 tfp_le_to_cpu_32(resp.max_entries_supported);
1021         em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
1022         em_caps->record_entry_size =
1023                 tfp_le_to_cpu_16(resp.record_entry_size);
1024         em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
1025
1026         return rc;
1027 }
1028
1029 int
1030 tf_msg_em_cfg(struct tf *tfp,
1031               uint32_t num_entries,
1032               uint16_t key0_ctx_id,
1033               uint16_t key1_ctx_id,
1034               uint16_t record_ctx_id,
1035               uint16_t efc_ctx_id,
1036               uint8_t flush_interval,
1037               int dir)
1038 {
1039         int rc;
1040         struct hwrm_tf_ext_em_cfg_input  req = {0};
1041         struct hwrm_tf_ext_em_cfg_output resp = {0};
1042         uint32_t flags;
1043         struct tfp_send_msg_parms parms = { 0 };
1044         struct tf_dev_info *dev;
1045         struct tf_session *tfs;
1046
1047         /* Retrieve the session information */
1048         rc = tf_session_get_session_internal(tfp, &tfs);
1049         if (rc) {
1050                 TFP_DRV_LOG(ERR,
1051                             "%s: Failed to lookup session, rc:%s\n",
1052                             tf_dir_2_str(dir),
1053                             strerror(-rc));
1054                 return rc;
1055         }
1056
1057         /* Retrieve the device information */
1058         rc = tf_session_get_device(tfs, &dev);
1059         if (rc) {
1060                 TFP_DRV_LOG(ERR,
1061                             "%s: Failed to lookup device, rc:%s\n",
1062                             tf_dir_2_str(dir),
1063                             strerror(-rc));
1064                 return rc;
1065         }
1066
1067         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1068                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1069         flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
1070
1071         req.flags = tfp_cpu_to_le_32(flags);
1072         req.num_entries = tfp_cpu_to_le_32(num_entries);
1073
1074         req.flush_interval = flush_interval;
1075
1076         req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
1077         req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
1078         req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
1079         req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
1080
1081         parms.tf_type = HWRM_TF_EXT_EM_CFG;
1082         parms.req_data = (uint32_t *)&req;
1083         parms.req_size = sizeof(req);
1084         parms.resp_data = (uint32_t *)&resp;
1085         parms.resp_size = sizeof(resp);
1086         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1087
1088         rc = tfp_send_msg_direct(tfp,
1089                                  &parms);
1090         return rc;
1091 }
1092
1093 int
1094 tf_msg_em_op(struct tf *tfp,
1095              int dir,
1096              uint16_t op)
1097 {
1098         int rc;
1099         struct hwrm_tf_ext_em_op_input req = {0};
1100         struct hwrm_tf_ext_em_op_output resp = {0};
1101         uint32_t flags;
1102         struct tfp_send_msg_parms parms = { 0 };
1103         struct tf_dev_info *dev;
1104         struct tf_session *tfs;
1105
1106         /* Retrieve the session information */
1107         rc = tf_session_get_session_internal(tfp, &tfs);
1108         if (rc) {
1109                 TFP_DRV_LOG(ERR,
1110                             "%s: Failed to lookup session, rc:%s\n",
1111                             tf_dir_2_str(dir),
1112                             strerror(-rc));
1113                 return rc;
1114         }
1115
1116         /* Retrieve the device information */
1117         rc = tf_session_get_device(tfs, &dev);
1118         if (rc) {
1119                 TFP_DRV_LOG(ERR,
1120                             "%s: Failed to lookup device, rc:%s\n",
1121                             tf_dir_2_str(dir),
1122                             strerror(-rc));
1123                 return rc;
1124         }
1125
1126         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1127                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1128         req.flags = tfp_cpu_to_le_32(flags);
1129         req.op = tfp_cpu_to_le_16(op);
1130
1131         parms.tf_type = HWRM_TF_EXT_EM_OP;
1132         parms.req_data = (uint32_t *)&req;
1133         parms.req_size = sizeof(req);
1134         parms.resp_data = (uint32_t *)&resp;
1135         parms.resp_size = sizeof(resp);
1136         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1137
1138         rc = tfp_send_msg_direct(tfp,
1139                                  &parms);
1140         return rc;
1141 }
1142
1143 int
1144 tf_msg_tcam_entry_set(struct tf *tfp,
1145                       struct tf_dev_info *dev,
1146                       struct tf_tcam_set_parms *parms)
1147 {
1148         int rc;
1149         struct tfp_send_msg_parms mparms = { 0 };
1150         struct hwrm_tf_tcam_set_input req = { 0 };
1151         struct hwrm_tf_tcam_set_output resp = { 0 };
1152         struct tf_msg_dma_buf buf = { 0 };
1153         uint8_t *data = NULL;
1154         int data_size = 0;
1155         uint8_t fw_session_id;
1156
1157         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1158         if (rc) {
1159                 TFP_DRV_LOG(ERR,
1160                             "%s: Unable to lookup FW id, rc:%s\n",
1161                             tf_dir_2_str(parms->dir),
1162                             strerror(-rc));
1163                 return rc;
1164         }
1165
1166         /* Populate the request */
1167         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1168         req.type = parms->hcapi_type;
1169         req.idx = tfp_cpu_to_le_16(parms->idx);
1170         if (parms->dir == TF_DIR_TX)
1171                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
1172
1173         req.key_size = parms->key_size;
1174         req.mask_offset = parms->key_size;
1175         /* Result follows after key and mask, thus multiply by 2 */
1176         req.result_offset = 2 * parms->key_size;
1177         req.result_size = parms->result_size;
1178         data_size = 2 * req.key_size + req.result_size;
1179
1180         if (data_size <= TF_PCI_BUF_SIZE_MAX) {
1181                 /* use pci buffer */
1182                 data = &req.dev_data[0];
1183         } else {
1184                 /* use dma buffer */
1185                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
1186                 rc = tf_msg_alloc_dma_buf(&buf, data_size);
1187                 if (rc)
1188                         goto cleanup;
1189                 data = buf.va_addr;
1190                 tfp_memcpy(&req.dev_data[0],
1191                            &buf.pa_addr,
1192                            sizeof(buf.pa_addr));
1193         }
1194
1195         tfp_memcpy(&data[0], parms->key, parms->key_size);
1196         tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
1197         tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
1198
1199         mparms.tf_type = HWRM_TF_TCAM_SET;
1200         mparms.req_data = (uint32_t *)&req;
1201         mparms.req_size = sizeof(req);
1202         mparms.resp_data = (uint32_t *)&resp;
1203         mparms.resp_size = sizeof(resp);
1204         mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1205
1206         rc = tfp_send_msg_direct(tfp,
1207                                  &mparms);
1208
1209 cleanup:
1210         tf_msg_free_dma_buf(&buf);
1211
1212         return rc;
1213 }
1214
1215 int
1216 tf_msg_tcam_entry_free(struct tf *tfp,
1217                        struct tf_dev_info *dev,
1218                        struct tf_tcam_free_parms *in_parms)
1219 {
1220         int rc;
1221         struct hwrm_tf_tcam_free_input req =  { 0 };
1222         struct hwrm_tf_tcam_free_output resp = { 0 };
1223         struct tfp_send_msg_parms parms = { 0 };
1224         uint8_t fw_session_id;
1225
1226         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1227         if (rc) {
1228                 TFP_DRV_LOG(ERR,
1229                             "%s: Unable to lookup FW id, rc:%s\n",
1230                             tf_dir_2_str(in_parms->dir),
1231                             strerror(-rc));
1232                 return rc;
1233         }
1234
1235         /* Populate the request */
1236         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1237         req.type = in_parms->hcapi_type;
1238         req.count = 1;
1239         req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
1240         if (in_parms->dir == TF_DIR_TX)
1241                 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
1242
1243         parms.tf_type = HWRM_TF_TCAM_FREE;
1244         parms.req_data = (uint32_t *)&req;
1245         parms.req_size = sizeof(req);
1246         parms.resp_data = (uint32_t *)&resp;
1247         parms.resp_size = sizeof(resp);
1248         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1249
1250         rc = tfp_send_msg_direct(tfp,
1251                                  &parms);
1252         return rc;
1253 }
1254
1255 int
1256 tf_msg_set_tbl_entry(struct tf *tfp,
1257                      enum tf_dir dir,
1258                      uint16_t hcapi_type,
1259                      uint16_t size,
1260                      uint8_t *data,
1261                      uint32_t index)
1262 {
1263         int rc;
1264         struct hwrm_tf_tbl_type_set_input req = { 0 };
1265         struct hwrm_tf_tbl_type_set_output resp = { 0 };
1266         struct tfp_send_msg_parms parms = { 0 };
1267         uint8_t fw_session_id;
1268         struct tf_dev_info *dev;
1269         struct tf_session *tfs;
1270
1271         /* Retrieve the session information */
1272         rc = tf_session_get_session_internal(tfp, &tfs);
1273         if (rc) {
1274                 TFP_DRV_LOG(ERR,
1275                             "%s: Failed to lookup session, rc:%s\n",
1276                             tf_dir_2_str(dir),
1277                             strerror(-rc));
1278                 return rc;
1279         }
1280
1281         /* Retrieve the device information */
1282         rc = tf_session_get_device(tfs, &dev);
1283         if (rc) {
1284                 TFP_DRV_LOG(ERR,
1285                             "%s: Failed to lookup device, rc:%s\n",
1286                             tf_dir_2_str(dir),
1287                             strerror(-rc));
1288                 return rc;
1289         }
1290
1291         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1292         if (rc) {
1293                 TFP_DRV_LOG(ERR,
1294                             "%s: Unable to lookup FW id, rc:%s\n",
1295                             tf_dir_2_str(dir),
1296                             strerror(-rc));
1297                 return rc;
1298         }
1299
1300         /* Populate the request */
1301         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1302         req.flags = tfp_cpu_to_le_16(dir);
1303         req.type = tfp_cpu_to_le_32(hcapi_type);
1304         req.size = tfp_cpu_to_le_16(size);
1305         req.index = tfp_cpu_to_le_32(index);
1306
1307         /* Check for data size conformity */
1308         if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
1309                 rc = -EINVAL;
1310                 TFP_DRV_LOG(ERR,
1311                             "%s: Invalid parameters for msg type, rc:%s\n",
1312                             tf_dir_2_str(dir),
1313                             strerror(-rc));
1314                 return rc;
1315         }
1316
1317         tfp_memcpy(&req.data,
1318                    data,
1319                    size);
1320
1321         parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1322         parms.req_data = (uint32_t *)&req;
1323         parms.req_size = sizeof(req);
1324         parms.resp_data = (uint32_t *)&resp;
1325         parms.resp_size = sizeof(resp);
1326         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1327
1328         rc = tfp_send_msg_direct(tfp,
1329                                  &parms);
1330         if (rc)
1331                 return rc;
1332
1333         return tfp_le_to_cpu_32(parms.tf_resp_code);
1334 }
1335
1336 int
1337 tf_msg_get_tbl_entry(struct tf *tfp,
1338                      enum tf_dir dir,
1339                      uint16_t hcapi_type,
1340                      uint16_t size,
1341                      uint8_t *data,
1342                      uint32_t index)
1343 {
1344         int rc;
1345         struct hwrm_tf_tbl_type_get_input req = { 0 };
1346         struct hwrm_tf_tbl_type_get_output resp = { 0 };
1347         struct tfp_send_msg_parms parms = { 0 };
1348         uint8_t fw_session_id;
1349         struct tf_dev_info *dev;
1350         struct tf_session *tfs;
1351
1352         /* Retrieve the session information */
1353         rc = tf_session_get_session_internal(tfp, &tfs);
1354         if (rc) {
1355                 TFP_DRV_LOG(ERR,
1356                             "%s: Failed to lookup session, rc:%s\n",
1357                             tf_dir_2_str(dir),
1358                             strerror(-rc));
1359                 return rc;
1360         }
1361
1362         /* Retrieve the device information */
1363         rc = tf_session_get_device(tfs, &dev);
1364         if (rc) {
1365                 TFP_DRV_LOG(ERR,
1366                             "%s: Failed to lookup device, rc:%s\n",
1367                             tf_dir_2_str(dir),
1368                             strerror(-rc));
1369                 return rc;
1370         }
1371
1372         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1373         if (rc) {
1374                 TFP_DRV_LOG(ERR,
1375                             "%s: Unable to lookup FW id, rc:%s\n",
1376                             tf_dir_2_str(dir),
1377                             strerror(-rc));
1378                 return rc;
1379         }
1380
1381         /* Populate the request */
1382         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1383         req.flags = tfp_cpu_to_le_16(dir);
1384         req.type = tfp_cpu_to_le_32(hcapi_type);
1385         req.index = tfp_cpu_to_le_32(index);
1386
1387         parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1388         parms.req_data = (uint32_t *)&req;
1389         parms.req_size = sizeof(req);
1390         parms.resp_data = (uint32_t *)&resp;
1391         parms.resp_size = sizeof(resp);
1392         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1393
1394         rc = tfp_send_msg_direct(tfp,
1395                                  &parms);
1396         if (rc)
1397                 return rc;
1398
1399         /* Verify that we got enough buffer to return the requested data */
1400         if (tfp_le_to_cpu_32(resp.size) != size)
1401                 return -EINVAL;
1402
1403         tfp_memcpy(data,
1404                    &resp.data,
1405                    size);
1406
1407         return tfp_le_to_cpu_32(parms.tf_resp_code);
1408 }
1409
1410 /* HWRM Tunneled messages */
1411
1412 int
1413 tf_msg_get_global_cfg(struct tf *tfp,
1414                       struct tf_global_cfg_parms *params)
1415 {
1416         int rc = 0;
1417         struct tfp_send_msg_parms parms = { 0 };
1418         struct hwrm_tf_global_cfg_get_input req = { 0 };
1419         struct hwrm_tf_global_cfg_get_output resp = { 0 };
1420         uint32_t flags = 0;
1421         uint8_t fw_session_id;
1422         uint16_t resp_size = 0;
1423         struct tf_dev_info *dev;
1424         struct tf_session *tfs;
1425
1426         /* Retrieve the session information */
1427         rc = tf_session_get_session_internal(tfp, &tfs);
1428         if (rc) {
1429                 TFP_DRV_LOG(ERR,
1430                             "%s: Failed to lookup session, rc:%s\n",
1431                             tf_dir_2_str(params->dir),
1432                             strerror(-rc));
1433                 return rc;
1434         }
1435
1436         /* Retrieve the device information */
1437         rc = tf_session_get_device(tfs, &dev);
1438         if (rc) {
1439                 TFP_DRV_LOG(ERR,
1440                             "%s: Failed to lookup device, rc:%s\n",
1441                             tf_dir_2_str(params->dir),
1442                             strerror(-rc));
1443                 return rc;
1444         }
1445
1446         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1447         if (rc) {
1448                 TFP_DRV_LOG(ERR,
1449                             "%s: Unable to lookup FW id, rc:%s\n",
1450                             tf_dir_2_str(params->dir),
1451                             strerror(-rc));
1452                 return rc;
1453         }
1454
1455         flags = (params->dir == TF_DIR_TX ?
1456                  HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1457                  HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1458
1459         /* Populate the request */
1460         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1461         req.flags = tfp_cpu_to_le_32(flags);
1462         req.type = tfp_cpu_to_le_32(params->type);
1463         req.offset = tfp_cpu_to_le_32(params->offset);
1464         req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1465
1466         parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1467         parms.req_data = (uint32_t *)&req;
1468         parms.req_size = sizeof(req);
1469         parms.resp_data = (uint32_t *)&resp;
1470         parms.resp_size = sizeof(resp);
1471         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1472
1473         rc = tfp_send_msg_direct(tfp, &parms);
1474         if (rc != 0)
1475                 return rc;
1476
1477         /* Verify that we got enough buffer to return the requested data */
1478         resp_size = tfp_le_to_cpu_16(resp.size);
1479         if (resp_size < params->config_sz_in_bytes)
1480                 return -EINVAL;
1481
1482         if (params->config)
1483                 tfp_memcpy(params->config,
1484                            resp.data,
1485                            resp_size);
1486         else
1487                 return -EFAULT;
1488
1489         return tfp_le_to_cpu_32(parms.tf_resp_code);
1490 }
1491
1492 int
1493 tf_msg_set_global_cfg(struct tf *tfp,
1494                       struct tf_global_cfg_parms *params)
1495 {
1496         int rc = 0;
1497         struct tfp_send_msg_parms parms = { 0 };
1498         struct hwrm_tf_global_cfg_set_input req = { 0 };
1499         struct hwrm_tf_global_cfg_set_output resp = { 0 };
1500         uint32_t flags = 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_internal(tfp, &tfs);
1507         if (rc) {
1508                 TFP_DRV_LOG(ERR,
1509                             "%s: Failed to lookup session, rc:%s\n",
1510                             tf_dir_2_str(params->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(params->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(params->dir),
1530                             strerror(-rc));
1531                 return rc;
1532         }
1533
1534         flags = (params->dir == TF_DIR_TX ?
1535                  HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
1536                  HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
1537
1538         /* Populate the request */
1539         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1540         req.flags = tfp_cpu_to_le_32(flags);
1541         req.type = tfp_cpu_to_le_32(params->type);
1542         req.offset = tfp_cpu_to_le_32(params->offset);
1543
1544         /* Check for data size conformity */
1545         if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
1546                 rc = -EINVAL;
1547                 TFP_DRV_LOG(ERR,
1548                             "%s: Invalid parameters for msg type, rc:%s\n",
1549                             tf_dir_2_str(params->dir),
1550                             strerror(-rc));
1551                 return rc;
1552         }
1553
1554         tfp_memcpy(req.data, params->config,
1555                    params->config_sz_in_bytes);
1556
1557         /* Only set mask if pointer is provided
1558          */
1559         if (params->config_mask) {
1560                 tfp_memcpy(req.mask,
1561                            params->config_mask,
1562                            params->config_sz_in_bytes);
1563         }
1564
1565         req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1566
1567         parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
1568         parms.req_data = (uint32_t *)&req;
1569         parms.req_size = sizeof(req);
1570         parms.resp_data = (uint32_t *)&resp;
1571         parms.resp_size = sizeof(resp);
1572         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1573
1574         rc = tfp_send_msg_direct(tfp, &parms);
1575
1576         if (rc != 0)
1577                 return rc;
1578
1579         return tfp_le_to_cpu_32(parms.tf_resp_code);
1580 }
1581
1582 int
1583 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
1584                           enum tf_dir dir,
1585                           uint16_t hcapi_type,
1586                           uint32_t starting_idx,
1587                           uint16_t num_entries,
1588                           uint16_t entry_sz_in_bytes,
1589                           uint64_t physical_mem_addr)
1590 {
1591         int rc;
1592         struct tfp_send_msg_parms parms = { 0 };
1593         struct tf_tbl_type_bulk_get_input req = { 0 };
1594         struct tf_tbl_type_bulk_get_output resp = { 0 };
1595         int data_size = 0;
1596         uint8_t fw_session_id;
1597         struct tf_dev_info *dev;
1598         struct tf_session *tfs;
1599
1600         /* Retrieve the session information */
1601         rc = tf_session_get_session(tfp, &tfs);
1602         if (rc) {
1603                 TFP_DRV_LOG(ERR,
1604                             "%s: Failed to lookup session, rc:%s\n",
1605                             tf_dir_2_str(dir),
1606                             strerror(-rc));
1607                 return rc;
1608         }
1609
1610         /* Retrieve the device information */
1611         rc = tf_session_get_device(tfs, &dev);
1612         if (rc) {
1613                 TFP_DRV_LOG(ERR,
1614                             "%s: Failed to lookup device, rc:%s\n",
1615                             tf_dir_2_str(dir),
1616                             strerror(-rc));
1617                 return rc;
1618         }
1619
1620         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1621         if (rc) {
1622                 TFP_DRV_LOG(ERR,
1623                             "%s: Unable to lookup FW id, rc:%s\n",
1624                             tf_dir_2_str(dir),
1625                             strerror(-rc));
1626                 return rc;
1627         }
1628
1629         /* Populate the request */
1630         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1631         req.flags = tfp_cpu_to_le_16(dir);
1632         req.type = tfp_cpu_to_le_32(hcapi_type);
1633         req.start_index = tfp_cpu_to_le_32(starting_idx);
1634         req.num_entries = tfp_cpu_to_le_32(num_entries);
1635
1636         data_size = num_entries * entry_sz_in_bytes;
1637
1638         req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1639
1640         MSG_PREP(parms,
1641                  dev->ops->tf_dev_get_mailbox(),
1642                  HWRM_TF,
1643                  HWRM_TFT_TBL_TYPE_BULK_GET,
1644                  req,
1645                  resp);
1646
1647         rc = tfp_send_msg_tunneled(tfp, &parms);
1648         if (rc)
1649                 return rc;
1650
1651         /* Verify that we got enough buffer to return the requested data */
1652         if (tfp_le_to_cpu_32(resp.size) != data_size)
1653                 return -EINVAL;
1654
1655         return tfp_le_to_cpu_32(parms.tf_resp_code);
1656 }
1657
1658 int
1659 tf_msg_get_if_tbl_entry(struct tf *tfp,
1660                         struct tf_if_tbl_get_parms *params)
1661 {
1662         int rc = 0;
1663         struct tfp_send_msg_parms parms = { 0 };
1664         struct hwrm_tf_if_tbl_get_input req = { 0 };
1665         struct hwrm_tf_if_tbl_get_output resp = { 0 };
1666         uint32_t flags = 0;
1667         struct tf_dev_info *dev;
1668         struct tf_session *tfs;
1669
1670         /* Retrieve the session information */
1671         rc = tf_session_get_session(tfp, &tfs);
1672         if (rc) {
1673                 TFP_DRV_LOG(ERR,
1674                             "%s: Failed to lookup session, rc:%s\n",
1675                             tf_dir_2_str(params->dir),
1676                             strerror(-rc));
1677                 return rc;
1678         }
1679
1680         /* Retrieve the device information */
1681         rc = tf_session_get_device(tfs, &dev);
1682         if (rc) {
1683                 TFP_DRV_LOG(ERR,
1684                             "%s: Failed to lookup device, rc:%s\n",
1685                             tf_dir_2_str(params->dir),
1686                             strerror(-rc));
1687                 return rc;
1688         }
1689
1690         flags = (params->dir == TF_DIR_TX ?
1691                 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
1692                 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
1693
1694         /* Populate the request */
1695         req.fw_session_id =
1696                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1697         req.flags = flags;
1698         req.type = params->hcapi_type;
1699         req.index = tfp_cpu_to_le_16(params->idx);
1700         req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1701
1702         parms.tf_type = HWRM_TF_IF_TBL_GET;
1703         parms.req_data = (uint32_t *)&req;
1704         parms.req_size = sizeof(req);
1705         parms.resp_data = (uint32_t *)&resp;
1706         parms.resp_size = sizeof(resp);
1707         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1708
1709         rc = tfp_send_msg_direct(tfp, &parms);
1710
1711         if (rc != 0)
1712                 return rc;
1713
1714         if (parms.tf_resp_code != 0)
1715                 return tfp_le_to_cpu_32(parms.tf_resp_code);
1716
1717         tfp_memcpy(params->data, resp.data, req.size);
1718
1719         return tfp_le_to_cpu_32(parms.tf_resp_code);
1720 }
1721
1722 int
1723 tf_msg_set_if_tbl_entry(struct tf *tfp,
1724                         struct tf_if_tbl_set_parms *params)
1725 {
1726         int rc = 0;
1727         struct tfp_send_msg_parms parms = { 0 };
1728         struct hwrm_tf_if_tbl_set_input req = { 0 };
1729         struct hwrm_tf_if_tbl_get_output resp = { 0 };
1730         uint32_t flags = 0;
1731         struct tf_dev_info *dev;
1732         struct tf_session *tfs;
1733
1734         /* Retrieve the session information */
1735         rc = tf_session_get_session(tfp, &tfs);
1736         if (rc) {
1737                 TFP_DRV_LOG(ERR,
1738                             "%s: Failed to lookup session, rc:%s\n",
1739                             tf_dir_2_str(params->dir),
1740                             strerror(-rc));
1741                 return rc;
1742         }
1743
1744         /* Retrieve the device information */
1745         rc = tf_session_get_device(tfs, &dev);
1746         if (rc)
1747                 return rc;
1748
1749         flags = (params->dir == TF_DIR_TX ?
1750                 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1751                 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1752
1753         /* Populate the request */
1754         req.fw_session_id =
1755                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1756         req.flags = flags;
1757         req.type = params->hcapi_type;
1758         req.index = tfp_cpu_to_le_32(params->idx);
1759         req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1760         tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1761
1762         parms.tf_type = HWRM_TF_IF_TBL_SET;
1763         parms.req_data = (uint32_t *)&req;
1764         parms.req_size = sizeof(req);
1765         parms.resp_data = (uint32_t *)&resp;
1766         parms.resp_size = sizeof(resp);
1767         parms.mailbox = dev->ops->tf_dev_get_mailbox();
1768
1769         rc = tfp_send_msg_direct(tfp, &parms);
1770
1771         if (rc != 0)
1772                 return rc;
1773
1774         return tfp_le_to_cpu_32(parms.tf_resp_code);
1775 }