7fffb6baf824f3c0375d0412da20eaf106b3635c
[dpdk.git] / drivers / net / bnxt / tf_core / tf_msg.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 Broadcom
3  * All rights reserved.
4  */
5
6 #include <inttypes.h>
7 #include <stdbool.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "tf_msg_common.h"
12 #include "tf_device.h"
13 #include "tf_msg.h"
14 #include "tf_util.h"
15 #include "tf_common.h"
16 #include "tf_session.h"
17 #include "tfp.h"
18 #include "hwrm_tf.h"
19 #include "tf_em.h"
20
21 /**
22  * This is the MAX data we can transport across regular HWRM
23  */
24 #define TF_PCI_BUF_SIZE_MAX 88
25
26 /**
27  * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
28  */
29 struct tf_msg_dma_buf {
30         void *va_addr;
31         uint64_t pa_addr;
32 };
33
34 /**
35  * Allocates a DMA buffer that can be used for message transfer.
36  *
37  * [in] buf
38  *   Pointer to DMA buffer structure
39  *
40  * [in] size
41  *   Requested size of the buffer in bytes
42  *
43  * Returns:
44  *    0      - Success
45  *   -ENOMEM - Unable to allocate buffer, no memory
46  */
47 static int
48 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
49 {
50         struct tfp_calloc_parms alloc_parms;
51         int rc;
52
53         /* Allocate session */
54         alloc_parms.nitems = 1;
55         alloc_parms.size = size;
56         alloc_parms.alignment = 4096;
57         rc = tfp_calloc(&alloc_parms);
58         if (rc)
59                 return -ENOMEM;
60
61         buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
62         buf->va_addr = alloc_parms.mem_va;
63
64         return 0;
65 }
66
67 /**
68  * Free's a previous allocated DMA buffer.
69  *
70  * [in] buf
71  *   Pointer to DMA buffer structure
72  */
73 static void
74 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
75 {
76         tfp_free(buf->va_addr);
77 }
78
79 /* HWRM Direct messages */
80
81 int
82 tf_msg_session_open(struct tf *tfp,
83                     char *ctrl_chan_name,
84                     uint8_t *fw_session_id)
85 {
86         int rc;
87         struct hwrm_tf_session_open_input req = { 0 };
88         struct hwrm_tf_session_open_output resp = { 0 };
89         struct tfp_send_msg_parms parms = { 0 };
90
91         /* Populate the request */
92         tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
93
94         parms.tf_type = HWRM_TF_SESSION_OPEN;
95         parms.req_data = (uint32_t *)&req;
96         parms.req_size = sizeof(req);
97         parms.resp_data = (uint32_t *)&resp;
98         parms.resp_size = sizeof(resp);
99         parms.mailbox = TF_KONG_MB;
100
101         rc = tfp_send_msg_direct(tfp,
102                                  &parms);
103         if (rc)
104                 return rc;
105
106         *fw_session_id = resp.fw_session_id;
107
108         return rc;
109 }
110
111 int
112 tf_msg_session_attach(struct tf *tfp __rte_unused,
113                       char *ctrl_chan_name __rte_unused,
114                       uint8_t tf_fw_session_id __rte_unused)
115 {
116         return -1;
117 }
118
119 int
120 tf_msg_session_close(struct tf *tfp)
121 {
122         int rc;
123         struct hwrm_tf_session_close_input req = { 0 };
124         struct hwrm_tf_session_close_output resp = { 0 };
125         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
126         struct tfp_send_msg_parms parms = { 0 };
127
128         /* Populate the request */
129         req.fw_session_id =
130                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
131
132         parms.tf_type = HWRM_TF_SESSION_CLOSE;
133         parms.req_data = (uint32_t *)&req;
134         parms.req_size = sizeof(req);
135         parms.resp_data = (uint32_t *)&resp;
136         parms.resp_size = sizeof(resp);
137         parms.mailbox = TF_KONG_MB;
138
139         rc = tfp_send_msg_direct(tfp,
140                                  &parms);
141         return rc;
142 }
143
144 int
145 tf_msg_session_qcfg(struct tf *tfp)
146 {
147         int rc;
148         struct hwrm_tf_session_qcfg_input req = { 0 };
149         struct hwrm_tf_session_qcfg_output resp = { 0 };
150         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
151         struct tfp_send_msg_parms parms = { 0 };
152
153         /* Populate the request */
154         req.fw_session_id =
155                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
156
157         parms.tf_type = HWRM_TF_SESSION_QCFG,
158         parms.req_data = (uint32_t *)&req;
159         parms.req_size = sizeof(req);
160         parms.resp_data = (uint32_t *)&resp;
161         parms.resp_size = sizeof(resp);
162         parms.mailbox = TF_KONG_MB;
163
164         rc = tfp_send_msg_direct(tfp,
165                                  &parms);
166         return rc;
167 }
168
169 int
170 tf_msg_session_resc_qcaps(struct tf *tfp,
171                           enum tf_dir dir,
172                           uint16_t size,
173                           struct tf_rm_resc_req_entry *query,
174                           enum tf_rm_resc_resv_strategy *resv_strategy)
175 {
176         int rc;
177         int i;
178         struct tfp_send_msg_parms parms = { 0 };
179         struct hwrm_tf_session_resc_qcaps_input req = { 0 };
180         struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
181         uint8_t fw_session_id;
182         struct tf_msg_dma_buf qcaps_buf = { 0 };
183         struct tf_rm_resc_req_entry *data;
184         int dma_size;
185
186         TF_CHECK_PARMS3(tfp, query, resv_strategy);
187
188         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
189         if (rc) {
190                 TFP_DRV_LOG(ERR,
191                             "%s: Unable to lookup FW id, rc:%s\n",
192                             tf_dir_2_str(dir),
193                             strerror(-rc));
194                 return rc;
195         }
196
197         /* Prepare DMA buffer */
198         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
199         rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
200         if (rc)
201                 return rc;
202
203         /* Populate the request */
204         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
205         req.flags = tfp_cpu_to_le_16(dir);
206         req.qcaps_size = size;
207         req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
208
209         parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
210         parms.req_data = (uint32_t *)&req;
211         parms.req_size = sizeof(req);
212         parms.resp_data = (uint32_t *)&resp;
213         parms.resp_size = sizeof(resp);
214         parms.mailbox = TF_KONG_MB;
215
216         rc = tfp_send_msg_direct(tfp, &parms);
217         if (rc)
218                 return rc;
219
220         /* Process the response
221          * Should always get expected number of entries
222          */
223         if (tfp_le_to_cpu_32(resp.size) != size) {
224                 TFP_DRV_LOG(ERR,
225                             "%s: QCAPS message size error, rc:%s\n",
226                             tf_dir_2_str(dir),
227                             strerror(-EINVAL));
228                 return -EINVAL;
229         }
230
231         printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
232
233         /* Post process the response */
234         data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
235
236         printf("\nQCAPS\n");
237         for (i = 0; i < size; i++) {
238                 query[i].type = tfp_le_to_cpu_32(data[i].type);
239                 query[i].min = tfp_le_to_cpu_16(data[i].min);
240                 query[i].max = tfp_le_to_cpu_16(data[i].max);
241
242                 printf("type: %d(0x%x) %d %d\n",
243                        query[i].type,
244                        query[i].type,
245                        query[i].min,
246                        query[i].max);
247
248         }
249
250         *resv_strategy = resp.flags &
251               HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
252
253         tf_msg_free_dma_buf(&qcaps_buf);
254
255         return rc;
256 }
257
258 int
259 tf_msg_session_resc_alloc(struct tf *tfp,
260                           enum tf_dir dir,
261                           uint16_t size,
262                           struct tf_rm_resc_req_entry *request,
263                           struct tf_rm_resc_entry *resv)
264 {
265         int rc;
266         int i;
267         struct tfp_send_msg_parms parms = { 0 };
268         struct hwrm_tf_session_resc_alloc_input req = { 0 };
269         struct hwrm_tf_session_resc_alloc_output resp = { 0 };
270         uint8_t fw_session_id;
271         struct tf_msg_dma_buf req_buf = { 0 };
272         struct tf_msg_dma_buf resv_buf = { 0 };
273         struct tf_rm_resc_req_entry *req_data;
274         struct tf_rm_resc_entry *resv_data;
275         int dma_size;
276
277         TF_CHECK_PARMS3(tfp, request, resv);
278
279         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
280         if (rc) {
281                 TFP_DRV_LOG(ERR,
282                             "%s: Unable to lookup FW id, rc:%s\n",
283                             tf_dir_2_str(dir),
284                             strerror(-rc));
285                 return rc;
286         }
287
288         /* Prepare DMA buffers */
289         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
290         rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
291         if (rc)
292                 return rc;
293
294         dma_size = size * sizeof(struct tf_rm_resc_entry);
295         rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
296         if (rc)
297                 return rc;
298
299         /* Populate the request */
300         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
301         req.flags = tfp_cpu_to_le_16(dir);
302         req.req_size = size;
303
304         req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
305         for (i = 0; i < size; i++) {
306                 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
307                 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
308                 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
309         }
310
311         req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
312         req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
313
314         parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
315         parms.req_data = (uint32_t *)&req;
316         parms.req_size = sizeof(req);
317         parms.resp_data = (uint32_t *)&resp;
318         parms.resp_size = sizeof(resp);
319         parms.mailbox = TF_KONG_MB;
320
321         rc = tfp_send_msg_direct(tfp, &parms);
322         if (rc)
323                 return rc;
324
325         /* Process the response
326          * Should always get expected number of entries
327          */
328         if (tfp_le_to_cpu_32(resp.size) != size) {
329                 TFP_DRV_LOG(ERR,
330                             "%s: Alloc message size error, rc:%s\n",
331                             tf_dir_2_str(dir),
332                             strerror(-EINVAL));
333                 return -EINVAL;
334         }
335
336         printf("\nRESV\n");
337         printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
338
339         /* Post process the response */
340         resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
341         for (i = 0; i < size; i++) {
342                 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
343                 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
344                 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
345
346                 printf("%d type: %d(0x%x) %d %d\n",
347                        i,
348                        resv[i].type,
349                        resv[i].type,
350                        resv[i].start,
351                        resv[i].stride);
352         }
353
354         tf_msg_free_dma_buf(&req_buf);
355         tf_msg_free_dma_buf(&resv_buf);
356
357         return rc;
358 }
359
360 int
361 tf_msg_session_resc_flush(struct tf *tfp,
362                           enum tf_dir dir,
363                           uint16_t size,
364                           struct tf_rm_resc_entry *resv)
365 {
366         int rc;
367         int i;
368         struct tfp_send_msg_parms parms = { 0 };
369         struct hwrm_tf_session_resc_flush_input req = { 0 };
370         struct hwrm_tf_session_resc_flush_output resp = { 0 };
371         uint8_t fw_session_id;
372         struct tf_msg_dma_buf resv_buf = { 0 };
373         struct tf_rm_resc_entry *resv_data;
374         int dma_size;
375
376         TF_CHECK_PARMS2(tfp, resv);
377
378         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
379         if (rc) {
380                 TFP_DRV_LOG(ERR,
381                             "%s: Unable to lookup FW id, rc:%s\n",
382                             tf_dir_2_str(dir),
383                             strerror(-rc));
384                 return rc;
385         }
386
387         /* Prepare DMA buffers */
388         dma_size = size * sizeof(struct tf_rm_resc_entry);
389         rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
390         if (rc)
391                 return rc;
392
393         /* Populate the request */
394         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
395         req.flags = tfp_cpu_to_le_16(dir);
396         req.flush_size = size;
397
398         resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
399         for (i = 0; i < size; i++) {
400                 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
401                 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
402                 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
403         }
404
405         req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
406
407         parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
408         parms.req_data = (uint32_t *)&req;
409         parms.req_size = sizeof(req);
410         parms.resp_data = (uint32_t *)&resp;
411         parms.resp_size = sizeof(resp);
412         parms.mailbox = TF_KONG_MB;
413
414         rc = tfp_send_msg_direct(tfp, &parms);
415         if (rc)
416                 return rc;
417
418         tf_msg_free_dma_buf(&resv_buf);
419
420         return rc;
421 }
422
423 int
424 tf_msg_insert_em_internal_entry(struct tf *tfp,
425                                 struct tf_insert_em_entry_parms *em_parms,
426                                 uint16_t *rptr_index,
427                                 uint8_t *rptr_entry,
428                                 uint8_t *num_of_entries)
429 {
430         int rc;
431         struct tfp_send_msg_parms parms = { 0 };
432         struct hwrm_tf_em_insert_input req = { 0 };
433         struct hwrm_tf_em_insert_output resp = { 0 };
434         struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
435         struct tf_em_64b_entry *em_result =
436                 (struct tf_em_64b_entry *)em_parms->em_record;
437         uint32_t flags;
438
439         req.fw_session_id =
440                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
441         tfp_memcpy(req.em_key,
442                    em_parms->key,
443                    ((em_parms->key_sz_in_bits + 7) / 8));
444
445         flags = (em_parms->dir == TF_DIR_TX ?
446                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
447                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
448         req.flags = tfp_cpu_to_le_16(flags);
449         req.strength = (em_result->hdr.word1 &
450                         CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
451                         CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
452         req.em_key_bitlen = em_parms->key_sz_in_bits;
453         req.action_ptr = em_result->hdr.pointer;
454         req.em_record_idx = *rptr_index;
455
456         parms.tf_type = HWRM_TF_EM_INSERT;
457         parms.req_data = (uint32_t *)&req;
458         parms.req_size = sizeof(req);
459         parms.resp_data = (uint32_t *)&resp;
460         parms.resp_size = sizeof(resp);
461         parms.mailbox = TF_KONG_MB;
462
463         rc = tfp_send_msg_direct(tfp,
464                                  &parms);
465         if (rc)
466                 return rc;
467
468         *rptr_entry = resp.rptr_entry;
469         *rptr_index = resp.rptr_index;
470         *num_of_entries = resp.num_of_entries;
471
472         return 0;
473 }
474
475 int
476 tf_msg_delete_em_entry(struct tf *tfp,
477                        struct tf_delete_em_entry_parms *em_parms)
478 {
479         int rc;
480         struct tfp_send_msg_parms parms = { 0 };
481         struct hwrm_tf_em_delete_input req = { 0 };
482         struct hwrm_tf_em_delete_output resp = { 0 };
483         uint32_t flags;
484         struct tf_session *tfs =
485                 (struct tf_session *)(tfp->session->core_data);
486
487         req.fw_session_id =
488                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
489
490         flags = (em_parms->dir == TF_DIR_TX ?
491                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
492                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
493         req.flags = tfp_cpu_to_le_16(flags);
494         req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
495
496         parms.tf_type = HWRM_TF_EM_DELETE;
497         parms.req_data = (uint32_t *)&req;
498         parms.req_size = sizeof(req);
499         parms.resp_data = (uint32_t *)&resp;
500         parms.resp_size = sizeof(resp);
501         parms.mailbox = TF_KONG_MB;
502
503         rc = tfp_send_msg_direct(tfp,
504                                  &parms);
505         if (rc)
506                 return rc;
507
508         em_parms->index = tfp_le_to_cpu_16(resp.em_index);
509
510         return 0;
511 }
512
513 int
514 tf_msg_em_mem_rgtr(struct tf *tfp,
515                    int page_lvl,
516                    int page_size,
517                    uint64_t dma_addr,
518                    uint16_t *ctx_id)
519 {
520         int rc;
521         struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
522         struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
523         struct tfp_send_msg_parms parms = { 0 };
524
525         req.page_level = page_lvl;
526         req.page_size = page_size;
527         req.page_dir = tfp_cpu_to_le_64(dma_addr);
528
529         parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
530         parms.req_data = (uint32_t *)&req;
531         parms.req_size = sizeof(req);
532         parms.resp_data = (uint32_t *)&resp;
533         parms.resp_size = sizeof(resp);
534         parms.mailbox = TF_KONG_MB;
535
536         rc = tfp_send_msg_direct(tfp,
537                                  &parms);
538         if (rc)
539                 return rc;
540
541         *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
542
543         return rc;
544 }
545
546 int
547 tf_msg_em_mem_unrgtr(struct tf *tfp,
548                      uint16_t *ctx_id)
549 {
550         int rc;
551         struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
552         struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
553         struct tfp_send_msg_parms parms = { 0 };
554
555         req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
556
557         parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
558         parms.req_data = (uint32_t *)&req;
559         parms.req_size = sizeof(req);
560         parms.resp_data = (uint32_t *)&resp;
561         parms.resp_size = sizeof(resp);
562         parms.mailbox = TF_KONG_MB;
563
564         rc = tfp_send_msg_direct(tfp,
565                                  &parms);
566         return rc;
567 }
568
569 int
570 tf_msg_em_qcaps(struct tf *tfp,
571                 int dir,
572                 struct tf_em_caps *em_caps)
573 {
574         int rc;
575         struct hwrm_tf_ext_em_qcaps_input  req = {0};
576         struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
577         uint32_t             flags;
578         struct tfp_send_msg_parms parms = { 0 };
579
580         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
581                  HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
582         req.flags = tfp_cpu_to_le_32(flags);
583
584         parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
585         parms.req_data = (uint32_t *)&req;
586         parms.req_size = sizeof(req);
587         parms.resp_data = (uint32_t *)&resp;
588         parms.resp_size = sizeof(resp);
589         parms.mailbox = TF_KONG_MB;
590
591         rc = tfp_send_msg_direct(tfp,
592                                  &parms);
593         if (rc)
594                 return rc;
595
596         em_caps->supported = tfp_le_to_cpu_32(resp.supported);
597         em_caps->max_entries_supported =
598                 tfp_le_to_cpu_32(resp.max_entries_supported);
599         em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
600         em_caps->record_entry_size =
601                 tfp_le_to_cpu_16(resp.record_entry_size);
602         em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
603
604         return rc;
605 }
606
607 int
608 tf_msg_em_cfg(struct tf *tfp,
609               uint32_t num_entries,
610               uint16_t key0_ctx_id,
611               uint16_t key1_ctx_id,
612               uint16_t record_ctx_id,
613               uint16_t efc_ctx_id,
614               uint8_t flush_interval,
615               int dir)
616 {
617         int rc;
618         struct hwrm_tf_ext_em_cfg_input  req = {0};
619         struct hwrm_tf_ext_em_cfg_output resp = {0};
620         uint32_t flags;
621         struct tfp_send_msg_parms parms = { 0 };
622
623         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
624                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
625         flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
626
627         req.flags = tfp_cpu_to_le_32(flags);
628         req.num_entries = tfp_cpu_to_le_32(num_entries);
629
630         req.flush_interval = flush_interval;
631
632         req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
633         req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
634         req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
635         req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
636
637         parms.tf_type = HWRM_TF_EXT_EM_CFG;
638         parms.req_data = (uint32_t *)&req;
639         parms.req_size = sizeof(req);
640         parms.resp_data = (uint32_t *)&resp;
641         parms.resp_size = sizeof(resp);
642         parms.mailbox = TF_KONG_MB;
643
644         rc = tfp_send_msg_direct(tfp,
645                                  &parms);
646         return rc;
647 }
648
649 int
650 tf_msg_em_op(struct tf *tfp,
651              int dir,
652              uint16_t op)
653 {
654         int rc;
655         struct hwrm_tf_ext_em_op_input req = {0};
656         struct hwrm_tf_ext_em_op_output resp = {0};
657         uint32_t flags;
658         struct tfp_send_msg_parms parms = { 0 };
659
660         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
661                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
662         req.flags = tfp_cpu_to_le_32(flags);
663         req.op = tfp_cpu_to_le_16(op);
664
665         parms.tf_type = HWRM_TF_EXT_EM_OP;
666         parms.req_data = (uint32_t *)&req;
667         parms.req_size = sizeof(req);
668         parms.resp_data = (uint32_t *)&resp;
669         parms.resp_size = sizeof(resp);
670         parms.mailbox = TF_KONG_MB;
671
672         rc = tfp_send_msg_direct(tfp,
673                                  &parms);
674         return rc;
675 }
676
677 int
678 tf_msg_tcam_entry_set(struct tf *tfp,
679                       struct tf_tcam_set_parms *parms)
680 {
681         int rc;
682         struct tfp_send_msg_parms mparms = { 0 };
683         struct hwrm_tf_tcam_set_input req = { 0 };
684         struct hwrm_tf_tcam_set_output resp = { 0 };
685         struct tf_msg_dma_buf buf = { 0 };
686         uint8_t *data = NULL;
687         int data_size = 0;
688
689         req.type = parms->hcapi_type;
690         req.idx = tfp_cpu_to_le_16(parms->idx);
691         if (parms->dir == TF_DIR_TX)
692                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
693
694         req.key_size = parms->key_size;
695         req.mask_offset = parms->key_size;
696         /* Result follows after key and mask, thus multiply by 2 */
697         req.result_offset = 2 * parms->key_size;
698         req.result_size = parms->result_size;
699         data_size = 2 * req.key_size + req.result_size;
700
701         if (data_size <= TF_PCI_BUF_SIZE_MAX) {
702                 /* use pci buffer */
703                 data = &req.dev_data[0];
704         } else {
705                 /* use dma buffer */
706                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
707                 rc = tf_msg_alloc_dma_buf(&buf, data_size);
708                 if (rc)
709                         goto cleanup;
710                 data = buf.va_addr;
711                 tfp_memcpy(&req.dev_data[0],
712                            &buf.pa_addr,
713                            sizeof(buf.pa_addr));
714         }
715
716         tfp_memcpy(&data[0], parms->key, parms->key_size);
717         tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
718         tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
719
720         mparms.tf_type = HWRM_TF_TCAM_SET;
721         mparms.req_data = (uint32_t *)&req;
722         mparms.req_size = sizeof(req);
723         mparms.resp_data = (uint32_t *)&resp;
724         mparms.resp_size = sizeof(resp);
725         mparms.mailbox = TF_KONG_MB;
726
727         rc = tfp_send_msg_direct(tfp,
728                                  &mparms);
729         if (rc)
730                 goto cleanup;
731
732 cleanup:
733         tf_msg_free_dma_buf(&buf);
734
735         return rc;
736 }
737
738 int
739 tf_msg_tcam_entry_free(struct tf *tfp,
740                        struct tf_tcam_free_parms *in_parms)
741 {
742         int rc;
743         struct hwrm_tf_tcam_free_input req =  { 0 };
744         struct hwrm_tf_tcam_free_output resp = { 0 };
745         struct tfp_send_msg_parms parms = { 0 };
746
747         req.type = in_parms->hcapi_type;
748         req.count = 1;
749         req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
750         if (in_parms->dir == TF_DIR_TX)
751                 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
752
753         parms.tf_type = HWRM_TF_TCAM_FREE;
754         parms.req_data = (uint32_t *)&req;
755         parms.req_size = sizeof(req);
756         parms.resp_data = (uint32_t *)&resp;
757         parms.resp_size = sizeof(resp);
758         parms.mailbox = TF_KONG_MB;
759
760         rc = tfp_send_msg_direct(tfp,
761                                  &parms);
762         return rc;
763 }
764
765 int
766 tf_msg_set_tbl_entry(struct tf *tfp,
767                      enum tf_dir dir,
768                      uint16_t hcapi_type,
769                      uint16_t size,
770                      uint8_t *data,
771                      uint32_t index)
772 {
773         int rc;
774         struct hwrm_tf_tbl_type_set_input req = { 0 };
775         struct hwrm_tf_tbl_type_set_output resp = { 0 };
776         struct tfp_send_msg_parms parms = { 0 };
777         struct tf_session *tfs;
778
779         /* Retrieve the session information */
780         rc = tf_session_get_session(tfp, &tfs);
781         if (rc) {
782                 TFP_DRV_LOG(ERR,
783                             "%s: Failed to lookup session, rc:%s\n",
784                             tf_dir_2_str(dir),
785                             strerror(-rc));
786                 return rc;
787         }
788
789         /* Populate the request */
790         req.fw_session_id =
791                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
792         req.flags = tfp_cpu_to_le_16(dir);
793         req.type = tfp_cpu_to_le_32(hcapi_type);
794         req.size = tfp_cpu_to_le_16(size);
795         req.index = tfp_cpu_to_le_32(index);
796
797         tfp_memcpy(&req.data,
798                    data,
799                    size);
800
801         parms.tf_type = HWRM_TF_TBL_TYPE_SET;
802         parms.req_data = (uint32_t *)&req;
803         parms.req_size = sizeof(req);
804         parms.resp_data = (uint32_t *)&resp;
805         parms.resp_size = sizeof(resp);
806         parms.mailbox = TF_KONG_MB;
807
808         rc = tfp_send_msg_direct(tfp,
809                                  &parms);
810         if (rc)
811                 return rc;
812
813         return tfp_le_to_cpu_32(parms.tf_resp_code);
814 }
815
816 int
817 tf_msg_get_tbl_entry(struct tf *tfp,
818                      enum tf_dir dir,
819                      uint16_t hcapi_type,
820                      uint16_t size,
821                      uint8_t *data,
822                      uint32_t index)
823 {
824         int rc;
825         struct hwrm_tf_tbl_type_get_input req = { 0 };
826         struct hwrm_tf_tbl_type_get_output resp = { 0 };
827         struct tfp_send_msg_parms parms = { 0 };
828         struct tf_session *tfs;
829
830         /* Retrieve the session information */
831         rc = tf_session_get_session(tfp, &tfs);
832         if (rc) {
833                 TFP_DRV_LOG(ERR,
834                             "%s: Failed to lookup session, rc:%s\n",
835                             tf_dir_2_str(dir),
836                             strerror(-rc));
837                 return rc;
838         }
839
840         /* Populate the request */
841         req.fw_session_id =
842                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
843         req.flags = tfp_cpu_to_le_16(dir);
844         req.type = tfp_cpu_to_le_32(hcapi_type);
845         req.index = tfp_cpu_to_le_32(index);
846
847         parms.tf_type = HWRM_TF_TBL_TYPE_GET;
848         parms.req_data = (uint32_t *)&req;
849         parms.req_size = sizeof(req);
850         parms.resp_data = (uint32_t *)&resp;
851         parms.resp_size = sizeof(resp);
852         parms.mailbox = TF_KONG_MB;
853
854         rc = tfp_send_msg_direct(tfp,
855                                  &parms);
856         if (rc)
857                 return rc;
858
859         /* Verify that we got enough buffer to return the requested data */
860         if (tfp_le_to_cpu_32(resp.size) != size)
861                 return -EINVAL;
862
863         tfp_memcpy(data,
864                    &resp.data,
865                    size);
866
867         return tfp_le_to_cpu_32(parms.tf_resp_code);
868 }
869
870 /* HWRM Tunneled messages */
871
872 int
873 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
874                           enum tf_dir dir,
875                           uint16_t hcapi_type,
876                           uint32_t starting_idx,
877                           uint16_t num_entries,
878                           uint16_t entry_sz_in_bytes,
879                           uint64_t physical_mem_addr)
880 {
881         int rc;
882         struct tfp_send_msg_parms parms = { 0 };
883         struct tf_tbl_type_bulk_get_input req = { 0 };
884         struct tf_tbl_type_bulk_get_output resp = { 0 };
885         struct tf_session *tfs;
886         int data_size = 0;
887
888         /* Retrieve the session information */
889         rc = tf_session_get_session(tfp, &tfs);
890         if (rc) {
891                 TFP_DRV_LOG(ERR,
892                             "%s: Failed to lookup session, rc:%s\n",
893                             tf_dir_2_str(dir),
894                             strerror(-rc));
895                 return rc;
896         }
897
898         /* Populate the request */
899         req.fw_session_id =
900                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
901         req.flags = tfp_cpu_to_le_16(dir);
902         req.type = tfp_cpu_to_le_32(hcapi_type);
903         req.start_index = tfp_cpu_to_le_32(starting_idx);
904         req.num_entries = tfp_cpu_to_le_32(num_entries);
905
906         data_size = num_entries * entry_sz_in_bytes;
907
908         req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
909
910         MSG_PREP(parms,
911                  TF_KONG_MB,
912                  HWRM_TF,
913                  HWRM_TFT_TBL_TYPE_BULK_GET,
914                  req,
915                  resp);
916
917         rc = tfp_send_msg_tunneled(tfp, &parms);
918         if (rc)
919                 return rc;
920
921         /* Verify that we got enough buffer to return the requested data */
922         if (tfp_le_to_cpu_32(resp.size) != data_size)
923                 return -EINVAL;
924
925         return tfp_le_to_cpu_32(parms.tf_resp_code);
926 }