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