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