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_em_common.h"
13 #include "tf_msg_common.h"
14 #include "tf_device.h"
15 #include "tf_msg.h"
16 #include "tf_util.h"
17 #include "tf_common.h"
18 #include "tf_session.h"
19 #include "tfp.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 * This is the length of shared session name "tf_share"
63 */
64 #define TF_SHARED_SESSION_NAME_LEN 8
65
66 /**
67 * This is the length of tcam shared session name "tf_shared-wc_tcam"
68 */
69 #define TF_TCAM_SHARED_SESSION_NAME_LEN 17
70
71 /**
72 * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
73 */
74 struct tf_msg_dma_buf {
75 void *va_addr;
76 uint64_t pa_addr;
77 };
78
79 /**
80 * Allocates a DMA buffer that can be used for message transfer.
81 *
82 * [in] buf
83 * Pointer to DMA buffer structure
84 *
85 * [in] size
86 * Requested size of the buffer in bytes
87 *
88 * Returns:
89 * 0 - Success
90 * -ENOMEM - Unable to allocate buffer, no memory
91 */
92 static int
tf_msg_alloc_dma_buf(struct tf_msg_dma_buf * buf,int size)93 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
94 {
95 struct tfp_calloc_parms alloc_parms;
96 int rc;
97
98 /* Allocate session */
99 alloc_parms.nitems = 1;
100 alloc_parms.size = size;
101 alloc_parms.alignment = 4096;
102 rc = tfp_calloc(&alloc_parms);
103 if (rc)
104 return -ENOMEM;
105
106 buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
107 buf->va_addr = alloc_parms.mem_va;
108
109 return 0;
110 }
111
112 /**
113 * Free's a previous allocated DMA buffer.
114 *
115 * [in] buf
116 * Pointer to DMA buffer structure
117 */
118 static void
tf_msg_free_dma_buf(struct tf_msg_dma_buf * buf)119 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
120 {
121 tfp_free(buf->va_addr);
122 }
123
124 /* HWRM Direct messages */
125
126 int
tf_msg_session_open(struct bnxt * bp,char * ctrl_chan_name,uint8_t * fw_session_id,uint8_t * fw_session_client_id,struct tf_dev_info * dev,bool * shared_session_creator)127 tf_msg_session_open(struct bnxt *bp,
128 char *ctrl_chan_name,
129 uint8_t *fw_session_id,
130 uint8_t *fw_session_client_id,
131 struct tf_dev_info *dev,
132 bool *shared_session_creator)
133 {
134 int rc;
135 struct hwrm_tf_session_open_input req = { 0 };
136 struct hwrm_tf_session_open_output resp = { 0 };
137 struct tfp_send_msg_parms parms = { 0 };
138 int name_len;
139 char *session_name;
140 char *tcam_session_name;
141
142 /* Populate the request */
143 name_len = strnlen(ctrl_chan_name, TF_SESSION_NAME_MAX);
144 session_name = &ctrl_chan_name[name_len - strlen("tf_shared")];
145 tcam_session_name = &ctrl_chan_name[name_len - strlen("tf_shared-wc_tcam")];
146 if (!strncmp(tcam_session_name, "tf_shared-wc_tcam", strlen("tf_shared-wc_tcam")))
147 tfp_memcpy(&req.session_name, tcam_session_name, TF_TCAM_SHARED_SESSION_NAME_LEN);
148 else if (!strncmp(session_name, "tf_shared", strlen("tf_shared")))
149 tfp_memcpy(&req.session_name, session_name, TF_SHARED_SESSION_NAME_LEN);
150 else
151 tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
152
153 parms.tf_type = HWRM_TF_SESSION_OPEN;
154 parms.req_data = (uint32_t *)&req;
155 parms.req_size = sizeof(req);
156 parms.resp_data = (uint32_t *)&resp;
157 parms.resp_size = sizeof(resp);
158 parms.mailbox = dev->ops->tf_dev_get_mailbox();
159
160 rc = tfp_send_msg_direct(bp,
161 &parms);
162 if (rc)
163 return rc;
164
165 *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
166 *fw_session_client_id =
167 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
168 *shared_session_creator = (bool)tfp_le_to_cpu_32(resp.flags
169 & HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR);
170
171 return rc;
172 }
173
174 int
tf_msg_session_attach(struct tf * tfp __rte_unused,char * ctrl_chan_name __rte_unused,uint8_t tf_fw_session_id __rte_unused)175 tf_msg_session_attach(struct tf *tfp __rte_unused,
176 char *ctrl_chan_name __rte_unused,
177 uint8_t tf_fw_session_id __rte_unused)
178 {
179 return -1;
180 }
181
182 int
tf_msg_session_client_register(struct tf * tfp,struct tf_session * tfs,char * ctrl_channel_name,uint8_t * fw_session_client_id)183 tf_msg_session_client_register(struct tf *tfp,
184 struct tf_session *tfs,
185 char *ctrl_channel_name,
186 uint8_t *fw_session_client_id)
187 {
188 int rc;
189 struct hwrm_tf_session_register_input req = { 0 };
190 struct hwrm_tf_session_register_output resp = { 0 };
191 struct tfp_send_msg_parms parms = { 0 };
192 uint8_t fw_session_id;
193 struct tf_dev_info *dev;
194 int name_len;
195 char *session_name;
196 char *tcam_session_name;
197
198 /* Retrieve the device information */
199 rc = tf_session_get_device(tfs, &dev);
200 if (rc) {
201 TFP_DRV_LOG(ERR,
202 "Failed to lookup device, rc:%s\n",
203 strerror(-rc));
204 return rc;
205 }
206
207 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
208 if (rc) {
209 TFP_DRV_LOG(ERR,
210 "Unable to lookup FW id, rc:%s\n",
211 strerror(-rc));
212 return rc;
213 }
214
215 /* Populate the request */
216 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
217 name_len = strnlen(ctrl_channel_name, TF_SESSION_NAME_MAX);
218 session_name = &ctrl_channel_name[name_len - strlen("tf_shared")];
219 tcam_session_name = &ctrl_channel_name[name_len -
220 strlen("tf_shared-wc_tcam")];
221 if (!strncmp(tcam_session_name,
222 "tf_shared-wc_tcam",
223 strlen("tf_shared-wc_tcam")))
224 tfp_memcpy(&req.session_client_name,
225 tcam_session_name,
226 TF_TCAM_SHARED_SESSION_NAME_LEN);
227 else if (!strncmp(session_name, "tf_shared", strlen("tf_shared")))
228 tfp_memcpy(&req.session_client_name,
229 session_name,
230 TF_SHARED_SESSION_NAME_LEN);
231 else
232 tfp_memcpy(&req.session_client_name,
233 ctrl_channel_name,
234 TF_SESSION_NAME_MAX);
235
236 parms.tf_type = HWRM_TF_SESSION_REGISTER;
237 parms.req_data = (uint32_t *)&req;
238 parms.req_size = sizeof(req);
239 parms.resp_data = (uint32_t *)&resp;
240 parms.resp_size = sizeof(resp);
241 parms.mailbox = dev->ops->tf_dev_get_mailbox();
242
243 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
244 &parms);
245 if (rc)
246 return rc;
247
248 *fw_session_client_id =
249 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
250
251 return rc;
252 }
253
254 int
tf_msg_session_client_unregister(struct tf * tfp,struct tf_session * tfs,uint8_t fw_session_client_id)255 tf_msg_session_client_unregister(struct tf *tfp,
256 struct tf_session *tfs,
257 uint8_t fw_session_client_id)
258 {
259 int rc;
260 struct hwrm_tf_session_unregister_input req = { 0 };
261 struct hwrm_tf_session_unregister_output resp = { 0 };
262 struct tfp_send_msg_parms parms = { 0 };
263 uint8_t fw_session_id;
264 struct tf_dev_info *dev;
265
266 /* Retrieve the device information */
267 rc = tf_session_get_device(tfs, &dev);
268 if (rc) {
269 TFP_DRV_LOG(ERR,
270 "Failed to lookup device, rc:%s\n",
271 strerror(-rc));
272 return rc;
273 }
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 req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id);
286
287 parms.tf_type = HWRM_TF_SESSION_UNREGISTER;
288 parms.req_data = (uint32_t *)&req;
289 parms.req_size = sizeof(req);
290 parms.resp_data = (uint32_t *)&resp;
291 parms.resp_size = sizeof(resp);
292 parms.mailbox = dev->ops->tf_dev_get_mailbox();
293
294 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
295 &parms);
296
297 return rc;
298 }
299
300 int
tf_msg_session_close(struct tf * tfp,uint8_t fw_session_id,int mailbox)301 tf_msg_session_close(struct tf *tfp,
302 uint8_t fw_session_id,
303 int mailbox)
304 {
305 int rc;
306 struct hwrm_tf_session_close_input req = { 0 };
307 struct hwrm_tf_session_close_output resp = { 0 };
308 struct tfp_send_msg_parms parms = { 0 };
309
310 /* Populate the request */
311 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
312
313 parms.tf_type = HWRM_TF_SESSION_CLOSE;
314 parms.req_data = (uint32_t *)&req;
315 parms.req_size = sizeof(req);
316 parms.resp_data = (uint32_t *)&resp;
317 parms.resp_size = sizeof(resp);
318 parms.mailbox = mailbox;
319
320 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
321 &parms);
322 return rc;
323 }
324
325 int
tf_msg_session_qcfg(struct tf * tfp)326 tf_msg_session_qcfg(struct tf *tfp)
327 {
328 int rc;
329 struct hwrm_tf_session_qcfg_input req = { 0 };
330 struct hwrm_tf_session_qcfg_output resp = { 0 };
331 struct tfp_send_msg_parms parms = { 0 };
332 uint8_t fw_session_id;
333 struct tf_dev_info *dev;
334 struct tf_session *tfs;
335
336 /* Retrieve the session information */
337 rc = tf_session_get_session_internal(tfp, &tfs);
338 if (rc) {
339 TFP_DRV_LOG(ERR,
340 "Failed to lookup session, rc:%s\n",
341 strerror(-rc));
342 return rc;
343 }
344
345 /* Retrieve the device information */
346 rc = tf_session_get_device(tfs, &dev);
347 if (rc) {
348 TFP_DRV_LOG(ERR,
349 "Failed to lookup device, rc:%s\n",
350 strerror(-rc));
351 return rc;
352 }
353
354 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
355 if (rc) {
356 TFP_DRV_LOG(ERR,
357 "Unable to lookup FW id, rc:%s\n",
358 strerror(-rc));
359 return rc;
360 }
361
362 /* Populate the request */
363 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
364
365 parms.tf_type = HWRM_TF_SESSION_QCFG,
366 parms.req_data = (uint32_t *)&req;
367 parms.req_size = sizeof(req);
368 parms.resp_data = (uint32_t *)&resp;
369 parms.resp_size = sizeof(resp);
370 parms.mailbox = dev->ops->tf_dev_get_mailbox();
371
372 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
373 &parms);
374 return rc;
375 }
376
377 int
tf_msg_session_resc_qcaps(struct tf * tfp,struct tf_dev_info * dev,enum tf_dir dir,uint16_t size,struct tf_rm_resc_req_entry * query,enum tf_rm_resc_resv_strategy * resv_strategy,uint8_t * sram_profile)378 tf_msg_session_resc_qcaps(struct tf *tfp,
379 struct tf_dev_info *dev,
380 enum tf_dir dir,
381 uint16_t size,
382 struct tf_rm_resc_req_entry *query,
383 enum tf_rm_resc_resv_strategy *resv_strategy,
384 uint8_t *sram_profile)
385 {
386 int rc;
387 int i;
388 struct tfp_send_msg_parms parms = { 0 };
389 struct hwrm_tf_session_resc_qcaps_input req = { 0 };
390 struct hwrm_tf_session_resc_qcaps_output resp = { 0 };
391 struct tf_msg_dma_buf qcaps_buf = { 0 };
392 struct tf_rm_resc_req_entry *data;
393 int dma_size;
394
395 TF_CHECK_PARMS3(tfp, query, resv_strategy);
396
397 /* Prepare DMA buffer */
398 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
399 rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size);
400 if (rc)
401 return rc;
402
403 /* Populate the request */
404 req.fw_session_id = 0;
405 req.flags = tfp_cpu_to_le_16(dir);
406 req.qcaps_size = size;
407 req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr);
408
409 parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS;
410 parms.req_data = (uint32_t *)&req;
411 parms.req_size = sizeof(req);
412 parms.resp_data = (uint32_t *)&resp;
413 parms.resp_size = sizeof(resp);
414 parms.mailbox = dev->ops->tf_dev_get_mailbox();
415
416 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
417 if (rc)
418 goto cleanup;
419
420 /* Process the response
421 * Should always get expected number of entries
422 */
423 if (tfp_le_to_cpu_32(resp.size) != size) {
424 TFP_DRV_LOG(WARNING,
425 "%s: QCAPS message size error, rc:%s, request %d vs response %d\n",
426 tf_dir_2_str(dir),
427 strerror(EINVAL),
428 size,
429 resp.size);
430 }
431
432 /* Post process the response */
433 data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
434
435 for (i = 0; i < resp.size; i++) {
436 query[i].type = tfp_le_to_cpu_32(data[i].type);
437 query[i].min = tfp_le_to_cpu_16(data[i].min);
438 query[i].max = tfp_le_to_cpu_16(data[i].max);
439 }
440
441 *resv_strategy = resp.flags &
442 HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK;
443
444 if (sram_profile != NULL)
445 *sram_profile = resp.sram_profile;
446
447 cleanup:
448 tf_msg_free_dma_buf(&qcaps_buf);
449
450 return rc;
451 }
452
453 int
tf_msg_session_resc_alloc(struct tf * tfp,struct tf_dev_info * dev,enum tf_dir dir,uint16_t size,struct tf_rm_resc_req_entry * request,struct tf_rm_resc_entry * resv)454 tf_msg_session_resc_alloc(struct tf *tfp,
455 struct tf_dev_info *dev,
456 enum tf_dir dir,
457 uint16_t size,
458 struct tf_rm_resc_req_entry *request,
459 struct tf_rm_resc_entry *resv)
460 {
461 int rc;
462 int i;
463 struct tfp_send_msg_parms parms = { 0 };
464 struct hwrm_tf_session_resc_alloc_input req = { 0 };
465 struct hwrm_tf_session_resc_alloc_output resp = { 0 };
466 uint8_t fw_session_id;
467 struct tf_msg_dma_buf req_buf = { 0 };
468 struct tf_msg_dma_buf resv_buf = { 0 };
469 struct tf_rm_resc_req_entry *req_data;
470 struct tf_rm_resc_entry *resv_data;
471 int dma_size;
472 struct tf_session *tfs;
473
474 /* Retrieve the session information */
475 rc = tf_session_get_session_internal(tfp, &tfs);
476 if (rc) {
477 TFP_DRV_LOG(ERR,
478 "Failed to lookup session, rc:%s\n",
479 strerror(-rc));
480 return rc;
481 }
482
483 TF_CHECK_PARMS3(tfp, request, resv);
484
485 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
486 if (rc) {
487 TFP_DRV_LOG(ERR,
488 "%s: Unable to lookup FW id, rc:%s\n",
489 tf_dir_2_str(dir),
490 strerror(-rc));
491 return rc;
492 }
493
494 /* Prepare DMA buffers */
495 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
496 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
497 if (rc)
498 return rc;
499
500 dma_size = size * sizeof(struct tf_rm_resc_entry);
501 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
502 if (rc) {
503 tf_msg_free_dma_buf(&req_buf);
504 return rc;
505 }
506
507 /* Populate the request */
508 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
509 req.flags = tfp_cpu_to_le_16(dir);
510 req.req_size = size;
511
512 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
513 for (i = 0; i < size; i++) {
514 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
515 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
516 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
517 }
518
519 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
520 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
521
522 parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC;
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 = dev->ops->tf_dev_get_mailbox();
528
529 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
530 if (rc)
531 goto cleanup;
532
533 /* Process the response
534 * Should always get expected number of entries
535 */
536 if (tfp_le_to_cpu_32(resp.size) != size) {
537 TFP_DRV_LOG(ERR,
538 "%s: Alloc message size error, rc:%s\n",
539 tf_dir_2_str(dir),
540 strerror(EINVAL));
541 rc = -EINVAL;
542 goto cleanup;
543 }
544
545 /* Post process the response */
546 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
547 for (i = 0; i < size; i++) {
548 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
549 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
550 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
551 }
552
553 cleanup:
554 tf_msg_free_dma_buf(&req_buf);
555 tf_msg_free_dma_buf(&resv_buf);
556
557 return rc;
558 }
559
560 int
tf_msg_session_resc_info(struct tf * tfp,struct tf_dev_info * dev,enum tf_dir dir,uint16_t size,struct tf_rm_resc_req_entry * request,struct tf_rm_resc_entry * resv)561 tf_msg_session_resc_info(struct tf *tfp,
562 struct tf_dev_info *dev,
563 enum tf_dir dir,
564 uint16_t size,
565 struct tf_rm_resc_req_entry *request,
566 struct tf_rm_resc_entry *resv)
567 {
568 int rc;
569 int i;
570 struct tfp_send_msg_parms parms = { 0 };
571 struct hwrm_tf_session_resc_info_input req = { 0 };
572 struct hwrm_tf_session_resc_info_output resp = { 0 };
573 uint8_t fw_session_id;
574 struct tf_msg_dma_buf req_buf = { 0 };
575 struct tf_msg_dma_buf resv_buf = { 0 };
576 struct tf_rm_resc_req_entry *req_data;
577 struct tf_rm_resc_entry *resv_data;
578 int dma_size;
579 struct tf_session *tfs;
580
581 /* Retrieve the session information */
582 rc = tf_session_get_session_internal(tfp, &tfs);
583 if (rc) {
584 TFP_DRV_LOG(ERR,
585 "Failed to lookup session, rc:%s\n",
586 strerror(-rc));
587 return rc;
588 }
589
590 TF_CHECK_PARMS3(tfp, request, resv);
591
592 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
593 if (rc) {
594 TFP_DRV_LOG(ERR,
595 "%s: Unable to lookup FW id, rc:%s\n",
596 tf_dir_2_str(dir),
597 strerror(-rc));
598 return rc;
599 }
600
601 /* Prepare DMA buffers */
602 dma_size = size * sizeof(struct tf_rm_resc_req_entry);
603 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
604 if (rc)
605 return rc;
606
607 dma_size = size * sizeof(struct tf_rm_resc_entry);
608 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
609 if (rc) {
610 tf_msg_free_dma_buf(&req_buf);
611 return rc;
612 }
613
614 /* Populate the request */
615 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
616 req.flags = tfp_cpu_to_le_16(dir);
617 req.req_size = size;
618
619 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
620 for (i = 0; i < size; i++) {
621 req_data[i].type = tfp_cpu_to_le_32(request[i].type);
622 req_data[i].min = tfp_cpu_to_le_16(request[i].min);
623 req_data[i].max = tfp_cpu_to_le_16(request[i].max);
624 }
625
626 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
627 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
628
629 parms.tf_type = HWRM_TF_SESSION_RESC_INFO;
630 parms.req_data = (uint32_t *)&req;
631 parms.req_size = sizeof(req);
632 parms.resp_data = (uint32_t *)&resp;
633 parms.resp_size = sizeof(resp);
634 parms.mailbox = dev->ops->tf_dev_get_mailbox();
635
636 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
637 if (rc)
638 goto cleanup;
639
640 /* Process the response
641 * Should always get expected number of entries
642 */
643 if (tfp_le_to_cpu_32(resp.size) != size) {
644 TFP_DRV_LOG(ERR,
645 "%s: Alloc message size error, rc:%s\n",
646 tf_dir_2_str(dir),
647 strerror(EINVAL));
648 rc = -EINVAL;
649 goto cleanup;
650 }
651
652 /* Post process the response */
653 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
654 for (i = 0; i < size; i++) {
655 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
656 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
657 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
658 }
659
660 cleanup:
661 tf_msg_free_dma_buf(&req_buf);
662 tf_msg_free_dma_buf(&resv_buf);
663
664 return rc;
665 }
666
667 int
tf_msg_session_resc_flush(struct tf * tfp,enum tf_dir dir,uint16_t size,struct tf_rm_resc_entry * resv)668 tf_msg_session_resc_flush(struct tf *tfp,
669 enum tf_dir dir,
670 uint16_t size,
671 struct tf_rm_resc_entry *resv)
672 {
673 int rc;
674 int i;
675 struct tfp_send_msg_parms parms = { 0 };
676 struct hwrm_tf_session_resc_flush_input req = { 0 };
677 struct hwrm_tf_session_resc_flush_output resp = { 0 };
678 uint8_t fw_session_id;
679 struct tf_msg_dma_buf resv_buf = { 0 };
680 struct tf_rm_resc_entry *resv_data;
681 int dma_size;
682 struct tf_dev_info *dev;
683 struct tf_session *tfs;
684
685 TF_CHECK_PARMS2(tfp, resv);
686
687 /* Retrieve the session information */
688 rc = tf_session_get_session_internal(tfp, &tfs);
689 if (rc) {
690 TFP_DRV_LOG(ERR,
691 "%s: Failed to lookup session, rc:%s\n",
692 tf_dir_2_str(dir),
693 strerror(-rc));
694 return rc;
695 }
696
697 /* Retrieve the device information */
698 rc = tf_session_get_device(tfs, &dev);
699 if (rc) {
700 TFP_DRV_LOG(ERR,
701 "%s: Failed to lookup device, rc:%s\n",
702 tf_dir_2_str(dir),
703 strerror(-rc));
704 return rc;
705 }
706
707 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
708 if (rc) {
709 TFP_DRV_LOG(ERR,
710 "%s: Unable to lookup FW id, rc:%s\n",
711 tf_dir_2_str(dir),
712 strerror(-rc));
713 return rc;
714 }
715
716 /* Prepare DMA buffers */
717 dma_size = size * sizeof(struct tf_rm_resc_entry);
718 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
719 if (rc)
720 return rc;
721
722 /* Populate the request */
723 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
724 req.flags = tfp_cpu_to_le_16(dir);
725 req.flush_size = size;
726
727 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
728 for (i = 0; i < size; i++) {
729 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type);
730 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start);
731 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride);
732 }
733
734 req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
735
736 parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH;
737 parms.req_data = (uint32_t *)&req;
738 parms.req_size = sizeof(req);
739 parms.resp_data = (uint32_t *)&resp;
740 parms.resp_size = sizeof(resp);
741 parms.mailbox = dev->ops->tf_dev_get_mailbox();
742
743 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
744
745 tf_msg_free_dma_buf(&resv_buf);
746
747 return rc;
748 }
749
750 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)751 tf_msg_insert_em_internal_entry(struct tf *tfp,
752 struct tf_insert_em_entry_parms *em_parms,
753 uint16_t *rptr_index,
754 uint8_t *rptr_entry,
755 uint8_t *num_of_entries)
756 {
757 int rc;
758 struct tfp_send_msg_parms parms = { 0 };
759 struct hwrm_tf_em_insert_input req = { 0 };
760 struct hwrm_tf_em_insert_output resp = { 0 };
761 struct tf_em_64b_entry *em_result =
762 (struct tf_em_64b_entry *)em_parms->em_record;
763 uint16_t flags;
764 uint8_t fw_session_id;
765 uint8_t msg_key_size;
766 struct tf_dev_info *dev;
767 struct tf_session *tfs;
768
769 RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_em_insert_input) !=
770 TF_MSG_SIZE_HWRM_TF_EM_INSERT);
771
772 /* Retrieve the session information */
773 rc = tf_session_get_session_internal(tfp, &tfs);
774 if (rc) {
775 TFP_DRV_LOG(ERR,
776 "%s: Failed to lookup session, rc:%s\n",
777 tf_dir_2_str(em_parms->dir),
778 strerror(-rc));
779 return rc;
780 }
781
782 /* Retrieve the device information */
783 rc = tf_session_get_device(tfs, &dev);
784 if (rc) {
785 TFP_DRV_LOG(ERR,
786 "%s: Failed to lookup device, rc:%s\n",
787 tf_dir_2_str(em_parms->dir),
788 strerror(-rc));
789 return rc;
790 }
791
792 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
793 if (rc) {
794 TFP_DRV_LOG(ERR,
795 "%s: Unable to lookup FW id, rc:%s\n",
796 tf_dir_2_str(em_parms->dir),
797 strerror(-rc));
798 return rc;
799 }
800
801 /* Populate the request */
802 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
803
804 /* Check for key size conformity */
805 msg_key_size = (em_parms->key_sz_in_bits + 7) / 8;
806 if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) {
807 rc = -EINVAL;
808 TFP_DRV_LOG(ERR,
809 "%s: Invalid parameters for msg type, rc:%s\n",
810 tf_dir_2_str(em_parms->dir),
811 strerror(-rc));
812 return rc;
813 }
814
815 tfp_memcpy(req.em_key,
816 em_parms->key,
817 msg_key_size);
818
819 flags = (em_parms->dir == TF_DIR_TX ?
820 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
821 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
822 req.flags = tfp_cpu_to_le_16(flags);
823 req.strength = (em_result->hdr.word1 &
824 CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
825 CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
826 req.em_key_bitlen = em_parms->key_sz_in_bits;
827 req.action_ptr = em_result->hdr.pointer;
828 req.em_record_idx = *rptr_index;
829
830 parms.tf_type = HWRM_TF_EM_INSERT;
831 parms.req_data = (uint32_t *)&req;
832 parms.req_size = sizeof(req);
833 parms.resp_data = (uint32_t *)&resp;
834 parms.resp_size = sizeof(resp);
835 parms.mailbox = dev->ops->tf_dev_get_mailbox();
836
837 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
838 &parms);
839 if (rc)
840 return rc;
841
842 *rptr_entry = resp.rptr_entry;
843 *rptr_index = resp.rptr_index;
844 *num_of_entries = resp.num_of_entries;
845
846 return 0;
847 }
848
849 int
tf_msg_hash_insert_em_internal_entry(struct tf * tfp,struct tf_insert_em_entry_parms * em_parms,uint32_t key0_hash,uint32_t key1_hash,uint16_t * rptr_index,uint8_t * rptr_entry,uint8_t * num_of_entries)850 tf_msg_hash_insert_em_internal_entry(struct tf *tfp,
851 struct tf_insert_em_entry_parms *em_parms,
852 uint32_t key0_hash,
853 uint32_t key1_hash,
854 uint16_t *rptr_index,
855 uint8_t *rptr_entry,
856 uint8_t *num_of_entries)
857 {
858 int rc;
859 struct tfp_send_msg_parms parms = { 0 };
860 struct hwrm_tf_em_hash_insert_input req = { 0 };
861 struct hwrm_tf_em_hash_insert_output resp = { 0 };
862 uint16_t flags;
863 uint8_t fw_session_id;
864 uint8_t msg_record_size;
865 struct tf_dev_info *dev;
866 struct tf_session *tfs;
867
868 /* Retrieve the session information */
869 rc = tf_session_get_session_internal(tfp, &tfs);
870 if (rc) {
871 TFP_DRV_LOG(ERR,
872 "%s: Failed to lookup session, rc:%s\n",
873 tf_dir_2_str(em_parms->dir),
874 strerror(-rc));
875 return rc;
876 }
877
878 /* Retrieve the device information */
879 rc = tf_session_get_device(tfs, &dev);
880 if (rc) {
881 TFP_DRV_LOG(ERR,
882 "%s: Failed to lookup device, rc:%s\n",
883 tf_dir_2_str(em_parms->dir),
884 strerror(-rc));
885 return rc;
886 }
887
888 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
889 if (rc) {
890 TFP_DRV_LOG(ERR,
891 "%s: Unable to lookup FW id, rc:%s\n",
892 tf_dir_2_str(em_parms->dir),
893 strerror(-rc));
894 return rc;
895 }
896
897 /* Populate the request */
898 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
899
900 /* Check for key size conformity */
901 msg_record_size = (em_parms->em_record_sz_in_bits + 7) / 8;
902
903 if (msg_record_size > TF_MSG_EM_INSERT_RECORD_SIZE) {
904 rc = -EINVAL;
905 TFP_DRV_LOG(ERR,
906 "%s: Record size to large, rc:%s\n",
907 tf_dir_2_str(em_parms->dir),
908 strerror(-rc));
909 return rc;
910 }
911
912 tfp_memcpy((char *)req.em_record,
913 em_parms->em_record,
914 msg_record_size);
915
916 flags = (em_parms->dir == TF_DIR_TX ?
917 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
918 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
919 req.flags = tfp_cpu_to_le_16(flags);
920 req.em_record_size_bits = em_parms->em_record_sz_in_bits;
921 req.em_record_idx = *rptr_index;
922 req.key0_hash = key0_hash;
923 req.key1_hash = key1_hash;
924
925 parms.tf_type = HWRM_TF_EM_HASH_INSERT;
926 parms.req_data = (uint32_t *)&req;
927 parms.req_size = sizeof(req);
928 parms.resp_data = (uint32_t *)&resp;
929 parms.resp_size = sizeof(resp);
930 parms.mailbox = dev->ops->tf_dev_get_mailbox();
931
932 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
933 &parms);
934 if (rc)
935 return rc;
936
937 *rptr_entry = resp.rptr_entry;
938 *rptr_index = resp.rptr_index;
939 *num_of_entries = resp.num_of_entries;
940
941 return 0;
942 }
943
944 int
tf_msg_delete_em_entry(struct tf * tfp,struct tf_delete_em_entry_parms * em_parms)945 tf_msg_delete_em_entry(struct tf *tfp,
946 struct tf_delete_em_entry_parms *em_parms)
947 {
948 int rc;
949 struct tfp_send_msg_parms parms = { 0 };
950 struct hwrm_tf_em_delete_input req = { 0 };
951 struct hwrm_tf_em_delete_output resp = { 0 };
952 uint16_t flags;
953 uint8_t fw_session_id;
954 struct tf_dev_info *dev;
955 struct tf_session *tfs;
956
957 /* Retrieve the session information */
958 rc = tf_session_get_session_internal(tfp, &tfs);
959 if (rc) {
960 TFP_DRV_LOG(ERR,
961 "%s: Failed to lookup session, rc:%s\n",
962 tf_dir_2_str(em_parms->dir),
963 strerror(-rc));
964 return rc;
965 }
966
967 /* Retrieve the device information */
968 rc = tf_session_get_device(tfs, &dev);
969 if (rc) {
970 TFP_DRV_LOG(ERR,
971 "%s: Failed to lookup device, rc:%s\n",
972 tf_dir_2_str(em_parms->dir),
973 strerror(-rc));
974 return rc;
975 }
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(em_parms->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
989 flags = (em_parms->dir == TF_DIR_TX ?
990 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
991 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
992 req.flags = tfp_cpu_to_le_16(flags);
993 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
994
995 parms.tf_type = HWRM_TF_EM_DELETE;
996 parms.req_data = (uint32_t *)&req;
997 parms.req_size = sizeof(req);
998 parms.resp_data = (uint32_t *)&resp;
999 parms.resp_size = sizeof(resp);
1000 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1001
1002 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1003 &parms);
1004 if (rc)
1005 return rc;
1006
1007 em_parms->index = tfp_le_to_cpu_16(resp.em_index);
1008
1009 return 0;
1010 }
1011
1012 int
tf_msg_move_em_entry(struct tf * tfp,struct tf_move_em_entry_parms * em_parms)1013 tf_msg_move_em_entry(struct tf *tfp,
1014 struct tf_move_em_entry_parms *em_parms)
1015 {
1016 int rc;
1017 struct tfp_send_msg_parms parms = { 0 };
1018 struct hwrm_tf_em_move_input req = { 0 };
1019 struct hwrm_tf_em_move_output resp = { 0 };
1020 uint16_t flags;
1021 uint8_t fw_session_id;
1022 struct tf_dev_info *dev;
1023 struct tf_session *tfs;
1024
1025 /* Retrieve the session information */
1026 rc = tf_session_get_session_internal(tfp, &tfs);
1027 if (rc) {
1028 TFP_DRV_LOG(ERR,
1029 "%s: Failed to lookup session, rc:%s\n",
1030 tf_dir_2_str(em_parms->dir),
1031 strerror(-rc));
1032 return rc;
1033 }
1034
1035 /* Retrieve the device information */
1036 rc = tf_session_get_device(tfs, &dev);
1037 if (rc) {
1038 TFP_DRV_LOG(ERR,
1039 "%s: Failed to lookup device, rc:%s\n",
1040 tf_dir_2_str(em_parms->dir),
1041 strerror(-rc));
1042 return rc;
1043 }
1044
1045 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1046 if (rc) {
1047 TFP_DRV_LOG(ERR,
1048 "%s: Unable to lookup FW id, rc:%s\n",
1049 tf_dir_2_str(em_parms->dir),
1050 strerror(-rc));
1051 return rc;
1052 }
1053
1054 /* Populate the request */
1055 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1056
1057 flags = (em_parms->dir == TF_DIR_TX ?
1058 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
1059 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
1060 req.flags = tfp_cpu_to_le_16(flags);
1061 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
1062 req.new_index = tfp_cpu_to_le_32(em_parms->new_index);
1063
1064 parms.tf_type = HWRM_TF_EM_MOVE;
1065 parms.req_data = (uint32_t *)&req;
1066 parms.req_size = sizeof(req);
1067 parms.resp_data = (uint32_t *)&resp;
1068 parms.resp_size = sizeof(resp);
1069 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1070
1071 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1072 &parms);
1073 if (rc)
1074 return rc;
1075
1076 em_parms->index = tfp_le_to_cpu_16(resp.em_index);
1077
1078 return 0;
1079 }
1080
tf_msg_ext_em_ctxt_mem_alloc(struct tf * tfp,struct hcapi_cfa_em_table * tbl,uint64_t * dma_addr,uint32_t * page_lvl,uint32_t * page_size)1081 int tf_msg_ext_em_ctxt_mem_alloc(struct tf *tfp,
1082 struct hcapi_cfa_em_table *tbl,
1083 uint64_t *dma_addr,
1084 uint32_t *page_lvl,
1085 uint32_t *page_size)
1086 {
1087 struct tfp_send_msg_parms parms = { 0 };
1088 struct hwrm_tf_ctxt_mem_alloc_input req = {0};
1089 struct hwrm_tf_ctxt_mem_alloc_output resp = {0};
1090 uint32_t mem_size_k;
1091 int rc = 0;
1092 struct tf_dev_info *dev;
1093 struct tf_session *tfs;
1094 uint32_t fw_se_id;
1095
1096 /* Retrieve the session information */
1097 rc = tf_session_get_session_internal(tfp, &tfs);
1098 if (rc) {
1099 TFP_DRV_LOG(ERR,
1100 "Failed to lookup session, rc:%s\n",
1101 strerror(-rc));
1102 return rc;
1103 }
1104
1105 /* Retrieve the device information */
1106 rc = tf_session_get_device(tfs, &dev);
1107 if (rc) {
1108 TFP_DRV_LOG(ERR,
1109 "Failed to lookup device, rc:%s\n",
1110 strerror(-rc));
1111 return rc;
1112 }
1113 /* Retrieve the session information */
1114 fw_se_id = tfs->session_id.internal.fw_session_id;
1115
1116 if (tbl->num_entries && tbl->entry_size) {
1117 /* unit: kbytes */
1118 mem_size_k = (tbl->num_entries / TF_KILOBYTE) * tbl->entry_size;
1119 req.mem_size = tfp_cpu_to_le_32(mem_size_k);
1120 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1121 parms.tf_type = HWRM_TF_CTXT_MEM_ALLOC;
1122 parms.req_data = (uint32_t *)&req;
1123 parms.req_size = sizeof(req);
1124 parms.resp_data = (uint32_t *)&resp;
1125 parms.resp_size = sizeof(resp);
1126 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1127 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1128 if (rc) {
1129 TFP_DRV_LOG(ERR, "Failed ext_em_alloc error rc:%s\n",
1130 strerror(-rc));
1131 return rc;
1132 }
1133
1134 *dma_addr = tfp_le_to_cpu_64(resp.page_dir);
1135 *page_lvl = resp.page_level;
1136 *page_size = resp.page_size;
1137 }
1138
1139 return rc;
1140 }
1141
tf_msg_ext_em_ctxt_mem_free(struct tf * tfp,uint32_t mem_size_k,uint64_t dma_addr,uint8_t page_level,uint8_t page_size)1142 int tf_msg_ext_em_ctxt_mem_free(struct tf *tfp,
1143 uint32_t mem_size_k,
1144 uint64_t dma_addr,
1145 uint8_t page_level,
1146 uint8_t page_size)
1147 {
1148 struct tfp_send_msg_parms parms = { 0 };
1149 struct hwrm_tf_ctxt_mem_free_input req = {0};
1150 struct hwrm_tf_ctxt_mem_free_output resp = {0};
1151 int rc = 0;
1152 struct tf_dev_info *dev;
1153 struct tf_session *tfs;
1154 uint32_t fw_se_id;
1155
1156 /* Retrieve the session information */
1157 rc = tf_session_get_session_internal(tfp, &tfs);
1158 if (rc) {
1159 TFP_DRV_LOG(ERR,
1160 "Failed to lookup session, rc:%s\n",
1161 strerror(-rc));
1162 return rc;
1163 }
1164
1165 /* Retrieve the device information */
1166 rc = tf_session_get_device(tfs, &dev);
1167 if (rc) {
1168 TFP_DRV_LOG(ERR,
1169 "Failed to lookup device, rc:%s\n",
1170 strerror(-rc));
1171 return rc;
1172 }
1173 /* Retrieve the session information */
1174 fw_se_id = tfs->session_id.internal.fw_session_id;
1175
1176 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1177 req.mem_size = tfp_cpu_to_le_32(mem_size_k);
1178 req.page_dir = tfp_cpu_to_le_64(dma_addr);
1179 req.page_level = page_level;
1180 req.page_size = page_size;
1181 parms.tf_type = HWRM_TF_CTXT_MEM_FREE;
1182 parms.req_data = (uint32_t *)&req;
1183 parms.req_size = sizeof(req);
1184 parms.resp_data = (uint32_t *)&resp;
1185 parms.resp_size = sizeof(resp);
1186 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1187 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1188
1189 return rc;
1190 }
1191
1192 int
tf_msg_em_mem_rgtr(struct tf * tfp,int page_lvl,int page_size,uint64_t dma_addr,uint16_t * ctx_id)1193 tf_msg_em_mem_rgtr(struct tf *tfp,
1194 int page_lvl,
1195 int page_size,
1196 uint64_t dma_addr,
1197 uint16_t *ctx_id)
1198 {
1199 int rc;
1200 struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
1201 struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
1202 struct tfp_send_msg_parms parms = { 0 };
1203 struct tf_dev_info *dev;
1204 struct tf_session *tfs;
1205 uint32_t fw_se_id;
1206
1207 /* Retrieve the session information */
1208 rc = tf_session_get_session_internal(tfp, &tfs);
1209 if (rc) {
1210 TFP_DRV_LOG(ERR,
1211 "Failed to lookup session, rc:%s\n",
1212 strerror(-rc));
1213 return rc;
1214 }
1215
1216 /* Retrieve the device information */
1217 rc = tf_session_get_device(tfs, &dev);
1218 if (rc) {
1219 TFP_DRV_LOG(ERR,
1220 "Failed to lookup device, rc:%s\n",
1221 strerror(-rc));
1222 return rc;
1223 }
1224 fw_se_id = tfs->session_id.internal.fw_session_id;
1225
1226 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1227 req.page_level = page_lvl;
1228 req.page_size = page_size;
1229 req.page_dir = tfp_cpu_to_le_64(dma_addr);
1230
1231 parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
1232 parms.req_data = (uint32_t *)&req;
1233 parms.req_size = sizeof(req);
1234 parms.resp_data = (uint32_t *)&resp;
1235 parms.resp_size = sizeof(resp);
1236 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1237
1238 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1239 &parms);
1240 if (rc)
1241 return rc;
1242
1243 *ctx_id = tfp_le_to_cpu_16(resp.ctx_id);
1244
1245 return rc;
1246 }
1247
1248 int
tf_msg_em_mem_unrgtr(struct tf * tfp,uint16_t * ctx_id)1249 tf_msg_em_mem_unrgtr(struct tf *tfp,
1250 uint16_t *ctx_id)
1251 {
1252 int rc;
1253 struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
1254 struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0};
1255 struct tfp_send_msg_parms parms = { 0 };
1256 struct tf_dev_info *dev;
1257 struct tf_session *tfs;
1258 uint32_t fw_se_id;
1259
1260 /* Retrieve the session information */
1261 rc = tf_session_get_session_internal(tfp, &tfs);
1262 if (rc) {
1263 TFP_DRV_LOG(ERR,
1264 "Failed to lookup session, rc:%s\n",
1265 strerror(-rc));
1266 return rc;
1267 }
1268
1269 /* Retrieve the device information */
1270 rc = tf_session_get_device(tfs, &dev);
1271 if (rc) {
1272 TFP_DRV_LOG(ERR,
1273 "Failed to lookup device, rc:%s\n",
1274 strerror(-rc));
1275 return rc;
1276 }
1277
1278 fw_se_id = tfs->session_id.internal.fw_session_id;
1279 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1280
1281 req.ctx_id = tfp_cpu_to_le_32(*ctx_id);
1282
1283 parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR;
1284 parms.req_data = (uint32_t *)&req;
1285 parms.req_size = sizeof(req);
1286 parms.resp_data = (uint32_t *)&resp;
1287 parms.resp_size = sizeof(resp);
1288 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1289
1290 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1291 &parms);
1292 return rc;
1293 }
1294
1295 int
tf_msg_em_qcaps(struct tf * tfp,int dir,struct tf_em_caps * em_caps)1296 tf_msg_em_qcaps(struct tf *tfp,
1297 int dir,
1298 struct tf_em_caps *em_caps)
1299 {
1300 int rc;
1301 struct hwrm_tf_ext_em_qcaps_input req = {0};
1302 struct hwrm_tf_ext_em_qcaps_output resp = { 0 };
1303 uint32_t flags;
1304 struct tfp_send_msg_parms parms = { 0 };
1305 struct tf_dev_info *dev;
1306 struct tf_session *tfs;
1307 uint32_t fw_se_id;
1308
1309 /* Retrieve the session information */
1310 rc = tf_session_get_session_internal(tfp, &tfs);
1311 if (rc) {
1312 TFP_DRV_LOG(ERR,
1313 "%s: Failed to lookup session, rc:%s\n",
1314 tf_dir_2_str(dir),
1315 strerror(-rc));
1316 return rc;
1317 }
1318 fw_se_id = tfs->session_id.internal.fw_session_id;
1319
1320 /* Retrieve the device information */
1321 rc = tf_session_get_device(tfs, &dev);
1322 if (rc) {
1323 TFP_DRV_LOG(ERR,
1324 "%s: Failed to lookup device, rc:%s\n",
1325 tf_dir_2_str(dir),
1326 strerror(-rc));
1327 return rc;
1328 }
1329
1330 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX :
1331 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX);
1332 req.flags = tfp_cpu_to_le_32(flags);
1333
1334 parms.tf_type = HWRM_TF_EXT_EM_QCAPS;
1335 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1336 parms.req_data = (uint32_t *)&req;
1337 parms.req_size = sizeof(req);
1338 parms.resp_data = (uint32_t *)&resp;
1339 parms.resp_size = sizeof(resp);
1340 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1341
1342 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1343 &parms);
1344 if (rc)
1345 return rc;
1346
1347 em_caps->supported = tfp_le_to_cpu_32(resp.supported);
1348 em_caps->max_entries_supported =
1349 tfp_le_to_cpu_32(resp.max_entries_supported);
1350 em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size);
1351 em_caps->record_entry_size =
1352 tfp_le_to_cpu_16(resp.record_entry_size);
1353 em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size);
1354
1355 return rc;
1356 }
1357
1358 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)1359 tf_msg_em_cfg(struct tf *tfp,
1360 uint32_t num_entries,
1361 uint16_t key0_ctx_id,
1362 uint16_t key1_ctx_id,
1363 uint16_t record_ctx_id,
1364 uint16_t efc_ctx_id,
1365 uint8_t flush_interval,
1366 int dir)
1367 {
1368 int rc;
1369 struct hwrm_tf_ext_em_cfg_input req = {0};
1370 struct hwrm_tf_ext_em_cfg_output resp = {0};
1371 uint32_t flags;
1372 struct tfp_send_msg_parms parms = { 0 };
1373 struct tf_dev_info *dev;
1374 struct tf_session *tfs;
1375
1376 /* Retrieve the session information */
1377 rc = tf_session_get_session_internal(tfp, &tfs);
1378 if (rc) {
1379 TFP_DRV_LOG(ERR,
1380 "%s: Failed to lookup session, rc:%s\n",
1381 tf_dir_2_str(dir),
1382 strerror(-rc));
1383 return rc;
1384 }
1385
1386 /* Retrieve the device information */
1387 rc = tf_session_get_device(tfs, &dev);
1388 if (rc) {
1389 TFP_DRV_LOG(ERR,
1390 "%s: Failed to lookup device, rc:%s\n",
1391 tf_dir_2_str(dir),
1392 strerror(-rc));
1393 return rc;
1394 }
1395
1396 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1397 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1398 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
1399
1400 req.flags = tfp_cpu_to_le_32(flags);
1401 req.num_entries = tfp_cpu_to_le_32(num_entries);
1402
1403 req.flush_interval = flush_interval;
1404
1405 req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id);
1406 req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id);
1407 req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id);
1408 req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id);
1409
1410 parms.tf_type = HWRM_TF_EXT_EM_CFG;
1411 parms.req_data = (uint32_t *)&req;
1412 parms.req_size = sizeof(req);
1413 parms.resp_data = (uint32_t *)&resp;
1414 parms.resp_size = sizeof(resp);
1415 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1416
1417 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1418 &parms);
1419 return rc;
1420 }
1421
1422 int
tf_msg_ext_em_cfg(struct tf * tfp,struct tf_tbl_scope_cb * tbl_scope_cb,uint32_t st_buckets,uint8_t flush_interval,enum tf_dir dir)1423 tf_msg_ext_em_cfg(struct tf *tfp,
1424 struct tf_tbl_scope_cb *tbl_scope_cb,
1425 uint32_t st_buckets,
1426 uint8_t flush_interval,
1427 enum tf_dir dir)
1428 {
1429 struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir];
1430 struct hcapi_cfa_em_table *lkup_tbl, *act_tbl;
1431 struct hwrm_tf_ext_em_cfg_input req = {0};
1432 struct hwrm_tf_ext_em_cfg_output resp = {0};
1433 struct tfp_send_msg_parms parms = { 0 };
1434 uint32_t flags;
1435 struct tf_dev_info *dev;
1436 struct tf_session *tfs;
1437 uint32_t fw_se_id;
1438 int rc;
1439
1440 /* Retrieve the session information */
1441 rc = tf_session_get_session_internal(tfp, &tfs);
1442 if (rc) {
1443 TFP_DRV_LOG(ERR,
1444 "%s: Failed to lookup session, rc:%s\n",
1445 tf_dir_2_str(dir),
1446 strerror(-rc));
1447 return rc;
1448 }
1449
1450 /* Retrieve the device information */
1451 rc = tf_session_get_device(tfs, &dev);
1452 if (rc) {
1453 TFP_DRV_LOG(ERR,
1454 "%s: Failed to lookup device, rc:%s\n",
1455 tf_dir_2_str(dir),
1456 strerror(-rc));
1457 return rc;
1458 }
1459 fw_se_id = tfs->session_id.internal.fw_session_id;
1460
1461 lkup_tbl = &ctxp->em_tables[TF_EM_LKUP_TABLE];
1462 act_tbl = &ctxp->em_tables[TF_ACTION_TABLE];
1463 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1464 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1465 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD;
1466
1467 req.flags = tfp_cpu_to_le_32(flags);
1468 req.num_entries = tfp_cpu_to_le_32(act_tbl->num_entries);
1469 req.lkup_static_buckets = tfp_cpu_to_le_32(st_buckets);
1470 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id);
1471 req.flush_interval = flush_interval;
1472 req.action_ctx_id = tfp_cpu_to_le_16(act_tbl->ctx_id);
1473 req.action_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id);
1474 req.lkup_ctx_id = tfp_cpu_to_le_16(lkup_tbl->ctx_id);
1475 req.lkup_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id);
1476
1477 req.enables = (HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_CTX_ID |
1478 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_TBL_SCOPE |
1479 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_CTX_ID |
1480 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_TBL_SCOPE |
1481 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_STATIC_BUCKETS |
1482 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_NUM_ENTRIES);
1483
1484 parms.tf_type = HWRM_TF_EXT_EM_CFG;
1485 parms.req_data = (uint32_t *)&req;
1486 parms.req_size = sizeof(req);
1487 parms.resp_data = (uint32_t *)&resp;
1488 parms.resp_size = sizeof(resp);
1489 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1490
1491 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1492 &parms);
1493 return rc;
1494 }
1495
1496 int
tf_msg_em_op(struct tf * tfp,int dir,uint16_t op)1497 tf_msg_em_op(struct tf *tfp,
1498 int dir,
1499 uint16_t op)
1500 {
1501 int rc;
1502 struct hwrm_tf_ext_em_op_input req = {0};
1503 struct hwrm_tf_ext_em_op_output resp = {0};
1504 uint32_t flags;
1505 struct tfp_send_msg_parms parms = { 0 };
1506 struct tf_dev_info *dev;
1507 struct tf_session *tfs;
1508
1509 /* Retrieve the session information */
1510 rc = tf_session_get_session_internal(tfp, &tfs);
1511 if (rc) {
1512 TFP_DRV_LOG(ERR,
1513 "%s: Failed to lookup session, rc:%s\n",
1514 tf_dir_2_str(dir),
1515 strerror(-rc));
1516 return rc;
1517 }
1518
1519 /* Retrieve the device information */
1520 rc = tf_session_get_device(tfs, &dev);
1521 if (rc) {
1522 TFP_DRV_LOG(ERR,
1523 "%s: Failed to lookup device, rc:%s\n",
1524 tf_dir_2_str(dir),
1525 strerror(-rc));
1526 return rc;
1527 }
1528
1529 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
1530 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
1531 req.flags = tfp_cpu_to_le_32(flags);
1532 req.op = tfp_cpu_to_le_16(op);
1533
1534 parms.tf_type = HWRM_TF_EXT_EM_OP;
1535 parms.req_data = (uint32_t *)&req;
1536 parms.req_size = sizeof(req);
1537 parms.resp_data = (uint32_t *)&resp;
1538 parms.resp_size = sizeof(resp);
1539 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1540
1541 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1542 &parms);
1543 return rc;
1544 }
1545
1546 int
tf_msg_tcam_entry_set(struct tf * tfp,struct tf_dev_info * dev,struct tf_tcam_set_parms * parms)1547 tf_msg_tcam_entry_set(struct tf *tfp,
1548 struct tf_dev_info *dev,
1549 struct tf_tcam_set_parms *parms)
1550 {
1551 int rc;
1552 struct tfp_send_msg_parms mparms = { 0 };
1553 struct hwrm_tf_tcam_set_input req = { 0 };
1554 struct hwrm_tf_tcam_set_output resp = { 0 };
1555 struct tf_msg_dma_buf buf = { 0 };
1556 uint8_t *data = NULL;
1557 int data_size = 0;
1558 uint8_t fw_session_id;
1559 struct tf_session *tfs;
1560
1561 /* Retrieve the session information */
1562 rc = tf_session_get_session_internal(tfp, &tfs);
1563 if (rc) {
1564 TFP_DRV_LOG(ERR,
1565 "Failed to lookup session, rc:%s\n",
1566 strerror(-rc));
1567 return rc;
1568 }
1569
1570 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1571 if (rc) {
1572 TFP_DRV_LOG(ERR,
1573 "%s: Unable to lookup FW id, rc:%s\n",
1574 tf_dir_2_str(parms->dir),
1575 strerror(-rc));
1576 return rc;
1577 }
1578
1579 /* Populate the request */
1580 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1581 req.type = parms->hcapi_type;
1582 req.idx = tfp_cpu_to_le_16(parms->idx);
1583 if (parms->dir == TF_DIR_TX)
1584 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
1585
1586 req.key_size = parms->key_size;
1587 req.mask_offset = parms->key_size;
1588 /* Result follows after key and mask, thus multiply by 2 */
1589 req.result_offset = 2 * parms->key_size;
1590 req.result_size = parms->result_size;
1591 data_size = 2 * req.key_size + req.result_size;
1592
1593 if (data_size <= TF_PCI_BUF_SIZE_MAX) {
1594 /* use pci buffer */
1595 data = &req.dev_data[0];
1596 } else {
1597 /* use dma buffer */
1598 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
1599 rc = tf_msg_alloc_dma_buf(&buf, data_size);
1600 if (rc)
1601 goto cleanup;
1602 data = buf.va_addr;
1603 tfp_memcpy(&req.dev_data[0],
1604 &buf.pa_addr,
1605 sizeof(buf.pa_addr));
1606 }
1607
1608 tfp_memcpy(&data[0], parms->key, parms->key_size);
1609 tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
1610 tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
1611
1612 mparms.tf_type = HWRM_TF_TCAM_SET;
1613 mparms.req_data = (uint32_t *)&req;
1614 mparms.req_size = sizeof(req);
1615 mparms.resp_data = (uint32_t *)&resp;
1616 mparms.resp_size = sizeof(resp);
1617 mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1618
1619 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1620 &mparms);
1621
1622 cleanup:
1623 tf_msg_free_dma_buf(&buf);
1624
1625 return rc;
1626 }
1627
1628 int
tf_msg_tcam_entry_get(struct tf * tfp,struct tf_dev_info * dev,struct tf_tcam_get_parms * parms)1629 tf_msg_tcam_entry_get(struct tf *tfp,
1630 struct tf_dev_info *dev,
1631 struct tf_tcam_get_parms *parms)
1632 {
1633 int rc;
1634 struct tfp_send_msg_parms mparms = { 0 };
1635 struct hwrm_tf_tcam_get_input req = { 0 };
1636 struct hwrm_tf_tcam_get_output resp = { 0 };
1637 uint8_t fw_session_id;
1638 struct tf_session *tfs;
1639
1640 /* Retrieve the session information */
1641 rc = tf_session_get_session_internal(tfp, &tfs);
1642 if (rc) {
1643 TFP_DRV_LOG(ERR,
1644 "Failed to lookup session, rc:%s\n",
1645 strerror(-rc));
1646 return rc;
1647 }
1648
1649 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1650 if (rc) {
1651 TFP_DRV_LOG(ERR,
1652 "%s: Unable to lookup FW id, rc:%s\n",
1653 tf_dir_2_str(parms->dir),
1654 strerror(-rc));
1655 return rc;
1656 }
1657
1658 /* Populate the request */
1659 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1660 req.type = parms->hcapi_type;
1661 req.idx = tfp_cpu_to_le_16(parms->idx);
1662 if (parms->dir == TF_DIR_TX)
1663 req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX;
1664
1665 mparms.tf_type = HWRM_TF_TCAM_GET;
1666 mparms.req_data = (uint32_t *)&req;
1667 mparms.req_size = sizeof(req);
1668 mparms.resp_data = (uint32_t *)&resp;
1669 mparms.resp_size = sizeof(resp);
1670 mparms.mailbox = dev->ops->tf_dev_get_mailbox();
1671
1672 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1673 &mparms);
1674
1675 if (rc != 0)
1676 return rc;
1677
1678 if (parms->key_size < resp.key_size ||
1679 parms->result_size < resp.result_size) {
1680 rc = -EINVAL;
1681 TFP_DRV_LOG(ERR,
1682 "%s: Key buffer(%d) is smaller than the key(%d), rc:%s\n",
1683 tf_dir_2_str(parms->dir),
1684 parms->key_size,
1685 resp.key_size,
1686 strerror(-rc));
1687 return rc;
1688 }
1689 parms->key_size = resp.key_size;
1690 parms->result_size = resp.result_size;
1691 tfp_memcpy(parms->key, resp.dev_data, resp.key_size);
1692 tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size);
1693 tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size);
1694
1695 return 0;
1696 }
1697
1698 int
tf_msg_tcam_entry_free(struct tf * tfp,struct tf_dev_info * dev,struct tf_tcam_free_parms * in_parms)1699 tf_msg_tcam_entry_free(struct tf *tfp,
1700 struct tf_dev_info *dev,
1701 struct tf_tcam_free_parms *in_parms)
1702 {
1703 int rc;
1704 struct hwrm_tf_tcam_free_input req = { 0 };
1705 struct hwrm_tf_tcam_free_output resp = { 0 };
1706 struct tfp_send_msg_parms parms = { 0 };
1707 uint8_t fw_session_id;
1708 struct tf_session *tfs;
1709
1710 /* Retrieve the session information */
1711 rc = tf_session_get_session_internal(tfp, &tfs);
1712 if (rc) {
1713 TFP_DRV_LOG(ERR,
1714 "Failed to lookup session, rc:%s\n",
1715 strerror(-rc));
1716 return rc;
1717 }
1718
1719 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1720 if (rc) {
1721 TFP_DRV_LOG(ERR,
1722 "%s: Unable to lookup FW id, rc:%s\n",
1723 tf_dir_2_str(in_parms->dir),
1724 strerror(-rc));
1725 return rc;
1726 }
1727
1728 /* Populate the request */
1729 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1730 req.type = in_parms->hcapi_type;
1731 req.count = 1;
1732 req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
1733 if (in_parms->dir == TF_DIR_TX)
1734 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
1735
1736 parms.tf_type = HWRM_TF_TCAM_FREE;
1737 parms.req_data = (uint32_t *)&req;
1738 parms.req_size = sizeof(req);
1739 parms.resp_data = (uint32_t *)&resp;
1740 parms.resp_size = sizeof(resp);
1741 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1742
1743 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1744 &parms);
1745 return rc;
1746 }
1747
1748 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)1749 tf_msg_set_tbl_entry(struct tf *tfp,
1750 enum tf_dir dir,
1751 uint16_t hcapi_type,
1752 uint16_t size,
1753 uint8_t *data,
1754 uint32_t index)
1755 {
1756 int rc;
1757 struct hwrm_tf_tbl_type_set_input req = { 0 };
1758 struct hwrm_tf_tbl_type_set_output resp = { 0 };
1759 struct tfp_send_msg_parms parms = { 0 };
1760 uint8_t fw_session_id;
1761 struct tf_dev_info *dev;
1762 struct tf_session *tfs;
1763
1764 RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_tbl_type_set_input) !=
1765 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET);
1766
1767 /* Retrieve the session information */
1768 rc = tf_session_get_session_internal(tfp, &tfs);
1769 if (rc) {
1770 TFP_DRV_LOG(ERR,
1771 "%s: Failed to lookup session, rc:%s\n",
1772 tf_dir_2_str(dir),
1773 strerror(-rc));
1774 return rc;
1775 }
1776
1777 /* Retrieve the device information */
1778 rc = tf_session_get_device(tfs, &dev);
1779 if (rc) {
1780 TFP_DRV_LOG(ERR,
1781 "%s: Failed to lookup device, rc:%s\n",
1782 tf_dir_2_str(dir),
1783 strerror(-rc));
1784 return rc;
1785 }
1786
1787 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1788 if (rc) {
1789 TFP_DRV_LOG(ERR,
1790 "%s: Unable to lookup FW id, rc:%s\n",
1791 tf_dir_2_str(dir),
1792 strerror(-rc));
1793 return rc;
1794 }
1795
1796 /* Populate the request */
1797 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1798 req.flags = tfp_cpu_to_le_16(dir);
1799 req.type = tfp_cpu_to_le_32(hcapi_type);
1800 req.size = tfp_cpu_to_le_16(size);
1801 req.index = tfp_cpu_to_le_32(index);
1802
1803 /* Check for data size conformity */
1804 if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
1805 rc = -EINVAL;
1806 TFP_DRV_LOG(ERR,
1807 "%s: Invalid parameters for msg type, rc:%s\n",
1808 tf_dir_2_str(dir),
1809 strerror(-rc));
1810 return rc;
1811 }
1812
1813 tfp_memcpy(&req.data,
1814 data,
1815 size);
1816
1817 parms.tf_type = HWRM_TF_TBL_TYPE_SET;
1818 parms.req_data = (uint32_t *)&req;
1819 parms.req_size = sizeof(req);
1820 parms.resp_data = (uint32_t *)&resp;
1821 parms.resp_size = sizeof(resp);
1822 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1823
1824 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1825 &parms);
1826 if (rc)
1827 return rc;
1828
1829 return 0;
1830 }
1831
1832 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,bool clear_on_read)1833 tf_msg_get_tbl_entry(struct tf *tfp,
1834 enum tf_dir dir,
1835 uint16_t hcapi_type,
1836 uint16_t size,
1837 uint8_t *data,
1838 uint32_t index,
1839 bool clear_on_read)
1840 {
1841 int rc;
1842 struct hwrm_tf_tbl_type_get_input req = { 0 };
1843 struct hwrm_tf_tbl_type_get_output resp = { 0 };
1844 struct tfp_send_msg_parms parms = { 0 };
1845 uint8_t fw_session_id;
1846 struct tf_dev_info *dev;
1847 struct tf_session *tfs;
1848 uint32_t flags = 0;
1849
1850 /* Retrieve the session information */
1851 rc = tf_session_get_session_internal(tfp, &tfs);
1852 if (rc) {
1853 TFP_DRV_LOG(ERR,
1854 "%s: Failed to lookup session, rc:%s\n",
1855 tf_dir_2_str(dir),
1856 strerror(-rc));
1857 return rc;
1858 }
1859
1860 /* Retrieve the device information */
1861 rc = tf_session_get_device(tfs, &dev);
1862 if (rc) {
1863 TFP_DRV_LOG(ERR,
1864 "%s: Failed to lookup device, rc:%s\n",
1865 tf_dir_2_str(dir),
1866 strerror(-rc));
1867 return rc;
1868 }
1869
1870 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1871 if (rc) {
1872 TFP_DRV_LOG(ERR,
1873 "%s: Unable to lookup FW id, rc:%s\n",
1874 tf_dir_2_str(dir),
1875 strerror(-rc));
1876 return rc;
1877 }
1878 flags = (dir == TF_DIR_TX ?
1879 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_TX :
1880 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_RX);
1881
1882 if (clear_on_read)
1883 flags |= HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_CLEAR_ON_READ;
1884
1885 /* Populate the request */
1886 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1887 req.flags = tfp_cpu_to_le_16(flags);
1888 req.type = tfp_cpu_to_le_32(hcapi_type);
1889 req.index = tfp_cpu_to_le_32(index);
1890
1891 parms.tf_type = HWRM_TF_TBL_TYPE_GET;
1892 parms.req_data = (uint32_t *)&req;
1893 parms.req_size = sizeof(req);
1894 parms.resp_data = (uint32_t *)&resp;
1895 parms.resp_size = sizeof(resp);
1896 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1897
1898 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
1899 &parms);
1900 if (rc)
1901 return rc;
1902
1903 /*
1904 * The response will be 64 bytes long, the response size will
1905 * be in words (16). All we can test for is that the response
1906 * size is < to the requested size.
1907 */
1908 if ((tfp_le_to_cpu_32(resp.size) * 4) < size)
1909 return -EINVAL;
1910
1911 /*
1912 * Copy the requested number of bytes
1913 */
1914 tfp_memcpy(data,
1915 &resp.data,
1916 size);
1917
1918 return 0;
1919 }
1920
1921 /* HWRM Tunneled messages */
1922
1923 int
tf_msg_get_global_cfg(struct tf * tfp,struct tf_global_cfg_parms * params)1924 tf_msg_get_global_cfg(struct tf *tfp,
1925 struct tf_global_cfg_parms *params)
1926 {
1927 int rc = 0;
1928 struct tfp_send_msg_parms parms = { 0 };
1929 struct hwrm_tf_global_cfg_get_input req = { 0 };
1930 struct hwrm_tf_global_cfg_get_output resp = { 0 };
1931 uint32_t flags = 0;
1932 uint8_t fw_session_id;
1933 uint16_t resp_size = 0;
1934 struct tf_dev_info *dev;
1935 struct tf_session *tfs;
1936
1937 /* Retrieve the session information */
1938 rc = tf_session_get_session_internal(tfp, &tfs);
1939 if (rc) {
1940 TFP_DRV_LOG(ERR,
1941 "%s: Failed to lookup session, rc:%s\n",
1942 tf_dir_2_str(params->dir),
1943 strerror(-rc));
1944 return rc;
1945 }
1946
1947 /* Retrieve the device information */
1948 rc = tf_session_get_device(tfs, &dev);
1949 if (rc) {
1950 TFP_DRV_LOG(ERR,
1951 "%s: Failed to lookup device, rc:%s\n",
1952 tf_dir_2_str(params->dir),
1953 strerror(-rc));
1954 return rc;
1955 }
1956
1957 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
1958 if (rc) {
1959 TFP_DRV_LOG(ERR,
1960 "%s: Unable to lookup FW id, rc:%s\n",
1961 tf_dir_2_str(params->dir),
1962 strerror(-rc));
1963 return rc;
1964 }
1965
1966 flags = (params->dir == TF_DIR_TX ?
1967 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX :
1968 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX);
1969
1970 /* Populate the request */
1971 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
1972 req.flags = tfp_cpu_to_le_32(flags);
1973 req.type = tfp_cpu_to_le_32(params->type);
1974 req.offset = tfp_cpu_to_le_32(params->offset);
1975 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
1976
1977 parms.tf_type = HWRM_TF_GLOBAL_CFG_GET;
1978 parms.req_data = (uint32_t *)&req;
1979 parms.req_size = sizeof(req);
1980 parms.resp_data = (uint32_t *)&resp;
1981 parms.resp_size = sizeof(resp);
1982 parms.mailbox = dev->ops->tf_dev_get_mailbox();
1983
1984 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
1985 if (rc != 0)
1986 return rc;
1987
1988 /* Verify that we got enough buffer to return the requested data */
1989 resp_size = tfp_le_to_cpu_16(resp.size);
1990 if (resp_size < params->config_sz_in_bytes)
1991 return -EINVAL;
1992
1993 if (params->config)
1994 tfp_memcpy(params->config,
1995 resp.data,
1996 resp_size);
1997 else
1998 return -EFAULT;
1999
2000 return 0;
2001 }
2002
2003 int
tf_msg_set_global_cfg(struct tf * tfp,struct tf_global_cfg_parms * params)2004 tf_msg_set_global_cfg(struct tf *tfp,
2005 struct tf_global_cfg_parms *params)
2006 {
2007 int rc = 0;
2008 struct tfp_send_msg_parms parms = { 0 };
2009 struct hwrm_tf_global_cfg_set_input req = { 0 };
2010 struct hwrm_tf_global_cfg_set_output resp = { 0 };
2011 uint32_t flags = 0;
2012 uint8_t fw_session_id;
2013 struct tf_dev_info *dev;
2014 struct tf_session *tfs;
2015
2016 /* Retrieve the session information */
2017 rc = tf_session_get_session_internal(tfp, &tfs);
2018 if (rc) {
2019 TFP_DRV_LOG(ERR,
2020 "%s: Failed to lookup session, rc:%s\n",
2021 tf_dir_2_str(params->dir),
2022 strerror(-rc));
2023 return rc;
2024 }
2025
2026 /* Retrieve the device information */
2027 rc = tf_session_get_device(tfs, &dev);
2028 if (rc) {
2029 TFP_DRV_LOG(ERR,
2030 "%s: Failed to lookup device, rc:%s\n",
2031 tf_dir_2_str(params->dir),
2032 strerror(-rc));
2033 return rc;
2034 }
2035
2036 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2037 if (rc) {
2038 TFP_DRV_LOG(ERR,
2039 "%s: Unable to lookup FW id, rc:%s\n",
2040 tf_dir_2_str(params->dir),
2041 strerror(-rc));
2042 return rc;
2043 }
2044
2045 flags = (params->dir == TF_DIR_TX ?
2046 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX :
2047 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX);
2048
2049 /* Populate the request */
2050 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2051 req.flags = tfp_cpu_to_le_32(flags);
2052 req.type = tfp_cpu_to_le_32(params->type);
2053 req.offset = tfp_cpu_to_le_32(params->offset);
2054
2055 /* Check for data size conformity */
2056 if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) {
2057 rc = -EINVAL;
2058 TFP_DRV_LOG(ERR,
2059 "%s: Invalid parameters for msg type, rc:%s\n",
2060 tf_dir_2_str(params->dir),
2061 strerror(-rc));
2062 return rc;
2063 }
2064
2065 tfp_memcpy(req.data, params->config,
2066 params->config_sz_in_bytes);
2067
2068 /* Only set mask if pointer is provided
2069 */
2070 if (params->config_mask) {
2071 tfp_memcpy(req.mask,
2072 params->config_mask,
2073 params->config_sz_in_bytes);
2074 }
2075
2076 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes);
2077
2078 parms.tf_type = HWRM_TF_GLOBAL_CFG_SET;
2079 parms.req_data = (uint32_t *)&req;
2080 parms.req_size = sizeof(req);
2081 parms.resp_data = (uint32_t *)&resp;
2082 parms.resp_size = sizeof(resp);
2083 parms.mailbox = dev->ops->tf_dev_get_mailbox();
2084
2085 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2086
2087 if (rc != 0)
2088 return rc;
2089
2090 return 0;
2091 }
2092
2093 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,bool clear_on_read)2094 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
2095 enum tf_dir dir,
2096 uint16_t hcapi_type,
2097 uint32_t starting_idx,
2098 uint16_t num_entries,
2099 uint16_t entry_sz_in_bytes,
2100 uint64_t physical_mem_addr,
2101 bool clear_on_read)
2102 {
2103 int rc;
2104 struct tfp_send_msg_parms parms = { 0 };
2105 struct hwrm_tf_tbl_type_bulk_get_input req = { 0 };
2106 struct hwrm_tf_tbl_type_bulk_get_output resp = { 0 };
2107 int data_size = 0;
2108 uint8_t fw_session_id;
2109 struct tf_dev_info *dev;
2110 struct tf_session *tfs;
2111 uint32_t flags = 0;
2112
2113 /* Retrieve the session information */
2114 rc = tf_session_get_session(tfp, &tfs);
2115 if (rc) {
2116 TFP_DRV_LOG(ERR,
2117 "%s: Failed to lookup session, rc:%s\n",
2118 tf_dir_2_str(dir),
2119 strerror(-rc));
2120 return rc;
2121 }
2122
2123 /* Retrieve the device information */
2124 rc = tf_session_get_device(tfs, &dev);
2125 if (rc) {
2126 TFP_DRV_LOG(ERR,
2127 "%s: Failed to lookup device, rc:%s\n",
2128 tf_dir_2_str(dir),
2129 strerror(-rc));
2130 return rc;
2131 }
2132
2133 rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
2134 if (rc) {
2135 TFP_DRV_LOG(ERR,
2136 "%s: Unable to lookup FW id, rc:%s\n",
2137 tf_dir_2_str(dir),
2138 strerror(-rc));
2139 return rc;
2140 }
2141 flags = (dir == TF_DIR_TX ?
2142 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_TX :
2143 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_RX);
2144
2145 if (clear_on_read)
2146 flags |= HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_CLEAR_ON_READ;
2147
2148 /* Populate the request */
2149 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
2150 req.flags = tfp_cpu_to_le_16(flags);
2151 req.type = tfp_cpu_to_le_32(hcapi_type);
2152 req.start_index = tfp_cpu_to_le_32(starting_idx);
2153 req.num_entries = tfp_cpu_to_le_32(num_entries);
2154
2155 data_size = num_entries * entry_sz_in_bytes;
2156
2157 req.host_addr = tfp_cpu_to_le_64(physical_mem_addr);
2158
2159 parms.tf_type = HWRM_TF_TBL_TYPE_BULK_GET;
2160 parms.req_data = (uint32_t *)&req;
2161 parms.req_size = sizeof(req);
2162 parms.resp_data = (uint32_t *)&resp;
2163 parms.resp_size = sizeof(resp);
2164 parms.mailbox = dev->ops->tf_dev_get_mailbox();
2165
2166 rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
2167 &parms);
2168 if (rc)
2169 return rc;
2170
2171 /* Verify that we got enough buffer to return the requested data */
2172 if (tfp_le_to_cpu_32(resp.size) != data_size)
2173 return -EINVAL;
2174
2175 return 0;
2176 }
2177
2178 int
tf_msg_get_if_tbl_entry(struct tf * tfp,struct tf_if_tbl_get_parms * params)2179 tf_msg_get_if_tbl_entry(struct tf *tfp,
2180 struct tf_if_tbl_get_parms *params)
2181 {
2182 int rc = 0;
2183 struct tfp_send_msg_parms parms = { 0 };
2184 struct hwrm_tf_if_tbl_get_input req = { 0 };
2185 struct hwrm_tf_if_tbl_get_output resp = { 0 };
2186 uint32_t flags = 0;
2187 struct tf_dev_info *dev;
2188 struct tf_session *tfs;
2189
2190 /* Retrieve the session information */
2191 rc = tf_session_get_session(tfp, &tfs);
2192 if (rc) {
2193 TFP_DRV_LOG(ERR,
2194 "%s: Failed to lookup session, rc:%s\n",
2195 tf_dir_2_str(params->dir),
2196 strerror(-rc));
2197 return rc;
2198 }
2199
2200 /* Retrieve the device information */
2201 rc = tf_session_get_device(tfs, &dev);
2202 if (rc) {
2203 TFP_DRV_LOG(ERR,
2204 "%s: Failed to lookup device, rc:%s\n",
2205 tf_dir_2_str(params->dir),
2206 strerror(-rc));
2207 return rc;
2208 }
2209
2210 flags = (params->dir == TF_DIR_TX ?
2211 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX :
2212 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX);
2213
2214 /* Populate the request */
2215 req.fw_session_id =
2216 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
2217 req.flags = flags;
2218 req.type = params->hcapi_type;
2219 req.index = tfp_cpu_to_le_16(params->idx);
2220 req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes);
2221
2222 parms.tf_type = HWRM_TF_IF_TBL_GET;
2223 parms.req_data = (uint32_t *)&req;
2224 parms.req_size = sizeof(req);
2225 parms.resp_data = (uint32_t *)&resp;
2226 parms.resp_size = sizeof(resp);
2227 parms.mailbox = dev->ops->tf_dev_get_mailbox();
2228
2229 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2230
2231 if (rc != 0)
2232 return rc;
2233
2234 tfp_memcpy(¶ms->data[0], resp.data, req.size);
2235
2236 return 0;
2237 }
2238
2239 int
tf_msg_set_if_tbl_entry(struct tf * tfp,struct tf_if_tbl_set_parms * params)2240 tf_msg_set_if_tbl_entry(struct tf *tfp,
2241 struct tf_if_tbl_set_parms *params)
2242 {
2243 int rc = 0;
2244 struct tfp_send_msg_parms parms = { 0 };
2245 struct hwrm_tf_if_tbl_set_input req = { 0 };
2246 struct hwrm_tf_if_tbl_get_output resp = { 0 };
2247 uint32_t flags = 0;
2248 struct tf_dev_info *dev;
2249 struct tf_session *tfs;
2250
2251 /* Retrieve the session information */
2252 rc = tf_session_get_session(tfp, &tfs);
2253 if (rc) {
2254 TFP_DRV_LOG(ERR,
2255 "%s: Failed to lookup session, rc:%s\n",
2256 tf_dir_2_str(params->dir),
2257 strerror(-rc));
2258 return rc;
2259 }
2260
2261 /* Retrieve the device information */
2262 rc = tf_session_get_device(tfs, &dev);
2263 if (rc)
2264 return rc;
2265
2266 flags = (params->dir == TF_DIR_TX ?
2267 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX :
2268 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX);
2269
2270 /* Populate the request */
2271 req.fw_session_id =
2272 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
2273 req.flags = flags;
2274 req.type = params->hcapi_type;
2275 req.index = tfp_cpu_to_le_32(params->idx);
2276 req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes);
2277 tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes);
2278
2279 parms.tf_type = HWRM_TF_IF_TBL_SET;
2280 parms.req_data = (uint32_t *)&req;
2281 parms.req_size = sizeof(req);
2282 parms.resp_data = (uint32_t *)&resp;
2283 parms.resp_size = sizeof(resp);
2284 parms.mailbox = dev->ops->tf_dev_get_mailbox();
2285
2286 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms);
2287
2288 if (rc != 0)
2289 return rc;
2290
2291 return 0;
2292 }
2293
2294 int
tf_msg_get_version(struct bnxt * bp,struct tf_dev_info * dev,struct tf_get_version_parms * params)2295 tf_msg_get_version(struct bnxt *bp,
2296 struct tf_dev_info *dev,
2297 struct tf_get_version_parms *params)
2298
2299 {
2300 int rc;
2301 struct hwrm_tf_version_get_input req = { 0 };
2302 struct hwrm_tf_version_get_output resp = { 0 };
2303 struct tfp_send_msg_parms parms = { 0 };
2304
2305 /* Populate the request */
2306 parms.tf_type = HWRM_TF_VERSION_GET,
2307 parms.req_data = (uint32_t *)&req;
2308 parms.req_size = sizeof(req);
2309 parms.resp_data = (uint32_t *)&resp;
2310 parms.resp_size = sizeof(resp);
2311 parms.mailbox = dev->ops->tf_dev_get_mailbox();
2312
2313 rc = tfp_send_msg_direct(bp,
2314 &parms);
2315
2316 params->major = resp.major;
2317 params->minor = resp.minor;
2318 params->update = resp.update;
2319
2320 dev->ops->tf_dev_map_hcapi_caps(resp.dev_caps_cfg,
2321 ¶ms->dev_ident_caps,
2322 ¶ms->dev_tcam_caps,
2323 ¶ms->dev_tbl_caps,
2324 ¶ms->dev_em_caps);
2325
2326 return rc;
2327 }
2328