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