f20a5113bfdc82918658e5a41cd45421381d8010
[dpdk.git] / drivers / net / bnxt / tf_core / tf_msg.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5
6 #include <assert.h>
7 #include <inttypes.h>
8 #include <stdbool.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "tf_msg_common.h"
13 #include "tf_device.h"
14 #include "tf_msg.h"
15 #include "tf_util.h"
16 #include "tf_common.h"
17 #include "tf_session.h"
18 #include "tfp.h"
19 #include "hwrm_tf.h"
20 #include "tf_em.h"
21
22 /* Specific msg size defines as we cannot use defines in tf.yaml. This
23  * means we have to manually sync hwrm with these defines if the
24  * tf.yaml changes.
25  */
26 #define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE  16
27 #define TF_MSG_EM_INSERT_KEY_SIZE        64
28 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE    88
29
30 /* Compile check - Catch any msg changes that we depend on, like the
31  * defines listed above for array size checking.
32  *
33  * Checking array size is dangerous in that the type could change and
34  * we wouldn't be able to catch it. Thus we check if the complete msg
35  * changed instead. Best we can do.
36  *
37  * If failure is observed then both msg size (defines below) and the
38  * array size (define above) should be checked and compared.
39  */
40 #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56
41 static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
42               TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET,
43               "HWRM message size changed: hwrm_tf_global_cfg_set_input");
44
45 #define TF_MSG_SIZE_HWRM_TF_EM_INSERT      104
46 static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
47               TF_MSG_SIZE_HWRM_TF_EM_INSERT,
48               "HWRM message size changed: hwrm_tf_em_insert_input");
49
50 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET   128
51 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
52               TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
53               "HWRM message size changed: hwrm_tf_tbl_type_set_input");
54
55 /**
56  * This is the MAX data we can transport across regular HWRM
57  */
58 #define TF_PCI_BUF_SIZE_MAX 88
59
60 /**
61  * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
62  */
63 struct tf_msg_dma_buf {
64         void *va_addr;
65         uint64_t pa_addr;
66 };
67
68 /**
69  * Allocates a DMA buffer that can be used for message transfer.
70  *
71  * [in] buf
72  *   Pointer to DMA buffer structure
73  *
74  * [in] size
75  *   Requested size of the buffer in bytes
76  *
77  * Returns:
78  *    0      - Success
79  *   -ENOMEM - Unable to allocate buffer, no memory
80  */
81 static int
82 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
83 {
84         struct tfp_calloc_parms alloc_parms;
85         int rc;
86
87         /* Allocate session */
88         alloc_parms.nitems = 1;
89         alloc_parms.size = size;
90         alloc_parms.alignment = 4096;
91         rc = tfp_calloc(&alloc_parms);
92         if (rc)
93                 return -ENOMEM;
94
95         buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
96         buf->va_addr = alloc_parms.mem_va;
97
98         return 0;
99 }
100
101 /**
102  * Free's a previous allocated DMA buffer.
103  *
104  * [in] buf
105  *   Pointer to DMA buffer structure
106  */
107 static void
108 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
109 {
110         tfp_free(buf->va_addr);
111 }
112
113 /* HWRM Direct messages */
114
115 int
116 tf_msg_session_open(struct tf *tfp,
117                     char *ctrl_chan_name,
118                     uint8_t *fw_session_id,
119                     uint8_t *fw_session_client_id)
120 {
121         int rc;
122         struct hwrm_tf_session_open_input req = { 0 };
123         struct hwrm_tf_session_open_output resp = { 0 };
124         struct tfp_send_msg_parms parms = { 0 };
125
126         /* Populate the request */
127         tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
128
129         parms.tf_type = HWRM_TF_SESSION_OPEN;
130         parms.req_data = (uint32_t *)&req;
131         parms.req_size = sizeof(req);
132         parms.resp_data = (uint32_t *)&resp;
133         parms.resp_size = sizeof(resp);
134         parms.mailbox = TF_KONG_MB;
135
136         rc = tfp_send_msg_direct(tfp,
137                                  &parms);
138         if (rc)
139                 return rc;
140
141         *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
142         *fw_session_client_id =
143                 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
144
145         return rc;
146 }
147
148 int
149 tf_msg_session_attach(struct tf *tfp __rte_unused,
150                       char *ctrl_chan_name __rte_unused,
151                       uint8_t tf_fw_session_id __rte_unused)
152 {
153         return -1;
154 }
155
156 int
157 tf_msg_session_client_register(struct tf *tfp,
158                                char *ctrl_channel_name,
159                                uint8_t *fw_session_client_id)
160 {
161         int rc;
162         struct hwrm_tf_session_register_input req = { 0 };
163         struct hwrm_tf_session_register_output resp = { 0 };
164         struct tfp_send_msg_parms parms = { 0 };
165         uint8_t fw_session_id;
166
167         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
168         if (rc) {
169                 TFP_DRV_LOG(ERR,
170                             "Unable to lookup FW id, rc:%s\n",
171                             strerror(-rc));
172                 return rc;
173         }
174
175         /* Populate the request */
176         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
177         tfp_memcpy(&req.session_client_name,
178                    ctrl_channel_name,
179                    TF_SESSION_NAME_MAX);
180
181         parms.tf_type = HWRM_TF_SESSION_REGISTER;
182         parms.req_data = (uint32_t *)&req;
183         parms.req_size = sizeof(req);
184         parms.resp_data = (uint32_t *)&resp;
185         parms.resp_size = sizeof(resp);
186         parms.mailbox = TF_KONG_MB;
187
188         rc = tfp_send_msg_direct(tfp,
189                                  &parms);
190         if (rc)
191                 return rc;
192
193         *fw_session_client_id =
194                 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
195
196         return rc;
197 }
198
199 int
200 tf_msg_session_client_unregister(struct tf *tfp,
201                                  uint8_t fw_session_client_id)
202 {
203         int rc;
204         struct hwrm_tf_session_unregister_input req = { 0 };
205         struct hwrm_tf_session_unregister_output resp = { 0 };
206         struct tfp_send_msg_parms parms = { 0 };
207         uint8_t fw_session_id;
208
209         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
210         if (rc) {
211                 TFP_DRV_LOG(ERR,
212                             "Unable to lookup FW id, rc:%s\n",
213                             strerror(-rc));
214                 return rc;
215         }
216
217         /* Populate the request */
218         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
219         req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
220
221         parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
222         parms.req_data = (uint32_t *)&req;
223         parms.req_size = sizeof(req);
224         parms.resp_data = (uint32_t *)&resp;
225         parms.resp_size = sizeof(resp);
226         parms.mailbox = TF_KONG_MB;
227
228         rc = tfp_send_msg_direct(tfp,
229                                  &parms);
230
231         return rc;
232 }
233
234 int
235 tf_msg_session_close(struct tf *tfp)
236 {
237         int rc;
238         struct hwrm_tf_session_close_input req = { 0 };
239         struct hwrm_tf_session_close_output resp = { 0 };
240         struct tfp_send_msg_parms parms = { 0 };
241         uint8_t fw_session_id;
242
243         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
244         if (rc) {
245                 TFP_DRV_LOG(ERR,
246                             "Unable to lookup FW id, rc:%s\n",
247                             strerror(-rc));
248                 return rc;
249         }
250
251         /* Populate the request */
252         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
253
254         parms.tf_type = HWRM_TF_SESSION_CLOSE;
255         parms.req_data = (uint32_t *)&req;
256         parms.req_size = sizeof(req);
257         parms.resp_data = (uint32_t *)&resp;
258         parms.resp_size = sizeof(resp);
259         parms.mailbox = TF_KONG_MB;
260
261         rc = tfp_send_msg_direct(tfp,
262                                  &parms);
263         return rc;
264 }
265
266 int
267 tf_msg_session_qcfg(struct tf *tfp)
268 {
269         int rc;
270         struct hwrm_tf_session_qcfg_input req = { 0 };
271         struct hwrm_tf_session_qcfg_output resp = { 0 };
272         struct tfp_send_msg_parms parms = { 0 };
273         uint8_t fw_session_id;
274
275         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
276         if (rc) {
277                 TFP_DRV_LOG(ERR,
278                             "Unable to lookup FW id, rc:%s\n",
279                             strerror(-rc));
280                 return rc;
281         }
282
283         /* Populate the request */
284         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
285
286         parms.tf_type = HWRM_TF_SESSION_QCFG,
287         parms.req_data = (uint32_t *)&req;
288         parms.req_size = sizeof(req);
289         parms.resp_data = (uint32_t *)&resp;
290         parms.resp_size = sizeof(resp);
291         parms.mailbox = TF_KONG_MB;
292
293         rc = tfp_send_msg_direct(tfp,
294                                  &parms);
295         return rc;
296 }
297
298 int
299 tf_msg_session_resc_qcaps(struct tf *tfp,
300                           enum tf_dir dir,
301                           uint16_t size,
302                           struct tf_rm_resc_req_entry *query,
303                           enum tf_rm_resc_resv_strategy *resv_strategy)
304 {
305         int rc;
306         int i;
307         struct tfp_send_msg_parms parms = { 0 };
308         struct hwrm_tf_session_resc_qcaps_input req = { 0 };
309         struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
310         uint8_t fw_session_id;
311         struct tf_msg_dma_buf qcaps_buf = { 0 };
312         struct tf_rm_resc_req_entry *data;
313         int dma_size;
314
315         TF_CHECK_PARMS3(tfp, query, resv_strategy);
316
317         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
318         if (rc) {
319                 TFP_DRV_LOG(ERR,
320                             "%s: Unable to lookup FW id, rc:%s\n",
321                             tf_dir_2_str(dir),
322                             strerror(-rc));
323                 return rc;
324         }
325
326         /* Prepare DMA buffer */
327         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
328         rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
329         if (rc)
330                 return rc;
331
332         /* Populate the request */
333         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
334         req.flags = tfp_cpu_to_le_16(dir);
335         req.qcaps_size = size;
336         req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
337
338         parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
339         parms.req_data = (uint32_t *)&req;
340         parms.req_size = sizeof(req);
341         parms.resp_data = (uint32_t *)&resp;
342         parms.resp_size = sizeof(resp);
343         parms.mailbox = TF_KONG_MB;
344
345         rc = tfp_send_msg_direct(tfp, &parms);
346         if (rc)
347                 goto cleanup;
348
349         /* Process the response
350          * Should always get expected number of entries
351          */
352         if (tfp_le_to_cpu_32(resp.size) != size) {
353                 TFP_DRV_LOG(ERR,
354                             "%s: QCAPS message size error, rc:%s\n",
355                             tf_dir_2_str(dir),
356                             strerror(EINVAL));
357                 rc = -EINVAL;
358                 goto cleanup;
359         }
360
361         /* Post process the response */
362         data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
363
364         for (i = 0; i < size; i++) {
365                 query[i].type = tfp_le_to_cpu_32(data[i].type);
366                 query[i].min = tfp_le_to_cpu_16(data[i].min);
367                 query[i].max = tfp_le_to_cpu_16(data[i].max);
368         }
369
370         *resv_strategy = resp.flags &
371               HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
372
373 cleanup:
374         tf_msg_free_dma_buf(&qcaps_buf);
375
376         return rc;
377 }
378
379 int
380 tf_msg_session_resc_alloc(struct tf *tfp,
381                           enum tf_dir dir,
382                           uint16_t size,
383                           struct tf_rm_resc_req_entry *request,
384                           struct tf_rm_resc_entry *resv)
385 {
386         int rc;
387         int i;
388         struct tfp_send_msg_parms parms = { 0 };
389         struct hwrm_tf_session_resc_alloc_input req = { 0 };
390         struct hwrm_tf_session_resc_alloc_output resp = { 0 };
391         uint8_t fw_session_id;
392         struct tf_msg_dma_buf req_buf = { 0 };
393         struct tf_msg_dma_buf resv_buf = { 0 };
394         struct tf_rm_resc_req_entry *req_data;
395         struct tf_rm_resc_entry *resv_data;
396         int dma_size;
397
398         TF_CHECK_PARMS3(tfp, request, resv);
399
400         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
401         if (rc) {
402                 TFP_DRV_LOG(ERR,
403                             "%s: Unable to lookup FW id, rc:%s\n",
404                             tf_dir_2_str(dir),
405                             strerror(-rc));
406                 return rc;
407         }
408
409         /* Prepare DMA buffers */
410         dma_size = size * sizeof(struct tf_rm_resc_req_entry);
411         rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
412         if (rc)
413                 return rc;
414
415         dma_size = size * sizeof(struct tf_rm_resc_entry);
416         rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
417         if (rc) {
418                 tf_msg_free_dma_buf(&req_buf);
419                 return rc;
420         }
421
422         /* Populate the request */
423         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
424         req.flags = tfp_cpu_to_le_16(dir);
425         req.req_size = size;
426
427         req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
428         for (i = 0; i < size; i++) {
429                 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
430                 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
431                 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
432         }
433
434         req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
435         req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
436
437         parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
438         parms.req_data = (uint32_t *)&req;
439         parms.req_size = sizeof(req);
440         parms.resp_data = (uint32_t *)&resp;
441         parms.resp_size = sizeof(resp);
442         parms.mailbox = TF_KONG_MB;
443
444         rc = tfp_send_msg_direct(tfp, &parms);
445         if (rc)
446                 goto cleanup;
447
448         /* Process the response
449          * Should always get expected number of entries
450          */
451         if (tfp_le_to_cpu_32(resp.size) != size) {
452                 TFP_DRV_LOG(ERR,
453                             "%s: Alloc message size error, rc:%s\n",
454                             tf_dir_2_str(dir),
455                             strerror(EINVAL));
456                 rc = -EINVAL;
457                 goto cleanup;
458         }
459
460         /* Post process the response */
461         resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
462         for (i = 0; i < size; i++) {
463                 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
464                 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
465                 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
466         }
467
468 cleanup:
469         tf_msg_free_dma_buf(&req_buf);
470         tf_msg_free_dma_buf(&resv_buf);
471
472         return rc;
473 }
474
475 int
476 tf_msg_session_resc_flush(struct tf *tfp,
477                           enum tf_dir dir,
478                           uint16_t size,
479                           struct tf_rm_resc_entry *resv)
480 {
481         int rc;
482         int i;
483         struct tfp_send_msg_parms parms = { 0 };
484         struct hwrm_tf_session_resc_flush_input req = { 0 };
485         struct hwrm_tf_session_resc_flush_output resp = { 0 };
486         uint8_t fw_session_id;
487         struct tf_msg_dma_buf resv_buf = { 0 };
488         struct tf_rm_resc_entry *resv_data;
489         int dma_size;
490
491         TF_CHECK_PARMS2(tfp, resv);
492
493         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
494         if (rc) {
495                 TFP_DRV_LOG(ERR,
496                             "%s: Unable to lookup FW id, rc:%s\n",
497                             tf_dir_2_str(dir),
498                             strerror(-rc));
499                 return rc;
500         }
501
502         /* Prepare DMA buffers */
503         dma_size = size * sizeof(struct tf_rm_resc_entry);
504         rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
505         if (rc)
506                 return rc;
507
508         /* Populate the request */
509         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
510         req.flags = tfp_cpu_to_le_16(dir);
511         req.flush_size = size;
512
513         resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
514         for (i = 0; i < size; i++) {
515                 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
516                 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
517                 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
518         }
519
520         req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
521
522         parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
523         parms.req_data = (uint32_t *)&req;
524         parms.req_size = sizeof(req);
525         parms.resp_data = (uint32_t *)&resp;
526         parms.resp_size = sizeof(resp);
527         parms.mailbox = TF_KONG_MB;
528
529         rc = tfp_send_msg_direct(tfp, &parms);
530
531         tf_msg_free_dma_buf(&resv_buf);
532
533         return rc;
534 }
535
536 int
537 tf_msg_insert_em_internal_entry(struct tf *tfp,
538                                 struct tf_insert_em_entry_parms *em_parms,
539                                 uint16_t *rptr_index,
540                                 uint8_t *rptr_entry,
541                                 uint8_t *num_of_entries)
542 {
543         int rc;
544         struct tfp_send_msg_parms parms = { 0 };
545         struct hwrm_tf_em_insert_input req = { 0 };
546         struct hwrm_tf_em_insert_output resp = { 0 };
547         struct tf_em_64b_entry *em_result =
548                 (struct tf_em_64b_entry *)em_parms->em_record;
549         uint16_t flags;
550         uint8_t fw_session_id;
551         uint8_t msg_key_size;
552
553         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
554         if (rc) {
555                 TFP_DRV_LOG(ERR,
556                             "%s: Unable to lookup FW id, rc:%s\n",
557                             tf_dir_2_str(em_parms->dir),
558                             strerror(-rc));
559                 return rc;
560         }
561
562         /* Populate the request */
563         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
564
565         /* Check for key size conformity */
566         msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
567         if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
568                 rc = -EINVAL;
569                 TFP_DRV_LOG(ERR,
570                             "%s: Invalid parameters for msg type, rc:%s\n",
571                             tf_dir_2_str(em_parms->dir),
572                             strerror(-rc));
573                 return rc;
574         }
575
576         tfp_memcpy(req.em_key,
577                    em_parms->key,
578                    msg_key_size);
579
580         flags = (em_parms->dir == TF_DIR_TX ?
581                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
582                  HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
583         req.flags = tfp_cpu_to_le_16(flags);
584         req.strength = (em_result->hdr.word1 &
585                         CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
586                         CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
587         req.em_key_bitlen = em_parms->key_sz_in_bits;
588         req.action_ptr = em_result->hdr.pointer;
589         req.em_record_idx = *rptr_index;
590
591         parms.tf_type = HWRM_TF_EM_INSERT;
592         parms.req_data = (uint32_t *)&req;
593         parms.req_size = sizeof(req);
594         parms.resp_data = (uint32_t *)&resp;
595         parms.resp_size = sizeof(resp);
596         parms.mailbox = TF_KONG_MB;
597
598         rc = tfp_send_msg_direct(tfp,
599                                  &parms);
600         if (rc)
601                 return rc;
602
603         *rptr_entry = resp.rptr_entry;
604         *rptr_index = resp.rptr_index;
605         *num_of_entries = resp.num_of_entries;
606
607         return 0;
608 }
609
610 int
611 tf_msg_delete_em_entry(struct tf *tfp,
612                        struct tf_delete_em_entry_parms *em_parms)
613 {
614         int rc;
615         struct tfp_send_msg_parms parms = { 0 };
616         struct hwrm_tf_em_delete_input req = { 0 };
617         struct hwrm_tf_em_delete_output resp = { 0 };
618         uint16_t flags;
619         uint8_t fw_session_id;
620
621         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
622         if (rc) {
623                 TFP_DRV_LOG(ERR,
624                             "%s: Unable to lookup FW id, rc:%s\n",
625                             tf_dir_2_str(em_parms->dir),
626                             strerror(-rc));
627                 return rc;
628         }
629
630         /* Populate the request */
631         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
632
633         flags = (em_parms->dir == TF_DIR_TX ?
634                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
635                  HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
636         req.flags = tfp_cpu_to_le_16(flags);
637         req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
638
639         parms.tf_type = HWRM_TF_EM_DELETE;
640         parms.req_data = (uint32_t *)&req;
641         parms.req_size = sizeof(req);
642         parms.resp_data = (uint32_t *)&resp;
643         parms.resp_size = sizeof(resp);
644         parms.mailbox = TF_KONG_MB;
645
646         rc = tfp_send_msg_direct(tfp,
647                                  &parms);
648         if (rc)
649                 return rc;
650
651         em_parms->index = tfp_le_to_cpu_16(resp.em_index);
652
653         return 0;
654 }
655
656 int
657 tf_msg_em_mem_rgtr(struct tf *tfp,
658                    int page_lvl,
659                    int page_size,
660                    uint64_t dma_addr,
661                    uint16_t *ctx_id)
662 {
663         int rc;
664         struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
665         struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
666         struct tfp_send_msg_parms parms = { 0 };
667
668         req.page_level = page_lvl;
669         req.page_size = page_size;
670         req.page_dir = tfp_cpu_to_le_64(dma_addr);
671
672         parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
673         parms.req_data = (uint32_t *)&req;
674         parms.req_size = sizeof(req);
675         parms.resp_data = (uint32_t *)&resp;
676         parms.resp_size = sizeof(resp);
677         parms.mailbox = TF_KONG_MB;
678
679         rc = tfp_send_msg_direct(tfp,
680                                  &parms);
681         if (rc)
682                 return rc;
683
684         *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
685
686         return rc;
687 }
688
689 int
690 tf_msg_em_mem_unrgtr(struct tf *tfp,
691                      uint16_t *ctx_id)
692 {
693         int rc;
694         struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
695         struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
696         struct tfp_send_msg_parms parms = { 0 };
697
698         req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
699
700         parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
701         parms.req_data = (uint32_t *)&req;
702         parms.req_size = sizeof(req);
703         parms.resp_data = (uint32_t *)&resp;
704         parms.resp_size = sizeof(resp);
705         parms.mailbox = TF_KONG_MB;
706
707         rc = tfp_send_msg_direct(tfp,
708                                  &parms);
709         return rc;
710 }
711
712 int
713 tf_msg_em_qcaps(struct tf *tfp,
714                 int dir,
715                 struct tf_em_caps *em_caps)
716 {
717         int rc;
718         struct hwrm_tf_ext_em_qcaps_input  req = {0};
719         struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
720         uint32_t             flags;
721         struct tfp_send_msg_parms parms = { 0 };
722
723         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
724                  HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
725         req.flags = tfp_cpu_to_le_32(flags);
726
727         parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
728         parms.req_data = (uint32_t *)&req;
729         parms.req_size = sizeof(req);
730         parms.resp_data = (uint32_t *)&resp;
731         parms.resp_size = sizeof(resp);
732         parms.mailbox = TF_KONG_MB;
733
734         rc = tfp_send_msg_direct(tfp,
735                                  &parms);
736         if (rc)
737                 return rc;
738
739         em_caps->supported = tfp_le_to_cpu_32(resp.supported);
740         em_caps->max_entries_supported =
741                 tfp_le_to_cpu_32(resp.max_entries_supported);
742         em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
743         em_caps->record_entry_size =
744                 tfp_le_to_cpu_16(resp.record_entry_size);
745         em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
746
747         return rc;
748 }
749
750 int
751 tf_msg_em_cfg(struct tf *tfp,
752               uint32_t num_entries,
753               uint16_t key0_ctx_id,
754               uint16_t key1_ctx_id,
755               uint16_t record_ctx_id,
756               uint16_t efc_ctx_id,
757               uint8_t flush_interval,
758               int dir)
759 {
760         int rc;
761         struct hwrm_tf_ext_em_cfg_input  req = {0};
762         struct hwrm_tf_ext_em_cfg_output resp = {0};
763         uint32_t flags;
764         struct tfp_send_msg_parms parms = { 0 };
765
766         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
767                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
768         flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
769
770         req.flags = tfp_cpu_to_le_32(flags);
771         req.num_entries = tfp_cpu_to_le_32(num_entries);
772
773         req.flush_interval = flush_interval;
774
775         req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
776         req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
777         req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
778         req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
779
780         parms.tf_type = HWRM_TF_EXT_EM_CFG;
781         parms.req_data = (uint32_t *)&req;
782         parms.req_size = sizeof(req);
783         parms.resp_data = (uint32_t *)&resp;
784         parms.resp_size = sizeof(resp);
785         parms.mailbox = TF_KONG_MB;
786
787         rc = tfp_send_msg_direct(tfp,
788                                  &parms);
789         return rc;
790 }
791
792 int
793 tf_msg_em_op(struct tf *tfp,
794              int dir,
795              uint16_t op)
796 {
797         int rc;
798         struct hwrm_tf_ext_em_op_input req = {0};
799         struct hwrm_tf_ext_em_op_output resp = {0};
800         uint32_t flags;
801         struct tfp_send_msg_parms parms = { 0 };
802
803         flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
804                  HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
805         req.flags = tfp_cpu_to_le_32(flags);
806         req.op = tfp_cpu_to_le_16(op);
807
808         parms.tf_type = HWRM_TF_EXT_EM_OP;
809         parms.req_data = (uint32_t *)&req;
810         parms.req_size = sizeof(req);
811         parms.resp_data = (uint32_t *)&resp;
812         parms.resp_size = sizeof(resp);
813         parms.mailbox = TF_KONG_MB;
814
815         rc = tfp_send_msg_direct(tfp,
816                                  &parms);
817         return rc;
818 }
819
820 int
821 tf_msg_tcam_entry_set(struct tf *tfp,
822                       struct tf_tcam_set_parms *parms)
823 {
824         int rc;
825         struct tfp_send_msg_parms mparms = { 0 };
826         struct hwrm_tf_tcam_set_input req = { 0 };
827         struct hwrm_tf_tcam_set_output resp = { 0 };
828         struct tf_msg_dma_buf buf = { 0 };
829         uint8_t *data = NULL;
830         int data_size = 0;
831         uint8_t fw_session_id;
832
833         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
834         if (rc) {
835                 TFP_DRV_LOG(ERR,
836                             "%s: Unable to lookup FW id, rc:%s\n",
837                             tf_dir_2_str(parms->dir),
838                             strerror(-rc));
839                 return rc;
840         }
841
842         /* Populate the request */
843         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
844         req.type = parms->hcapi_type;
845         req.idx = tfp_cpu_to_le_16(parms->idx);
846         if (parms->dir == TF_DIR_TX)
847                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
848
849         req.key_size = parms->key_size;
850         req.mask_offset = parms->key_size;
851         /* Result follows after key and mask, thus multiply by 2 */
852         req.result_offset = 2 * parms->key_size;
853         req.result_size = parms->result_size;
854         data_size = 2 * req.key_size + req.result_size;
855
856         if (data_size <= TF_PCI_BUF_SIZE_MAX) {
857                 /* use pci buffer */
858                 data = &req.dev_data[0];
859         } else {
860                 /* use dma buffer */
861                 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
862                 rc = tf_msg_alloc_dma_buf(&buf, data_size);
863                 if (rc)
864                         goto cleanup;
865                 data = buf.va_addr;
866                 tfp_memcpy(&req.dev_data[0],
867                            &buf.pa_addr,
868                            sizeof(buf.pa_addr));
869         }
870
871         tfp_memcpy(&data[0], parms->key, parms->key_size);
872         tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
873         tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
874
875         mparms.tf_type = HWRM_TF_TCAM_SET;
876         mparms.req_data = (uint32_t *)&req;
877         mparms.req_size = sizeof(req);
878         mparms.resp_data = (uint32_t *)&resp;
879         mparms.resp_size = sizeof(resp);
880         mparms.mailbox = TF_KONG_MB;
881
882         rc = tfp_send_msg_direct(tfp,
883                                  &mparms);
884
885 cleanup:
886         tf_msg_free_dma_buf(&buf);
887
888         return rc;
889 }
890
891 int
892 tf_msg_tcam_entry_free(struct tf *tfp,
893                        struct tf_tcam_free_parms *in_parms)
894 {
895         int rc;
896         struct hwrm_tf_tcam_free_input req =  { 0 };
897         struct hwrm_tf_tcam_free_output resp = { 0 };
898         struct tfp_send_msg_parms parms = { 0 };
899         uint8_t fw_session_id;
900
901         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
902         if (rc) {
903                 TFP_DRV_LOG(ERR,
904                             "%s: Unable to lookup FW id, rc:%s\n",
905                             tf_dir_2_str(in_parms->dir),
906                             strerror(-rc));
907                 return rc;
908         }
909
910         /* Populate the request */
911         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
912         req.type = in_parms->hcapi_type;
913         req.count = 1;
914         req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
915         if (in_parms->dir == TF_DIR_TX)
916                 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
917
918         parms.tf_type = HWRM_TF_TCAM_FREE;
919         parms.req_data = (uint32_t *)&req;
920         parms.req_size = sizeof(req);
921         parms.resp_data = (uint32_t *)&resp;
922         parms.resp_size = sizeof(resp);
923         parms.mailbox = TF_KONG_MB;
924
925         rc = tfp_send_msg_direct(tfp,
926                                  &parms);
927         return rc;
928 }
929
930 int
931 tf_msg_set_tbl_entry(struct tf *tfp,
932                      enum tf_dir dir,
933                      uint16_t hcapi_type,
934                      uint16_t size,
935                      uint8_t *data,
936                      uint32_t index)
937 {
938         int rc;
939         struct hwrm_tf_tbl_type_set_input req = { 0 };
940         struct hwrm_tf_tbl_type_set_output resp = { 0 };
941         struct tfp_send_msg_parms parms = { 0 };
942         uint8_t fw_session_id;
943
944         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
945         if (rc) {
946                 TFP_DRV_LOG(ERR,
947                             "%s: Unable to lookup FW id, rc:%s\n",
948                             tf_dir_2_str(dir),
949                             strerror(-rc));
950                 return rc;
951         }
952
953         /* Populate the request */
954         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
955         req.flags = tfp_cpu_to_le_16(dir);
956         req.type = tfp_cpu_to_le_32(hcapi_type);
957         req.size = tfp_cpu_to_le_16(size);
958         req.index = tfp_cpu_to_le_32(index);
959
960         /* Check for data size conformity */
961         if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
962                 rc = -EINVAL;
963                 TFP_DRV_LOG(ERR,
964                             "%s: Invalid parameters for msg type, rc:%s\n",
965                             tf_dir_2_str(dir),
966                             strerror(-rc));
967                 return rc;
968         }
969
970         tfp_memcpy(&req.data,
971                    data,
972                    size);
973
974         parms.tf_type = HWRM_TF_TBL_TYPE_SET;
975         parms.req_data = (uint32_t *)&req;
976         parms.req_size = sizeof(req);
977         parms.resp_data = (uint32_t *)&resp;
978         parms.resp_size = sizeof(resp);
979         parms.mailbox = TF_KONG_MB;
980
981         rc = tfp_send_msg_direct(tfp,
982                                  &parms);
983         if (rc)
984                 return rc;
985
986         return tfp_le_to_cpu_32(parms.tf_resp_code);
987 }
988
989 int
990 tf_msg_get_tbl_entry(struct tf *tfp,
991                      enum tf_dir dir,
992                      uint16_t hcapi_type,
993                      uint16_t size,
994                      uint8_t *data,
995                      uint32_t index)
996 {
997         int rc;
998         struct hwrm_tf_tbl_type_get_input req = { 0 };
999         struct hwrm_tf_tbl_type_get_output resp = { 0 };
1000         struct tfp_send_msg_parms parms = { 0 };
1001         uint8_t fw_session_id;
1002
1003         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1004         if (rc) {
1005                 TFP_DRV_LOG(ERR,
1006                             "%s: Unable to lookup FW id, rc:%s\n",
1007                             tf_dir_2_str(dir),
1008                             strerror(-rc));
1009                 return rc;
1010         }
1011
1012         /* Populate the request */
1013         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1014         req.flags = tfp_cpu_to_le_16(dir);
1015         req.type = tfp_cpu_to_le_32(hcapi_type);
1016         req.index = tfp_cpu_to_le_32(index);
1017
1018         parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1019         parms.req_data = (uint32_t *)&req;
1020         parms.req_size = sizeof(req);
1021         parms.resp_data = (uint32_t *)&resp;
1022         parms.resp_size = sizeof(resp);
1023         parms.mailbox = TF_KONG_MB;
1024
1025         rc = tfp_send_msg_direct(tfp,
1026                                  &parms);
1027         if (rc)
1028                 return rc;
1029
1030         /* Verify that we got enough buffer to return the requested data */
1031         if (tfp_le_to_cpu_32(resp.size) != size)
1032                 return -EINVAL;
1033
1034         tfp_memcpy(data,
1035                    &resp.data,
1036                    size);
1037
1038         return tfp_le_to_cpu_32(parms.tf_resp_code);
1039 }
1040
1041 /* HWRM Tunneled messages */
1042
1043 int
1044 tf_msg_get_global_cfg(struct tf *tfp,
1045                       struct tf_global_cfg_parms *params)
1046 {
1047         int rc = 0;
1048         struct tfp_send_msg_parms parms = { 0 };
1049         struct hwrm_tf_global_cfg_get_input req = { 0 };
1050         struct hwrm_tf_global_cfg_get_output resp = { 0 };
1051         uint32_t flags = 0;
1052         uint8_t fw_session_id;
1053         uint16_t resp_size = 0;
1054
1055         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1056         if (rc) {
1057                 TFP_DRV_LOG(ERR,
1058                             "%s: Unable to lookup FW id, rc:%s\n",
1059                             tf_dir_2_str(params->dir),
1060                             strerror(-rc));
1061                 return rc;
1062         }
1063
1064         flags = (params->dir == TF_DIR_TX ?
1065                  HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1066                  HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1067
1068         /* Populate the request */
1069         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1070         req.flags = tfp_cpu_to_le_32(flags);
1071         req.type = tfp_cpu_to_le_32(params->type);
1072         req.offset = tfp_cpu_to_le_32(params->offset);
1073         req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1074
1075         parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1076         parms.req_data = (uint32_t *)&req;
1077         parms.req_size = sizeof(req);
1078         parms.resp_data = (uint32_t *)&resp;
1079         parms.resp_size = sizeof(resp);
1080         parms.mailbox = TF_KONG_MB;
1081
1082         rc = tfp_send_msg_direct(tfp, &parms);
1083         if (rc != 0)
1084                 return rc;
1085
1086         /* Verify that we got enough buffer to return the requested data */
1087         resp_size = tfp_le_to_cpu_16(resp.size);
1088         if (resp_size < params->config_sz_in_bytes)
1089                 return -EINVAL;
1090
1091         if (params->config)
1092                 tfp_memcpy(params->config,
1093                            resp.data,
1094                            resp_size);
1095         else
1096                 return -EFAULT;
1097
1098         return tfp_le_to_cpu_32(parms.tf_resp_code);
1099 }
1100
1101 int
1102 tf_msg_set_global_cfg(struct tf *tfp,
1103                       struct tf_global_cfg_parms *params)
1104 {
1105         int rc = 0;
1106         struct tfp_send_msg_parms parms = { 0 };
1107         struct hwrm_tf_global_cfg_set_input req = { 0 };
1108         struct hwrm_tf_global_cfg_set_output resp = { 0 };
1109         uint32_t flags = 0;
1110         uint8_t fw_session_id;
1111
1112         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1113         if (rc) {
1114                 TFP_DRV_LOG(ERR,
1115                             "%s: Unable to lookup FW id, rc:%s\n",
1116                             tf_dir_2_str(params->dir),
1117                             strerror(-rc));
1118                 return rc;
1119         }
1120
1121         flags = (params->dir == TF_DIR_TX ?
1122                  HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
1123                  HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
1124
1125         /* Populate the request */
1126         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1127         req.flags = tfp_cpu_to_le_32(flags);
1128         req.type = tfp_cpu_to_le_32(params->type);
1129         req.offset = tfp_cpu_to_le_32(params->offset);
1130
1131         /* Check for data size conformity */
1132         if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
1133                 rc = -EINVAL;
1134                 TFP_DRV_LOG(ERR,
1135                             "%s: Invalid parameters for msg type, rc:%s\n",
1136                             tf_dir_2_str(params->dir),
1137                             strerror(-rc));
1138                 return rc;
1139         }
1140
1141         tfp_memcpy(req.data, params->config,
1142                    params->config_sz_in_bytes);
1143
1144         /* Only set mask if pointer is provided
1145          */
1146         if (params->config_mask) {
1147                 tfp_memcpy(req.data + params->config_sz_in_bytes,
1148                            params->config_mask,
1149                            params->config_sz_in_bytes);
1150         }
1151
1152         req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1153
1154         parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
1155         parms.req_data = (uint32_t *)&req;
1156         parms.req_size = sizeof(req);
1157         parms.resp_data = (uint32_t *)&resp;
1158         parms.resp_size = sizeof(resp);
1159         parms.mailbox = TF_KONG_MB;
1160
1161         rc = tfp_send_msg_direct(tfp, &parms);
1162
1163         if (rc != 0)
1164                 return rc;
1165
1166         return tfp_le_to_cpu_32(parms.tf_resp_code);
1167 }
1168
1169 int
1170 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
1171                           enum tf_dir dir,
1172                           uint16_t hcapi_type,
1173                           uint32_t starting_idx,
1174                           uint16_t num_entries,
1175                           uint16_t entry_sz_in_bytes,
1176                           uint64_t physical_mem_addr)
1177 {
1178         int rc;
1179         struct tfp_send_msg_parms parms = { 0 };
1180         struct tf_tbl_type_bulk_get_input req = { 0 };
1181         struct tf_tbl_type_bulk_get_output resp = { 0 };
1182         int data_size = 0;
1183         uint8_t fw_session_id;
1184
1185         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1186         if (rc) {
1187                 TFP_DRV_LOG(ERR,
1188                             "%s: Unable to lookup FW id, rc:%s\n",
1189                             tf_dir_2_str(dir),
1190                             strerror(-rc));
1191                 return rc;
1192         }
1193
1194         /* Populate the request */
1195         req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1196         req.flags = tfp_cpu_to_le_16(dir);
1197         req.type = tfp_cpu_to_le_32(hcapi_type);
1198         req.start_index = tfp_cpu_to_le_32(starting_idx);
1199         req.num_entries = tfp_cpu_to_le_32(num_entries);
1200
1201         data_size = num_entries * entry_sz_in_bytes;
1202
1203         req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
1204
1205         MSG_PREP(parms,
1206                  TF_KONG_MB,
1207                  HWRM_TF,
1208                  HWRM_TFT_TBL_TYPE_BULK_GET,
1209                  req,
1210                  resp);
1211
1212         rc = tfp_send_msg_tunneled(tfp, &parms);
1213         if (rc)
1214                 return rc;
1215
1216         /* Verify that we got enough buffer to return the requested data */
1217         if (tfp_le_to_cpu_32(resp.size) != data_size)
1218                 return -EINVAL;
1219
1220         return tfp_le_to_cpu_32(parms.tf_resp_code);
1221 }
1222
1223 int
1224 tf_msg_get_if_tbl_entry(struct tf *tfp,
1225                         struct tf_if_tbl_get_parms *params)
1226 {
1227         int rc = 0;
1228         struct tfp_send_msg_parms parms = { 0 };
1229         struct hwrm_tf_if_tbl_get_input req = { 0 };
1230         struct hwrm_tf_if_tbl_get_output resp = { 0 };
1231         uint32_t flags = 0;
1232         struct tf_session *tfs;
1233
1234         /* Retrieve the session information */
1235         rc = tf_session_get_session(tfp, &tfs);
1236         if (rc) {
1237                 TFP_DRV_LOG(ERR,
1238                             "%s: Failed to lookup session, rc:%s\n",
1239                             tf_dir_2_str(params->dir),
1240                             strerror(-rc));
1241                 return rc;
1242         }
1243
1244         flags = (params->dir == TF_DIR_TX ?
1245                 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
1246                 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
1247
1248         /* Populate the request */
1249         req.fw_session_id =
1250                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1251         req.flags = flags;
1252         req.type = params->hcapi_type;
1253         req.index = tfp_cpu_to_le_16(params->idx);
1254         req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
1255
1256         parms.tf_type = HWRM_TF_IF_TBL_GET;
1257         parms.req_data = (uint32_t *)&req;
1258         parms.req_size = sizeof(req);
1259         parms.resp_data = (uint32_t *)&resp;
1260         parms.resp_size = sizeof(resp);
1261         parms.mailbox = TF_KONG_MB;
1262
1263         rc = tfp_send_msg_direct(tfp, &parms);
1264
1265         if (rc != 0)
1266                 return rc;
1267
1268         if (parms.tf_resp_code != 0)
1269                 return tfp_le_to_cpu_32(parms.tf_resp_code);
1270
1271         tfp_memcpy(&params->data[0], resp.data, req.size);
1272
1273         return tfp_le_to_cpu_32(parms.tf_resp_code);
1274 }
1275
1276 int
1277 tf_msg_set_if_tbl_entry(struct tf *tfp,
1278                         struct tf_if_tbl_set_parms *params)
1279 {
1280         int rc = 0;
1281         struct tfp_send_msg_parms parms = { 0 };
1282         struct hwrm_tf_if_tbl_set_input req = { 0 };
1283         struct hwrm_tf_if_tbl_get_output resp = { 0 };
1284         uint32_t flags = 0;
1285         struct tf_session *tfs;
1286
1287         /* Retrieve the session information */
1288         rc = tf_session_get_session(tfp, &tfs);
1289         if (rc) {
1290                 TFP_DRV_LOG(ERR,
1291                             "%s: Failed to lookup session, rc:%s\n",
1292                             tf_dir_2_str(params->dir),
1293                             strerror(-rc));
1294                 return rc;
1295         }
1296
1297
1298         flags = (params->dir == TF_DIR_TX ?
1299                 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
1300                 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
1301
1302         /* Populate the request */
1303         req.fw_session_id =
1304                 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
1305         req.flags = flags;
1306         req.type = params->hcapi_type;
1307         req.index = tfp_cpu_to_le_32(params->idx);
1308         req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
1309         tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
1310
1311         parms.tf_type = HWRM_TF_IF_TBL_SET;
1312         parms.req_data = (uint32_t *)&req;
1313         parms.req_size = sizeof(req);
1314         parms.resp_data = (uint32_t *)&resp;
1315         parms.resp_size = sizeof(resp);
1316         parms.mailbox = TF_KONG_MB;
1317
1318         rc = tfp_send_msg_direct(tfp, &parms);
1319
1320         if (rc != 0)
1321                 return rc;
1322
1323         return tfp_le_to_cpu_32(parms.tf_resp_code);
1324 }